★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

第 23章バックアップとリストア

目次
23.1. SQLによるダンプ
23.1.1. ダンプのリストア
23.1.2. pg_dumpallの使用
23.1.3. 大規模データベースの扱い
23.2. ファイルシステムレベルのバックアップ
23.3. オンラインバックアップとポイントインタイムリカバリ(PITR)
23.3.1. WAL保管の設定
23.3.2. ベースバックアップの作成
23.3.3. オンラインバックアップを使用した復旧
23.3.4. 時系列
23.3.5. 警告
23.4. リリース間の移行

貴重なデータを全て保存しているため、PostgreSQLデータベースは定期的にバックアップされなければなりません。 バックアップの手順は基本的に簡単ですが、使用されている技術といくつかの仮定となる条件の基本的理解は重要です。

PostgreSQLのデータをバックアップする場合、3つの異なる手法があります。

それぞれ長所と短所があります。

23.1. SQLによるダンプ

SQLによるダンプ方法の背景にある考え方はSQLコマンドでテキストファイルを生成し、そのファイルをサーバが再度読み込みを行った時に、ダンプした時点と同じ状態が再構築されるということです。 この目的のため、PostgreSQLpg_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の接続は(第20章で説明されている)通常のクライアント認証方法によることを思い出してください。

pg_dumpで作成されたダンプは、内部的に整合性があります。つまり、pg_dumpが行われている際のデータベース更新はダンプに含まれません。pg_dumpの操作はデータベースに対する他の作業を妨げません(VACUUM FULL などの、排他的なロックが必要な作業は例外です)。

重要項目: (例えば外部キーのように)データベーススキーマがOIDに依存している場合、pg_dumpにOIDも一緒にダンプするよう指定しなければなりません。これを行うには-oコマンドラインオプションを使用します。

23.1.1. ダンプのリストア

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

psql dbname < infile

ここでinfilepg_dumpコマンドでoutfileとしたものです。 dbnameデータベースはこのコマンドでは作成されません。 (例えばcreatedb -T template0 dbname のようにして)psqlを実行する前に自分でtemplate0から作成してください。 psqlにはpg_dumpと似たような、データベースサーバの場所とユーザ名を指定する機能があります。 詳細については、psqlのリファレンスページを参照してください。

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

リストアした後、オプティマイザが有用な統計情報を持つように、各データベースに対してANALYZEを実行することを勧めます。 簡単な方法は、vacuumdb -a -zを実行して全てのデータベースに対してVACUUM ANALYZEを行うことです。 これは、手作業でVACUUM ANALYZEを実行することと同じです。

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

pg_dump -h host1 dbname | psql -h host2 dbname

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

効率的に大規模なデータをPostgreSQLにロードする方法に関する案内については、項13.4を参照してください。

23.1.2. pg_dumpallの使用

上で説明した手法はデータベースクラスタ全てをバックアップする際に扱いにくく不適切です。 この理由でpg_dumpallプログラムが提供されています。 pg_dumpallは指定されたクラスタの各データベースのバックアップを行い、そして、ユーザやグループなどのクラスタ全体にわたるデータを保存します。 このコマンドの基本的な使用方法は

pg_dumpall > outfile

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

psql -f infile postgres

(実際、開始時に任意の既存のデータベース名を指定することができますが、空のクラスタ内に再ロードする場合は、一般的に postgres を使用すべきです。) ユーザとグループの情報をリストアしなければならないので、pg_dumpallのダンプをリストアする時には、データベーススーパーユーザのアクセス権限を確実に必要とします。

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

PostgreSQLはシステム上で最大可能なファイルサイズよりも大きなテーブルを扱えるので、ファイルにダンプする際に、システムで許容されているファイルサイズを超えてしまうという問題に遭遇する可能性があります。 pg_dumpは標準出力に書き出しますので、この問題を解決するためにUnix標準のツールを使用して回避できます。

圧縮ダンプの使用. gzipのような好みの圧縮プログラムを使うことができます。

pg_dump dbname | gzip > filename.gz

元に戻すには次のようにします。

createdb dbname
gunzip -c filename.gz | psql dbname

あるいは次のようにもできます。

cat filename.gz | gunzip | psql dbname

splitの使用. splitコマンドで結果を使用しているファイルシステムが受け付けられる大きさに分割することができます。 例えば1メガバイトずつに分割するには次のようにします。

pg_dump dbname | split -b 1m - filename

元に戻すには次のようにします。

createdb dbname
cat filename* | psql dbname

カスタムダンプ書式の使用. もしPostgreSQLzlib圧縮ライブラリインストール済みのシステム上で構築されたのなら、カスタムダンプ書式では出力ファイルに書き出す時にデータを圧縮します。 gzipを使用した時と似通ったダンプサイズとなりますが、テーブルの復元を部分的に行えるという点で優れていると言えます。 以下のコマンドは、カスタムダンプ書式でのデータベースのダンプを行います。

pg_dump -Fc dbname > filename

カスタム書式のダンプはpsql用のスクリプトではありませんので、代わりにpg_restoreでリストアしなければなりません。 詳細はpg_dumppg_restoreのリファレンスページを参照してください。