Pg_恢复错误: 角色 XXX 不存在

尝试将数据库从一个系统复制到另一个系统,涉及的版本是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不应该首先注意不在转储中包含所有者特定的命令吗?

52828 次浏览

I realized the --no-owner is not the same as the -x. I added the -x to all pg_dump commands, which means:

-x, --no-privileges          do not dump privileges (grant/revoke)

which in effect excludes the offending GRANT/REVOKE commands from the dump. Problem resolved.

Restore DB backup using below command

pg_restore --no-privileges --no-owner -h localhost -p <DB_Port> -U <DB_User> -d <DB_Name>-1 <DB_Backup_Path>

Use flag --no-privileges To prevent restoration of access privileges (grant/revoke commands) and

--no-owner To prevent setting ownership of objects to match the original database

To restore the db, run the following command:

pg_restore -x --no-owner -d <db name> backup.dump