Chapter 8. バックアップとリストア

Table of Contents
8.1. SQL Dump
8.2. ファイルシステムレベルバックアップ
8.3. リリース間の移行

Postgresデータベースのすべての貴重なデータは、 定期的にバックアップする必要があります。 バックアップの 手順は簡単ですが、その下にあるテクニックや概念などを理解する 必要があります。

Postgres には、データのバックアップを行うために 2つの方法があります。

8.1. SQL Dump

この方法の背後には、SQLコマンド群が書かれたテキストファイルを生成し、 サーバにそのファイルを読み込ませたら、ダンプされた時と同じ 状態を再構築する、と言ったものがあります。このため、 Postgresにはユーティリティプログラムとして pg_dumpを提供しています。このコマンドの 一般的な使用方法は下記の通りです。

pg_dump dbname > outfile
お分かり頂けるように、pg_dumpは結果を標準出力に 書き出します。これがどのように活用できるかをこれから説明していきます。

pg_dumpは、すぐれた機能を持っている、 Postgresの標準クライアントアプリケーションです。 したがって、データベースに接続可能な、あらゆるリモートホストから バックアップの機能を実行することができます。しかし、 pg_dumpは特別な権限で動作するわけではありません。 具体的には、バックアップを行うすべてのテーブルに対して読むアクセス権が 必要となります。実際には、ほとんどの場合、データベースのスーパーユーザ である必要があります。

pg_dumpを行うデータベースサーバを特定するには、 コマンドラインオプション、-h host-p portを使用します。デフォルトの ホストはローカルホスト、または環境変数PGHOSTが 指定するものです。同様に、デフォルトのポートは環境変数 PGPORTで指定されているか、コンパイルされた時に 設定されているデフォルトとなります。(普通サーバは同じ コンパイルデフォルトとなります。)

他のPostgresのクライアントアプリケーションと 同様に、pg_dumpはデフォルトで、 現在のUnixユーザ名と同じデータベースユーザ名で接続します。 これの対処方法の1つとしては、-uオプションを 付けて、強制的にユーザ名を入力するためのプロンプトを表示させる 方法があります。また、環境変数PGUSERを 設定するのも1つの方法です。pg_dumpの 接続は普通のクライアント認証方法によるものであることに ご注意下さい。

pg_dumpで作成されたダンプは内部的に整合性があります。 これはつまり、pg_dumpが行われている際の更新は ダンプには反映されません。また、pg_dumpが 作動している時でも、データベースの他の作業は妨げられません。 (しかし、VACUUMなどの、排他的なロックが必要な 作業は例外となります。)

Important: データベースのスキーマが外部キーなどのOIDに依存している場合、 OIDも一緒にダンプするようにpg_dumpに指定する 必要があります。これを行うには、コマンドラインオプションとして -oを使用して下さい。

8.1.1. ダンプのリストア

pg_dumpで作成されたテキストファイルは、 psqlプログラムで読み込まれることを 意図しています。下記は、ダンプをリストアする一般的な方法です。

psql dbname < infile
ここで、infileとは pg_dumpコマンドを実行した際の出力 ファイル名です。このコマンドを実行してもdbname (データベース)は作成されません。必ずpsqlを 使ってtemplate0から作成して下さい(例:createdb -T template0 dbname)。 psqlにはpg_dumpと似たような、 データベースサーバのロケーションとユーザ名を操作する機能があります。 その詳細については、該当するページを参照して下さい。

データベース内のオブジェクトの所有権が別のユーザにあった場合、 ダンプはpsqlに該当するユーザとして順番に接続させ、 適切なオブジェクトを作成させます。この方法により、オリジナルの 所有権が保たれます。しかしまた、それらのユーザはあらかじめ存在 しなければならず、それぞれのユーザとして該当する各データベースに 接続できる権限を持っていなければなりません。したがって、 一時的にクライアント認証設定を緩める必要があるでしょう。

pg_dumppsqlでパイプから 読み書きが行えることは、1つのサーバから別のサーバへと データベースのディレクトリをダンプすることが可能となります。 下記はその例です。

pg_dump -h host1 dbname | psql -h host2 dbname

Important: pg_dumpで作成されたダンプはtemplate0に相対しています。 これはつまり、template1に追加されたあらゆる言語、手順なども pg_dumpでダンプされます。その結果、リストアする際に、 カスタマイズされたtemplate1を使用している場合は上記のように、 template0から空のデータベースを作成する必要があります。

8.1.2. pg_dumpallの利用

上記に説明のあったものは、データベースクラスタすべてをバックアップする 際にはとても厄介で、不適当なものです。これに対応するために、 pg_dumpallがあります。pg_dumpallは 指定されたクラスタの各データベースのバックアップを行い、 ユーザやグループなどのグローバルデータの状態が確実に保存されるように します。この方法の記述方法は下記の通りです。

pg_dumpall > outfile
ダンプの結果は上記の説明の通り、psqlで リストアすることが可能です。しかしこの場合、ユーザとグループの 情報を保存するので、データベースのスーパーユーザの権限が必要です。

実はpg_dumpallには、1つの小さな欠点が あります。それは、ダンプする各データベースの対話型ユーザ認証が 実装されていないということです。パスワード認証を使用していた場合、 環境変数PGPASSWORDに設定を行い、pg_dumpの 下にある関数に引き渡してあげる必要があります。また、各データベースで 異なるパスワードを使用している場合には、全てのpg_dumpallは 失敗に終ってしまいます。バックアップを行うために認証方法を変えるか、 pg_dumpallのシェルスクリプトをニーズに 合うように書き換えて下さい。

8.1.3. 大きいデータベース

謝辞: 原文はHannu Krosing氏によって書かれました。 () 1999-06-19

Postgresでは、システムでの可能な 最大ファイルサイズよりも大きなテーブルが可能ですので、 ファイルにダンプする際に、可能ファイルサイズよりも大きくなってしまう、 という問題に遭遇する可能性があります。pg_dumpは 標準出力に書き出しますので、この問題を解決するには、*nixのツールを 使用して回避することができます。

圧縮ダンプの使用. gzipのような、お好みの圧縮ソフトを 使用します。

pg_dump dbname | gzip > filename.gz
解凍方法としては
createdb dbname
gunzip -c filename.gz | psql dbname
または
cat filename.gz | gunzip | psql dbname
があります。

splitの使用. この方法は、結果を環境下にあるシステムで受けつけられる大きさに分割します。 例えば、1メガバイトのチャンクを分割するには、下記のコマンドを実行します。

pg_dump dbname | split -b 1m - filename

元に戻すには、

createdb dbname
cat filename.* | psql dbname

とします。

カスタムダンプ形式を使用(V7.1). PostgreSQLが、zlibデータ圧縮ライブラリがインストールされているシステムに インストールされているならば、カスタムダンプ形式を使用すれば、結果ファイルを 出力している用に、データを圧縮します。大きいデータベースでは、 gzipを使用しているのと同様なダンプサイズとなります。しかし、テーブルの 復元が部分的に行えるという点で、優れていると言えます。下記のコマンドを 実行するとカスタムダンプ形式でデータベースのダンプを行います。

pg_dump -Fc dbname > filename

より詳細はpg_dumppg_restoreの レファレンスページをご覧下さい。

8.1.4. 警告

pg_dump(実装面ではpg_dumpallも)には システムカタログからデータベースを復元する際、復元するのが困難な情報が 中にはあるために生じる、いくつかの制約があります。

特に、pg_dumpがオブジェクトを書き出す順序は 洗練されていません。これは、例えば列のデフォルト値として関数が 使用されている場合などで問題となります。この問題を解決するには、 手動でダンプ順序を変更する方法以外ありません。スキーマで巡回依存を 作成していた場合は、これ以上の作業が必要となります。

逆互換性の理由から、pg_dumpのデフォルトでは ラージオブジェクトのダンプは行いません。ラージオブジェクトのダンプを 行うには出力形式をカスタムする、もしくはTAR形式を使用する必要があり、 pg_dumpに-Bオプションを付ける必要があります。 詳細はレファレンスページを参照して下さい。Postgres ソースツリーのcontrib/pg_dumploディレクトリにも ラージオブジェクトをダンプする方法があります。

pg_dumpのレファレンスページを 読み親しんで下さい。