PostgreSQL中partman.run_maintenance_proc()默认分区含特殊日期值的执行问题咨询
解决pg_partman维护时因默认分区特殊值导致的内存溢出问题
核心问题原因
pg_partman的run_maintenance_proc()在检测到默认分区中存在超出当前已创建分区范围的极值时,会尝试自动创建所有中间分区以覆盖该极值(比如从当前最新分区一直到9999-12),这直接导致内存耗尽。
分步解决方案
1. 彻底处理现有9999-12-31特殊值
你已经创建了对应分区,接下来需要完成数据迁移并确保默认分区不再包含超出范围的数据:
- 迁移默认分区中
efftv_to_dt = '9999-12-31 00:00:00'的数据到新分区:INSERT INTO test.acct_p9999_12 SELECT * FROM test.acct_default WHERE efftv_to_dt = '9999-12-31 00:00:00'; - 删除默认分区中的对应数据:
DELETE FROM test.acct_default WHERE efftv_to_dt = '9999-12-31 00:00:00'; - (可选)如果默认分区已无数据,可以将其 detach,避免后续误插入:
ALTER TABLE test.acct DETACH PARTITION test.acct_default;
2. 配置pg_partman防止无限制创建分区
修改partman的分区配置,添加停止创建到最后一个分区的限制:
- 针对
test.acct表更新partman配置:UPDATE partman.part_config SET stop_at_last_partition = true, retention = '12 months' -- 根据业务需求设置保留周期 WHERE parent_table = 'test.acct';
stop_at_last_partition参数会让partman只创建到当前规划的最后一个分区,不会因为极值无限制扩展。
3. 预防未来出现其他特殊值
- 添加表级约束,限制
efftv_to_dt的取值范围(根据业务合理设置上限,比如2100-01-01):
这样可以直接阻止超出合理范围的值插入,从源头避免问题。ALTER TABLE test.acct ADD CONSTRAINT chk_efftv_to_dt_range CHECK (efftv_to_dt < '2100-01-01 00:00:00'); - 定期监控默认分区的数据量:
可以创建定时任务检查默认分区是否有数据,一旦发现及时处理:SELECT count(*) FROM test.acct_default;
验证维护命令
完成上述配置后,重新执行维护命令:
CALL partman.run_maintenance_proc();
内容的提问来源于stack exchange,提问作者Hieu Hoang
相关产品推荐
相关产品推荐

