#!/bin/sh if [ "$(whoami)" != "postgres" ]; then echo " only postgres user can run this Script" exit fi # # Postgresql backup script # # Version # | # -- 1.1.2 # # Description # | # -- A bourne shell script that automates the backup, vacuum and # analyze of databases running on a postgresql server. # # # Requirements # | # -- grep, awk, sed, echo, gzip, chmod, touch, mkdir, date, psql, # test, expr, dirname, find, tail, du, pg_dump, vacuum_db # # Installation # | # -- Set the path and shell you wish to use for this script on the # | first line of this file. Keep in mind this script has only been # | tested on the shells above in the "Tested on" section. # | # -- Set the configuration variables below in the configuration # | section to appropriate values. # | # -- Remove the line at the end of the configuration section so that # | the script will run. # | # -- Now save the script and perform the following command: # | # | chmod x ./pg_backup.sh # | # -- Now run the configuration test: # | # | ./pg_backup.sh configtest # | # | This will test the configuration details. # | # -- Once you have done that add similiar entries given as examples # below to the crontab (`crontab -e`) without the the _first_ # # characters. # # # Run a backup, vacuum and analyze every morning at 03:00 # 00 03 * * * /server/postgres/pg_backup.sh bva > /dev/null 2>&1 # # Run a backup at 09:00, 12:00, 15:00, 18:00 everyday # 00 09 * * * /server/postgres/pg_backup.sh b > /dev/null 2>&1 # 00 12 * * * /server/postgres/pg_backup.sh b > /dev/null 2>&1 # 00 15 * * * /server/postgres/pg_backup.sh b > /dev/null 2>&1 # 00 18 * * * /server/postgres/pg_backup.sh b > /dev/null 2>&1 # # Restoration # | # -- Restoration can be performed by using psql or pg_restore. # | Here are two examples: # | # | a) If the backup is plain text: # | # | Firstly gunzip your backup file (if it was gzipped). # | # | gunzip backup_file.gz # | psql -U postgres database < backup_file # | # | b) If the backup is not plain text: # | # | Firstly gunzip your backup file (if it was gzipped). # | # | gunzip backup_file # | pg_restore -d database -F {c|t} backup_file # | # | Note: {c|t} is the format the database was backed up as. # | # | pg_restore -d database -F t backup_file_tar # | # -- Refer to the following url for more pg_restore help: # # http://www.postgresql.org/idocs/index.php?app-pgrestore.html # # To Do List # 1. db_connectivity() is BROKEN, if the script can not create a # connection to postmaster it should die and write to the logfile # that it could not connect. # 2. make configtest check for every required binary # ######################################################################## # Start configuration # ######################################################################## # ################## # Authentication # ################## # # Postgresql username to perform backups under. postgresql_username="postgres" # Postgresql password for the Postgresql username (if required). postgresql_password="password" # Postgresql hostname to connect to. postgresql_hostname="localhost" ################## # Locations # ################## # # Location to place backups. location_backup_dir="/var/lib/pgsql/data/backup" # Location to place the pg_backup.sh logfile. location_logfile="/var/lib/pgsql/data/backup/dump.log" # Location of the psql binaries. location_binaries="/usr/bin" ################## # Permissions # ################## # # Permissions for the backup location. permissions_backup_dir="0755" # Permissions for the backup files. permissions_backup_file="0644" # Permissions for the backup logfile. permissions_backup_log="0644" ################## # Other options # ################## # # Databases to exclude from the backup process (separated by a space) exclusions="template" # Backup format # | # -- p = plain text : psql database < backup_file # -- t = tar : pg_restore -F t -d database backup_file # -- c = custom : pg_restore -F c -d database backup_file # backup_format="c" # Backup large objects backup_large_objects="yes" # Gzip the backups backup_gzip="yes" # Date format for the backup # | # -- %d-%m-%Y = DD-MM-YYYY # -- %Y-%m-%d = YYYY-MM-DD # -- %A-%b-%Y = Tuesday-Sep-2001 # -- %A-%Y-%d-%m-%Y = Tuesday-2001-18-09-2001 # | # -- For more date formats type: # # date --help # backup_date_format="%Y-%m-%d" # You must comment out the line below before using this script #echo "You must set all values in the configuration section in this file then run ./pg_backup.sh configtest before using this script" && exit 1 ######################################################################## # End configuration # ######################################################################## # ################# # Variables # ################# # version="1.1.2" current_time=`date %H:%M` date_info=`date $backup_date_format` PGUSER="$postgresql_username" PGPASSWORD="$postgresql_password" PATH="$PATH:/bin:/usr/bin" # Export the variables export PGUSER PGPASSWORD PATH ################# # Checking # ################# # # Check the backup format if [ "$backup_format" = "p" ]; then backup_type="Plain text SQL" backup_args="-F $backup_format" elif [ "$backup_format" = "t" ]; then backup_type="Tar" if [ "$backup_large_objects" = "yes" ]; then backup_args="-b -F $backup_format" else backup_args="-F $backup_format" fi elif [ "$backup_format" = "c" ]; then backup_type="Custom" if [ "$backup_large_objects" = "yes" ]; then backup_args="-b -F $backup_format" else backup_args="-F $backup_format" fi else backup_format="c" backup_args="-F $backup_format" backup_type="Custom" fi ################# # Functions # ################# # # Obtain a list of available databases with reference to the user # defined exclusions db_connectivity() { tmp=`echo -n '(';echo -n $exclusions | sed 's/\ /\|/g'; echo -n ')'` if [ "$exclusions" = "" ]; then databases=`$location_binaries/psql -h $postgresql_hostname -U $postgresql_username -q -c "\l" template1 | sed -n 4,/\eof/p | grep -v rows\) | awk {'print $1'} || echo "Database connection could not be established at $timeinfo" >> $location_logfile` else databases=`$location_binaries/psql -h $postgresql_hostname -U $postgresql_username -q -c "\l" template1 | sed -n 4,/\eof/p | grep -v rows\) | grep -Ev $tmp | awk {'print $1'} || echo "Database connection could not be established at $timeinfo" >> $location_logfile` fi } # Setup the permissions according to the Permissions section set_permissions() { # Make the backup directories and secure them. mkdir -m $permissions_backup_dir -p "$location_backup_dir/`date %B-%Y`/$date_info" # Touch the log file touch "$location_logfile" # Make the backup tree chmod -f $permissions_backup_log "$location_logfile" chmod -f $permissions_backup_dir "$location_backup_dir" chmod -f $permissions_backup_dir "$location_backup_dir/`date %B-%Y`" chmod -f $permissions_backup_dir "$location_backup_dir/`date %B-%Y`/$date_info" } # Run backup run_b() { for i in $databases; do start_time=`date ' %s'` timeinfo=`date ' %T %x'` "$location_binaries/pg_dump" $backup_args -h $postgresql_hostname $i > "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" if [ "$backup_gzip" = "yes" ]; then gzip "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup.gz" else chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" fi finish_time=`date ' %s'` duration=`expr $finish_time - $start_time` echo "Backup complete (duration $duration seconds) at $timeinfo for schedule $current_time on database: $i, format: $backup_type" >> $location_logfile echo "Backup file name:"$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup done exit 1 } # Run backup and vacuum run_bv() { for i in $databases; do start_time=`date ' %s'` timeinfo=`date ' %T %x'` "$location_binaries/vacuumdb" -h $postgresql_hostname -U $postgresql_username $i >/dev/null 2>&1 "$location_binaries/pg_dump" $backup_args -h $postgresql_hostname $i > "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" if [ "$backup_gzip" = "yes" ]; then gzip "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup.gz" else chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" fi finish_time=`date ' %s'` duration=`expr $finish_time - $start_time` echo "Backup and Vacuum complete (duration $duration seconds) at $timeinfo for schedule $current_time on database: $i, format: $backup_type" >> $location_logfile done exit 1 } # Run backup, vacuum and analyze run_bva() { for i in $databases; do start_time=`date ' %s'` timeinfo=`date ' %T %x'` "$location_binaries/vacuumdb" -z -h $postgresql_hostname -U $postgresql_username $i >/dev/null 2>&1 "$location_binaries/pg_dump" $backup_args -h $postgresql_hostname $i > "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" if [ "$backup_gzip" = "yes" ]; then gzip "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup.gz" else chmod $permissions_backup_file "$location_backup_dir/`date %B-%Y`/$date_info/$current_time-postgresql_database-$i-backup" fi finish_time=`date ' %s'` duration=`expr $finish_time - $start_time` echo "Backup, Vacuum and Analyze complete (duration $duration seconds) at $timeinfo for schedule $current_time on database: $i, format: $backup_type" >> $location_logfile done exit 1 } # Run vacuum run_v() { for i in $databases; do start_time=`date ' %s'` timeinfo=`date ' %T %x'` "$location_binaries/vacuumdb" -h $postgresql_hostname -U $postgresql_username $i >/dev/null 2>&1 finish_time=`date ' %s'` duration=`expr $finish_time - $start_time` echo "Vacuum complete (duration $duration seconds) at $timeinfo for schedule $current_time on database: $i " >> $location_logfile done exit 1 } # Run vacuum and analyze run_va() { for i in $databases; do start_time=`date ' %s'` timeinfo=`date ' %T %x'` "$location_binaries/vacuumdb" -z -h $postgresql_hostname -U $postgresql_username $i >/dev/null 2>&1 finish_time=`date ' %s'` duration=`expr $finish_time - $start_time` echo "Vacuum and Analyze complete (duration $duration seconds) at $timeinfo for schedule $current_time on database: $i " >> $location_logfile done exit 1 } # Print information regarding available backups print_info() { echo "Postgresql backup script version $version" echo "" echo "Available backups:" echo "" if [ ! -d $location_backup_dir ] ; then echo "There are currently no available backups" echo "" exit 0 else for i in `find "$location_backup_dir" -type d -maxdepth 2`; do echo "$i `du -h \"$i\" | tail -n 1 | awk {'print $1'}`" #for j in `ls "$location_backup_dir/$i"`; do # echo " $j `du -h \"$location_backup_dir/$i/$j\" | tail -n 1 | awk {'print $1'}`" #done done echo "" fi exit 1 } # Print configuration test print_configtest() { echo "Postgresql backup script version $version" echo "" echo "Configuration test..." echo "" # Check database connectivity information echo -n "Database hostname : " echo "$postgresql_hostname" echo -n "Database username : " echo "$postgresql_username" echo -n "Database connectivity : " $location_binaries/psql -h $postgresql_hostname -U $postgresql_username -q -c "select now()" template1 > /dev/null 2>&1 && echo "Yes" || echo "Connection could not be established..." # Backup information echo "" echo "Backup information:" echo "" echo -n "Backup format : " if [ "$backup_format" = "p" ]; then echo "Plain text SQL" elif [ "$backup_format" = "t" ]; then echo "Tar" else echo "Custom" fi echo -n "Backup large objects : " if [ "$backup_large_objects" = "yes" ]; then echo "Yes" else echo "No" fi echo -n "Gzip backups : " if [ "$backup_gzip" = "yes" ]; then echo "Yes" else echo "No" fi echo -n "Backup date format : $date_info" echo "" # File locations echo -n "Backup directory : " echo "$location_backup_dir" echo -n "Backup logfile : " echo "$location_logfile" echo -n "Postgresql binaries : " echo "$location_binaries" # Backup file permissions echo -n "Backup directory permissions : " echo "$permissions_backup_dir" echo -n "Backup file permissions : " echo "$permissions_backup_file" echo -n "Backup log permissions : " echo "$permissions_backup_log" # Databases that will be backed up echo -n "Databases that will be backed up : " echo "" for i in $databases; do echo " $i" done # Databases that will not be backed up echo -n "Databases that will not be backed up :" echo "" if [ "$exclusions" = "" ]; then echo " none" else for i in $exclusions; do echo " $i" done echo "" fi # Check if the backups location is writable echo "Checking permissions:" echo "" echo -n "Write access : $location_backup_dir: " # Needed to create/write to the dump location" test -w "$location_backup_dir" && echo "Yes" || echo "No" # Check if the logfile location is writable echo -n "Write access : $location_logfile: " # Needed to create/write to this scripts logfile" if [ ! -x $location_logfile ] ; then test -w `dirname "$location_logfile"` && echo "Yes" || echo "No" else test -w "$location_logfile" && echo "Yes" || echo "No" fi # Check if the binaries are executable echo -n "Execute access : $location_binaries/psql: " test -x $location_binaries/psql && echo "Yes" || echo "No" echo -n "Execute access : $location_binaries/pg_dump: " test -x $location_binaries/pg_dump && echo "Yes" || echo "No" echo -n "Execute access : $location_binaries/vacuumdb: " test -x $location_binaries/vacuumdb && echo "Yes" || echo "No" echo "" exit 1 } # Print help print_help() { echo "Postgresql backup script version $version" echo "" echo "Usage: $0 [options]" echo "" echo "Options:" echo " b, Backup ALL databases" echo " bv, Backup and Vacuum ALL databases" echo " bva, Backup, Vacuum and Analyze ALL databases" echo " v, Vacuum ALL databases" echo " va, Vacuum and Analyze ALL databases" echo " info, Information regarding all available backups" echo " configtest, Configuration test" echo " help, This message" echo "" echo "Report bugs to <support@dbceo.com >." exit 1 } case "$1" in # Run backup b) db_connectivity set_permissions run_b exit 1 ;; # Run backup and vacuum bv) db_connectivity set_permissions run_bv exit 1 ;; # Run backup, vacuum and analyze bva) db_connectivity set_permissions run_bva exit 1 ;; # Run vacuum v) db_connectivity set_permissions run_v exit 1 ;; # Run vacuum and analyze va) db_connectivity set_permissions run_va exit 1 ;; # Print info info) set_permissions print_info exit 1 ;; # Print configtest configtest) db_connectivity set_permissions print_configtest exit 1 ;; # Default *) print_help exit 1 ;; esac |
PostgreSQL Database >