PostgreSQLの本番運用では、論理バックアップと物理バックアップを併用し、WALアーカイブによるポイントインタイムリカバリ(PITR)を組み合わせる構成が最も現実的です。単一のバックアップ方式に依存すると、データ量の増加時にリストア時間が想定を超えたり、直近数分の更新分だけが失われる事態が起こります。本記事では、pg_dumpとpg_basebackupの使い分け、定期バックアップの設計、実際のリカバリ手順、障害時の監視体制までを実務目線で解説します。

  • バックアップ方式の選び方
  • 定期バックアップの設計
  • リカバリ手順の実践
  • 障害対策と監視体制
  • よくある質問

バックアップ方式の選び方

PostgreSQLには複数のバックアップ方式が用意されており、それぞれデータサイズ・停止許容時間・復元粒度に応じて向き不向きがあります。まず全体像を比較表で整理します。

方式取得コマンド特徴向いている用途
論理バックアップpg_dump / pg_dumpallSQL形式またはカスタム形式でデータを出力。バージョン間の移行に強い数GB〜数十GB規模、開発・検証環境の複製
物理バックアップpg_basebackupデータディレクトリをそのまま複製。取得・復元が高速数百GB以上の本番DB、高速リストアが必要な場合
WALアーカイブarchive_command設定更新ログを継続保存し、任意時点への復元(PITR)を実現秒単位の更新を守りたい基幹システム

論理バックアップの特徴

pg_dumpはテーブル単位・スキーマ単位で出力できるため、特定のテーブルだけを別環境に復元したい場合に扱いやすい方式です。カスタム形式(-Fc)で出力しておけば、pg_restoreで並列リストア(-j オプション)が可能になり、単純なSQLダンプよりも復元時間を短縮できます。ただし、データ量が大きくなるとダンプ自体に時間がかかり、業務時間中の実行は本番への負荷が無視できません。一般的に、数十GBを超えるデータベースでは物理バックアップとの併用を検討する段階に入ります。

pg_dumpallはロールやテーブルスペースといったクラスタ全体の情報を含められる点が特徴です。個別データベースの移行にはpg_dump、サーバー全体の複製にはpg_dumpallという使い分けが基本です。

物理バックアップの活用

pg_basebackupはデータディレクトリ全体をバイナリレベルでコピーするため、同一メジャーバージョン間であれば復元後すぐにサーバーを起動できます。取得中もサーバーを稼働させたまま実行できる点が実務上のメリットです。レプリケーション用のユーザーを用意し、以下のようなコマンドで取得します。

pg_basebackup -h [ホスト] -U replicator -D /backup/base -Fp -Xs -P

-Xsオプションを付けると、バックアップ取得中に発生したWALをストリーミングで同時取得できるため、取得完了時点までの一貫性を保った状態でリストアできます。物理バックアップはメジャーバージョンをまたぐ移行には使えないため、その場合はpg_dumpによる論理移行が必要です。

WALアーカイブとPITR

WAL(Write Ahead Log)は、テーブルへの変更を先行して記録するログファイルです。postgresql.confでwal_level=replicaまたはlogicalを設定し、archive_modeをonにしてarchive_commandでWALファイルの退避先を指定すると、継続的なアーカイブが始まります。

archive_mode = on
archive_command = 'cp %p /backup/wal_archive/%f'

物理バックアップ(ベースバックアップ)とWALアーカイブを組み合わせることで、任意の秒単位の時点まで復元するPITRが可能になります。人為的な誤ったDELETE文を実行してしまった場合でも、その直前の時点まで復元できるのが最大の利点です。実運用ではcpコマンドではなく、後述するpgBackRestやWAL-Gなどの専用ツールを使う構成が一般的です。

定期バックアップの設計

方式を決めた後は、取得頻度・保持期間・保管先を業務要件に合わせて設計します。ここを曖昧にしたまま運用を始めると、復旧目標時間(RTO)と復旧時点目標(RPO)のどちらも達成できない状態に陥ります。

バックアップ間隔の目安

フルバックアップの頻度は、データ更新量とリストア許容時間のバランスで決めます。目安として次のような組み合わせが実務でよく採用されています。

  • フルバックアップ:1日1回、深夜帯のアクセス最小時間帯に実行
  • WALアーカイブ:常時継続、RPOを数分〜数秒単位に維持
  • バックアップ検証:週1回程度、実際にリストアして起動確認を行う

フルバックアップの間隔を延ばすほど、リカバリ時に適用するWAL量が増え、復旧完了までの時間が伸びます。1週間分のWALをまとめて再生する構成は、障害発生時に数時間単位の復旧待ちが発生する可能性があるため、更新頻度の高いシステムでは日次以下の間隔を推奨します。

自動化とcron運用

手動運用は取得忘れや世代管理ミスの温床になるため、cronまたはsystemdタイマーでの自動化が前提になります。単純なシェルスクリプトでも運用は可能ですが、増分バックアップやリテンション管理まで含めるなら、pgBackRestやbarmanといった専用ツールの導入がスクリプトの自作より保守負荷を下げます。

0 2 * * * /usr/bin/pgbackrest --stanza=main backup

自動化スクリプトには、実行結果を必ずログに残し、失敗時に通知が飛ぶ仕組みを組み込みます。バックアップが「取得できているつもり」で実際は数週間失敗し続けていたという事態は、監視を怠った現場で繰り返し起きています。

保管先の選び方

バックアップの保管先は、本番サーバーと物理的・論理的に分離することが前提です。同一ディスク上に保存していると、ディスク障害時にデータ本体とバックアップの両方を失います。

  • ローカルディスクとは別のストレージへの複製
  • オブジェクトストレージ(S3互換など)へのオフサイト保管
  • 世代管理:直近数日分は即時リストア用、長期分は圧縮・アーカイブ用に分離

暗号化やアクセス権限の設定は、保管先のサービス仕様に沿って個別に確認してください。設定内容は環境によって異なるため、公式ドキュメントを参照したうえで自己責任で実施する事項です。

リカバリ手順の実践

バックアップは取得よりも復元の成否がすべてです。取得できていても、リストア手順を検証していなければ本番障害時に手が止まります。

論理バックアップの復元

pg_dumpで取得したカスタム形式ファイルは、pg_restoreで復元します。並列リストアを使うと、単一プロセスでの復元より所要時間を短縮できます。

pg_restore -h [ホスト] -U postgres -d [DB名] -j 4 backup.dump

復元先に既存のテーブルが残っている場合は、–cleanオプションで事前にオブジェクトを削除してから復元するか、まっさらなデータベースを用意してから流し込みます。復元後は主要テーブルの件数を元環境と突き合わせ、欠損がないか確認します。

特定時点への復元

PITRでは、ベースバックアップを復元先ディレクトリに展開したうえで、recovery.signalファイルを配置し、postgresql.confにrestore_commandと復元目標時刻を設定します。

restore_command = 'cp /backup/wal_archive/%f %p'
recovery_target_time = '2026-08-23 09:15:00'

設定後にサーバーを起動すると、指定時刻までWALが順次再生され、目標時点でリカバリが完了します。recovery_target_actionをpromoteに設定しておけば、復旧完了後に自動でリードライト状態へ昇格します。誤操作による障害では、実行時刻を運用ログやアプリケーションログから特定し、その直前の時刻を復元目標に指定することが重要です。

復元後の整合性確認

復元が完了しても、それだけで作業終了とはみなしません。以下の観点で確認を行います。

  • 主要テーブルの件数・最終更新日時が想定範囲か
  • シーケンス(連番)の現在値がずれていないか
  • 外部キー制約や一意制約がエラーなく成立しているか
  • アプリケーション側から接続し、主要機能が正常に動作するか

特にシーケンスは、論理バックアップの復元後にリセットされるケースがあり、次の採番で重複エラーが発生することがあります。復元直後に一度setval関数で現在値を明示的に補正しておくと、後続の障害を防げます。

障害対策と監視体制

バックアップとリカバリの仕組みを整えても、失敗に気づけなければ意味がありません。取得の成否と保管先の状態を継続的に監視する体制まで含めて「バックアップ運用」です。

バックアップ失敗の検知

cronジョブの終了コードをチェックし、失敗時にはメールやチャットツールへ通知する仕組みを組み込みます。加えて、以下の項目を定期的に点検します。

  • 直近のバックアップファイルのタイムスタンプが想定間隔内か
  • バックアップファイルのサイズが極端に小さくなっていないか(取得中断の兆候)
  • WALアーカイブの遅延(pg_stat_archiverビューで確認可能)
  • 保管先ストレージの空き容量

pg_stat_archiverには最後にアーカイブしたWALファイル名とタイムスタンプが記録されており、archive_commandの失敗が続いている場合はfailed_countが増加します。このビューを定期監視に組み込むことで、アーカイブ停止を早期に検知できます。

レプリケーション併用

バックアップはあくまで過去時点への復元手段であり、サーバーダウン時の即時切り替えには対応しません。可用性を高めたい場合は、ストリーミングレプリケーションによるスタンバイサーバーを別途用意し、バックアップとは役割を分けて運用します。

  • バックアップ:データ破損・誤操作からの復旧、長期保管
  • レプリケーション:サーバー障害時の即時フェイルオーバー

両者は目的が異なるため、どちらか一方で代替することはできません。基幹システムでは、レプリケーションによる可用性確保と、バックアップによる復旧保証を並行して設計する構成が現実的です。

よくある質問

Q. pg_dumpとpg_basebackupはどちらを優先すべきですか

A. データ量が小さく、テーブル単位での柔軟な復元が必要ならpg_dump、数百GB以上で復元速度を優先するならpg_basebackupが適しています。両方を併用し、日次の論理バックアップと継続的な物理バックアップ・WALアーカイブを組み合わせる構成も広く採用されています。

Q. バックアップの保持期間はどれくらいが目安ですか

A. 一般的な目安として、日次バックアップは1〜2週間、週次の長期保管分は1〜3ヶ月程度を保持する運用が見られます。業界の規制や社内のデータ保持ポリシーがある場合は、そちらの要件を優先してください。

Q. リストアのテストはどのくらいの頻度で行うべきですか

A. 最低でも月1回、可能であれば週1回のペースで、実際に別環境へリストアしサーバーが起動することまで確認してください。取得だけを確認しリストアを試していない状態は、動作未確認のバックアップとみなすべきです。

Q. archive_commandの設定を間違えるとどうなりますか

A. WALファイルの退避が失敗し続け、pg_walディレクトリにWALが蓄積してディスク容量を圧迫します。放置するとディスクフルによりサーバーが停止する可能性があるため、pg_stat_archiverでの監視が欠かせません。

Q. メジャーバージョンアップ時のバックアップ方式は変わりますか

A. pg_basebackupによる物理バックアップは同一メジャーバージョン間でのみ有効です。バージョンをまたぐ移行にはpg_dump/pg_restoreによる論理バックアップ、またはpg_upgradeを使用してください。手順の詳細はPostgreSQL公式ドキュメントの該当バージョンのリリースノートを確認することを推奨します。

関連記事

まとめ

PostgreSQLのバックアップ運用は、論理バックアップ・物理バックアップ・WALアーカイブを組み合わせ、RPOとRTOの要件に合わせて取得頻度と保管先を設計することが土台になります。取得を自動化するだけでなく、pg_stat_archiverなどを使った失敗検知と、定期的なリストア試験を運用フローに組み込むことで、実際の障害時に手順が機能する状態を維持できます。バージョン依存の挙動や具体的なパラメータ設定は、使用しているPostgreSQLのバージョンに対応した公式ドキュメントを参照し、本番環境への適用は必ず検証環境での確認を経たうえで、自己の責任において実施してください。

【編集・制作ポリシー】
本記事はInfra Academy編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。 編集ポリシーはこちら
ABOUT ME
たから
フリーランスIT講師/エンジニア。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900//サーティファイC言語/情報処理技術者 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営