环境

系统平台:银河麒麟 (X86_64)
版本:4.7.5

症状

对表执行相关操作(vacuum freeze,alter table等)时报错,提示缺少约束记录。

highgo=# vacuum freeze XXX;
ERROR:  XX000: 1 constraint record(s) missing for rel XXX
STATEMENT:  vacuum freeze XXX;
ERROR:  XX000: 1 constraint record(s) missing for rel XXX
highgo=# 

问题原因

数据库中的每个表在pg_class中有一条记录,名为relchecks的字段记录该表拥有的检查约束(CHECK)总数。而每个检查约束的详细定义则存储在另一个系统表pg_constraint中。 当relchecks的值不等于pg_constraint中实际关联到该表的约束记录数时,数据库在进行某些操作(如查询、修改表结构)时,就会检测到这个不一致,并抛出“constraint record(s) missing for rel 表名”的错误。导致不一致的常见原因有系统表损坏,人为修改系统表。

解决方案

解决方案的核心是使pg_class.relchecks的值与pg_constraint中的实际约束数量保持一致。需要人为修改系统表。

计算表实际拥有的约束数量。你需要找到那个报错的表(假设表名为 your_table_name),并查询pg_constraint。

-- 替换 your_table_name 为实际的表名
SELECT COUNT(*)
FROM pg_constraint
WHERE conrelid = 'your_table_name'::regclass AND contype = 'c';

记下查询的结果,假设为 actual_constraint_count。

更新pg_class表,将relchecks字段修正为正确的数字。

-- 警告:直接更新系统表是危险操作,请务必在测试环境验证并做好备份!
UPDATE pg_class
SET relchecks = actual_constraint_count  -- 替换为上面查询到的实际数量
WHERE oid = 'your_table_name'::regclass;

重新执行操作,报错消失,可正常执行vacuum操作。

highgo=# vacuum freeze test_constmis;
VACUUM

因为不确定系统表损坏程度,需要重建数据库,导出表结构和数据,导入新库使用。

报错编码

XX000

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐