★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

24.1. SQLによるダンプ

このダンプ方法の背景にはSQLコマンドでファイルを生成し、そのファイルをサーバが再度読み込みを行った時に、ダンプした時点と同じ状態が再構築されるという意図があります。 この目的のため、PostgreSQLpg_dumpユーティリティプログラムを提供しています。 このコマンドの基本となる使い方は以下の通りです。

pg_dump dbname > outfile

見てわかる通り、pg_dumpは結果を標準出力に書き出します。 これがどのように活用できるかをこれから説明します。 上記のコマンドはテキストファイルを作成しますが、pg_dumpは並列処理を可能にしたり、オブジェクトのリストアをより細かく制御できる他のフォーマットでファイルを作れます。

pg_dumpは、PostgreSQLの通常のクライアントアプリケーションです(その中でも特に優れた機能を発揮するものですが)。 ということは、データベースに接続可能なあらゆるリモートホストからこのバックアップ手順を実行できます。 しかし、pg_dumpは特別な権限で実行される訳ではないことを忘れないでください。 特に、バックアップを行う全てのテーブルに対して読み取り権限が必要ですので、データベース全体のバックアップを実行する場合、ほとんど常にデータベースのスーパーユーザとして実行しなければなりません。 (もしデータベース全体のバックアップを取るのに十分な権限を持っていない場合には、-n schemaもしくは、-t tableのようなオプションを使って、データベースのアクセス権のある部分をバックアップできます。)

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

他のPostgreSQLのクライアントアプリケーションのように、pg_dumpはデフォルトでオペレーティングシステムの現在のユーザ名と同じデータベースユーザ名で接続します。これを書き換えるには-Uオプションを付けるかPGUSER環境変数を設定します。pg_dumpの接続は(19章クライアント認証で説明されている)通常のクライアント認証方法によることを思い出してください。

後で述べる他のバックアップ手法に対するpg_dumpの重要な利点は、pg_dumpの出力は一般に新しいバージョンのPostgreSQLに再ロードできるということです。一方、ファイルレベルのバックアップと継続的アーカイブは両方とも非常にサーバ、バージョン依存です。 pg_dumpは、32ビットから64ビットのサーバに移行するなどの異なるマシンアーキテクチャにデータベースを移す場合に上手くいく唯一の方法でもあります。

pg_dumpで作成されたダンプは、内部的に整合性があります。つまり、ダンプはpg_dumpが開始された際のデータベースのスナップショットを示しています。pg_dumpの操作はデータベースに対する他の作業を妨げません(ALTER TABLEのほとんどの形態であるような排他的ロックが必要な作業は例外です)。

24.1.1. ダンプのリストア

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

psql dbname < infile

ここでinfilepg_dumpコマンドにより出力されたファイルです。 dbnameデータベースはこのコマンドでは作成されません。 (例えばcreatedb -T template0 dbname のようにして)psqlを実行する前に自分でtemplate0から作成してください。psqlpg_dumpと似たような、接続データベースサーバと使用するユーザ名を指定するオプションに対応しています。詳細については、psqlのリファレンスページを参照してください。 テキスト形式ではないダンプファイルはpg_restore ユーティリティを使いリストアします。

SQLダンプのリストアを実行する前に、ダンプされたデータベース内のオブジェクトを所有するユーザやそのオブジェクト上に権限を与えられたユーザも存在しなければなりません。 存在していない場合、リストアはそのオブジェクトの元々の所有権や付与された権限を再作成することができません (このようにしたい場合もあるでしょうが、通常そうではありません)。

デフォルトでpsqlスクリプトは、SQLエラーが起きた後も実行を継続します。 ON_ERROR_STOP変数を設定してpsqlを実行することで、その動作を変更し、SQLエラーが起きた場合にpsqlが、終了ステータス3で終了するようにしたいと思うかもしれません。

psql --set ON_ERROR_STOP=on dbname < infile

どちらにしても、部分的にリストアされたデータベースにしかなりません。 他に、ダンプ全体を1つのトランザクションとしてリストアするように指定することができます。 こうすれば、リストアが完全に終わるか、完全にロールバックされるかのどちらかになります。 このモードは、psqlのコマンドラインオプションに-1または--single-transactionを渡すことで指定できます。 このモードを使用する場合、数時間かけて実行していたリストアが軽微なエラーでロールバックしてしまうことに注意してください。しかし、部分的にリストアされたダンプから手作業で複雑なデータベースを整理するよりまだましかもしれません。

pg_dumppsqlではパイプから読み書きができるので、あるサーバから別のサーバへデータベースを直接ダンプできます。 以下に例を示します。

pg_dump -h host1 dbname | psql -h host2 dbname

重要

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

バックアップをリストアした後、問い合わせオプティマイザが有用な統計情報を使用できるように、各データベースに対してANALYZEを実行することを勧めます。 より詳しくは、23.1.3. プランナ用の統計情報の更新23.1.6. 自動バキュームデーモンを参照してください。 効率的に大規模なデータをPostgreSQLにロードする方法に関するより多くの勧告については、14.4. データベースへのデータ投入を参照してください。

24.1.2. pg_dumpallの使用

pg_dumpは一度に単一のデータベースのみをダンプします。 また、ロールやテーブル空間についての情報はダンプしません。 (これらはデータベース毎ではなくクラスタ全体のものだからです。) データベースクラスタの全内容の簡便なダンプをサポートするために、pg_dumpallプログラムが提供されています。 pg_dumpallは指定されたクラスタの各データベースのバックアップを行い、そして、ロールやテーブル空間定義などのクラスタ全体にわたるデータを保存します。 このコマンドの基本的な使用方法は

pg_dumpall > outfile

です。 ダンプの結果はpsqlでリストアできます。

psql -f infile postgres

(実際、開始時に任意の既存のデータベース名を指定することができますが、空のクラスタ内にロードする場合は、通常 postgres を使用すべきです。) ロールやテーブル空間の情報をリストアしなければならないので、pg_dumpallのダンプをリストアする時には、データベーススーパーユーザのアクセス権限を確実に必要とします。 テーブル空間を使用している場合、ダンプ内のテーブル空間のパスが新しいインストレーションで適切であることを確認してください。

pg_dumpallはコマンドを発令することによりロール、テーブル空間、およびデータベースを再作成し、それぞれのデータベースに対してpg_dumpを起動します。このことは、それぞれのデータベースには内部的に矛盾がない一方、異なるデータベースのスナップショットは完全に同期しないことを示しています。

クラスタレベルでのデータはpg_dumpall--globals-only オプションを使用して出力することができます。 このコマンドは個々のデータベースにpg_dump コマンドを実行しつつ、フルバックアップを取得する際に必要です。

24.1.3. 大規模データベースの扱い

オペレーティングシステムの中には最大ファイルサイズに制限があるものがあり、大きなpg_dump出力ファイルを作成しているときに問題を引き起こします。 幸運なことに、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のカスタムダンプ書式の使用. もしPostgreSQLzlib圧縮ライブラリインストール済みのシステム上で構築されたのなら、カスタムダンプ書式では出力ファイルに書き出す時にデータを圧縮します。 gzipを使用した時と似通ったダンプサイズとなりますが、テーブルの復元を部分的に行えるという点で優れていると言えます。 以下のコマンドは、カスタムダンプ書式でのデータベースのダンプを行います。

pg_dump -Fc dbname > filename

カスタム書式のダンプはpsql用のスクリプトではありませんので、代わりにpg_restoreでリストアしなければなりません。例えば以下のようにします。

pg_restore -d dbname filename

詳細はpg_dumppg_restoreのリファレンスページを参照してください。

巨大なデータベースに対しては、そのほかの2つの手法のうちの1つと一緒にsplitを組み合わせる必要があるかもしれません。

pg_dumpの並列実行. pg_dumpを並列実行することで、大きなデータベースのダンプを高速に実行することができます。 これは同時に複数テーブルのダンプを実行します。 並列度は-jパラメータを指定することで制御できます。 並列ダンプはディレクトリダンプ書式のみサポートします。

pg_dump -j num -F d -f out.dir dbname

pg_restore -jコマンドでダンプファイルを並列でリストアすることができます。これはpg_dump -jでダンプファイルが作成されたか、否かにかかわらず、カスタムもしくはディレクトリダンプ書式で作成されたダンプファイルに使用できます。