■PITRバックアップとリカバリ
 PITRバックアップとはポイントタイムリカバリの略でデータベースが
 壊れる直前、又は指定した時間まで戻す事が出来るバックアップです。

●WAL
 ログの先行書き込み(write ahead logging)の事でデータベースは
 データを変更した場合変更を全てログに書き出し、後でデータ
 ファイルに反映させています。
 このログの事をトランザクションログと言います。

●ログのバックアップ
 トランザクションログはローテーションで使用されている為
 古い物は破棄されてしまいます。破棄される時に保存する事が
 でき、それをアーカイブログと言います。

●リカバリ
 ベースとなるバックアップとアーカイブログ、トランザクション
 ログがあればベースバックアップにアーカイブログとトランザク
 ションログを適用する事によって最新の状態に復旧できます。
 これをリカバリ(復元)と言います。


○イメージとしては上記のようになります。
 ・データベース変更はトランザクションログに書かれ、順次アーカイブログに保存されます(右上)
 ・障害が発生したとしてもベースバックアップとアーカイブログ・トランザクションログがあればデータを復旧出来ます。
  ※Aの部分です。ベースとなるバックアップに変更点のアーカイブログ、トランザクションログを適用
   する事によって障害発生までのデータを復元する事が出来ます。

●事前準備
 ・ベースとなるバックアップを行います。
  ※定期的に行う必要があります。
 ・pg_start_backupを実行します。
 ・tarコマンドを使用してDataディレクトリをバックアップします。
 ・pg_stop_backupを実行します。
 上記3つの手順を行います。DBを停止する必要はありません。

 ・アーカイブログを保存します。
  ※初期設定では保存されません。

●リカバリ
 ・ベースバックアップを復旧します。
 ・データベースの変更点を記録したファイルを適用します。

●以下のメンテナンスが定期的に必要になります。
 ○アーカイブログ・ベースバックアップの削除
  アーカイブログ・ベースバックアップのバックアップは
  どんどん増えて行くので必要な物のみを残し、古い物は削除する必要があります。
  削除には追加モジュールのpg_archivecleanupが使用できます。
  ※上の図のBにあたります。最新のベースバックアップとアーカイブログがあれば復元可能です。

 ○.backupファイル
  バックアップを行うと.backupファイルが作成されます。pg_start_backup
  で指定した文字等バックアップの情報が入っています。
  これも削除されません。

##############################################################################

■バックアップ・リカバリの実践
 ●アーカイブログのバックアップ
   初期設定に含めました。(下の方にあります。)

 ●設定確認
  設定が正しいか確認しておきましょう。※pg_switch_xlogコマンドで強制的にアーカイブログへ出力出来ます。
  # su -l postgres
  $ psql -U postgres testdb
  testdb=# SELECT pg_switch_xlog();
  ※ここで保存先を確認するとアーカイブログが出来ているはずです。
  $ ls -l /mnt/usbdisk1/postgres/arch/
  合計 81920
  -rw-------. 1 postgres postgres 16777216  6月 16 03:35 2014 000000010000000000000001
  -rw-------. 1 postgres postgres 16777216  6月 16 03:36 2014 000000010000000000000002
  -rw-------. 1 postgres postgres 16777216  6月 16 03:37 2014 000000010000000000000003
  -rw-------. 1 postgres postgres 16777216  6月 16 03:41 2014 000000010000000000000004
  -rw-------. 1 postgres postgres 16777216  6月 16 03:45 2014 000000010000000000000005

 ●pg_start_backupを実行する
  -bash-4.1$  psql -c "select pg_start_backup('20140615')"
   pg_start_backup
  -----------------
   0/7000024
  (1 行)

 ●tarコマンドを使用してDataディレクトリをバックアップ
  -bash-4.1$ cd /var/lib/pgsql/9.3/
  -bash-4.1$ tar zcf /mnt/usbdisk1/postgres/base/20140615_backup.gz data
  ※必ずcdでカレントディレクトリを変更してバックアップを取る事

 ●pg_stop_backupを実行する
  -bash-4.1$ psql -c "select pg_stop_backup()"
  NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
  pg_stop_backup
  ----------------
  0/7000204
  (1 行)

 ●ファイルの確認
  -bash-4.1$ ls -l /mnt/usbdisk1/postgres/arch/
  合計 114692
  -rw-------. 1 postgres postgres 16777216  6月 16 03:35 2014 000000010000000000000001
  -rw-------. 1 postgres postgres 16777216  6月 16 03:36 2014 000000010000000000000002
  -rw-------. 1 postgres postgres 16777216  6月 16 03:37 2014 000000010000000000000003
  -rw-------. 1 postgres postgres 16777216  6月 16 03:41 2014 000000010000000000000004
  -rw-------. 1 postgres postgres 16777216  6月 16 03:45 2014 000000010000000000000005
  -rw-------. 1 postgres postgres 16777216  6月 16 03:52 2014 000000010000000000000006
  -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000007
  -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup

  -bash-4.1$ ls -l /var/lib/pgsql/9.3/data/pg_xlog/
  合計 49160
  -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000007
  -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup
  -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000008
  -rw-------. 1 postgres postgres 16777216  6月 16 03:52 2014 000000010000000000000009
  drwx------. 2 postgres postgres     4096  6月 16 04:07 2014 archive_status
  ※.backupが作成されているのが分かります。

 ●データ確認
  $ psql -U testuser testdb
  testdb=> INSERT INTO ms_sales(id, date, code, quantity, price, money)
  testdb->     VALUES (13, '2014-06-03', 3, 5, 80, 400);
  INSERT 0 1
  testdb=> select * from ms_sales;
   id |    date    | code | quantity | price | money
  ----+------------+------+----------+-------+-------
    1 | 2014-06-01 |    1 |        1 |   100 |   100
    2 | 2014-06-01 |    1 |        2 |   100 |   200
    3 | 2014-06-01 |    2 |        1 |   120 |   120
    4 | 2014-06-01 |    2 |        2 |   130 |   260
    5 | 2014-06-01 |    3 |        3 |   120 |   360
    6 | 2014-06-01 |    3 |        1 |   120 |   120
    7 | 2014-06-01 |    4 |        2 |    10 |    20
    8 | 2014-06-01 |    5 |        3 |    80 |   240
    9 | 2014-06-02 |    5 |        1 |    80 |    80
   10 | 2014-06-02 |    6 |        2 |   110 |   220
   11 | 2014-06-02 |    1 |        3 |   100 |   300
   12 | 2014-06-02 |    2 |        4 |   110 |   440
   13 | 2014-06-03 |    3 |        5 |    80 |   400
  (13 行)
  元からあったデータに対し、1件追加してみました。

 ●pg_switch_xlogで強制的にアーカイブログを作成
  testdb=> \q
  -bash-4.1$ psql -U postgres testdb
  psql (9.3.4)
  "help" でヘルプを表示します.

  testdb=# SELECT pg_switch_xlog();
   pg_switch_xlog
  ----------------
   0/8000C04
  (1 行)

 ●改めてファイルの確認
  testdb=# \q
  -bash-4.1$ ls -l /mnt/usbdisk1/postgres/arch/
  合計 147460
  -rw-------. 1 postgres postgres 16777216  6月 16 03:35 2014 000000010000000000000001
  -rw-------. 1 postgres postgres 16777216  6月 16 03:36 2014 000000010000000000000002
  -rw-------. 1 postgres postgres 16777216  6月 16 03:37 2014 000000010000000000000003
  -rw-------. 1 postgres postgres 16777216  6月 16 03:41 2014 000000010000000000000004
  -rw-------. 1 postgres postgres 16777216  6月 16 03:45 2014 000000010000000000000005
  -rw-------. 1 postgres postgres 16777216  6月 16 03:52 2014 000000010000000000000006
  -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000007
  -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup
  -rw-------. 1 postgres postgres 16777216  6月 16 04:19 2014 000000010000000000000008
  -rw-------. 1 postgres postgres 16777216  6月 16 04:23 2014 000000010000000000000009
  -bash-4.1$ ls -l /var/lib/pgsql/9.3/data/pg_xlog/
  合計 49160
  -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup
  -rw-------. 1 postgres postgres 16777216  6月 16 04:19 2014 000000010000000000000008
  -rw-------. 1 postgres postgres 16777216  6月 16 04:23 2014 000000010000000000000009
  -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 00000001000000000000000A
  drwx------. 2 postgres postgres     4096  6月 16 04:23 2014 archive_status
  ※SELECT pg_switch_xlog();は何度か実行しています。

 ●データベース停止
  -bash-4.1$ pg_ctl stop
  サーバ停止処理の完了を待っています........完了
  サーバは停止しました

 ●念の為、Dataディレクトリをリネーム
  -bash-4.1$ cd /var/lib/pgsql/9.3/
  -bash-4.1$ mv data data.old
  ※dataファイルが無くなった事により障害を擬似的に発生させる。

 ●データベースのファイルをdataディレクトリへ戻す
  -bash-4.1$ tar zxf /mnt/usbdisk1/postgres/base/20140615_backup.gz
  ※これがベースバックアップの復元です。
  ※設定ファイル込みの復元になります。各設定終了後に行いましょう。

 ●最新のトランザクションログを戻す
  -bash-4.1$ rm -rf data/pg_xlog/
  -bash-4.1$ cp -r data.old/pg_xlog/ data
  ※ベースバックアップのトランザクションログはベースバックアップをとった時点のファイルです。
   そこから障害が起こったまでのファイルを復元させます。
  ※ここが問題で外付けのHDDにファイルが無い為定期的にdata/pg_xlog/の中身をバックアップする必要があります。
  ※アーカイブログは外付けのHDD /mnt/usbdisk1/postgres/arch/ に保存している為、移動する必要はありません。

 ●rcovery.conf.sampleからrecovery.confを作成
  -bash-4.1$ cp /usr/pgsql-9.3/share/recovery.conf.sample  data/recovery.conf
  -bash-4.1$ vi data/recovery.conf
  ※以下の文を追加します。
  restore_command = 'cp /mnt/usbdisk1/postgres/arch/%f %p' 

 ●PostgreSQLを起動
  -bash-4.1$ pg_ctl start
  pg_ctl: 他のサーバが動作中の可能性がありますが、とにかくpostmasterの起動を試みます。
  サーバは起動中です。
  -bash-4.1$ < 2013-12-12 17:48:24.071 JST >LOG:  redirecting log output to logging collector process
  < 2013-12-12 17:48:24.071 JST >HINT:  Future log output will appear in directory "/var/log/postgresql".

 ●確認
  -bash-4.1$ psql -U postgres testdb
  psql (9.3.4)
  "help" でヘルプを表示します.
  
  testdb=# select * from ms_sales;
   id |    date    | code | quantity | price | money
  ----+------------+------+----------+-------+-------
    1 | 2014-06-01 |    1 |        1 |   100 |   100
    2 | 2014-06-01 |    1 |        2 |   100 |   200
    3 | 2014-06-01 |    2 |        1 |   120 |   120
    4 | 2014-06-01 |    2 |        2 |   130 |   260
    5 | 2014-06-01 |    3 |        3 |   120 |   360
    6 | 2014-06-01 |    3 |        1 |   120 |   120
    7 | 2014-06-01 |    4 |        2 |    10 |    20
    8 | 2014-06-01 |    5 |        3 |    80 |   240
    9 | 2014-06-02 |    5 |        1 |    80 |    80
   10 | 2014-06-02 |    6 |        2 |   110 |   220
   11 | 2014-06-02 |    1 |        3 |   100 |   300
   12 | 2014-06-02 |    2 |        4 |   110 |   440
   13 | 2014-06-03 |    3 |        5 |    80 |   400
  (13 行)
 ※無事復旧出来ました。

##############################################################################
■不要なログの削除
 ●pg_archivecleanup
  .backupファイルを指定する事によって必要の無いファイルを削除出来るコマンド
  古い.backupファイルは削除されないので注意
  追加モジュールのインストールが必要です。

 ●実行ログ
  ○実行前確認
   -bash-4.1$ ls -l /mnt/usbdisk1/postgres/arch/
   合計 180232
   -rw-------. 1 postgres postgres 16777216  6月 16 03:35 2014 000000010000000000000001
   -rw-------. 1 postgres postgres 16777216  6月 16 03:36 2014 000000010000000000000002
   -rw-------. 1 postgres postgres 16777216  6月 16 03:37 2014 000000010000000000000003
   -rw-------. 1 postgres postgres 16777216  6月 16 03:41 2014 000000010000000000000004
   -rw-------. 1 postgres postgres 16777216  6月 16 03:45 2014 000000010000000000000005
   -rw-------. 1 postgres postgres 16777216  6月 16 03:52 2014 000000010000000000000006
   -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000007
   -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup
   -rw-------. 1 postgres postgres 16777216  6月 16 04:19 2014 000000010000000000000008
   -rw-------. 1 postgres postgres 16777216  6月 16 04:23 2014 000000010000000000000009
   -rw-------. 1 postgres postgres 16777216  6月 16 04:29 2014 00000001000000000000000A
   -rw-------. 1 postgres postgres 16777216  6月 16 04:39 2014 00000001000000000000000B
   -rw-------. 1 postgres postgres       41  6月 16 04:39 2014 00000002.history
   -bash-4.1$
 
  ○コマンド発行
   -bash-4.1$ pg_archivecleanup /mnt/usbdisk1/postgres/arch/ 000000010000000000000007.00000024.backup
   ※ディレクトリとファイル名の間にはスペースが必要です。

  ○実行後確認
   -bash-4.1$ ls -l /mnt/usbdisk1/postgres/arch/                                   合計 81928
   -rw-------. 1 postgres postgres 16777216  6月 16 04:07 2014 000000010000000000000007
   -rw-------. 1 postgres postgres      292  6月 16 04:07 2014 000000010000000000000007.00000024.backup
   -rw-------. 1 postgres postgres 16777216  6月 16 04:19 2014 000000010000000000000008
   -rw-------. 1 postgres postgres 16777216  6月 16 04:23 2014 000000010000000000000009
   -rw-------. 1 postgres postgres 16777216  6月 16 04:29 2014 00000001000000000000000A
   -rw-------. 1 postgres postgres 16777216  6月 16 04:39 2014 00000001000000000000000B
   -rw-------. 1 postgres postgres       41  6月 16 04:39 2014 00000002.history

■最後に
 トランザクションログについてはいい方法を探しております。
 今回説明が長く、ログが多いですが仕組みが分からないと対応出来ないと思います。
 今後はトランザクションログのバックアップやレプリケーション等も調べたいと思います。

トップへ戻る