-jオプションとは
pg_dumpの-Fc(カスタムフォーマット)で取得したダンプは、pg_restoreの-j(--jobs)オプションで複数テーブルを並列にリストアできる。ダンプ内のテーブルは互いに独立したエントリとして格納されているため、-jに指定した数のプロセスで同時にデータロードやインデックス作成を進められる。
プレインテキスト形式のダンプは先頭から順にSQL文を実行する仕組みのため、この並列リストアは利用できない。
$ pg_restore -U postgres -d restoredb -j 4 dump.sql
pg_restore: error: input file appears to be a text format dump. Please use psql.
プレインテキスト形式のダンプはそもそもpg_restoreの対象外であり、psqlでリストアする必要がある。
並列リストアの効果を確認する
1テーブルあたり200万行のデータを持つ4つのテーブルをダンプし、-jの有無でリストア時間を比較する。
CREATE TABLE t1 (id serial PRIMARY KEY, val text);
CREATE TABLE t2 (id serial PRIMARY KEY, val text);
CREATE TABLE t3 (id serial PRIMARY KEY, val text);
CREATE TABLE t4 (id serial PRIMARY KEY, val text);
INSERT INTO t1 (val) SELECT md5(random()::text) FROM generate_series(1, 2000000);
INSERT INTO t2 (val) SELECT md5(random()::text) FROM generate_series(1, 2000000);
INSERT INTO t3 (val) SELECT md5(random()::text) FROM generate_series(1, 2000000);
INSERT INTO t4 (val) SELECT md5(random()::text) FROM generate_series(1, 2000000);
$ pg_dump -U postgres -Fc mydb -f dump.custom
-jを指定せずにリストアすると、テーブルが順番に処理される。
$ time pg_restore -U postgres -d restoredb_single dump.custom
real 0m3.970s
-j 4を指定すると、4つのテーブルが並列に処理される。
$ time pg_restore -U postgres -d restoredb_parallel -j 4 dump.custom
real 0m2.735s
同じダンプファイルでも、並列度を上げることでリストア時間が短縮されている。今回の環境(4コア)ではおよそ3割短縮されており、テーブル数やデータ量が多いダンプほど効果は大きくなる。
ディレクトリフォーマットでも利用できる
並列リストアはカスタムフォーマットだけでなく、-Fd(--format=directory)で取得したディレクトリフォーマットのダンプでも利用できる。ディレクトリフォーマットはテーブルごとに個別のファイルへ出力する形式であり、pg_dump自体も-jで並列にダンプできる。
$ pg_dump -U postgres -Fd mydb -f dump_dir -j 4
$ pg_restore -U postgres -d restoredb -j 4 dump_dir
まとめ
pg_restoreの-jオプションは、カスタムフォーマットとディレクトリフォーマットのダンプを複数プロセスで並列にリストアする機能である。プレインテキスト形式では利用できず、psqlで先頭から順に実行するしかない。テーブル数が多い、または1テーブルあたりのデータ量が大きいダンプほど、並列度を上げることでリストア時間の短縮効果が大きくなる。
