#!/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 {} \;