backup-rcopy/hosts/scripts/pgsql_backup.sh

469 lines
14 KiB
Bash
Executable File

#!/usr/bin/env bash
## - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
## -
## - assuming your remote user is called "back", you have
## - to give sudoer rights to him as follow:
## -
## - visudo (edits /etc/sudoers file)
## -
## - add lines:
## - back ALL = (postgres) NOPASSWD: /usr/bin/psql
## - back ALL = (postgres) NOPASSWD: /usr/bin/pg_dump
## - back ALL = (postgres) NOPASSWD: /usr/bin/pg_dumpall
## -
## - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
err_Log=${LOCK_DIR}/pgsql.err.log
> $err_Log
## - load functions
## -
. $rcopy_functions_file
# --------------------------------------------------- #
# -------------------- Variable --------------------- #
#
_backupDestArchiveDir="${script_backup_dir}/PostgreSQL"
if [ ! -d $_backupDestArchiveDir ]; then
mkdir -p $_backupDestArchiveDir
fi
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
psql=`$ssh ${ssh_user}@$srcHost which psql`
pg_dump=`$ssh ${ssh_user}@$srcHost which pg_dump`
pg_dumpall=`$ssh ${ssh_user}@$srcHost which pg_dumpall`
sudo=`$ssh ${ssh_user}@$srcHost which sudo`
su=`$ssh ${ssh_user}@$srcHost which su`
ssh_options="-o BatchMode=yes -o ConnectTimeout=360"
if [[ -z "$psql" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'psql' command on remote host '$srcHost'."
psql="/usr/bin/psql"
echolog "\t Set 'psql' to '$psql' manually."
fi
if [[ -z "$pg_dump" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'pg_dump' command on remote host '$srcHost'."
pg_dump="/usr/bin/pg_dump"
echolog "\t Set 'pg_dump' to '$pg_dump' manually."
fi
if [[ -z "$pg_dumpall" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'pg_dumpall' command on remote host '$srcHost'."
pg_dumpall="/usr/bin/pg_dumpall"
echolog "\t Set 'pg_dumpall' to '$pg_dumpall' manually."
fi
if [[ -z "$sudo" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'sudo' command on remote host '$srcHost'."
sudo="$(which sudo)"
[[ -z "$sudo" ]] && sudo="/usr/bin/sudo"
echolog "\t Set 'sudo' to '$sudo' manually."
fi
if [[ -z "$su" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'su' command on remote host '$srcHost'."
su="$(which su)"
[[ -z "$su" ]] && su="/usr/bin/su"
echolog "\t Set 'su' to '$su' manually."
fi
else
psql="$(which psql)"
pg_dump="$(which pg_dump)"
pg_dumpall="$(which pg_dumpall)"
if [[ -z "$psql" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'psql' command on localhost. Try another way to determin it.."
if [[ -x "/usr/local/pgsql/bin/psql" ]] ; then
psql="/usr/local/pgsql/bin/psql"
elif [[ -x "/usr/bin/psql" ]] ; then
psql="/usr/bin/psql"
fi
if [[ -n "$psql" ]]; then
echolog "\t Found executable 'psql' command: $psql ."
else
print_error_stdout "Determin 'psql' command failed on localhost."
echolog ""
echolog "\t[ERROR] Determin 'psql' command failed on localhost."
fi
fi
if [[ -z "$pg_dump" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'pg_dump' command on localhost. Try another way to determin it.."
if [[ -x "/usr/local/pgsql/bin/pg_dump" ]] ; then
pg_dump="/usr/local/pgsql/bin/pg_dump"
elif [[ -x "/usr/bin/pg_dump" ]] ; then
pg_dump="/usr/bin/pg_dump"
fi
if [[ -n "$pg_dump" ]]; then
echolog "\t Found executable 'pg_dump' command: $pg_dump ."
else
print_error_stdout "Determin 'pg_dump' command failed on localhost."
echolog ""
echolog "\t[ERROR] Determin 'pg_dump' command failed on localhost."
fi
fi
if [[ -z "$pg_dumpall" ]] ; then
echolog ""
echolog "\t[WARN]: Cannot determin 'pg_dumpall' command on localhost. Try another way to determin it.."
if [[ -x "/usr/local/pgsql/bin/pg_dumpall" ]] ; then
pg_dumpall="/usr/local/pgsql/bin/pg_dumpall"
elif [[ -x "/usr/bin/pg_dumpall" ]] ; then
pg_dumpall="/usr/bin/pg_dumpall"
fi
if [[ -n "$pg_dumpall" ]]; then
echolog "\t Found executable 'pg_dumpall' command: $pg_dumpall ."
else
print_error_stdout "Determin 'pg_dumpall' command failed on localhost."
echolog ""
echolog "\t[ERROR] Determin 'pg_dumpall' command failed on localhost."
fi
fi
fi
err_msg="Determin existing databases failed"
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
DATABASES="$($ssh ${ssh_user}@$srcHost "$sudo -u $pgsql_user $psql -lt" \
| $grep -v -e"^$" | $awk '{print$1}' 2> /tmp/error)"
retval=$?
else
DATABASES="$($su - $pgsql_user -c "$psql -lt" | $grep -v -e"^$" | $awk '{print$1}' 2> /tmp/error)"
retval=$?
fi
if [ "$retval" != "0" ]; then
print_error_stdout "${err_msg}:\n $(cat $err_Log)"
echolog ""
echolog "\t[ERROR] ${err_msg}\n\t $(cat $err_Log)\n"
fi
# ------------------ Ende Variable ------------------ #
# --------------------------------------------------- #
echolog ""
if $ARCHIVE ;then
## ---------------------------
## - Backup PostgreSQL's Roles
## -
info_msg="save PostgreSQL's Roles"
echononl "\t$info_msg"
## - begin timestamp
## -
b_timestamp=`$date +"%s"`
filedate=`$date +"%Y-%m-%d-%H%M"`
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
$(
$ssh $ssh_options ${ssh_user}@$srcHost "$sudo -u $pgsql_user $pg_dumpall -g -c " \
> ${_backupDestArchiveDir}/PostreSQL_Roles-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
else
$(
$su $pgsql_user -c "$pg_dumpall -g -c" \
> ${_backupDestArchiveDir}/PostreSQL_Roles-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
fi
err_msg="Cannot save PostgreSQL's Roles"
keep_backup_on_error=false
if [ "$retval" = 0 ];then
[ -z $pgsql_gzip ] && pgsql_gzip=false
if $pgsql_gzip ; then
$gzip ${_backupDestArchiveDir}/PostreSQL_Roles-${filedate}.sql 2> $err_Log
retval=$?
err_msg="Cannot gzip PostreSQL_Roles-${filedate}.sql"
keep_backup_on_error=true
fi
fi
## - end timestamp
## -
e_timestamp=`$date +"%s"`
## - determin duration
## -
_time=`expr $e_timestamp - $b_timestamp`
t_h=`expr $_time / 60 / 60`
t_rest_h=`expr $_time - $t_h \\* 60 \\* 60`
t_m=`expr $t_rest_h / 60`
t_s=`expr $t_rest_h - $t_m \\* 60`
duration=""
if [ $t_h -gt 0 ]; then
duration="$t_h h : $t_m min : $t_s sec"
elif [ $t_m -gt 0 ];then
duration="$t_m min : $t_s sec"
else
duration="$t_s sec"
fi
## - look about errors..
## -
if [ "$retval" != "0" ]; then
print_error_stdout "${err_msg}:\n $(cat $err_Log)"
echolog ""
echolog "\t[ERROR] ${err_msg} [ $duration ]\n\t`$cat $err_Log`\n"
if ! $keep_backup_on_error ; then
rm -f ${_backupDestArchiveDir}/PostreSQL_Roles-${filedate}.sql
fi
else
## - print durations right-aligned
## -
[ -z $right_tabstop ] && right_tabstop=65
_tmp_string="${info_msg}${duration}"
_strlen=${#_tmp_string}
_count_blank=`expr $right_tabstop - $_strlen`
_str_blanks=""
while [ $_count_blank -gt 1 ]; do
_str_blanks="$_str_blanks "
_count_blank=`expr $_count_blank - 1`
done
echononl "$_str_blanks"
echolog " [ $duration ]"
fi
## - END: Backup PostgreSQL's Roles
## ---------------------------------
## -----------------------------------
## - Create Database Creation SQL file
## -
info_msg="create Database Creation SQL file"
echononl "\t$info_msg"
## - begin timestamp
## -
b_timestamp=`$date +"%s"`
filedate=`$date +"%Y-%m-%d-%H%M"`
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
$(
$ssh $ssh_options ${ssh_user}@$srcHost "$sudo -u $pgsql_user $pg_dumpall -s " | \
grep -e "^CREATE DATABASE" \
> ${_backupDestArchiveDir}/PostreSQL_Create_Databases-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
else
$(
$su - $pgsql_user -c "$pg_dumpall -s" | \
grep -e "^CREATE DATABASE" \
> ${_backupDestArchiveDir}/PostreSQL_Create_Databases-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
fi
err_msg="Cannot create Database Creation SQL file"
keep_backup_on_error=false
if [ "$retval" = 0 ];then
[ -z $pgsql_gzip ] && pgsql_gzip=false
if $pgsql_gzip ; then
$gzip ${_backupDestArchiveDir}/PostreSQL_Create_Databases-${filedate}.sql 2> $err_Log
retval=$?
err_msg="Cannot gzip PostreSQL_Databases-${filedate}.sql"
keep_backup_on_error=true
fi
fi
## - end timestamp
## -
e_timestamp=`$date +"%s"`
## - determin duration
## -
_time=`expr $e_timestamp - $b_timestamp`
t_h=`expr $_time / 60 / 60`
t_rest_h=`expr $_time - $t_h \\* 60 \\* 60`
t_m=`expr $t_rest_h / 60`
t_s=`expr $t_rest_h - $t_m \\* 60`
duration=""
if [ $t_h -gt 0 ]; then
duration="$t_h h : $t_m min : $t_s sec"
elif [ $t_m -gt 0 ];then
duration="$t_m min : $t_s sec"
else
duration="$t_s sec"
fi
## - look about errors..
## -
if [ "$retval" != "0" ]; then
print_error_stdout "${err_msg}:\n $(cat $err_Log)"
echolog ""
echolog "\t[ERROR] ${err_msg} [ $duration ]\n\t`$cat $err_Log`\n"
if ! $keep_backup_on_error ; then
rm -f ${_backupDestArchiveDir}/PostreSQL_Create_Databases-${filedate}.sql
fi
else
## - print durations right-aligned
## -
[ -z $right_tabstop ] && right_tabstop=65
_tmp_string="${info_msg}${duration}"
_strlen=${#_tmp_string}
_count_blank=`expr $right_tabstop - $_strlen`
_str_blanks=""
while [ $_count_blank -gt 1 ]; do
_str_blanks="$_str_blanks "
_count_blank=`expr $_count_blank - 1`
done
echononl "$_str_blanks"
echolog " [ $duration ]"
fi
## - End: Create Database Creation SQL file
## ----------------------------------------
## - backup all databases..
## -
for i in $DATABASES ; do
if [ "$i" = "template0" ]; then
continue
fi
if [ "$i" = ":" -o "$i" = "|" ]; then
continue
fi
filedate=`$date +"%Y-%m-%d-%H%M"`
## - begin timestamp
## -
b_timestamp=`$date +"%s"`
if [ "$destHost" = "localhost" ]; then
if [ ! -d ${_backupDestArchiveDir}/${i} ] ; then
$mkdir -p ${_backupDestArchiveDir}/${i}
fi
fi
info_msg="save database $i.."
echononl "\t$info_msg"
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
$(
$ssh $ssh_options ${ssh_user}@$srcHost "$sudo -u $pgsql_user $pg_dump -c $i" \
> ${_backupDestArchiveDir}/${i}/${i}-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
else
$(
$su - $pgsql_user -c "$pg_dump -c $i" \
> ${_backupDestArchiveDir}/${i}/${i}-${filedate}.sql 2> $err_Log
exit $?
)
retval=$?
fi
err_msg="Cannot save database \"$i\""
keep_backup_on_error=false
if [ "$retval" = 0 ];then
[ -z $pgsql_gzip ] && pgsql_gzip=false
if $pgsql_gzip ; then
$gzip ${_backupDestArchiveDir}/${i}/${i}-${filedate}.sql 2> $err_Log
retval=$?
err_msg="Cannot gzip database \"$i\""
keep_backup_on_error=true
fi
fi
## - end timestamp
## -
e_timestamp=`$date +"%s"`
## - determin duration
## -
_time=`expr $e_timestamp - $b_timestamp`
t_h=`expr $_time / 60 / 60`
t_rest_h=`expr $_time - $t_h \\* 60 \\* 60`
t_m=`expr $t_rest_h / 60`
t_s=`expr $t_rest_h - $t_m \\* 60`
duration=""
if [ $t_h -gt 0 ]; then
duration="$t_h h : $t_m min : $t_s sec"
elif [ $t_m -gt 0 ];then
duration="$t_m min : $t_s sec"
else
duration="$t_s sec"
fi
## - look about errors..
## -
if [ "$retval" != "0" ]; then
print_error_stdout "${err_msg}:\n $(cat $err_Log)"
echolog ""
echolog "\t[ERROR] ${err_msg} [ $duration ]\n\t`$cat $err_Log`\n"
if ! $keep_backup_on_error ; then
rm -f ${_backupDestArchiveDir}/${i}/${i}-${filedate}.sql
fi
continue
else
## - print durations right-aligned
## -
[ -z $right_tabstop ] && right_tabstop=65
_tmp_string="${info_msg}${duration}"
_strlen=${#_tmp_string}
_count_blank=`expr $right_tabstop - $_strlen`
_str_blanks=""
while [ $_count_blank -gt 1 ]; do
_str_blanks="$_str_blanks "
_count_blank=`expr $_count_blank - 1`
done
echononl "$_str_blanks"
echolog " [ $duration ]"
fi
done
if [ $srcHost != "localhost" ] || $_via_ssh_tunnel ;then
$ssh ${ssh_user}@$srcHost "$sudo -u $pgsql_user $psql -lt" > ${_backupDestArchiveDir}/database-list_${filedate}.txt
else
$su - $pgsql_user -c "$psql -lt" > ${_backupDestArchiveDir}/database-list_${filedate}.txt
fi
else
echolog "\tARCHIVE is set to $ARCHIVE. So nothing to do."
fi
echolog ""
## - remove all files older than $days days..
## -
$find $_backupDestArchiveDir -type f -mtime +${days} -exec rm {} \;