トップ  »  Tech  »  Linux server

基本的には、PostgreSQLのpg_dump、pg_dumpallコマンドを利用してデータベースをdumpすることでバックアップをします。


作業の流れとしては、各DBはpg_dumpで個別のファイルに落とし、全体の設定をpg_dumpallコマンドに-sオプションを付与してファイルに保存します。リストア時にはpg_dumpall -sの結果と、pg_dumpの結果を使用します。


pg_dump

pg_dumpコマンドに-cオプションを付けて各データベースをバックアップします。SQL文が標準出力に表示されるので、リダイレクトでファイルに保存します。

[root]# pg_dump -h localhost -U pgsql -c DBName > DBName.dump

pg_dumpのオプション -c でdrop databaseする文を追加している。これは、restore時に「既存DBを破棄してから復元」という処理ができるようになる。


PostgreSQLのmanよりオプション「-c」の解説。

  -c
  --clean
    Output  commands  to clean (drop) database objects prior
    to (the commands for) creating them.
    This option is only meaningful for the  plain-text  format.
    For the  archive  formats,  you may specify the option 
    when you call pg_restore.

以上を各DBについて実施します。template0とtemplate1は不要。postgresはダミーの空データベースなので、これもdump不要。


pg_dumpで各データベース毎に作成したdump結果にはcreate database文が含まれない。リストア作業前にcreate databaseするか、pg_dumpall -sの結果を使ってdatabaseを生成した後にリストアをする。


ここでは、pg_dumpで各DB内のデータを取り、pg_dumpall -sで全体の構成とテーブル定義を取得するという二段構えの方針で進める。しかし、pg_dumpとpg_dumpallの結果でどちらにもテーブル生成のSQL文が含まれる。psqlコマンドでの復元では"データのみ"というオプションが無いため、一見すると無駄なようにも思える。

そこでpg_dumpで各データベース毎に「データのみ」「スキーマのみ」の2段階にしても良いかもしれない。

全体リストア時にはpg_dumpallのスキーマと、pg_dumpのデータのみがあれば可能。個別データベースのファイルで「スキーマのみ」は、個別のデータベース復元の際に利用する...など。


pg_dumpall

スキーマおよびユーザ等のdumpをpg_dumpallコマンドで出力します。各データベースのdumpだけではroleの情報が出力されないため、pg_dumpallコマンドにオプション -s を付けてスキーマのみを取得します。各データベースはpg_dumpコマンドで取れているので、pg_dumpallを実施すると2重にデータが溜まって無駄になるため。

[root]# pg_dumpall -h localhost -U pgsql -c -s > pgframe.dump

オプションについて。

-sだとスキーマのみを出力する。
-cはpg_dumpと同じ。create前に既存をdropする。

PostgreSQLのmanより-sオプションの解説。

  -s
  --schema-only
    Dump only the object definitions (schema), not data.

以上のpg_dumpコマンドとpg_dumpallコマンドの結果をバックアップデータとして保存します。


バックアップ自動化のために

pg_dumpコマンドとpg_dumpallコマンドはどのユーザでも実行できますが、全体のバックアップを取るためには、それなりのアクセス権を持っている必要があります。


また、自動実行のためにPostgreSQLにパスワード無しでログインする仕組みも必要になります。localhost運用と言えどtrust認証は良くないため、ここでは.pgpassファイルを使います。内容は次の通りです。

localhost:5432:*:pgsql:password

1行に「DBホスト:ポート:DB名:ユーザ:パスワード」を書きます。DB名を*にすると全てのデータベースにアクセスできます。


このように ~/.pgpass を設定すると、コマンドラインのpsqlやpg_dumpを使う際にいちいちパスワードを入力する手間が省けます。なお、~/.pgpassファイルはパーミッションを600にしてオーナーのみが閲覧できるようにしなければなりません。


PostgreSQLのリストア

リストア先でPostgreSQLのデータベースが初期化されており、かつ、スーパーユーザpgsqlにパスワードが設定されログイン可能状態にあるものとします。


まずPostgreSQLを起動します。

[root]# service pgsql start

最初にpg_dumpallで取得したpg_frame.dump結果を利用してロールとスキーマを復元します。この作業時に既存のロールやスキーマはいったん削除されてからcreateされます。

[root]# psql -h localhost -U pgsql -f pgframe.dump postgres

空のデータベースであるpostgresを指定します。DBを指定しないとpsqlでエラーになります。


復旧が終了すると、dump元でのデータベースとテーブル、各ユーザ情報が生成されています。


次に各データベース内のデータを復旧させていきます。pg_dumpallの結果で各DBのテーブルが生成されており、ここでの処理でdropして再度createされますが気にしないように。

[root]# psql -h localhost -U pgsql -f DBName.dump DBName
  ~以降、全データベースに対して繰り返し適用。

リストア後にバキュームとアナライズを実施します。vaccumdbコマンドを使用し、オプション-aで全データベース対象。オプション-zでアナライズ実施。

[root]# vacuumdb -h localhost -U pgsql -a -z

以上でデータのリストアは終了です。復元後にpgsqlなどのユーザで各データベースにアクセスできるかを確認しておきます。

[root]# psql -h localhost -U pgsql testdb1
=# \d

より簡単なバックアップ&リストア方法

PostgreSQLを停止しても構わない場合はdumpよりも簡単にバックアップする方法がある。それはPostgreSQLのデータディレクトリを丸ごとコピーすることである。


1. PostgreSQL停止

[root]# service pgsql stop

2. データディレクトリをtarでまとめる。

[root]# cd /usr/local/pgsql
[root]# tar cvzf /tmp/pgsql_data.tgz ./data

3. tarファイルをバックアップ先にコピー。

4. バックアップ先で/usr/local/pgsqllに展開。

5. ログファイルをホスト名に合わせてリネーム。


以上でデータベースを丸ごと移設することができます。


この作業を行なう前後でinitdbコマンドの実行は不要です。対象ホストにPostgreSQLがインストールされてさえいればよい。dataディレクトリ以下を丸ごと移すので初期化処理をしなくても移設元のデータが利用されるため。