PostgreSQLのPITR(Point In Time Recovery)の操作についてまとめます。各操作の意味については「PostgreSQL PITR(Point In Time Recovery)基本概念の説明」を参照ください。
- PostgreSQL インストール
- PostgreSQL データベースの作成
- PostgreSQL contribモジュールの使い方
- PostgreSQL パラメタの設定方法
- PostgreSQL ベンチマークツールの紹介
- PostgreSQL WAL(Write Ahead Log)の基本説明
- PostgreSQL バックアップとリストア
- PostgreSQL PITR(Point In Time Recovery)基本概念の説明
- PostgreSQL PITR(Point In Time Recovery)操作方法の説明 (いまここ)
- PostgreSQL PITR(Point In Time Recovery)タイムライン操作
- PostgreSQL ストリーミングレプリケーションの最小構成
- PostgreSQL ストリーミングレプリケーションのパラメタ説明
- PostgreSQL ストリーミングレプリケーションの障害復旧
- PostgreSQL ストリーミングレプリケーションの多段構成
- PostgreSQL ストリーミングレプリケーションのDR向け設定
- PostgreSQL ストリーミングレプリケーションのコンフリクト
- PostgreSQL 自動バキューム(AUTO VACUUM)
- PostgreSQL HOT(Heap Only Tuple)
- PostgreSQL インデックスのメンテナンス
- PostgreSQL 統計情報の更新
- PostgreSQL 実行計画
- PostgreSQL スロークエリの調査方法
事前準備 アーカイブの出力
アーカイブの出力先として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: データベースシステムの接続受け付け準備が整いました