尝试将数据库从一个系统复制到另一个系统。涉及的版本为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
的错误。
在源数据库上,例如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)
这实际上从转储中排除了违规的CCD_ 18/CCD_。问题已解决。
要恢复数据库,请运行以下命令:
pg_restore -x --no-owner -d db_name backup.dump
使用以下命令恢复数据库备份
pg_restore--没有特权--没有所有者-h localhost-p<DB_端口>-U<;数据库用户>-d<;数据库名称>-1<;DB_Backup_Path>
使用标志--没有权限防止恢复访问权限(授予/撤销命令)和
--无所有者防止将对象的所有权设置为与原始数据库匹配
如果您已将数据库导出为"自定义";文件类型,可以使用以下命令。
pg_restore -c -U <USERNAME_FOR_DATABASE -d <DATABASE_NAME> -v <PATH_NAME_IN_STRING> -W
请确保您已经创建了一个数据库,并指定了文件的正确用户名和路径名。