系统表数据不一致导致悬空引用进而引发pg_dump备份失败
文章目录环境症状问题原因解决方案环境系统平台Linux x86-64 Red Hat Enterprise Linux 7版本4.5.8症状执行 pg_dump 时出现以下两个错误--错误一 schema with OID 39855 does not exist OID 为 39855 的模式不存在 --错误二 failed sanity check, parent table with OID 40001 of pg_rewrite entry with OID 40004 not found 健全检查失败,pg_rewrite项OID 40004 的源表 OID40001 未找到问题原因根本原因是数据库内部的系统表数据不一致存在“悬空引用“pg_dump的完整性检查无法通过。具体来说第一个错误某个数据库对象如表、函数声称自己属于OID为39855的模式但pg_namespace模式表中根本不存在这个模式。第二个错误pg_rewrite规则表中的一条记录OID 40004声称自己依附于某个父表OID 40001但这个父表在pg_class对象表中根本不存在。这些不一致通常是异常断电、磁盘故障或之前某些删除操作未正确清理残留造成的。解决方案在有问题的database下查找孤立对象并清理。通过查询系统目录定位问题对象然后手动修复。第一个错误的解决方案-- 查找引用了不存在 schema 的对象highgo# SELECT c.oid, c.relname, c.relnamespaceFROMpg_class cWHERENOTEXISTS(SELECT1FROMpg_namespace nWHEREn.oidc.relnamespace);-- 查找引用了不存在 schema 的存储过程highgo# SELECT c.oid, c.proname, c.pronamespaceFROMpg_proc cWHERENOTEXISTS(SELECT1FROMpg_namespace nWHEREn.oidc.pronamespace);-- 查找引用了不存在 schema 的数据类型highgo# SELECT c.oid, c.typname, c.typtype, c.typnamespaceFROMpg_type cWHERENOTEXISTS(SELECT1FROMpg_namespace nWHEREn.oidc.typnamespace);-- 查找引用了不存在 schema 的操作符highgo# SELECT c.oid, c.oprname, c.oprnamespaceFROMpg_operator cWHERENOTEXISTS(SELECT1FROMpg_namespace nWHEREn.oidc.oprnamespace);-- 查找引用了不存在 schema 的操作符类highgo# SELECT c.oid, c.opcname, c.opcnamespaceFROMpg_opclass cWHERENOTEXISTS(SELECT1FROMpg_namespace nWHEREn.oidc.opcnamespace);找到孤立记录后把相关系统表中损坏对象的模式schema更新为一个已知存在的模式OID如public模式的OID。--示例UPDATEpg_classSETrelnamespace(SELECToidFROMpg_namespaceWHEREnspnamepublic)WHERErelnamespace39855;UPDATEpg_typeSETtypnamespace(SELECToidFROMpg_namespaceWHEREnspnamepublic)WHEREtypnamespace39855;第二个错误的解决方案-- 查找 pg_rewrite 中引用了不存在表的规则/视图highgo# SELECT r.oid, r.rulename, r.ev_classFROMpg_rewrite rWHERENOTEXISTS(SELECT1FROMpg_class cWHEREc.oidr.ev_class);找到孤立记录后使用 DELETE 从系统目录删除需超级用户-- 示例删除孤立视图/规则谨慎操作highgo# CREATE TABLE pg_rewrite_bak AS SELECT * FROM pg_rewrite LIMIT 0; -- 创建备份表highgo# INSERT INTO pg_rewrite_bak SELECT * FROM pg_rewrite WHERE oid 40004; -- 孤立的记录保存到备份表中highgo# DELETE FROM pg_rewrite WHERE oid 40004; -- 需超级用户谨慎使用注意事项对 pg_rewrite、pg_class 等系统目录直接执行 DELETE 有风险务必先备份或在测试环境验证生产环境操作前请确认已有可用的物理备份pg_basebackup