Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
postgresql_backup_recovery [2019/05/28 09:13] – [Appendix] andonovj | postgresql_backup_recovery [2025/05/12 15:48] (current) – andonovj | ||
---|---|---|---|
Line 7: | Line 7: | ||
- | ======Backup====== | + | ======Backup |
Basically there are two ways how a PostgreSQL database can be backed up: | Basically there are two ways how a PostgreSQL database can be backed up: | ||
- | * Physically | + | * [[PostgreSQL_backup_recovery_physical|Physical]] |
- | * Logically | + | * [[PostgreSQL_backup_recovery_logical|Logical]] |
+ | * [[postgresql_barman_configuration| Barman]] | ||
+ | * [[postgresql_pgbackrest_configuration | Pgbackrest]] | ||
- | ===== Physical ===== | ||
- | Base backup is done in 3 steps | ||
- | |||
- | - Ensure that WAL archiving is enabled and working. | ||
- | - Connect to the database as a superuser and issue the command: | ||
- | - SELECT pg_start_backup(' | ||
- | - Perform a backup (either via rsync or cp or others) | ||
- | - SELECT pg_stop_backup(); | ||
- | - | ||
- | ===Manually=== | ||
- | <sxh bash> | ||
- | -bash-4.1$ psql -c " | ||
- | | ||
- | ----------------- | ||
- | | ||
- | (1 row) | ||
- | |||
- | rsync -cva --inplace --exclude=*pg_xlog* / | ||
- | [email protected]' | ||
- | sending incremental file list | ||
- | ./ | ||
- | backup_label | ||
- | postgresql.conf | ||
- | postmaster.pid | ||
- | base/13275/ | ||
- | base/ | ||
- | base/ | ||
- | global/ | ||
- | global/ | ||
- | global/ | ||
- | pg_log/ | ||
- | pg_notify/ | ||
- | pg_stat/ | ||
- | pg_stat_tmp/ | ||
- | pg_stat_tmp/ | ||
- | pg_stat_tmp/ | ||
- | pg_stat_tmp/ | ||
- | |||
- | sent 152804 bytes received 2005 bytes 20641.20 bytes/sec | ||
- | total size is 22936284 | ||
- | |||
- | -bash-4.1$ psql -c " | ||
- | NOTICE: | ||
- | | ||
- | ---------------- | ||
- | | ||
- | (1 row) | ||
- | |||
- | -bash-4.1$ | ||
- | </ | ||
- | |||
- | This will copy all files from the source folder into the destination folder, while the PostgreSQL server is running. Please do not forget to exit the backup mode. Even though it will be safe to leave it as it is. It is a good practice to finish the backup mode as soon as possible. | ||
- | |||
- | ===Automatic=== | ||
- | You can use pg_basebackup which will perform all steps automatically. | ||
- | |||
- | <sxh bash> | ||
- | -bash-4.1$ pg_basebackup -U postgres -D /backup/ | ||
- | NOTICE: | ||
- | -bash-4.1$ ls -lart | ||
- | total 128 | ||
- | dr-xr-xr-x. 23 root | ||
- | -rwxrwx---. | ||
- | -rwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | -rwxrwx---. | ||
- | drwxrwx---. | ||
- | -rw-------. | ||
- | drwxrwx---. | ||
- | -rwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | -rwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxrwx---. | ||
- | drwxr-xr-x. 20 postgres postgres | ||
- | -bash-4.1$ pwd | ||
- | /backup | ||
- | -bash-4.1$ | ||
- | </ | ||
- | |||
- | You can of course configure more sophisticated options, such as a tar file using gzip utilities. | ||
- | After the base backup is done, it a copy of the database to a specific point of time, that copy can be pushed forward (recovered) via XLOGs. | ||
- | The barman application, | ||
- | |||
- | You can also use the pg_basebackup tool to take the backup, instead of manually copying the files. This tool will do the equivalent of pg_start_backup(), | ||
- | |||
- | Some file system backup tools emit warnings or errors if the files they are trying to copy change while the copy proceeds. When taking a base backup of an active database, this situation is normal and not an error. However, you need to ensure that you can distinguish complaints of this sort from real errors. For example, some versions of rsync return a separate exit code for " | ||
- | |||
- | It is not necessary to be concerned about the amount of time elapsed between pg_start_backup and the start of the actual backup, nor between the end of the backup and pg_stop_backup; | ||
- | |||
- | |||
- | |||
- | |||
- | =====Logical===== | ||
- | Logical backup refers to simple export of a data, achieved by the pg_dump. It is important to note that logical backup cannot be used in conjunction of XLOG or other incremental features, but it is very convenient for data migration. | ||
- | |||
- | Logical backup can also be configured in many ways, as simple as to dump a particular database in SQL script file: | ||
- | |||
- | |||
- | <sxh bash> | ||
- | -bash-4.1$ pg_dump sales -C > sales.sql --Will include CREATE statements | ||
- | -bash-4.1$ | ||
- | -bash-4.1$ | ||
- | -bash-4.1$ ls -lart | ||
- | total 12 | ||
- | dr-xr-xr-x. 23 root | ||
- | drwxr-xr-x. | ||
- | -rw-r--r--. | ||
- | -bash-4.1$ head sales.sql | ||
- | -- | ||
- | -- PostgreSQL database dump | ||
- | -- | ||
- | |||
- | -- Dumped from database version 9.6.7 | ||
- | -- Dumped by pg_dump version 9.6.7 | ||
- | |||
- | SET statement_timeout = 0; | ||
- | SET lock_timeout = 0; | ||
- | SET idle_in_transaction_session_timeout = 0; | ||
- | -bash-4.1$ | ||
- | -bash-4.1$ | ||
- | </ | ||
- | |||
- | Or even, further to dump the database in a directory using 5 slaves: | ||
- | |||
- | |||
- | <sxh bash> | ||
- | -bash-4.1$ pg_dump -Fd sales -j 5 -f salesdir | ||
- | -bash-4.1$ | ||
- | -bash-4.1$ ls -lart | ||
- | total 20 | ||
- | dr-xr-xr-x. 23 root | ||
- | -rw-r--r--. | ||
- | drwx------. | ||
- | drwxr-xr-x. | ||
- | drwx------. | ||
- | -bash-4.1$ cd salesdir/ | ||
- | -bash-4.1$ ls -lart | ||
- | total 20 | ||
- | -rw-r--r--. 1 postgres postgres 2048 Mar 20 10:05 toc.dat | ||
- | -rw-r--r--. 1 postgres postgres | ||
- | -rw-r--r--. 1 postgres postgres | ||
- | drwx------. 2 postgres postgres 4096 Mar 20 10:05 . | ||
- | drwxr-xr-x. 3 postgres postgres 4096 Mar 20 10:05 .. | ||
- | </ | ||
- | |||
- | ======Restore & Recovery====== | ||
- | Restore and Recovery have been ALWAYS a different topics in the eyes of a DBA: | ||
- | |||
- | * Restore - Relates to the physical restore of files, not for making the files work together and be consistent between themselves, but only to put some version of the dataifiles somewhere, that is all what restore stands for. | ||
- | * Recovery - Relates to the synchronization between the datafiles and log files, in other words making everything consistent. | ||
- | |||
- | |||
- | =====Physical===== | ||
- | |||
- | ====Whole server===== | ||
- | With Barman we can easily restore your, if you have one :). Please ensure that **YOU NEVER RESTORE IN YOUR ORIGINAL DATA DIRECTORY**, | ||
- | |||
- | To list existing backups, log in on your central barman server and issue the following command: | ||
- | |||
- | <sxh bash> | ||
- | -bash-4.2$ barman list-backup pg | ||
- | pg 20180603T074928 - Sun Jun 3 13:48:58 2018 - Size: 28.9 MiB - WAL Size: 53.2 KiB | ||
- | pg 20180603T073804 - Sun Jun 3 13:37:35 2018 - Size: 28.9 MiB - WAL Size: 53.2 KiB | ||
- | pg 20180404T061948 - Wed Apr 4 12:19:20 2018 - Size: 28.9 MiB - WAL Size: 117.2 KiB | ||
- | |||
- | |||
- | -bash-4.2$ | ||
- | Backup 20180603T074928: | ||
- | Server Name : pg | ||
- | Status | ||
- | PostgreSQL Version | ||
- | PGDATA directory | ||
- | |||
- | Base backup information: | ||
- | Disk usage : 28.9 MiB (28.9 MiB with WALs) | ||
- | Incremental size : 8.8 KiB (-99.97%) | ||
- | Timeline | ||
- | Begin WAL : 00000001000000000000003C | ||
- | End WAL : 00000001000000000000003C | ||
- | WAL number | ||
- | WAL compression ratio: 99.84% | ||
- | Begin time : 2018-06-03 13: | ||
- | End time : 2018-06-03 13: | ||
- | Copy time : less than one second | ||
- | Estimated throughput : 13.9 KiB/s | ||
- | Begin Offset | ||
- | End Offset | ||
- | Begin LSN : 0/3C000028 | ||
- | End LSN : 0/3C0000F8 | ||
- | |||
- | WAL information: | ||
- | No of files : 2 | ||
- | Disk usage : 53.2 KiB | ||
- | WAL rate : 15.19/hour | ||
- | Compression ratio : 99.84% | ||
- | Last available | ||
- | |||
- | Catalog information: | ||
- | Retention Policy | ||
- | Previous Backup | ||
- | Next Backup | ||
- | |||
- | </ | ||
- | |||
- | This will show us the list of the backups, their status and the late command, will show us the latest one: | ||
- | |||
- | |||
- | <sxh bash> | ||
- | -bash-4.2$ barman recover --remote-ssh-command "ssh [email protected]" | ||
- | Starting remote restore for server pg using backup 20180603T074928 | ||
- | Destination directory: / | ||
- | Doing PITR. Recovery target time: ' | ||
- | Copying the base backup. | ||
- | Copying required WAL segments. | ||
- | Generating recovery.conf | ||
- | Identify dangerous settings in destination directory. | ||
- | |||
- | IMPORTANT | ||
- | These settings have been modified to prevent data losses | ||
- | |||
- | postgresql.conf line 216: archive_command = false | ||
- | |||
- | Your PostgreSQL server has been successfully prepared for recovery! | ||
- | </ | ||
- | |||
- | The barman will prepare also your recovery.conf script. | ||
- | |||
- | <sxh bash> | ||
- | [root@postegresqlmaster data_restore]# | ||
- | restore_command = 'cp barman_xlog/ | ||
- | recovery_end_command = 'rm -fr barman_xlog' | ||
- | recovery_target_time = ' | ||
- | </ | ||
- | |||
- | |||
- | You can also instruct PostgreSQL to use barman for the recovery of the xlog files. Here example of such recovery.conf file. | ||
- | |||
- | <sxh bash> | ||
- | standby_mode = ' | ||
- | primary_conninfo = ' | ||
- | |||
- | # The ' | ||
- | restore_command = ' | ||
- | </ | ||
- | |||
- | So in order to start the recovery, just rename the data folder and restart the service: | ||
- | |||
- | <sxh bash> | ||
- | [root@postegresqlmaster data]# service postgresql-9.6 start | ||
- | Starting postgresql-9.6 service: | ||
- | [root@postegresqlmaster data]# | ||
- | </ | ||
- | |||
- | Once the recovery has performed, the server will change the recovery.conf file to recovery.done, | ||
- | |||
- | |||
- | <sxh bash> | ||
- | [root@postegresqlmaster data]# cat recovery.done | ||
- | restore_command = 'cp barman_xlog/ | ||
- | recovery_end_command = 'rm -fr barman_xlog' | ||
- | recovery_target_time = ' | ||
- | [root@postegresqlmaster data]# su - postgres | ||
- | -bash-4.1$ | ||
- | -bash-4.1$ psql | ||
- | psql (9.6.7) | ||
- | Type " | ||
- | |||
- | postgres=# \l | ||
- | List of databases | ||
- | | ||
- | -----------+----------+----------+-------------+-------------+----------------------- | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | (4 rows) | ||
- | |||
- | postgres=# select * from testtable | ||
- | postgres-# ; | ||
- | id | ||
- | ---- | ||
- | 1 | ||
- | 1 | ||
- | 2 | ||
- | 2 | ||
- | </ | ||
- | |||
- | |||
- | ====Tablespace===== | ||
- | |||
- | |||
- | ====Table===== | ||
- | |||
- | =====Logical===== | ||
- | |||
- | The recovery depends on the backup, like any other database, backup and recovery tools come in pairs. | ||
- | So let's see how to recover a file generated by pg_dump. | ||
- | |||
- | <sxh bash> | ||
- | -bash-4.2$ psql -a -f hunter_dev_pgsql.sql | ||
- | -- | ||
- | -- PostgreSQL database dump | ||
- | -- | ||
- | -- Dumped from database version 10.0 | ||
- | -- Dumped by pg_dump version 10.0 | ||
- | SET statement_timeout = 0; | ||
- | SET | ||
- | SET lock_timeout = 0; | ||
- | SET | ||
- | SET idle_in_transaction_session_timeout = 0; | ||
- | SET | ||
- | SET client_encoding = ' | ||
- | SET | ||
- | SET standard_conforming_strings = on; | ||
- | SET | ||
- | SET check_function_bodies = false; | ||
- | SET | ||
- | SET client_min_messages = warning; | ||
- | SET | ||
- | SET row_security = off; | ||
- | SET | ||
- | </ | ||
- | |||
- | This command will execute and show all the input of file: hunter_dev_pgsql.sql | ||
- | |||
- | ===== Appendix ===== | ||
- | ---- | ||
- | Here is a nice script to automate the export of all databases on a server: | ||
- | |||
- | |||
- | <sxh bash> | ||
- | #!/bin/bash | ||
- | # => location to place backups | ||
- | backup_dir="/ | ||
- | backup_file="/ | ||
- | # => string to append to the name of the backup files | ||
- | backup_date=`date +%F` | ||
- | # => number of days you want to keep copies of your databases | ||
- | # | ||
- | number_of_days=1 | ||
- | |||
- | #elimina il file di log vecchio | ||
- | rm -rf $backup_file | ||
- | |||
- | # get a list of databases to back up | ||
- | databases=`psql -l -t | egrep -v "^ ( |template[01])" | ||
- | |||
- | echo $databases >> $backup_file | ||
- | |||
- | # starting time | ||
- | echo [`date`] START PostgreSQL backups >> $backup_file | ||
- | |||
- | # back up each database | ||
- | numero_database=0 | ||
- | for i in $databases; do | ||
- | numero_database=$(( $numero_database + 1 )) | ||
- | outfile=$backup_dir$backup_date-$i.dump.gz | ||
- | echo -n " | ||
- | / | ||
- | outfilesize=`ls -lh $outfile | awk '{ print $5 }'` | ||
- | echo " ($outfilesize)" | ||
- | done | ||
- | |||
- | # clean old backups | ||
- | echo " | ||
- | rm -f `find $backup_dir -type f -prune -mtime +$number_of_days` | ||
- | |||
- | # finish time | ||
- | echo [`date`] STOP PostgreSQL backups >> $backup_file | ||
- | |||
- | data=`date +%Y-%m-%d` | ||
- | backup_file_today=$backup_dir$data" | ||
- | backup_creati=`find $backup_file_today -maxdepth 1 -type f -print | wc -l` | ||
- | |||
- | #Controllo che il numero di backup creati sia uguale al numero dei database | ||
- | if [ $numero_database == $backup_creati ] ; then | ||
- | echo " | ||
- | else | ||
- | echo " | ||
- | fi | ||
- | </ | ||
- | |||
- | |||
- | Which can be put in crontab as follows: | ||
- | |||
- | |||
- | <sxh bash> | ||
- | # Minute | ||
- | # (0-59) | ||
- | 0 | ||
- | </ |