从 TimescaleDB 迁移到 pg_partman
从 Postgres 17 开始,Supabase 项目不再提供 timescaledb 扩展。如果你的项目依赖 TimescaleDB 超表,你需要在升级前迁移到标准的 Postgres 表。
🌐 Starting from Postgres 17, Supabase projects do not have the timescaledb extension available. If your project relies on TimescaleDB hypertables, you will need to migrate to standard Postgres tables before upgrading.
本指南展示了一种将超表迁移到原生 Postgres 分区表的方法,并可以选择配置 pg_partman 来自动进行持续的分区维护。本指南中概述的方法也可以用于传统分区表。
🌐 This guide shows one approach to migrate a hypertable to a native Postgres partitioned table and optionally configure pg_partman to automate ongoing partition maintenance.
The approach outlined in this guide can also be used for traditional partitioned tables.
在你开始之前 #
🌐 Before you begin
- 在预发布环境中测试迁移路径(例如通过创建生产项目的副本或使用分支)。
- 检查一下你在申请中使用 TimescaleDB 特有的 SQL(比如
time_bucket()、压缩策略)。这些功能pg_partman是不提供的。
迁移概览 #
🌐 Migration overview
- 创建一个新的分区表。
- 把数据从超表复制到新表。
- 交换过去并删除超级表。
- 配置
pg_partman(可选)并安排维护。
示例:将 messages#
🌐 Example: Migrate messages from hypertable to native partitions
这个例子假设有一个按 sent_at 分区的 messages 超表。
🌐 This example assumes a messages hypertable partitioned by sent_at.
1. 重命名现有的超级表 #
🌐 1. Rename the existing hypertable
这样可以在创建一个新的分区表并使用原来的名字时保留原始数据。
🌐 This keeps the original data in place while you create a new partitioned table with the original name.
1alter table public.messages rename to ht_messages;2. 创建一个新的分区表 #
🌐 2. Create a new partitioned table
使用原生分区时,分区列必须包含在任何唯一索引中(包括主键)。
🌐 When using native partitioning, the partitioning column must be included in any unique index (including the primary key).
1create table public.messages (2 like public.ht_messages including all,3 primary key (sent_at, id)4)5partition by range (sent_at);3. 把数据复制到新表里 #
🌐 3. Copy data into the new table
对于大型表,可以考虑在维护窗口期间分批复制(例如按时间范围)。
🌐 For large tables, consider copying in batches (for example by time range) during a maintenance window.
1insert into public.messages2select *3from public.ht_messages;4. 删除旧的超表(和 TimescaleDB) #
🌐 4. Drop the old hypertable (and TimescaleDB)
只有在你迁移了所有超级表且没有其他对象依赖它之后才卸载这个扩展。
🌐 Only drop the extension once you’ve migrated all hypertables and no other objects depend on it.
1drop table public.ht_messages;23drop extension if exists timescaledb;5. 配置 pg_partman#
🌐 5. Configure pg_partman (optional)
启用 pg_partman 并注册你的表,这样分区就可以提前创建。
🌐 Enable pg_partman and register your table so partitions are created ahead of time.
1create schema if not exists partman;2create extension if not exists pg_partman with schema partman;34select partman.create_parent(5 p_parent_table := 'public.messages',6 p_control := 'sent_at',7 p_type := 'range',8 p_interval := '7 days',9 p_premake := 7,10 p_start_partition := '2025-01-01 00:00:00'11);保持分区更新 #
🌐 Keep partitions up to date
pg_partman 需要运行维护来预先创建分区并应用保留策略。
1call partman.run_maintenance_proc();要自动化这个,可以用 pg_cron 来安排。
🌐 To automate this, schedule it with pg_cron.
1create extension if not exists pg_cron;23select cron.schedule('@daily', $$call partman.run_maintenance_proc()$$);额外资源 #
🌐 Additional resources