-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テーブルあたりのデータ量が大きいダンプほど、並列度を上げることでリストア時間の短縮効果が大きくなる。

pg_dump
pg_restore