PostgreSQL下Citus列存pg_partman分区表的正确删除方法
错误原因
报错核心是Citus columnar列存储引擎不支持
DELETE ... RETURNING语法与CTID扫描,而pg_partman自带的undo_partition_proc存储过程底层通过DELETE RETURNING分批迁移数据,因此无法适配列存分区表。
正确删除方案
分两种使用场景选择对应操作:
场景1:无需保留任何数据,直接删除全部分区表
这是最简单的方案,直接调用pg_partman提供的drop_parent方法清理元数据并级联删除所有表即可,不需要走数据迁移流程:
-- p_keep_table设为false会同时删除父表和所有子表,自动清理pg_partman的分区注册信息 SELECT partman.drop_parent('public.test', p_keep_table := false);
场景2:需要先保留数据再删除分区表
如果需要先将分区表数据导出到普通表再删除,手动执行数据迁移即可,避开undo_partition_proc的不兼容逻辑:
操作步骤
- 创建结构与原分区表完全一致的普通目标表
-- 如需行存保留数据,USING heap可省略;如需列存保留则改为USING columnar CREATE TABLE test_single (LIKE test INCLUDING ALL) USING heap;
- 迁移全量数据到目标表
如果数据量较小,直接全量插入:
INSERT INTO test_single SELECT * FROM test;
如果数据量较大,可按子表分批迁移,避免长事务:
DO $$ DECLARE child_table text; BEGIN FOR child_table IN SELECT nmsp_child.nspname || '.' || child.relname FROM pg_inherits JOIN pg_class parent ON pg_inherits.inhparent = parent.oid JOIN pg_class child ON pg_inherits.inhrelid = child.oid JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace WHERE parent.relname='test' AND nmsp_parent.nspname='public' LOOP -- 迁移单个子表数据 EXECUTE format('INSERT INTO test_single SELECT * FROM %s', child_table); -- 可选:迁移完成后立即删除子表释放空间 EXECUTE format('DROP TABLE %s', child_table); END LOOP; END $$;
- 清理原分区表与pg_partman元数据
SELECT partman.drop_parent('public.test', p_keep_table := false);
- 后续不需要保留数据可直接删除目标表
DROP TABLE test_single;
内容的提问来源于stack exchange,提问作者ldocao
相关产品推荐
相关产品推荐

