DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

用了 --no-owner,pg_restore 仍报 role does not exist

恢复数据库时缺少旧角色:区分OWNER与GRANT/REVOKE,核对no-owner和no-acl范围,选择角色迁移或重新分配目标权限。

把备份恢复到新实例时,日志出现 role "app_reader" does not exist。即使加入 --no-owner,错误也可能继续:恢复脚本除了设置对象所有者,还可能向旧角色授予或撤销权限。

先找日志中 Command was: 对应的 SQL。ALTER ... OWNER TO 与 GRANT ... TO 是不同问题,不能仅凭缺失角色的名字选择参数。以下按 PostgreSQL 18 的工具说明,自定义或目录格式归档由 pg_restore 处理;普通 SQL 文件应另按 psql 的恢复流程检查。

数据库备份没有附带整个实例的角色

pg_dump 导出一个数据库,不会连同实例级角色一起创建。归档里可以保留原所有者和权限配置,因此目标端可能有表和数据,却缺少被这些命令引用的角色。源实例上能查到一个用户,也不能证明新实例已创建它。

在目标连接检查实际身份与缺失名称,app_reader 是示例:

SELECT current_database(), session_user, current_user;

SELECT rolname, rolcanlogin
FROM pg_roles
WHERE rolname = 'app_reader';

没有返回行就表示这个实例没有该角色。PostgreSQL 的用户也是角色,只是具有登录能力;不需要分别创建同名“用户”和“角色”。角色名称大小写、引用方式及实际连接的实例也要对照。

--no-owner 和 --no-acl 分别省略什么

--no-owner 省略恢复原所有权的命令,新创建对象按实际恢复身份拥有。它不会同时省略 GRANT 和 REVOKE。--no-acl 才用于跳过权限恢复,也可写作 --no-privileges。

如果目标环境已决定重新分配所有权和权限,可以先离线生成 SQL 预览。下面的 POSIX shell 示例不连接数据库执行恢复;文件名是占位值,输出含有数据库内容,应保存在受控目录:

umask 077
pg_restore --no-owner --no-acl \
  --file=restore-preview.sql backup.dump

检查预览中缺失角色是否仍被其他对象引用,例如策略或角色相关设置。两个选项只处理各自说明的命令,不是移除整个数据库中一切角色依赖。原归档保留,不对二进制文件执行文本替换。

正式恢复采用同样参数前,要批准目标所有者及应用权限方案。跳过原 ACL 后,业务账号不一定能读写,新旧权限也不一定等价;需要按目标环境重新授权和验证。不能把“恢复日志没有缺角色错误”当成权限迁移已完成。

需要保留旧权限时,先迁移角色

若目标必须保留原所有者和 ACL,则应先核对并迁移相关角色。实例级角色可用 pg_dumpall --roles-only 单独导出;导出内容可能含口令散列、成员关系和较大权限,必须审阅后由适当维护身份导入,不能直接覆盖已有目标角色的设计。

角色名存在仍不足以证明成员关系、登录方式和权限正确。托管数据库还可能限制角色管理或导入方式,应使用该服务支持的流程。给恢复账号增加 pg_write_server_files 或超级用户权限,并不会替它创建缺失角色;客户端恢复也通常不需要服务器文件读取权限。

恢复失败后,默认模式可能已留下部分对象或数据。保存完整日志和退出码,在独立空库核对恢复方案;不要直接重跑同一归档,也不要临时加 --clean 清除冲突。正式目标的处理必须按备份与切换方案进行。

最后用应用实际账号验证必要读写与禁止操作,并检查对象所有者、成员关系和权限清单。回退参数不会撤销已经创建的对象或授予的权限,需要保留目标变更前记录。如果失败的是 COMMENT ON EXTENSION,应另查扩展注释的所有权,--no-owner 同样不能代替那项判断。