參考:http://www.postgresql.org/docs/9.5/static/continuous-archiving.html
http://www.mkyong.com/database/postgresql-point-in-time-recovery-incremental-backup/
wal,即預寫式日志,是日志的標准實現方式,簡單而言就是將對數據庫的變動記錄到日志 中,而后在將具體的新數據刷新到磁盤。PostgreSQL將該日志維護在數據文件夾下的子文件夾pg_xlog中。當數據庫崩潰后,可以通過“重放”日志中的“動作”,將數據庫恢復。也就是說,只要擁有一個基礎備份和完整的日志文件,理論上可以將數據庫庫恢復到任意基礎備份以來的任意時刻點。不僅如此,如果在另一個實例上將這些日志不停的“重放”,那么就擁有了一個完整的在線備份,也就是“復制”。
pg_xlog下日志文件不會無限制增多,也就是說並不用擔心日志的增多使得磁盤空間捉襟見肘。默認每個日志文件為16M大小,即當增長到16M時,就會切換到別的文件,並復用之前的文件 。因此,為了保證有個完整的日志鏈,必須將寫滿的文件復制保存到一個特定的文件 夾。對於最后一個還未滿16M的日志文件,可以手動觸發一次切換。
備份(操作均使用系統賬號postgres完成 )
- 登錄數據庫創建測試數據庫
postgres@debian:~$ psql psql (9.5.0) Type "help" for help. postgres=# CREATE DATABASE test; CREATE DATABASE
- 修改配置文件,開啟日志備份,將寫滿的文件復制到archive文件夾下
vim /etc/postgresql/9.5/main/postgresql.conf wal_level = archive archive_mode = on archive_command = ' test ! -f /var/lib/postgresql/archive/%f && cp %p /var/lib/postgresql/archive/%f'
- 創建archive文件夾,並重啟數據庫服務
postgres@debian:~$ mkdir archive postgres@debian:~$ /usr/lib/postgresql/9.5/bin/pg_ctl restart -D /var/lib/postgresql/9.5/main/ -o "-c config_file=/etc/postgresql/9.5/main/postgresql.conf" 2016-01-18 09:30:42 CST [2937-2] LOG: received fast shutdown request 2016-01-18 09:30:42 CST [2937-3] LOG: aborting any active transactions 2016-01-18 09:30:42 CST [2942-2] LOG: autovacuum launcher shutting down 2016-01-18 09:30:42 CST [2939-1] LOG: shutting down waiting for server to shut down.....2016-01-18 09:30:44 CST [2939-2] LOG: database system is shut down done server stopped server starting postgres@debian:~$ 2016-01-18 09:30:45 CST [2972-1] LOG: database system was shut down at 2016-01-18 09:30:44 CST 2016-01-18 09:30:45 CST [2972-2] LOG: MultiXact member wraparound protections are now enabled 2016-01-18 09:30:45 CST [2971-1] LOG: database system is ready to accept connections 2016-01-18 09:30:45 CST [2976-1] LOG: autovacuum launcher started
- 創建測試表
postgres@debian:~$ psql psql (9.5.0) Type "help" for help. postgres=# \c test You are now connected to database "test" as user "postgres". test=# CREATE TABLE testPITR1 AS SELECT * FROM pg_class, pg_description; SELECT 1192063
- 創建基礎備份
psql -c "SELECT pg_start_backup('base', true)" cd /var/lib/postgresql/9.5/ tar -cvf main.tar main psql -c "SELECT pg_stop_backup()"
6. 繼續創建測試表,切換日志
postgres@debian:~$ psql psql (9.5.0) Type "help" for help. postgres=# \c test You are now connected to database "test" as user "postgres". test=# CREATE TABLE testPITR2 AS SELECT * FROM pg_class, pg_description; SELECT 1203562 test=# select * from current_timestamp; now ------------------------------- 2016-01-18 10:02:15.229335+08 (1 row) test=# CREATE TABLE testPITR3 AS SELECT * FROM pg_class, pg_description; SELECT 1215061 test=# select * from current_timestamp; now ------------------------------- 2016-01-18 10:02:51.029447+08 (1 row) test=# select pg_switch_xlog(); pg_switch_xlog ---------------- 0/3DDE6750 (1 row)
恢復
關閉數據庫,模擬數據庫宕機,此時,數據庫test中應該有3張表,其中1張表在基礎備份前,也就是恢復完數據文件即可找回,而另2張表則需恢復相應的日志文件。模擬恢復到testPITR2創建時刻點。
- 關閉數據庫服務,重命名數據文件夾
postgres@debian:~$ /usr/lib/postgresql/9.5/bin/pg_ctl stop -D /var/lib/postgresql/9.5/main/ 2016-01-18 10:06:12 CST [2971-2] LOG: received fast shutdown request 2016-01-18 10:06:12 CST [2971-3] LOG: aborting any active transactions 2016-01-18 10:06:12 CST [2976-2] LOG: autovacuum launcher shutting down 2016-01-18 10:06:12 CST [2973-1] LOG: shutting down waiting for server to shut down.....2016-01-18 10:06:13 CST [2973-2] LOG: database system is shut down done server stopped postgres@debian:~$ mv 9.5/main 9.5/main.old
- 解壓備份數據文件,開啟服務,驗證此時只有基礎備份前的表testpitr1
postgres@debian:~$cd /var/lib/postgresql/9.5/ postgres@debian:~/9.5$ tar -xvf 9.5/main.tar postgres@debian:~$ 2016-01-18 10:26:40 CST [3342-1] LOG: database system was interrupted; last known up at 2016-01-18 09:54:56 CST 2016-01-18 10:26:40 CST [3342-2] LOG: redo starts at 0/17000098 2016-01-18 10:26:40 CST [3342-3] LOG: invalid record length at 0/17009348 2016-01-18 10:26:40 CST [3342-4] LOG: redo done at 0/170092D8 2016-01-18 10:26:40 CST [3342-5] LOG: last completed transaction was at log time 2016-01-18 09:48:26.585085+08 2016-01-18 10:26:40 CST [3342-6] LOG: MultiXact member wraparound protections are now enabled 2016-01-18 10:26:40 CST [3341-1] LOG: database system is ready to accept connections 2016-01-18 10:26:40 CST [3346-1] LOG: autovacuum launcher started postgres@debian:~$ psql psql (9.5.0) Type "help" for help. postgres=# \c test You are now connected to database "test" as user "postgres". test=# \d List of relations Schema | Name | Type | Owner --------+-----------+-------+---------- public | testpitr1 | table | postgres (1 row)
- 停掉數據庫,刪除數據文件夾,重新解壓基礎備份,創建recovery.conf,將數據庫恢復到testpitr2時刻
vi recovery.conf restore_command = 'cp /var/lib/postgresql/archive/%f %p' recovery_target_time = '2016-01-18 10:02:15' postgres@debian:~/9.5/main$ /usr/lib/postgresql/9.5/bin/pg_ctl start -D /var/lib/postgresql/9.5/main/ -o "-c config_file=/etc/postgresql/9.5/main/postgresql.conf" -l /var/lib/postgresql/recovery.log
可以在恢復日志中看到這么一句話:
2016-01-18 11:22:39 CST [1743-44] LOG: recovery stopping before commit of transaction 630, time 2016-01-18 10:02:46.080443+08
- 驗證,進入數據庫,發現testpitr2已經恢復
postgres@debian:~$ psql psql (9.5.0) Type "help" for help. postgres=# \c test You are now connected to database "test" as user "postgres". test=# \dt List of relations Schema | Name | Type | Owner --------+-----------+-------+---------- public | testpitr1 | table | postgres public | testpitr2 | table | postgres (2 rows)
如果需要恢復table3,則必須再次刪除數據文件夾,建立recovery.conf。