PostgreSQL 13 PITR(Point In Time Recovery)操作方法の説明

スポンサーリンク

PostgreSQLのPITR(Point In Time Recovery)の操作についてまとめます。各操作の意味については「PostgreSQL PITR(Point In Time Recovery)基本概念の説明」を参照ください。

事前準備 アーカイブの出力

アーカイブの出力先としてNFSサーバを構築し、そこにWAL出力先用途のディレクトリを作成します。

NFSサーバの構築方法については説明を省略します。

mkdir -p /nfs/postgres/wal
chown -R postgres:postgres /nfs/postgres

postgresql.confを以下のように編集します。

# vi /var/lib/pgsql/13/data/postgresql.conf 

 <omitted>

archive_mode = on
archive_command = 'cp -p %p /nfs/postgres/wal/%f'
archive_timeout = 60

設定を反映させます。

systemctl restart postgresql-13.service

バックアップの取得

pg_basebackup 最低限のオプション

pg_basebackupコマンドを使用すると、バックアップ処理だけでなく「PostgreSQL PITR(Point In Time Recovery)基本概念」で説明したpg_start_backup()とpg_stop_backup()を前後に実行します。

pg_basebackupに-Dオプションでバックアップ保存先を指定します。

pg_basebackup -D /nfs/postgres/backup/

-Dオプションで指定したバックアップ先を見ると、PostgreSQLのデータ全てがバックアップされている事が分かります。

[postgres@centos10 ~]$ ls -l /nfs/postgres/backup/
total 196
-rw-------. 1 postgres postgres    224 Dec 23 21:45 backup_label
-rw-------. 1 postgres postgres 135416 Dec 23 21:45 backup_manifest
drwx------. 5 postgres postgres     41 Dec 23 21:45 base
-rw-------. 1 postgres postgres     30 Dec 23 21:45 current_logfiles
drwx------. 2 postgres postgres   4096 Dec 23 21:45 global
drwx------. 2 postgres postgres     32 Dec 23 21:45 log

 <omitted>

pg_walおよびアーカイビング先を参照すると、.backupファイルが作成されている事が分かります。

[postgres@centos10 ~]$ ls -l 13/data/pg_wal/
total 49156
-rw-------. 1 postgres postgres      337 Dec 23 21:45 000000010000000000000004.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 21:50 000000010000000000000005
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000006
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000007
drwx------. 2 postgres postgres       96 Dec 23 21:50 archive_status
[postgres@centos10 ~]$ ls -l /nfs/postgres/wal/
total 81924
-rw-------. 1 postgres postgres 16777216 Dec 23 21:37 000000010000000000000001
-rw-------. 1 postgres postgres 16777216 Dec 23 21:42 000000010000000000000002
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000003
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000004
-rw-------. 1 postgres postgres      337 Dec 23 21:45 000000010000000000000004.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 21:50 000000010000000000000005
[postgres@centos10 ~]$ 

.backupファイルを見ると、バックアップ時刻, LSN, ラベル名などを確認する事ができます。デフォルトでは「pg_basebackup base backup」というラベル名が付与されますが、pg_basebackupの-lオプションでラベル名を変更する事もできます。

[postgres@centos10 ~]$ cat /nfs/postgres/wal/000000010000000000000004.00000028.backup 
START WAL LOCATION: 0/4000028 (file 000000010000000000000004)
STOP WAL LOCATION: 0/4000138 (file 000000010000000000000004)
CHECKPOINT LOCATION: 0/4000060
BACKUP METHOD: streamed
BACKUP FROM: master
START TIME: 2020-12-23 21:45:09 JST
LABEL: pg_basebackup base backup
START TIMELINE: 1
STOP TIME: 2020-12-23 21:45:19 JST
STOP TIMELINE: 1
[postgres@centos10 ~]$ 

pg_basebackup よく使用するオプション

pg_basebackupでよく使用するオプションは以下の通りです。WALをバックアップ対象外にしたり、tar.gzで圧縮すると便利です。

オプション 意味
-D バックアップ先のディレクトリを指定
-F バックアップファイアルのフォーマットを指定。pはplain file形式で、tはtar形式となる
-X WALをバックアップするかどうかを指定。nを指定した場合はWALがバックアップ対象外となる
-z zip圧縮を行う。-F tを併用した場合は、tar.gzのバックアップが作成される。

上記オプションを使用した操作例は以下の通りです。

rm -rf /nfs/postgres/backup
pg_basebackup -D /nfs/postgres/backup -F t -X n -z

tar.gzのバックアップファイルが作成された事を確認します。

[postgres@centos10 ~]$ ls -l /nfs/postgres/backup/
total 3184
-rw-------. 1 postgres postgres  135557 Dec 23 22:18 backup_manifest
-rw-------. 1 postgres postgres 3119302 Dec 23 22:18 base.tar.gz
[postgres@centos10 ~]$ 

アーカイビングの削除

定期的にpg_basebackupを実行するような運用を想定すると、全てのWALは必要ない事が分かります。

例えば、以下のような出力の場合、チェックポイント以前である000000010000000000000001から00000010000000000000005までのWALは不要である事が分かります。

[postgres@centos10 ~]$ ls -l /nfs/postgres/wal/
total 114696
-rw-------. 1 postgres postgres 16777216 Dec 23 21:37 000000010000000000000001
-rw-------. 1 postgres postgres 16777216 Dec 23 21:42 000000010000000000000002
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000003
-rw-------. 1 postgres postgres 16777216 Dec 23 21:45 000000010000000000000004
-rw-------. 1 postgres postgres      337 Dec 23 21:45 000000010000000000000004.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 21:50 000000010000000000000005
-rw-------. 1 postgres postgres 16777216 Dec 23 22:18 000000010000000000000006
-rw-------. 1 postgres postgres      337 Dec 23 22:18 000000010000000000000006.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 22:23 000000010000000000000007
[postgres@centos10 ~]$

これら不要なWALを1つずつ指定して削除するのはオペレーションミスの元で、安全に削除するツールがPostgreSQLには用意されています。書式は以下の通りです。

pg_archivecleanup <アーカイブ先ディレクトリ> <.backupファイル名>

-nオプションを付与すればdry runが可能です。

[postgres@centos10 ~]$ /usr/pgsql-13/bin/pg_archivecleanup -n /nfs/postgres/wal/ 000000010000000000000006.00000028.backup 
/nfs/postgres/wal//000000010000000000000001
/nfs/postgres/wal//000000010000000000000002
/nfs/postgres/wal//000000010000000000000003
/nfs/postgres/wal//000000010000000000000004
/nfs/postgres/wal//000000010000000000000005
[postgres@centos10 ~]$ 

アーカイブ先に保存された不要WALを削除する操作例は以下の通りです。

[postgres@centos10 ~]$ /usr/pgsql-13/bin/pg_archivecleanup /nfs/postgres/wal/ 000000010000000000000006.00000028.backup 
[postgres@centos10 ~]$ ls -l /nfs/postgres/wal/
total 32776
-rw-------. 1 postgres postgres      337 Dec 23 21:45 000000010000000000000004.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 22:18 000000010000000000000006
-rw-------. 1 postgres postgres      337 Dec 23 22:18 000000010000000000000006.00000028.backup
-rw-------. 1 postgres postgres 16777216 Dec 23 22:23 000000010000000000000007
[postgres@centos10 ~]$ 

リストア操作

バックアップしたtar.gzファイルを${PGDATA}配下に展開します。

rm -rf /var/lib/pgsql/13/data/*
cd /var/lib/pgsql/13/data/
tar xvzf /nfs/postgres/backup/base.tar.gz 

バックアップからの復元である事を意味するファイルを作成します。

touch /var/lib/pgsql/13/data/recovery.signal

WALを眺め、どこまでをリストアするかを確認します。

[root@centos11 ~]# /usr/pgsql-13/bin/pg_waldump /nfs/postgres/wal/000000010000000000000007 
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/07000028, prev 0/06000100, desc: RUNNING_XACTS nextXid 486 latestCompletedXid 485 oldestRunningXid 486
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/07000060, prev 0/07000028, desc: RUNNING_XACTS nextXid 486 latestCompletedXid 485 oldestRunningXid 486
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/07000098, prev 0/07000060, desc: CHECKPOINT_ONLINE redo 0/7000060; tli 1; prev tli 1; fpw true; xid 0:486; oid 14385; multi 1; offset 0; oldest xid 479 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 486; online
rmgr: XLOG        len (rec/tot):     24/    24, tx:          0, lsn: 0/07000110, prev 0/07000098, desc: SWITCH 

postgresql.confにリストアに関するパラメタを追記します。「PostgreSQL PITR(Point In Time Recovery)基本概念の説明」では省略しましたが、この時にarchive_cleanup_commandを指定すると便利です。

archive_cleanup_commandはリカバリ実行時に呼び出されるコマンドで、前述の不要なWALの削除を実施すると便利でしょう。変数%rには、リストアを実施する時の.backupファイルの名前が格納されますので、「archive_cleanup_command = ‘pg_archivecleanup /nfs/postgres/wal/ %r’」のような指定をすれば、WALを削除する手作業の手間を省く事ができます。

vi /var/lib/pgsql/13/data/postgresql.conf 
 
#archive_mode = on
#archive_command = 'cp -p %p /nfs/postgres/wal/%f'
#archive_timeout = 60
restore_command = 'cp /nfs/postgres/wal/%f %p'
recovery_target_action = 'promote'
recovery_target_lsn = '0/07000098'
archive_cleanup_command = '/usr/pgsql-13/bin/pg_archivecleanup /nfs/postgres/wal/ %r'

PostgreSQLを起動し、PITRを実施します。

systemctl start postgresql-13.service

想定通りのLSNまでリストアされた事を確認します。

[root@centos11 ~]# cat /var/lib/pgsql/13/data/log/postgresql-Wed.log 

 <omitted>

2020-12-23 23:57:28.819 JST [1771] LOG:  PostgreSQL 13.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), 64-bit を起動しています
2020-12-23 23:57:28.820 JST [1771] LOG:  IPv6アドレス"::1"、ポート5432で待ち受けています
2020-12-23 23:57:28.820 JST [1771] LOG:  IPv4アドレス"127.0.0.1"、ポート5432で待ち受けています
2020-12-23 23:57:28.822 JST [1771] LOG:  Unixソケット"/var/run/postgresql/.s.PGSQL.5432"で待ち受けています
2020-12-23 23:57:28.828 JST [1771] LOG:  Unixソケット"/tmp/.s.PGSQL.5432"で待ち受けています
2020-12-23 23:57:28.832 JST [1774] LOG:  データベースシステムは中断されました: 2020-12-23 22:18:13 JST まで動作していたことは確認できます
cp: '/nfs/postgres/wal/00000002.history' を stat できません: No such file or directory
2020-12-23 23:57:29.392 JST [1774] LOG:  WAL位置(LSN) "0/7000098"までのポイントインタイムリカバリを開始します
2020-12-23 23:57:29.409 JST [1774] LOG:  ログファイル"000000010000000000000006"をアーカイブからリストアしました
2020-12-23 23:57:29.474 JST [1774] LOG:  REDOを0/6000028から開始します
2020-12-23 23:57:29.478 JST [1774] LOG:  0/6000100 でリカバリの一貫性が確保されました
2020-12-23 23:57:29.479 JST [1771] LOG:  データベースシステムはリードオンリー接続の受け付け準備ができました
2020-12-23 23:57:29.498 JST [1774] LOG:  ログファイル"000000010000000000000007"をアーカイブからリストアしました
2020-12-23 23:57:29.544 JST [1774] LOG:  リカバリ処理はWAL位置(LSN)"0/7000098"の後で停止します
2020-12-23 23:57:29.544 JST [1774] LOG:  REDOが0/7000098で終了しました
cp: '/nfs/postgres/wal/00000002.history' を stat できません: No such file or directory
2020-12-23 23:57:29.550 JST [1774] LOG:  新しいタイムラインIDを選択: 2
2020-12-23 23:57:29.632 JST [1774] LOG:  アーカイブリカバリが完了しました
cp: '/nfs/postgres/wal/00000001.history' を stat できません: No such file or directory
2020-12-23 23:57:29.657 JST [1771] LOG:  データベースシステムの接続受け付け準備が整いました
タイトルとURLをコピーしました