お問い合わせ
03-5979-2701
PowerGres
PowerGres 体験記 戻る

第 2 回 PITR 使って直前の状態まで復旧してみよう

対象バージョン: PowerGres 7 / PostgreSQL 8.4
本文では Microsoft Windows 7 (64 ビット版) において PowerGres on Windows 7.1 を使用して解説しています。

日々のデータベース運用管理作業において、バックアップは重要な作業のひとつです。また、バックアップファイルからデータベースを復旧するリストアの作業もあります。さらに、定期的にバックアップを実施していないと、障害時に復旧できずにサービスに深刻な影響が発生します。第2回ではまず、PowerGres でのバックアップ・リストアの手順について説明していきます。

  1. 3 つのバックアップ戦略
  2. コールドバックアップの手順
  3. pg_dump によるホットバックアップの手順
    1. スケジュールバックアップ
  4. ホットバックアップからのリストア手順
  5. 障害発生時に備えての PITR の設定
  6. 障害を発生させる
    1. ケース 1. オペレーションミスで誤ってデータを削除してしまった場合
    2. ケース 2. ディスク障害が発生した場合

3 つのバックアップ戦略

PowerGres および PostgreSQL には主に以下の表の、3つのバックアップ戦略が採用されています。

バックアップ方法説明
コールドバックアップOS 付属のコマンドによるもので、データベースを停止させた状態でデータベースクラスタを物理的にコピーをする方法。
ホットバックアップPostgreSQL 付属のコマンド pg_dump コマンドを用いる方法。バックアップを取る際にデータベースを停止させる必要がない。
PITR (Point-In-Time Recovery)ベースとなるデータベースクラスタのスナップショットを取り、その後のデータの更新によって発生するトランザクションログ (更新差分) をアーカイブログとして保存しておき、スナップショットとそれらのアーカイブログを用いて、直近の状態まで復旧する。
これらのうち、どれかひとつを採用すればよいというものではなく、それぞれ以下のような利点・欠点があります。

コールドバックアップの手順

コールドバックアップはその名の通り、データベースを停止してからバックアップを行わなければなりません。PowerGres でコールドバックアップを行うには最初にPowerGres Managerで「サービスを停止」をクリックし、データベースを停止させます。

その後、データベースクラスタのフォルダを別の名前でコピーするだけです。「第 1 回 PowerGres を使ってみよう」に従って PowerGres をセットアップしている場合には、データベースクラスタは C:\data_1 となっているので、そのフォルダをコピーして、D:\data_1_back と名前を変更して、これをバックアップとします。

図: データベースクラスタをまるごとコピー

コールドバックアップからのリカバリ手順は、データベースが起動している場合には停止してから、バックアップしておいたフォルダを元の位置に戻して起動するだけです。

pg_dump によるホットバックアップの手順

ホットバックアップは、PostgreSQL の場合にはコマンドラインで pg_dump というコマンドを実行して行いますが、PowerGres の場合には PowerGres Manager から行うことができます。もちろん、PowerGres でも pg_dump コマンドでバックアップすることも可能です。 ここでは、PowerGres Manager からホットバックアップを行う手順について説明します。

ホットバックアップを実際に行ってみましょう。バックアップを行うには、PowerGres Manager を起動して「バックアップ / リストア」の「バックアップ」タブをクリックします。

図: バックアップタブ

ここでのバックアップ時の設定値は以下の通りです。

設定項目説明設定値
出力ファイルバックアップファイル名を指定します。 D:\dumpfile\testdb.dump
対象データベースバックアップの対象となるデータベースを指定します。 testdb
データとスキーマ何をバックアップするのかを指定します。バックアップファイルのみでリカバリできるようにするには、「両方出力」を選択してスキーマ (テーブル定義) とデータの両方ともバックアップする必要があります。両方出力
出力形式どのような形式で出力するかを指定します。「テキスト (SQL)」の場合には SQL としてバックアップされるので、後からエディタを使って SQL を編集することが可能です。「Tar 形式」と「圧縮形式」はいずれもバイナリとしてバックアップされるので、基本的にファイルを編集することはできませんが、pg_restore コマンドを使ってデータの一部のみをリストアするなど、リストア内容をカスタマイズすることが可能です。テキスト形式(SQL)
ダンプデータ形式ダンプデータの形式を指定します。通常はデータの投入が高速な COPY 形式を選択します。COPY 形式ではすべてのデータの投入に成功するか否かのいずれかなので、データに不正な文字エンコーディングが含まれているなどして一部のデータだけでも投入したいといった特殊な場合には INSERT 形式を選択します。COPY 形式

図: バックアップ作成ウィンドウ

後程、スケジュールバックアップの設定を行うので、「バックアップ設定を保存」をクリックして適当なフォルダに D:\night_sch という名前で保存しておいてください。 最後に「バックアップ作成」をクリックすると、「出力ファイル」に指定した名前でバックアップファイルが作成されます。

スケジュールバックアップ

バックアップは、基本的に定期的に行うものです。定期的にバックアップを行いたい場合には、PowerGres 管理ツールのスケジュールバックアップを利用するのが簡単で便利です。

スケジュールバックアップを行うには、「スケジュール」タブの追加をクリックして、スケジュールの設定を行います。その際、バックアップの設定ファイル作成しておく必要があります。これは、PowerGres 管理ツールの「バックアップ」タブから保存する事ができます。先ほどバックアップの時に保存したバックアップ設定ファイル D:\night_sch をここでは用いるようにします。

図: スケジュールバックアップ設定済画面

「スケジュール」タブで「追加」をクリックし、以下の設定を日時(毎日、毎週)など設定を行います。ここでは以下の設定をしています。

設定項目説明設定値
バックアップ頻度曜日指定や毎日などの設定が可能曜日指定 日曜日
時刻0:00 - 23:59 の範囲で任意の時間の設定が可能1 時 10 分
バックアップ設定ファイルバックアップ設定ファイルに指定された方法でバックアップを実行 D:\night_sch

最後に、「適用」をクリックし、スーパーユーザのアカウントとパスワードを入力すると、「タスク」のボックスにスケジュールが追加されたことが確認できます。

ホットバックアップからのリストア手順

リストアをする場合は、「リストア」タブをクリックします。バックアップファイルを指定して、リストアするデータベースを指定します。

リストア先のデータベースをまだ作成していないので、先に空のデータベース( testdb_restore )を作成しておきます。データベースの属性は、 testdb のものと同じものです。

図: 空のデータベースを作成

次に「リストア」タブで作成したバックアップファイル( D:\dumpfile\testdb.dump )と、リストア先のデータベースを指定し、「リストアを実行」をクリックします。リストアはこれで完了です。

図: リストア設定画面

ちゃんとリストアされたかリストア先のデータベースを確認してみましょう。psqltestdb_restore に接続し、テーブル一覧を \d コマンドで確認してみましょう。正常にテーブルやデータもリストアされている事がわかります。

障害発生時に備えての PITR の設定

PITR とはデータベースのデータの更新によって発生した差分 (トランザクションログ) をアーカイブログとして保存しておき、障害発生時にスナップショット (ベースバックアップ) にアーカイブログを適用してリカバリする障害復旧の機能です。

図: pitr 図解

PostgreSQL で PITR を設定するには以下 URL のマニュアルをご参照ください。
https://www.sraoss.co.jp/PostgreSQL/Manual/document/pg842doc/html/continuous-archiving.html
PITR は障害が発生する直近の状態まで復旧できるという大きな魅力がありますが、設定ファイルの変更の手間、またその変更による単純な設定ミス、リカバリ手順の煩雑さなど、設定やリカバリに際しての手間がどうしても多く、煩雑になりがちです。

そういった PITR の煩雑さを軽減して設定・リカバリを容易に行うには PowerGres Manager を用います。それでは、実際に PowerGres Manager を使って PITR の設定を行っていきます。

図: アーカイブモード設定完了

「PITR」の「全般」タブで、「オンラインバックアップを有効にする」にチェックを入れます。そして、「ベースバックアップ」内の「バックアップを格納するディレクトリ」を指定します。ここでは、 D:\archive_log に作成します。「適用」ボタンをクリックし、サービスの再起動を行うと、アーカイブログが指定したディレクトリに保存されるようになります。

トランザクションログをアーカイブログして保存する設定はこれで終了です。次にスナップショットとなるベースバックアップを作成します。

「ベースバックアップ」タブの「ベースバックアップの作成」をクリックします。

図: ベースバックアップ作成画面

ベースバックアップの作成に成功すると、作成日時とサイズが表示されます。

図: ベースバックアップ作成完了

障害を発生させる

では、それぞれ障害を発生させて、復旧させてみましょう。

ケース1.オペレーションミスで誤ってデータを削除してしまった場合(WHERE 句なしで DELETE)

例えば、WHERE 句を指定せずに誤って DELETE 文を実行してデータを削除してしまった場合、データベースとしては正常な操作なので当然すべてのデータが削除されます。 このような単純なオペレーションミスでなくとも任意の時点までデータを戻したいということがあります。

そういった場合にも PITR を設定しておけば、スナップショットの取得後から現在までの任意の時点にリカバリすることが可能です。 ここでは、オペレーションミスで削除してしまったデータの復旧を例に PITR による任意時点へのリカバリ手順について解説します。

まず、psql から testdb に接続して、employee テーブルを確認します。

\c testdb
\SET ROLE testuser;
\encoding sjis
SELECT * FROM employee;
    
図: 現在のテーブル確認

現在時刻を確認しておきます。

SELECT CURRENT_TIMESTAMP;
図: DELETE前の現在時刻確認

INSERT INTO employee VALUES (2101027, '大沢 真利子', 'staff', '2010-08-19');
図: 1行追加

SELECT * FROM employee;
図: employeeテーブル表示

ここで、DELETE 文に WHERE 句をつけないで、すべての行を消してしまうオペレーションミスを行います。

SELECT CURRENT_TIMESTAMP;
DELETE FROM employee;
    
図: employeeテーブルを削除

今度はここから、大沢さんが INSERT されたところまで復旧させてみましょう。

オペレーションミスなどのようにデータ自体が破損していない場合には、まだアーカイブログとして保存されていないトランザクションログを強制的にアーカイブ化することにより、より直近の状態まで復旧することができるようになります。 それには、「ベースバックアップ」内の「トランザクションログを強制的にアーカイブ化」をクリックします。

図: トランザクションログを強制アーカイブする画面

「PITR」->「リカバリ」タブで、「日付を指定してリカバリする」にチェックを入れます。先ほどタイムスタンプを取ったのは、「指定した日時の直前までリカバリする」で、時刻を入力したかったからです。DELETE する直前の時刻に設定し、「リカバリを実行」をクリックします。 実際にはオペレーションミスを行ってしまったことに後から気付いて正確な時刻が不明な場合もあります。 その場合にはリカバリを繰り返してどの時点まで戻すべきかを調節する必要があります。

図: INSERT 直後の状態までリカバリする設定画面

その後 psql で testdb の employee テーブルの状態を確認してみましょう。DELETE 直前の INSERT 直後の状態であり、障害復旧できている事が確認できます。

\c testdb
SET ROLE testuser;
\encoding sjis
SELECT * FROM employee;
    

図: DELETE前のSELECT画面

このように、PITR を用いる事で任意の状態まで復旧させる事ができます。

ケース2.ディスク障害が発生した場合(データベースクラスタ自体を削除)

次に、ディスク障害が発生してデータベースクラスタがすべて消失してしまったことを想定し、スナップショットとアーカイブログを順番に適用して、障害直前の状態まで復旧させてみましょう。

スナップショットをここで一度取っておきましょう。過去の必要のないスナップショットは、削除ができます。

図: 2回目のベースバックアップ

まず testdb の現在の状態を把握しておきましょう。先ほど任意の時点に戻した状態ですね。

図: 現在のtestdbの状態select
この後、 employee テーブルに削除、更新、挿入など更新をかけてみましょう。

UPDATE employee SET position = 'staff' WHERE number = 1782822;
INSERT INTO employee(number, name, position, date_of_hire) VALUES (2101028, 'PITR 最新状態次郎', 'chief', '2010-08-26');
DELETE FROM employee WHERE number = 2081577;
SELECT * FROM employee;
    

図: リカバリした状態から更新をかけるウィンドウ

ここまでの更新で、データベースサービスを停止して、データベースクラスタ( C:\data_1)を( C:\data_1_crash )に名前を変更し、ディスク障害が発生してデータベースクラスタが消失してしまった状態を作ります。

図: データベースクラスタの名前変更

リカバリを行うには、「PITR」の「リカバリ」のタブの「最新の状態までリカバリする」にチェックを入れ、「リカバリ」ボタンを押すだけです。

図: 最新の状態に戻す画面

リカバリが完了すると、データベースクラスタが障害が発生する直近の状態まで戻ります。 psql で testdb の employee テーブルの状態を確認してみましょう。 employee テーブルの更新内容が復旧されているでしょうか。

図: 最新のemployeeテーブルをSELECTした画面

タイミングによっては employee テーブルの更新内容が復旧されていない場合があります。 復旧されていなくても手順が誤っているわけではありません。 トランザクションログはいくつかの条件に基づいてアーカイブログとして保存されていきますが、障害の発生するタイミングによってはまだアーカイブ化される前のトランザクションログが存在します。

PITR ではアーカイブログとして保存されていないデータの更新は復旧できないため、タイミングによっては最新のデータの更新まで復旧できない場合があります。 PITR を使ってもデータの更新をすべて復旧できるわけではないことに注意してください。

このように PowerGres 管理ツールを用いる事で PITR の煩雑な手続きを省いての復旧が容易になります。第 3 回目では、可用性を高めるためのシステム構成「ウォームスタンバイ」を PowerGres で設定してみましょう。