PostgreSQL 11升级至16时pg_dump角色OID不存在错误求助
PostgreSQL 11升级至16时OID缺失角色的解决方法
问题场景
将PostgreSQL 11升级至16时,执行pg_upgrade报错:pg_dump: error: role with OID 21338 does not exist,源库在11版本下运行正常,但升级时因缺失对应OID的角色导致失败。以下是两种解决方法:
方法1:创建指定OID的角色
PostgreSQL默认不支持创建角色时直接指定OID,需通过修改系统表实现,操作需在**源库(PostgreSQL 11)**中执行:
以超级用户
postgres登录源库:psql -U postgres创建临时角色(名称可自定义):
CREATE ROLE temp_role WITH LOGIN PASSWORD 'your_secure_password'; -- 若无需登录权限,可去掉WITH LOGIN备份系统角色表(操作前务必备份,防止出错):
CREATE TABLE pg_authid_backup AS SELECT * FROM pg_catalog.pg_authid;修改临时角色的OID为目标值21338:
UPDATE pg_catalog.pg_authid SET oid = 21338 WHERE rolname = 'temp_role';(可选)若知道原角色名称,将临时角色重命名为原名称:
ALTER ROLE temp_role RENAME TO original_role_name;
方法2:修复关联异常OID的对象至现有角色
找出所有所有者为OID 21338的数据库对象,将其所有者变更为已存在的合法角色,操作同样在**源库(PostgreSQL 11)**中执行:
步骤1:查询关联OID 21338的对象
执行以下SQL查询所有受影响的表、视图、序列、函数:
-- 查询表、视图、物化视图、序列 SELECT n.nspname AS schema_name, c.relname AS object_name, CASE c.relkind WHEN 'r' THEN 'TABLE' WHEN 'v' THEN 'VIEW' WHEN 'm' THEN 'MATERIALIZED VIEW' WHEN 's' THEN 'SEQUENCE' ELSE c.relkind::TEXT END AS object_type FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE c.relowner = 21338; -- 查询函数 SELECT n.nspname AS schema_name, p.proname AS function_name, pg_get_function_identity_arguments(p.oid) AS function_args FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid WHERE p.proowner = 21338;
步骤2:批量修改对象所有者
将以下SQL中的existing_role替换为你要指定的现有角色名称,执行即可批量变更所有者:
DO $$ DECLARE rec RECORD; BEGIN -- 处理表、视图、物化视图、序列 FOR rec IN SELECT 'ALTER TABLE "' || n.nspname || '"."' || c.relname || '" OWNER TO existing_role;' AS cmd FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE c.relowner = 21338 AND c.relkind IN ('r', 'v', 'm', 's') LOOP EXECUTE rec.cmd; END LOOP; -- 处理函数 FOR rec IN SELECT 'ALTER FUNCTION "' || n.nspname || '"."' || p.proname || '"(' || pg_get_function_identity_arguments(p.oid) || ') OWNER TO existing_role;' AS cmd FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid WHERE p.proowner = 21338 LOOP EXECUTE rec.cmd; END LOOP; END $$;
验证
执行步骤1的查询语句,确认无返回结果,说明所有关联对象已修复。
内容的提问来源于stack exchange,提问作者fluffy_mart
相关产品推荐
相关产品推荐

