Japan
サイト内の現在位置
PostgreSQL
pg_rmanを用いたバックアップ・リカバリの実現方法
本ページでは、pg_rmanを用いたバックアップ・リカバリの実現方法について解説します。サンプルシナリオでは具体的な運用例についてもご紹介していますので、ぜひ最後までご覧ください。
pg_rmanのメリット
pg_rmanを使用すると、バックアップ取得と管理、およびリカバリに関する以下の各機能が使用できます。
・コマンド1つで、テーブルスペースまで含めてデータベース全体のバックアップを取得できます。
・コマンド1つで、バックアップからの完全リカバリを行うことができます。
・増分バックアップやバックアップの圧縮を行えるため、バックアップファイルをコンパクトにできます。
・バックアップは世代ごとに管理され、一覧表示することができます。
また、各作業において実施手順が容易になるため、作業時間の短縮と作業ミスの防止に役立ちます。
・ストレージ・スナップショットをサポートし、バックアップ取得時間を短縮します。
※pg_rmanの機能概要についてはこちらをご覧ください。
pg_rmanの使い方
では、実際にpg_rmanによるバックアップ・リカバリの動作を確認してみましょう。
この章ではpg_rmanの初期設定や必須オプション、及びバックアップ・リカバリの手順について解説します。本ページでご紹介するバックアップ・リカバリ例の流れは以下の通りです。
① 10万件のテストデータを作成し、全体バックアップを取得する。
② レコードを1万件追加し(総レコード数11万件)、増分バックアップを取得する。
③ レコードをさらに1万件追加し(総レコード数12万件)、その後障害が発生したものとして最新状態にリカバリする(レコード12万件の状態に戻る)[図1]。
④ ③とは別に、時刻指定パラメータありでリカバリを実行する(レコード11万件の状態に戻る)[図2]。


初期設定
pg_rmanは、取得したバックアップファイルや管理情報を「バックアップカタログ」という領域に保存します。このため、まず最初にバックアップカタログを初期化する必要があります。以下の項目をpostgresユーザーで実行します。
$ vi ~/.bash_profile #バックアップカタログパス環境変数化
#下記2行を追記して上書き保存
BACKUP_PATH=[バックアップカタログパス]
export BACKUP_PATH
$ source ~/.bash_profile
$ pg_rman init #バックアップカタログの初期化
initコマンドを実行することにより、バックアップカタログパスにpg_rmanの各種管理情報ファイルが作成されます。
必須オプション
バックアップ・リカバリ実行時には、以下の3つが必須オプションとなります。
必須オプション |
項目名 |
補足説明 |
---|---|---|
-B PATH |
バックアップカタログパス |
バックアップ先 / リストア元 (絶対パス) |
-D PATH |
データベースクラスタパス |
バックアップ元 / リストア先 (絶対パス) |
-A PATH |
WALアーカイブパス (PostgreSQL本体) |
バックアップ元 / リストア先 (絶対パス) |
(例)
#バックアップの実行
$ pg_rman backup -b full -B [バックアップカタログパス(pg_rman管理)] -D [データベースクラスタパス(PostgreSQL本体)] -A [WALアーカイブパス(PostgreSQL本体)]
#リカバリの実行
$ pg_rman restore -B [バックアップカタログパス(pg_rman管理)] -D [データベースクラスタパス(PostgreSQL本体)] -A [WALアーカイブパス(PostgreSQL本体)]
以降のバックアップ・リカバリコマンドの実行例では、3つの必須オプションを環境変数またはpg_rman.iniファイル内で設定することでオプションの指定を省略しています。実際のバックアップ・リカバリ実行時には必要に応じて前述の3つの必須オプションをパラメータ指定してください。
バックアップ
ここからは①~④の手順に沿って、バックアップ・リカバリの動作について解説します。10万件のテストデータを作成し全体バックアップを取得した後、レコードを1万件追加しその分の増分バックアップを取得します。

①全体バックアップ
10万件のテストデータを作成し、DBクラスタ全体とWALアーカイブのバックアップを取得します。
1. テスト用のテーブル・レコードを作成します。
$ pgbench -i -s 1
postgres=# SELECT COUNT(*) FROM pgbench_accounts;
count
--------
100000
(1 行)
2. 全体バックアップを実行します。
指定値 |
バックアップ対象 |
説明 |
詳細情報 |
---|---|---|---|
full |
全体バックアップ |
全体バックアップと |
データベースクラスタ全体を |
incremental |
増分バックアップ |
増分バックアップと |
最新の検証済みバックアップの |
archive |
アーカイブWAL |
データベースはバックアップせず、 |
アーカイブ WAL のみ |
3. バックアップデータをリスト表示します。なお、この時点ではデータは未検証です。
$ pg_rman show detail

4. バックアップデータを検証します。

②増分バックアップ
レコードを1万件追加し(総レコード数11万件)、DBクラスタ増分とWALアーカイブのバックアップを取得します。
$ psql
postgres=# INSERT INTO pgbench_accounts SELECT GENERATE_SERIES(100001,110000),NULL,NULL,NULL;
postgres=# SELECT COUNT(*) FROM pgbench_accounts;
count
--------
110000
(1 行)
4. バックアップデータをリスト表示します。なお、この時点ではデータは未検証です。


リカバリ
今まで取得したバックアップを用いてリカバリを行います。本ページでは、次の二つの例をご紹介します。
・最新状態にリカバリ
・指定した時刻にリカバリ
テスト用のレコード数を1万件追加(総レコード数12万件)した後、障害が発生したものとして上記二つのリカバリを実行します。
③最新状態にリカバリ
$ psql
postgres=# INSERT INTO pgbench_accounts SELECT GENERATE_SERIES(110001,120000),NULL,NULL,NULL;
2. 更新されたテーブルのレコード数を表示します。
count
--------
120000
(1 行)
下記のコマンドを実行すると、DBクラスタ内の「postgresql.conf」ファイルが消失し、PostgreSQLを起動できなくなります。以降でリカバリされますが、 念のため削除前にDBクラスタをDBクラスタ外の場所にバックアップしておいてください。また、リストア時に一度DBクラスタが全消去される点にもご注意ください。
$ pg_ctl stop -m immediate #DB停止
$ rm ${PGDATA}/postgresql.conf #データ消失
5. PostgreSQLを起動します。
$ psql
postgres=# SELECT COUNT(*) FROM pgbench_accounts;
count
--------
120000
(1 行)
④指定した時刻にリカバリ

postgres=# SELECT COUNT(*) FROM pgbench_accounts;
count
--------
120000
(1 行)
下記のコマンドを実行すると、DBクラスタ内の「postgresql.conf」ファイルが消失し、PostgreSQLを起動できなくなります。以降でリカバリされますが、 念のため削除前にDBクラスタをDBクラスタ外の場所にバックアップしておいてください。また、リストア時に一度DBクラスタが全消去される点にもご注意ください。
$ pg_ctl stop -m immediate #DB停止
$ rm ${PGDATA}/postgresql.conf #データ消失
$ pg_rman restore --recovery-target-time 'YYYY-MM-DD hh:mm:ss'
(例)
$ pg_rman restore --recovery-target-time '2022-11-25 11:52:49'
--recovery-target-timeオプション付きのrestoreコマンドを実行することで時刻を指定してリカバリできます。ただし、リカバリを行う前に、実行対象のPostgreSQLサーバを停止させる必要があります。
4. PostgreSQLを起動し、リストアされたテーブル内のレコード数を表示します。
$ pg_ctl start #PostgreSQL起動
$ psql
postgres=# SELECT COUNT(*) FROM pgbench_accounts; #レコード数表示
count
--------
110000
(1 行)
5. リカバリの完了処理を実行します。
postgres=# SELECT pg_wal_replay_resume();
時刻指定でのリカバリの場合、4. の時点でDBは参照のみ可能 (更新不可)の状態になっています。そのため、リカバリ後のDBの状態を確認してから5. を実行し更新可能の状態にします。この処理は時刻指定でリカバリを行う場合のみ必要です。
サンプルシナリオ
ここでは、具体的な運用を想定したバックアップ・リカバリの例をご紹介します。実施内容は以下の通りです。
項目 |
説明 | |
---|---|---|
バックアップ取得日時と種別 |
初回 |
全体バックアップ |
月曜~土曜定時 |
増分バックアップ | |
日曜定時 |
全体バックアップ | |
世代管理 |
過去2世代分を保持 |
下記のコマンドを実行することで表3の要件を満たしたバックアップを取得できます。OS・DBともすべて「postgres」ユーザーで実行します。
#初回および日曜定時の全体バックアップ
$ pg_rman backup -b full -Z --keep-data-generations=2 > [ログファイル出力ファイル名フルパス].log 2>&1 #バックアップ
$ pg_rman validate #検証
$ pg_rman purge #不要管理情報削除
#月曜~土曜定時の増分バックアップ
$ pg_rman backup -b incremental -Z > [ログファイル出力ファイル名フルパス].log 2>&1 #バックアップ
$ pg_rman validate #検証
-Zオプションで圧縮、--keep-data-generationsオプションに2を指定して過去2世代分を保持するよう指定しています。また、バックアップ実行ログを残したい場合には> [ログファイル出力ファイル名フルパス].log 2>&1の記述も追加します。
[注意]不要なWALアーカイブファイルの削除
pg_rmanでのバックアップ取得後、不要となったWALアーカイブファイルはそのままWALアーカイブディレクトリ内に残り続けます。時間経過とともにストレージ領域の圧迫が大きくなるため、適宜メンテナンス操作を行い不要なWALアーカイブファイルを削除してください。
Advancedサポートサービスのご紹介
お問い合わせ