pg_dump, pg_restore 実行時のパラメータ
-j
パラメータを指定する
-j, --jobs=NUM use this many parallel jobs to dump
https://www.postgresql.org/docs/9.5/static/app-pgdump.html
https://www.postgresql.org/docs/9.5/static/app-pgrestore.html
pg_dump の場合
$ pg_dump -j -v NUMBER_OF_PARALLEL_JOBS -Fd -U POSTGRES_USER -h POSTGRES_HOST -d DB_NAME -f OUTPUT_DIRECTORY
-
-Fd
(directory output) と一緒にしか使えない。-Fc
等は不可。 - streaming replication をしているslaveサーバに対しては以下のエラーが出て実行できず、primaryサーバでのみ実行可能だった。
pg_dump: [archiver (db)] query failed: ERROR: cannot assign TransactionIds during recovery
pg_dump: [archiver (db)] query was: SELECT pg_catalog.pg_export_snapshot()
- 自分が試した範囲では、並列数を増やすとほぼ線形に時間が短縮され、DBと同じコア数のサーバでpg_dumpを走らせ、
NUMBER_OF_PARALLEL_JOBS
をコア数に合わせた時が最速だった。 - ただし、1プロセスで1テーブルを順々にdumpしているようで、最も大きなテーブルのdumpに必要な時間にひきづられて、そこからは時間が短縮できなくなった
- (要ソース/ドキュメント確認) 並列で動かした時は実行時間を最小にするため、大きなテーブルを最初に処理している。並列で無い時はテーブル名のアルファベット順。pg_restoreの処理される順番はdumpと一緒になるので、pg_restoreを並列で実行する場合はpg_dumpも並列で行うほうが望ましいっぽい
pg_restore の場合
$ pg_restore -j NUMBER_OF_PARALLEL_JOBS -Fd -U POSTGRES_USER -h POSTGRES_HOST -d DB_NAME --format=directory DUMP_FILE_DIRECTORY
- こちらは
NUMBER_OF_PARALLEL_JOBS
を増やしてもpg_dumpほどの性能向上は見られず。restrictionのチェック等の関係で並列に走らせれる箇所が限られているっぽい。 - データ量が多いが、制約が少ないデータベースであれば、大きな向上があるのかもしれない。(未確認)
- (要ソース/ドキュメント確認) pg_dumpを並列で行わなかった場合、pg_restoreを並列にしても、テーブル名のアルファベット順でrestoreが行われたので、最後にheavyなテーブルが来た場合は少しオーバーヘッドが生まれる可能性がある。
Postgresql本体のparameter設定
maintenance_work_mem
, checkpoint_segments
, checkpoint_timeout
パラメータの見直し、autovacuumのdisableなどを行っておく。 サーバのスペック等に依存するので、自分で色々と試してみるべし。restoreが終わったらパラメータを元に戻すのを忘れずに。また、RDS独自のconfigとして、RDSのmulti-AZを無効にすることや、EBSのIOPSに関する箇所が影響(gp2を使う場合はdiskサイズによって、IOPSが変わり、また初期クレジットがあるので、diskサイズによってはクレジットがある状態でpg_restoreをした方が速い)します。
参考:
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Procedural.Importing.html
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html