使用pg_upgrade升级PostgreSQL11至13时报role '29648'不存在错误
根因定位
报错中提到的角色ID29648是源库中曾经创建、后续被删除的角色残留,问题点出在pg_stat_statements扩展的函数权限记录上。
在源库查不到对应OID/名称的角色,是因为角色被删除时,没有同步清理掉挂载在该扩展函数上的ACL权限条目,这些条目里直接存储了旧角色的OID值。pg_dump导出时遇到无法匹配到角色名的ACL条目,会直接把条目中存储的OID作为角色名写入导出脚本,pg_upgrade调用pg_restore在新集群执行脚本时,找不到对应ID的角色就会抛出该错误。
其余数据库、自定义表、约束都能正常还原,也印证了问题仅出在这一条无效的扩展函数权限记录上,不涉及核心数据损坏。
可落地解决方案
方案1:升级前在源库清理残留(最推荐,无副作用)
在重新执行pg_upgrade之前,先连接源端PostgreSQL 11的postgres数据库,执行以下操作清理无效权限残留:
-- 重建扩展会自动清空所有挂载在扩展对象上的无效ACL条目 DROP EXTENSION pg_stat_statements; CREATE EXTENSION pg_stat_statements; -- 按需重新给相关账号授予函数执行权限即可 GRANT EXECUTE ON FUNCTION pg_stat_statements_reset() TO postgres;
操作完成后重新走pg_upgrade流程,不会再触发该报错,原有正常权限配置也不会受影响。
方案2:升级时跳过权限还原
不需要找pg_upgrade给pg_restore传参的特殊配置,pg_upgrade本身原生支持-x/--no-privileges参数,作用就是升级全流程跳过所有对象权限的导出与还原。直接在原本的pg_upgrade执行命令末尾加上-x参数即可执行升级。
注意:该方案升级完成后,需要手动给业务账号重新配置库、表、函数的对应访问权限,避免权限缺失导致业务访问异常。
方案3:已跑到报错步骤的兜底修复
如果不想重头执行全量升级流程,可以直接在当前进度基础上修复:
- 连接新部署的PostgreSQL 13集群的postgres库,执行以下语句重建扩展,清理无效权限:
DROP EXTENSION IF EXISTS pg_stat_statements; CREATE EXTENSION pg_stat_statements;
- 进入pg_upgrade生成的工作目录,找到对应模式还原的SQL脚本,注释掉报错的
pg_stat_statements_reset函数赋权语句,手动执行完剩余还原步骤即可。由于其余业务对象已全部还原成功,仅这一条无效权限语句报错,不会影响核心数据完整性。
内容的提问来源于stack exchange,提问作者TheEnglishMan_
相关产品推荐
相关产品推荐

