このダンプ方法の背景にある考え方はSQLコマンドでテキストファイルを生成し、そのファイルをサーバが再度読み込みを行った時に、ダンプした時点と同じ状態が再構築されるということです。 この目的のため、PostgreSQLはpg_dumpユーティリティプログラムを提供しています。 このコマンドの基本となる使い方は以下の通りです。
pg_dump dbname > outfile
見てわかる通り、pg_dumpは結果を標準出力に書き出します。 これがどのように活用できるかをこれから説明します。
pg_dumpは、(優れた機能を特に発揮する)PostgreSQLの通常のクライアントアプリケーションです。ということは、データベースに接続可能なあらゆるリモートホストからこのバックアップ手順を実行することができます。しかし、pg_dumpは動作に特別な権限を必要とするわけではありませんが、特に、バックアップを行う全てのテーブルに対して読み込み権限を必要とします。ですから、実際の作業はほとんどの場合、データベースのスーパーユーザでバックアップを行なわなければなりません。
pg_dumpを行うデータベースサーバを特定するにはコマンドラインの-h hostオプションと-p portオプションを使用します。デフォルトのホストはローカルホスト、またはPGHOST環境変数で指定したものです。同様に、デフォルトのポートはPGPORT環境変数で指定されているか、うまく行かない場合にはコンパイル時の設定がデフォルトとなります(そこはうまくできていて、サーバは通常コンパイル時の設定をデフォルトとします)。
他のPostgreSQLのクライアントアプリケーションのように、pg_dumpはデフォルトでオペレーティングシステムの現在のユーザ名と同じデータベースユーザ名で接続します。これを書き換えるには-Uオプションを付けるかPGUSER環境変数を設定します。pg_dumpの接続は(第21章で説明されている)通常のクライアント認証方法によることを思い出してください。
pg_dumpで作成されたダンプは、内部的に整合性があります。つまり、ダンプはpg_dumpが開始された際のデータベースのスナップショット示しています。pg_dumpの操作はデータベースに対する他の作業を妨げません(ALTER TABLEのほどんどの形態であるような排他的ロックが必要な作業は例外です)。
重要項目: (例えば外部キーのように)データベーススキーマがOIDに依存している場合、pg_dumpにOIDも一緒にダンプするよう指定しなければなりません。これを行うには-oコマンドラインオプションを使用します。
pg_dumpで作成されたテキストファイルはpsqlプログラムで読み込まれることを意図しています。以下に、ダンプをリストアする一般的なコマンドを示します。
psql dbname < infile
ここでinfileはpg_dumpコマンドでoutfileとしたものです。 dbnameデータベースはこのコマンドでは作成されません。 (例えばcreatedb -T template0 dbname のようにして)psqlを実行する前に自分でtemplate0から作成してください。psqlはpg_dumpのと似たような、接続データベースサーバと使用するユーザ名を指定するオプションに対応しています。詳細については、psqlのリファレンスページを参照してください。
SQLダンプのリストアを実行する前に、ダンプされたデータベース内のオブジェクトを所有するユーザやそのオブジェクト上に権限を与えられたユーザも存在しなければなりません。 存在していない場合、リストアはそのオブジェクトの元々の所有権や付与された権限を再作成することができません (このようにしたい場合もあるでしょうが、通常そうではありません)。
デフォルトでpsqlスクリプトは、SQLエラーが起きた後も実行を継続します。 スクリプトの先頭で以下のコマンドを使用しこの動きの変更を行うことで、エラーが起きた場合にpsqlが、終了ステータス3でプログラムから抜けるようにできます。
\set ON_ERROR_STOP
どちらしても、部分的にしかリストアされないデータベースになります。 他に、ダンプ全体を1つのトランザクションとしてリストアするように指定することができます。 こうすれば、リストアが完全に終わるか、完全にロールバックされるかのどちらかになります。 このモードは、psqlのコマンドラインオプションに-1または--single-transactionを渡すことで指定できます。 このモードを使用する場合、数時間かけて実行していたリストアが軽微なエラーでロールバックしてしまうことに注意してください。しかし、部分的にリストアされたダンプから手作業で複雑なデータベースを整理するよりまだましかもしれません。
pg_dumpとpsqlではパイプから読み書きができるので、あるサーバから別のサーバへデータベースを直接ダンプできます。 以下に例を示します。
pg_dump -h host1 dbname | psql -h host2 dbname
重要項目: pg_dumpで作成されるダンプはtemplate0と相対関係にあります。 つまりtemplate1を経由して追加されたあらゆる言語、プロシージャなどもpg_dumpによりダンプされます。 その結果としてリストアする際に、カスタマイズされたtemplate1を使用している場合は、上記の例のように、template0から空のデータベースを作成する必要があります。
バックアップをリストアした後、問い合わせオプティマイザが有効な統計情報を使用できるように、各データベースに対してANALYZEを実行することを勧めます。 このための簡単な方法は、vacuumdb -a -zを実行することです。 これは、各データベースに対してVACUUM ANALYZEを手作業で実行することと同じです。 効率的に大規模なデータをPostgreSQLにロードする方法に関するより多くの勧告については、項14.4を参照してください。
pg_dumpは同時に単一のデータベースのみをダンプします。 また、ロールやテーブル空間についての情報はダンプしません。 (これらはテーブル毎ではなくクラスタ全体のものだからです。) データベースクラスタの全内容の簡便なダンプをサポートするために、pg_dumpallプログラムが提供されています。 pg_dumpallは指定されたクラスタの各データベースのバックアップを行い、そして、ロールやテーブル空間定義などのクラスタ全体にわたるデータを保存します。 このコマンドの基本的な使用方法は
pg_dumpall > outfile
です。 ダンプの結果はpsqlでリストアできます。
psql -f infile postgres
(実際、開始時に任意の既存のデータベース名を指定することができますが、空のクラスタ内に再ロードする場合は、常に postgres を使用すべきです。) ロールやテーブル空間の情報をリストアしなければならないので、pg_dumpallのダンプをリストアする時には、データベーススーパーユーザのアクセス権限を確実に必要とします。 テーブル空間を使用している場合、ダンプ内のテーブル空間のパスが新しいインストレーションで適切であることを確認してください。
pg_dumpallはコマンドを発令することによりロール、テーブル空間、およびデータベースを再作成し、それぞれのデータベースに対してpg_dumpを起動します。このことは、それぞれのデータベースが内部的に矛盾がない限り、異なるデータベースのスナップショットは完全に同期しない可能性があることを示しています。
PostgreSQLはシステム上で最大可能なファイルサイズよりも大きなテーブルを扱えるので、ファイルにダンプする際に、システムで許容されているファイルサイズを超えてしまうという問題に遭遇する可能性があります。 pg_dumpは標準出力に書き出しますので、この問題を解決するためにUnix標準のツールを使用して回避できます。これを行う方法がいくつか存在します。
圧縮ダンプの使用. たとえば、自分が愛用しているgzipのような圧縮プログラムが使えます。
pg_dump dbname | gzip > filename.gz
元に戻すには次のようにします。
gunzip -c filename.gz | psql dbname
あるいは次のようにもできます。
cat filename.gz | gunzip | psql dbname
splitの使用. splitコマンドで結果を使用しているファイルシステムが受け付けられる大きさに分割することができます。 例えば1メガバイトずつに分割するには次のようにします。
pg_dump dbname | split -b 1m - filename
元に戻すには次のようにします。
cat filename* | psql dbname
pg_dumpのカスタムダンプ書式の使用. もしPostgreSQLがzlib圧縮ライブラリインストール済みのシステム上で構築されたのなら、カスタムダンプ書式では出力ファイルに書き出す時にデータを圧縮します。 gzipを使用した時と似通ったダンプサイズとなりますが、テーブルの復元を部分的に行えるという点で優れていると言えます。 以下のコマンドは、カスタムダンプ書式でのデータベースのダンプを行います。
pg_dump -Fc dbname > filename
カスタム書式のダンプはpsql用のスクリプトではありませんので、代わりにpg_restoreでリストアしなければなりません。例えば以下のようにします。
pg_restore -d dbname filename
詳細はpg_dumpとpg_restoreのリファレンスページを参照してください。
巨大なデータベースに対しては、そのほかの2つの手法のうちの1つと一緒にsplitを組み合わせる必要があるかもしれません。