Postgres 19 的新特性
内容提要
Postgres 19 引入核心功能 REPACK,可在线重写膨胀表以回收空间,无需长时间锁定,支持并发模式。JIT 默认关闭以减少 OLTP 查询开销,查询规划器通过预聚合优化提升性能。其他改进包括 lz4 压缩、锁等待日志、并行自动清理等,预计 2026 年 9 月发布。
延伸解读
REPACK 的适用场景与限制
REPACK (CONCURRENTLY) 适合在线回收膨胀表空间,但要求 wal_level 至少为 replica,且表必须有主键或 replica identity 索引。它不支持未记录日志的表,也不能在事务块内使用。执行期间需要额外磁盘空间存放新旧副本,并持有复制槽,可能增加 WAL 占用。此外,并发模式不是 MVCC 安全的,旧快照可能看到空表,且锁升级时可能因死锁被中止,导致整个重写回滚。
JIT 默认关闭的影响
Postgres 19 将 JIT 默认关闭,主要因为编译开销可能超过短查询的收益,尤其对 OLTP 场景。此前 JIT 默认开启,当估算成本超过阈值时触发,但估算不准可能导致频繁编译。关闭后,需要 JIT 的长分析查询可手动开启。这一变化提醒用户,性能优化需结合查询特征,默认设置并非最优,应根据实际 workload 调整。
查询规划器的改进与局限
预聚合优化通过先按外键分组减少连接行数,提升 JOIN+GROUP BY 性能,但仅在预期行数缩减至少 8 倍时触发。NOT IN 在无 NULL 时可转为反连接。pg_plan_advice 可固定查询计划,但仅覆盖连接和扫描,不包含聚合。这些改进并非万能,实际效果取决于数据分布和查询模式,建议通过 EXPLAIN 验证。
Q&A
Postgres 19 中 REPACK 功能的主要作用是什么?
REPACK 是 Postgres 19 引入的核心功能,用于在线重写膨胀的表以回收空间,类似于 VACUUM FULL 和 CLUSTER,但支持并发模式,在重写过程中允许读写操作继续。
REPACK 的并发模式是如何工作的?
REPACK (CONCURRENTLY) 通过以下步骤工作:先获取 SHARE UPDATE EXCLUSIVE 锁,允许读写;然后获取 MVCC 快照并打开复制槽;构建新表副本;同时将写入解码到临时文件;最后升级为 ACCESS EXCLUSIVE 锁,重放积压的更改并交换文件。
REPACK (CONCURRENTLY) 有哪些限制?
REPACK (CONCURRENTLY) 要求 wal_level 至少为 replica,不支持未记录的表、事务块内执行、没有主键或 replica identity 索引的表。此外,需要足够的磁盘空间,并持有复制槽,且不是 MVCC 安全的。
为什么 Postgres 19 默认关闭 JIT?
因为 JIT 编译开销可能超过查询本身的工作量,尤其是对于 OLTP 查询,当查询估计成本超过阈值时,即使查询很快也会触发编译,导致性能下降。因此 Postgres 19 默认关闭 JIT,让用户按需启用。
Postgres 19 的查询规划器有哪些改进?
主要改进包括 eager aggregation(预聚合),它可以在连接前对每个客户求和,减少连接行数;NOT IN 在无 NULL 时转换为反连接;新增 pg_plan_advice 用于固定查询计划。
Postgres 19 还有哪些其他新特性?
其他特性包括:lz4 作为新的 TOAST 默认压缩、锁等待日志默认开启、外键插入加速、MultiXact 偏移量扩展到 64 位、并行自动清理(默认关闭)、新的 SQL 语法(如 ON CONFLICT DO SELECT、GROUP BY ALL、COPY TO JSON、FOR PORTION OF)、max_locks_per_transaction 翻倍到 128、移除 RADIUS 认证、属性图支持等。
Postgres 19 预计什么时候正式发布?
Postgres 19 预计在 2026 年 9 月或 10 月达到 GA(正式发布)。