あるシステムから別のシステムにデータベースを複製しようとしています。関係するバージョンは9.5.0(ソース)と9.5.2(ターゲット)です。
ソースデータベース名はfoodb
で、所有者はpgdba
で、ターゲットデータベース名はfoodb_dev
で、所有者はpgdev
です。
すべてのコマンドは、レプリカをホストするターゲットシステムで実行されます。
pg_dump
コマンドは次のとおりです。
pg_dump -f schema_backup.dump --no-owner -Fc -U pgdba -h $PROD_DB_HOSTNAME -p $PROD_DB_PORT -d foodb -s --clean;
これはエラーなしで実行されます。
対応するpg_restore
は次のとおりです。
pg_restore --no-owner --if-exists -1 -c -U pgdev -d foodb_dev schema_backup.dump
エラーがスローされます:
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 3969; 0 0 ACL public pgdba
pg_restore: [archiver (db)] could not execute query: ERROR: role "pgdba" does not exist
Command was: REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM pgdba;
GRANT ALL ON SCHEMA public TO pgdba;
GRANT ...
プレーンテキスト形式(-Fp
)でダンプファイルを生成すると、次のようなエントリがいくつか含まれていることがわかります。
REVOKE ALL ON TABLE dump_thread FROM PUBLIC;
REVOKE ALL ON TABLE dump_thread FROM pgdba;
GRANT ALL ON TABLE dump_thread TO pgdba;
GRANT SELECT ON TABLE dump_thread TO readonly;
ユーザーpgdba
の権限を設定しようとします。もちろん、ユーザーpgdev
のみを持つターゲットシステムにユーザーとしても存在しないため、pg_restore
からのエラーが発生します。
ソースdbで、dump_thread
テーブルなどの特権:
# \dp+ dump_thread
Access privileges
-[ RECORD 1 ]-----+--------------------
Schema | public
Name | dump_thread
Type | table
Access privileges | pgdba=arwdDxt/pgdba+
| readonly=r/pgdba
Column privileges |
Policies |
簡単な解決策は、ターゲットクラスターにユーザーpgdba
を追加するだけです。
しかし、--no-owner
は、そもそも所有者固有のコマンドをダンプに含めないように注意すべきではありませんか?
--no-owner
は-x
と同じではないことに気付きました。 -x
をすべてのpg_dump
コマンドに追加しました。
-x, --no-privileges do not dump privileges (grant/revoke)
実際には、問題のGRANT
/REVOKE
コマンドをダンプから除外します。問題は解決しました。