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

pg_partman 被未来数据卡住:检查 ignore_default_data

默认分区中的未来记录使 pg_partman 维护尝试挂载异常范围,检查 5.4.3 的 ignore_default_data。恢复当前维护后,仍需处理已有记录与分区缺口。

按天分区的表,某台采集主机时钟短时跑到了几个月以后。未来记录落入默认分区,随后 pg_partman 维护失败,正常日期的分区也不再继续创建。日志中的失败操作却在挂载一个未来分区:

ERROR: updated partition constraint for default partition "history_default"
       would be violated by some row

这种情况要同时核对失败分区的范围、默认分区中的数据和 pg_partman 配置。不要只增加 premake,也不要把默认分区中的记录全部删除。

为什么未来记录会影响当前维护

没有对应子分区时,父表会将记录路由到已存在的默认分区。创建新子分区后,默认分区的允许范围需要排除这个新范围;如果其中已经有属于新范围的记录,PostgreSQL 就会拒绝挂载。

在 pg_partman 5.4.3 中,ignore_default_data 控制维护判断是否需要创建子分区时,要不要考虑默认分区里的数据。默认值是 true,但现有分区集的配置可能仍是 false。不能仅凭扩展已经升级到 5.x,就认定实际配置已经改变。

若它为 false,异常未来数据可能影响维护选择的范围;维护尝试挂载那个未来分区时,又被默认分区中的同范围行阻止。是否属于这个场景,应以日志中的 ATTACH PARTITION 范围与实际配置为依据。

先查安装版本与这个分区集

下面按 pg_partman 5.4.3 的配置字段说明。示例扩展 schema 为 partman,父表为 public.history;两者都应替换成实际名称。只读查询先确认连接目标和扩展位置:

SELECT current_database(), current_user, version();

SELECT e.extversion, n.nspname AS extension_schema
FROM pg_extension AS e
JOIN pg_namespace AS n ON n.oid = e.extnamespace
WHERE e.extname = 'pg_partman';

SELECT parent_table, control, partition_interval, epoch,
       premake, ignore_default_data, retention
FROM partman.part_config
WHERE parent_table = 'public.history';

对照父表定义与错误 SQL,确认控制列是时间戳还是 epoch 数值,单位与时区是否正确。日期偏离可能来自采集端时钟,也可能来自单位转换或业务输入;只有核对真实记录后才能决定数据是否无效。

确认为 false 时,可恢复正常维护的判断范围

如果已经确认异常未来数据影响维护选择,而正常维护应忽略这些默认分区数据,可以由获准的维护角色将该分区集设为 true。先记录原配置、保留数据备份,并确认没有其他维护任务同时修改它:

UPDATE partman.part_config
SET ignore_default_data = true
WHERE parent_table = 'public.history'
  AND ignore_default_data = false
RETURNING parent_table, ignore_default_data;

这只改一个分区集的维护配置,不会搬迁、删除或修正默认分区中的记录。没有返回行时,先核对父表名与当前配置,不要改成没有 WHERE 的全表更新。

在既定维护窗口重新运行这个分区集的维护。以下是 5.4.3 已确认签名的示例;其他安装版本应先核对对应函数:

SELECT partman.run_maintenance(p_parent_table := 'public.history');

这个调用还会执行该分区集启用的保留策略,可能影响旧分区,并非只创建一张空表。运行前确认 retention 及相关保留选项、锁等待和存储开销,按现有维护流程执行。若需要恢复配置,只撤回本次字段改动;已经完成的分区创建或保留处理不会随配置回退自动撤销。

当前维护恢复后,默认分区里的数据仍要处理

ignore_default_data = true 不保证以后永远不再报错。当正常时间窗口推进到那些未来记录的范围时,创建相应子分区仍可能遇到同一个约束冲突。

先判断记录的业务有效性。有效数据应按已安装版本支持的 partition_data_* 或相应过程迁入正确分区,并处理可能存在的分区范围缺口;提前确认函数签名、分批提交方式、并发写入、锁及目标边界。不能直接拿另一版本的过程参数处理生产数据。

若时间值确实错误,应保留原记录与核对依据,按业务修正流程处理采集端和受影响数据。删除默认分区、删除所有未来行或临时跳过完整性检查,都可能掩盖需要保留的数据。

验收时分别看维护日志、当前与预建分区范围,以及默认分区的积压。正常日期继续建分区,说明当前维护恢复;默认分区中的异常记录已被逐项处理、后续采集时间正确,才说明引发这次问题的输入也已处理。