展望 Postgres 19
摘要
PostgreSQL 19 beta 引入了关键特性,如 REPACK CONCURRENTLY、分区拆分与合并以及增强的逻辑复制,为生产数据库管理提供了实用改进。
暂无内容
查看缓存全文
缓存时间: 2026/06/30 15:36
# 展望 Postgres 19
来源:https://www.snowflake.com/en/blog/engineering/postgresql-19-features-beta/
每个 Postgres 版本都有其独特的个性。
有些版本主打一个重大功能,有些版本则致力于消除长期存在的痛点。还有一些版本充满了那些“哦,不错”的改进——在升级之前你可能不会完全体会到它们的好处,但升级后突然发现日常操作变得顺畅了一点。当然,几乎每个版本都会有一些性能改进的加持。
Postgres 19 感觉就像是一个集各种特点于一身的版本。`REPACK CONCURRENTLY` 是为大型生产数据库提供的一项重大生活质量升级,而且是内置的。当然,它也有一些重大功能。SQL 属性图查询将备受关注。逻辑复制也越来越完善。此外,在 VACUUM、EXPLAIN、COPY、分区、监控、性能和规划器行为方面,都有持续的改进,这些改进让 Postgres 变得更好——不是以一种华丽的方式,而是以非常实用的“这有助于我运行生产系统”的方式。
和往常一样,在测试版阶段,细节在正式发布前可能会有所变化。但随着 Postgres 19 进入测试阶段,现在是时候看看即将到来的功能,更重要的是,看看它对构建和运行 Postgres 的人意味着什么。
## 开箱即用的 REPACK
如果你运行 Postgres 的时间足够长,你可能有过这样的经历:想要回收表膨胀、重写表或重组数据——但你非常不希望承受 `VACUUM FULL` 或 `CLUSTER` 所带来的锁。
长期以来,围绕这个问题有一个扩展生态系统,最著名的是 `pg_repack`。这本身就说明了一些问题:用户有真实需求,而生态系统填补了这一空白。
Postgres 19 将一个新的 `REPACK` 命令引入了核心,包括对 `REPACK CONCURRENTLY` 的支持。
我预计 `REPACK CONCURRENTLY` 将成为生产 Postgres 用户比普通版本说明阅读者更关心的功能之一。
## 分区变得更加实用
Postgres 中的分区在过去几年中有了很大改进。从“你可以这样做,但你可能需要了解很多内部机制和潜在风险”变成了更容易上手的东西。
Postgres 19 通过支持合并和拆分分区,延续了这项工作。
这听起来很简单,但它解决了一个实际的操作问题。分区策略是那种你经常在不完全了解信息的情况下做出的选择。你一开始会使用当时有意义的方案。然后工作负载发生了变化。保留窗口发生了变化。数据量增长超出预期。或者一些分区变得笨重巨大,而其他分区却很小。
能够拆分和合并分区,让你有更多的空间来随时间演进你的设计。
```
-- 将 Q1 和 Q2 合并为一个分区
ALTER TABLE customer_orders MERGE PARTITIONS (orders_2026_q1, orders_2026_q2) INTO orders_2026_h1;
```
```
-- 将 Q3 分区拆分为按月间隔的分区
ALTER TABLE customer_orders SPLIT PARTITION orders_2026_q3 INTO (
PARTITION orders_2026_07 FOR VALUES FROM ('2026-07-01') TO ('2026-08-01'),
PARTITION orders_2026_08 FOR VALUES FROM ('2026-08-01') TO ('2026-09-01'),
PARTITION orders_2026_09 FOR VALUES FROM ('2026-09-01') TO ('2026-10-01')
);
```
这种功能之所以重要,是因为最好的数据库设计很少是静态的。好的系统会演进。Postgres 为你提供了更多调整方法,而无需全部从头重建,这正是那种能使长期运行 Postgres 更轻松的渐进式改进。
## 逻辑复制持续成熟
在过去几个版本中,逻辑复制一直是 Postgres 开发最重要的领域之一。它对于迁移、升级、报表系统、数据移动、选择性复制,以及越来越多的对于高可用性和操作工作流都非常有用。
Postgres 19 继续在一些重要方面完善逻辑复制。
重要的一点:现在可以同步序列值,以便订阅者更好地与发布者对齐。任何使用逻辑复制处理依赖序列的应用程序表的人,都知道这为什么重要。没有序列状态的数据复制可能会在切换后留下尴尬的问题。数据移动了,但下一个生成的 ID 可能不在你需要的位置。
Postgres 19 还为发布添加了 `ALL SEQUENCES` 支持、序列同步错误报告,以及围绕序列的更好的订阅刷新行为。
另一个不错的改进:发布可以使用 `EXCEPT` 子句在发布所有表时排除某些表。这符合人们操作系统的实际方式。你通常想要“基本上所有内容,除了这几个”。让这变得更容易是好事。
此外,`wal_level = replica` 现在能够在需要时自动启用逻辑复制,同时还有一个新的 `effective_wal_level` 来报告实际发生的情况。这是另一个实用的改进:更少的配置陷阱,以及当 Postgres 代你执行某些操作时更好的可见性。
逻辑复制仍然有细微差别。它总是会有的。但每个版本都让它感觉不再是一个专门的特性,而是 Postgres 正常操作工具箱的一部分。
## 自动清理变得更智能、更易观察
清理是最具 Postgres 特色的操作之一。
你可以使用 Postgres 多年而从不关心其内部机制。然后某一天,你的表膨胀增加、回卷警告出现或查询性能发生变化,然后你突然非常关心。
Postgres 19 在这方面有几项值得指出的改进。
自动清理现在可以使用并行清理工作者,可在全局和每个表级别控制。对于较大的表和索引,这使 Postgres 能够更好地完成维护工作。
```
-- 全局允许最多 4 个并行工作者用于自动清理进程
ALTER SYSTEM SET autovacuum_max_parallel_workers = 4;
```
还有一个新的评分系统来控制自动清理表的顺序。这一点很重要,因为自动清理总是在做权衡。哪个表最紧急?下一个应该处理哪个?使这种优先级排序更智能,正好能在 Postgres 用户需要帮助的地方发挥作用:在问题演变成事故之前保持系统健康。
```
-- 仅为此表调整优先级评分:
-- 为基于插入的清理赋予巨大的紧急提升(3.0),
-- 同时降低正常的更新/删除清理优先级(0.5),因为行很少被删除。
ALTER TABLE application_logs SET (
autovacuum_vacuum_insert_score_weight = 3.0,
autovacuum_vacuum_score_weight = 0.5
);
```
新的 `pg_stat_autovacuum_scores` 视图提供了对该决策过程的更多可见性。再加上在清理和分析进度视图、`VACUUM VERBOSE` 和自动清理日志中的内存使用和并行化详情,以及一个单独的 `log_autoanalyze_min_duration`,Postgres 19 感觉就像是一个试图让维护更具可观察性的版本。
这是一个我乐见其成的主题。数据库在后台工作很好。而数据库更好地解释这项工作则更好。
## SQL 属性图查询进入 Postgres
现在来看看一个更有趣的补充:SQL/PGQ,即 SQL 属性图查询。
图数据库多年来有过几次热潮。需要说明的是,确实存在一些工作负载,其中用顶点和边的思维方式是有用的模型:欺诈检测、推荐、网络分析、权限图、供应链、组织架构等等。
```
-- 示例属性图
CREATE PROPERTY GRAPH store_graph
VERTEX TABLES (
customers LABEL customer,
orders LABEL "order"
)
EDGE TABLES (
customer_orders
SOURCE customers
DESTINATION orders
LABEL placed_order
);
```
但我喜欢这个功能进入 Postgres 的一点是,它并没有要求你抛弃关系模型。它是 Postgres 添加了另一种方式来查询你已经拥有的数据。
这非常 Postgres。
Postgres 一直有一种吸收有用能力的方式,而不会强迫你采用全新的架构。JSONB 并不意味着你必须停止使用关系表。全文搜索并不意味着每个用例都需要一个单独的搜索数据库。扩展并不意味着分叉数据库。而现在,SQL/PGQ 为 Postgres 提供了一种图形状的方式来查看关系数据。
对我来说,最有趣的部分不是“Postgres 现在是一个图数据库”,而是“Postgres 继续让你已经选择的数据库变得更强大”。
这是一个微妙但重要的区别。
对于开发者来说,这意味着在许多情况下,图风格的查询可能无需添加另一个数据存储、另一个同步路径、另一个操作面、以及另一个在凌晨 2 点需要调试的东西就可以使用。作为一个花了很多时间处理托管数据库和生产事故的人,更少的移动部件通常是一种胜利。
## COPY 变得越来越有用
`COPY` 是 Postgres 中那些既无聊又精彩的功能之一。它快速导入导出数据,可靠。由于加载和导出数据是常见的工作流,即使是微小的改进也可能很重要。
Postgres 19 有几项不错的 `COPY` 改进。
`COPY FROM` 可以跳过多个标题行。这听起来微不足道,直到你又一次从供应商、内部工具或“导出”流程中得到一个顶部带有额外元数据行的 CSV 文件。
`COPY FROM` 还获得了 `ON_ERROR SET_NULL`,允许将无效输入值设置为 NULL。这为你提供了另一种选择,介于“全部加载失败”和“在别处预清理所有内容”之间。
```
-- 假设一个文件中价格列偶尔包含 'N/A' 或 'MISSING' 而不是数值
COPY product_catalog (product_id, title, price_usd)
FROM '/path/to/dirty_products.csv'
WITH (
FORMAT CSV,
HEADER,
ON_ERROR SET_NULL
);
```
`COPY TO` 可以输出 JSON 格式,包括作为单个 JSON 数组。而且 `COPY TO` 现在可以直接输出分区表,以前你需要使用 `COPY (SELECT ...)`。
```
-- 直接将整个表导出为格式整洁、有效的 JSON 数组
COPY customers TO '/path/to/customers_export.json' WITH (FORMAT JSON, ARRAY true);
```
这些都不会改变世界。但它们都让日常数据工作流变得更好。
## SQL 生活质量改进
Postgres 19 还带来了一些开发者会喜欢的 SQL 改进。
`GROUP BY ALL` 允许你自动按所有非聚合和非窗口目标列表表达式进行分组。这种语法可以使探索性 SQL 和报表查询更简洁。*(感谢我们自己的 David Christensen 为此做出的贡献。)*
```
-- 使用 GROUP BY ALL
SELECT
category,
manufacturer,
COUNT(*) as total_items,
AVG(price) as avg_price
FROM inventory_products
GROUP BY ALL;
```
窗口函数获得了 `IGNORE NULLS` 和 `RESPECT NULLS` 支持,适用于 `lead`、`lag`、`first_value`、`last_value` 和 `nth_value` 等函数。如果你曾经编写过笨拙的变通方法来获取系列中前一个非空值,那么这个功能应该会引起你的注意。
`INSERT ... ON CONFLICT DO SELECT ... RETURNING` 是另一个不错的补充。在应用程序代码中,Upsert 无处不在,能够更直接地返回冲突行,这给了开发者更多的灵活性。
```
INSERT INTO tags (tag_name)
VALUES ('postgres')
ON CONFLICT (tag_name) DO SELECT
RETURNING tag_id;
```
Postgres 还添加了 `UPDATE` 和 `DELETE FOR PORTION OF`,继续围绕时间用例开展工作。时间是实际应用中最常见的维度之一,在核心 SQL 中提供更好的时间语法是一个受欢迎的方向。
扩展的**`RANDOM()`**时间函数。*(感谢我们自己的 Paul Ramsey 和 Greg Sabino Mullane 为此所做的工作。)*
## 全面的性能改进
在 Postgres 19 中,规划器和执行器继续得到稳步改进。特别感谢 Snowflake 的 Tom Lane 在 Postgres 19 性能和其他多个领域所做的努力。
在反连接、半连接、常量折叠、带追加路径的增量排序、连接前的聚合处理、连接选择性计算、函数统计等方面都有改进。
这里简单的做法是列出规划器更改并结束。但更有用的结论是:Postgres 在识别常见查询的形状和减少不必要的工作方面变得越来越好。
一些聚合处理现在可以在连接之前进行,从而减少处理的行数。更多 `NOT IN` 和 `LEFT JOIN` 的情况可以变成高效的反连接。Memoize 在 `EXPLAIN` 中有了更多可见性。通过基数排序提高了排序性能。外键约束检查变得更快。`COPY FROM` 的文本和 CSV 输入可以使用 SIMD 指令。
这些并不总是需要你更改应用程序代码来使用的功能。在许多情况下,你升级后,Postgres 就有更大的机会做出正确的事情。
这是数据库改进中最好的一种。
## 为什么 Postgres 19 感觉很重要
对我来说,Postgres 19 的突出之处不是某单个功能,而是其广度。
有为应用程序开发者准备的功能:图查询、更好的 SQL 语法、窗口函数改进、更好的 upsert 行为。
有为运维人员准备的功能:`REPACK CONCURRENTLY`、更好的自动清理、更好的监控、在线校验和更改、更多的复制可见性。
有为关注性能的人准备的功能:规划器改进、SIMD 改进、异步 I/O 可见性、更快的外键检查、更好的排序。
有为在 Postgres 之上构建的人准备的功能:新的钩子、规划器建议模块、扩展改进、FDW 统计检索,以及对扩展生态系统的持续投入。
这种广度是 Postgres 持续获胜的原因之一。它不仅仅是为一种工作负载或一种角色变得更好。它作为一个应用程序数据库、一个操作数据库、一个分析数据库、一个可扩展的数据库和一个平台,都在变得更好。
Postgres 19 尚未正式发布,所以现在是测试的时候了。测试你的应用程序。运行你的迁移测试。检查你的扩展。查看你最重要查询的计划。如果你依赖逻辑复制,请测试它。运行你的维护工作流。看看有什么问题,趁还有时间修复。
Postgres 版本之所以变得更好,是因为人们用真实的工作负载来测试它们。
而基于 Postgres 19 测试版中已有的内容,这里有很多值得测试的东西。
相似文章
期待 PostgreSQL 19:是时候了
PostgreSQL 19 终于将引入原生的时态表支持,遵循 SQL:2011 标准,取代过去使用排除约束的手动方法。本文解释了当前方法的局限性以及新功能备受期待的优点。
期待 PostgreSQL 19:查询提示
PostgreSQL 19 通过新的 contrib 模块 pg_plan_advice 和 pg_stash_advice 引入了查询提示功能,结束了长期以来的社区争论,并为 DBA 提供了应对优化器边缘情况的应急方案。
PostgreSQL 18.4 和 17.10 版本修复了 11 个 CVE
PostgreSQL 已发布针对版本 18.4、17.10、16.14、15.18 和 14.23 的安全更新,修复了 11 个 CVE 和超过 60 个错误。值得注意的修复包括 CVE-2026-6473(整数回绕,CVSS 8.8)和 CVE-2026-6475(符号链接覆盖,CVSS 8.8)。
使用 Postgres 作为作业队列的潜在后果
文章分析了使用 PostgreSQL 作为作业队列的可扩展性限制,特别强调了高并发下 MultiXact SLRU 争用导致的性能瓶颈。文章解释了为什么这种架构在开发环境中表现良好,但在生产环境中却会失败,并建议考虑替代方案。
PostgresBench: 一个可复现的 Postgres 服务基准测试
ClickHouse 发布了 PostgresBench,这是一个公开且可复现的基准测试,用于比较托管式 Postgres 服务,它使用标准的 pgbench 工具,在多个缩放因子下运行类似 TPC-B 的工作负载。