PostgreSQL 大表分区冷热归档
利用 pg_mooncake 将按时间分区的 PostgreSQL 大表归档为 Parquet 与 Apache Iceberg 格式,直接删除旧行存分区释放磁盘,同时在列存镜像中完整保留全部历史数据。
pg_mooncake 的列存镜像表将数据写为高压缩比的 Parquet 文件(保存在本地磁盘或 AWS S3 / Cloudflare R2 对象存储上),使你能够在 PostgreSQL 行存中仅保留近期热分区,同时在列存镜像中以极低成本持久化保留完整的历史数据。
架构设计模式
分区冷热归档模式遵循以下三条核心原则:
- 为按时间或范围分区的 PostgreSQL 表创建列存镜像(
CALL mooncake.create_table)。 - 定期从行存中
DROP或TRUNCATE过期旧分区,立即释放昂贵的本地 NVMe / SSD 空间,避免VACUUM FULL锁表开销。 - 在列存镜像中完整保留全部历史数据——
pg_mooncake会有意忽略针对分区源表子分区的DROP TABLE与TRUNCATE事件,因此被删除分区的历史行依然完整保留在列存镜像中并可随时查询!
完整实操示例
下面以一张按范围分区的 transactions 交易流水表为例演示完整归档流程。
第 1 步:创建分区行存表
第 2 步:创建实时列存镜像表
第 3 步:创建第一个子分区并写入数据
第 4 步:从行存中直接删除历史旧分区
当 transactions_p1 变为历史冷数据、需要回收 PostgreSQL 本地磁盘空间时:
第 5 步:在列存镜像中查询历史数据
尽管 transactions_p1 已从行存中删除,但它的全部历史记录依然完好地保存在 transactions_archive 中:
第 6 步:继续挂载新分区并写入增量数据
最佳实践
- 切勿向已删除分区的键范围重复写入冲突数据:在删除或清空某个旧行存分区后,请勿重新创建相同范围的分区并写入重复主键,因为已删除分区的历史行仍保留在列存镜像中。
- 使用声明式分区表管理归档生命周期:
pg_mooncake专门针对分区子表的DROP/TRUNCATE做了归档保留处理。 - 配合 S3 / R2 对象存储实现无限容量归档:在创建镜像前设置
mooncake.default_bucket = 's3://...',即可将所有历史 Parquet 文件与 Iceberg 元数据直接存储在廉价的云端对象存储上。详见 Iceberg 与对象存储配置。