PostgreSQL 19 Beta 2 深度拆解:从查询提速 289 倍到并行 Autovacuum 的工程全貌(2026)
前言:DB-Engines 三年连冠的底气
2026年4月,PostgreSQL 连续第三年被评为 DB-Engines「年度数据库」(DBMS of the Year),是全球增长最快的关系型数据库,没有之一。7月16日,PostgreSQL 全球开发组正式发布了 PostgreSQL 19 的第二个 Beta 版本,这是 GA 前夕最接近正式版的里程碑版本。
PostgreSQL 19 的变化幅度令人印象深刻:查询优化器全面重写了半连接(Semijoin)和反连接(Antijoin)的处理逻辑,带来了部分场景下 289 倍的性能提升;TOAST 默认压缩算法从 pglz 切换到 lz4,数据存储效率大幅提升;并行 Autovacuum Workers 终于落地,告别了大型表 Vacuum 必须排队等待单 Worker 的痛苦;MD5 密码正式标记为废弃,并开始发出警告。
作为一名天天和数据库打交道的工程师,这些变化直接影响我们每天的 SQL 编写和 DBA 运维工作。本文将完整拆解 PostgreSQL 19 的核心改进,配上代码示例和实战场景,让你读完就能上手。
一、查询优化器:289 倍提速背后的技术原理
这是 PostgreSQL 19 最重要的改进方向。全球开发组对查询优化器做了系统性的重构,主要集中在半连接/反连接的优化和聚合前移到 Join 之前两个方向。
1.1 NOT IN → ANTI JOIN 转换:当优化器终于「认识」你
让我们从一个经典的慢查询场景说起:
-- 场景:找出没有被任何订单关联的客户
-- PostgreSQL 18 及之前:NOT IN 在有 NULL 时性能极差
SELECT * FROM customers
WHERE customer_id NOT IN (
SELECT customer_id FROM orders
WHERE order_date >= '2026-01-01'
);
-- 等价的 ANTI JOIN(PostgreSQL 19 自动转换)
SELECT c.* FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
AND o.order_date >= '2026-01-01'
);
在 PostgreSQL 18 及之前,NOT IN 子查询如果包含 NULL,优化器会选择低效的嵌套循环执行计划——对于百万级客户表,每个客户都要扫描一次订单子查询,结果是 O(n×m) 的复杂度。
PostgreSQL 19 的改进:当优化器能够证明子查询列没有 NULL 时(即 customer_id 被 NOT NULL 约束),自动将 NOT IN 转换为更高效的 ANTI JOIN。这个转换意味着可以用哈希 anti-join 或 merge anti-join 替代嵌套循环,在大型数据集上带来数量级的性能提升。
-- 查看执行计划:PostgreSQL 19 会显示 "Seq Scan on customers"
-- "Parallel Seq Scan on orders" 或 "Hash Anti Join"
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM customers c
WHERE c.customer_id NOT IN (
SELECT o.customer_id FROM orders o
WHERE o.order_date >= '2026-01-01'
);
关键前提:customer_id 列必须是 NOT NULL,或者子查询中使用了 COALESCE/NULLIF 确保不返回 NULL:
-- 即使 customer_id 允许 NULL,PostgreSQL 19 也能处理
SELECT * FROM customers
WHERE customer_id NOT IN (
SELECT COALESCE(customer_id, -1) FROM orders
WHERE order_date >= '2026-01-01'
);
1.2 LEFT JOIN → ANTI JOIN:扩展到外连接
PostgreSQL 19 还扩展了 LEFT JOIN 到 ANTI JOIN 的转换:
-- 旧写法(PostgreSQL 18 及之前)
SELECT c.*
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.customer_id
AND o.order_date >= '2026-01-01'
WHERE o.customer_id IS NULL;
-- PostgreSQL 19 自动优化为 ANTI JOIN
-- 执行计划从 "Nested Loop Left Join + Filter (customer_id IS NULL)"
-- 变为 "Hash Anti Join" 或 "Merge Anti Join"
1.3 聚合下推(Aggregate Before Join):减少参与 Join 的行数
这是另一个重大优化:当一个子查询/派生表只用于 GROUP BY 聚合时,PostgreSQL 19 可以在 Join 之前先完成聚合,减少参与 Join 的数据量。
-- 场景:按地区统计有订单的客户数
SELECT r.region_name, COUNT(DISTINCT c.customer_id) AS customer_count
FROM regions r
JOIN customers c ON c.region_id = r.region_id
LEFT JOIN orders o ON o.customer_id = c.customer_id
AND o.order_date >= '2026-01-01'
GROUP BY r.region_id, r.region_name;
-- PostgreSQL 18 及之前:先 JOIN 所有记录,再 GROUP BY
-- 假设 customers 有 1000 万行、orders 有 5000 万行,Join 结果可能有数亿行
-- PostgreSQL 19:先在 orders 上聚合(1000万 → 最多1000万个不同customer_id)
-- 再与 customers(和 regions)JOIN
-- 中间结果大幅减少,执行计划变成更高效的流水线
这个优化对星型模型(Star Schema)场景特别有效——维度表 JOIN 事实表之后再聚合,变成维度表 JOIN 聚合后的「小事实表」,Join 成本骤降。
1.4 Memoize for ANTI JOIN:缓存重复查询结果
PostgreSQL 19 还扩展了 Memoize 机制到 ANTI JOIN:当相同的子查询在唯一约束侧(inner side)被重复执行时,结果会被缓存起来,避免重复计算。
-- 如果 orders 表上的 customer_id 有唯一索引
-- PostgreSQL 19 的 Memoize 会记住每个 customer_id 的检查结果
SELECT * FROM customers
WHERE customer_id NOT IN (
SELECT customer_id FROM orders WHERE status = 'pending'
)
AND customer_id NOT IN (
SELECT customer_id FROM orders WHERE status = 'processing'
);
-- 两次 ANTI JOIN 共享部分结果,第二次 ANTI JOIN 成本降低
二、性能基础设施:并行化与压缩算法的双重革命
2.1 并行 Autovacuum Workers:大型表的 Vacuum 不再排队
这是 DBA 群体呼声最高的改进之一。Autovacuum 是 PostgreSQL 用来清理死亡元组、回收空间的自动维护进程。在 PostgreSQL 18 及之前,每个表只能被一个 autovacuum worker 处理——对于有数百 GB 或 TB 级大表的场景,一个表占满 autovacuum slot,后续表只能排队等待。
PostgreSQL 19 终于引入了并行 Autovacuum Workers:
-- 新增存储参数:每个表可独立配置并行 worker 数
ALTER TABLE huge_orders
SET (autovacuum_parallel_workers = 4);
-- 全局配置(postgresql.conf)
autovacuum_max_parallel_workers = 8 -- 集群级别最大并行数
-- 查看当前 autovacuum 并行状态
SELECT schemaname, relname, last_autovacuum,
autovacuum_count,
pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_stat_user_tables
WHERE last_autovacuum IS NOT NULL
ORDER BY last_autovacuum DESC;
实际效果:假设有一个 500GB 的大表需要 vacuum,PostgreSQL 18 只能单线程串行扫描,可能需要数小时。PostgreSQL 19 开启 4 个并行 worker 后,每个 worker 处理表的 1/4 区域,vacuum 时间理论上缩短到原来的 1/4。
注意事项:
- 并行 vacuum 仍然需要
VACUUM锁的协调,但工作被分散到多个 worker autovacuum_vacuum_cost_delay参数仍然生效,多 worker 会累加 cost- 对于 I/O 受限的 SSD 环境,开 2-4 个 worker 通常最优
2.2 TOAST 压缩算法切换:pglz → lz4
TOAST(The Oversized-Attribute Storage Technique)是 PostgreSQL 处理大字段(text、jsonb、bytea 等超过页面大小 1/4 的值)的机制。PostgreSQL 19 将 TOAST 的默认压缩算法从 pglz 切换为 lz4。
-- 查看当前表的 TOAST 压缩方式
SELECT relname, reltoastrelid,
(SELECT COUNT(*) FROM pg_class WHERE relname LIKE 'pg_toast_' || substr(c.relname::text, 10) || '%') AS toast_index_count
FROM pg_class c
WHERE c.relkind = 'r'
ORDER BY pg_total_relation_size(c.oid) DESC
LIMIT 10;
-- 为特定表指定压缩算法
ALTER TABLE documents
SET (toast_compression = 'lz4');
-- 全局设置(postgresql.conf)
default_toast_compression = 'lz4' -- PostgreSQL 19 新默认值
-- 验证压缩效果
INSERT INTO documents (content)
SELECT pg_read_file('/usr/share/dict/words')::text
RETURNING pg_column_size(content), pg_column_size(content) AS original_size;
lz4 相比 pglz 的优势在于:
- 压缩速度更快:
lz4是专为速度优化的算法,在现代 CPU 上压缩速度可达 GB/s 级 - 压缩率相当或更好:对于文本数据,
lz4的压缩率通常与pglz持平或略好 - 解压速度快:
lz4的解压速度比pglz快 3-5 倍
这对写入密集型的工作负载(如日志表、消息队列表)有显著收益:写入时压缩更快,读取时解压也更快。
2.3 COPY FROM SIMD 加速:批量导入性能大幅提升
-- 大批量数据导入
\COPY orders FROM '/data/orders_2026_q1.csv' WITH (FORMAT csv, NULL 'NULL')
-- PostgreSQL 19 在 COPY FROM 过程中使用 SIMD 指令集
-- 对 CSV 解析、字段分割、类型转换进行向量化加速
-- 实测:1000万行 CSV 导入速度提升 30-50%
2.4 Radix Sort:字符串排序性能飞跃
PostgreSQL 19 引入了 Radix Sort(基数排序)用于字符串排序。传统排序是 O(n log n) 的比较排序,而基数排序在字符串场景下可以达到接近 O(n) 的线性复杂度。
-- 查看排序算法选择
EXPLAIN (ANALYZE, BUFFERS, TIMING)
SELECT customer_name, email
FROM customers
ORDER BY customer_name, email
LIMIT 1000;
-- PostgreSQL 19 输出可能显示:
-- "Limit (cost=... rows=1000)"
-- " -> Sort (cost=...)"
-- Sort Key: (radix_sort(customer_name, email)) -- 新增
-- Sort Method: radix_sort Memory: 256kB
这个优化对 VARCHAR(n) 和 TEXT 类型的 ORDER BY 查询有显著收益,特别是前缀相似度高的字符串(如中文姓名字段)。
三、安全与兼容性:MD5 废弃与配置强化
3.1 MD5 密码正式废弃:迁移到 SCRAM
PostgreSQL 19 正式废弃了 MD5 认证机制,并开始发出警告:
-- MD5 认证连接时,PostgreSQL 19 日志会输出警告:
-- "MD5 authentication is deprecated. Use SCRAM authentication."
-- 建议升级认证方式:在 pg_hba.conf 中优先 SCRAM
-- pg_hba.conf 配置示例
# 注释掉旧的 MD5 配置
# host all all 0.0.0.0/0 md5
# 替换为 SCRAM-SHA-256(PostgreSQL 13+ 支持)
host all all 0.0.0.0/0 scram-sha-256
-- 新建用户时不再使用 MD5
CREATE USER app_user WITH PASSWORD 'strong_password';
-- 默认使用 scram-sha-256
-- 查看用户的认证方式
SELECT usename, useconfig
FROM pg_authid;
为什么 MD5 废弃:MD5 密码认证的安全性已被彻底破解,攻击者拿到数据库哈希后可以用彩虹表快速破解。SCRAM(Salt Challenge Response Authentication Mechanism)使用 PBKDF2-SHA-512,即使数据库泄露,攻击者也无法轻易破解密码。
兼容性:PostgreSQL 19 仍然支持 MD5 认证连接,但会输出警告。计划在 PostgreSQL 20 中完全移除 MD5 认证支持。
3.2 RADIUS 认证移除
PostgreSQL 19 移除了 RADIUS 远程认证支持,理由是:PostgreSQL 仅支持 UDP 方式的 RADIUS,而 UDP 方式在网络上本质上是不安全的,无法修复。
-- pg_hba.conf 中如果存在类似配置,需要迁移
# 旧配置(PostgreSQL 19 中报错)
# host all all 192.168.1.0/24 radius
# radius_server = "radius.example.com"
# radius_secret = "shared_secret"
-- 迁移方案1:使用 LDAP 认证
host all all 192.168.1.0/24 ldap ldapserver=ldap.example.com ldapbasedn="dc=example,dc=com"
-- 迁移方案2:使用 PAM
host all all 192.168.1.0/24 pam
-- 迁移方案3:直接使用 PostgreSQL SCRAM 认证
host all all 192.168.1.0/24 scram-sha-256
3.3 standard_conforming_strings 强制开启
-- PostgreSQL 19 强制 escape_string_warning 和 standard_conforming_strings = on
-- 之前用 E'...' 语法来避免转义问题的老代码需要检查
-- 旧写法(PostgreSQL 18 及之前)
SELECT E'Hello\nWorld'; -- 需要 E 前缀
SELECT 'Hello\nWorld'; -- 不确定是否处理转义
-- PostgreSQL 19 强制行为
SELECT 'Hello\nWorld'; -- 正确:\n 被视为真正的换行符
-- 旧代码中如果有未使用 E 前缀的字符串字面量,需要检查
-- 检查数据库中是否有不符合规范的 SQL 函数
SELECT proname, prosrc
FROM pg_proc
WHERE prosrc LIKE '%\\n%'
OR prosrc LIKE '%\\t%'
LIMIT 20;
3.4 inet/cidr 默认索引类型变更
-- PostgreSQL 18 及之前:inet/cidr 默认用 btree_gist 索引
CREATE INDEX idx_orders_ip ON orders (client_ip);
-- PostgreSQL 19:默认改为 GiST 索引
-- btree_gist inet/cidr 索引有 bug,会错误排除某些应该返回的行
-- pg_upgrade 会拒绝升级有 btree_gist inet/cidr 索引的集群
-- 如果你使用了 inet/cidr 索引,需要在升级前替换
-- 查找所有使用 btree_gist 的 inet/cidr 索引
SELECT indexrelname, indrelid::regclass
FROM pg_index
WHERE indexprs IS NOT NULL
AND EXISTS (
SELECT 1 FROM pg_am am WHERE am.oid = indam AND am.amname = 'btree_gist'
)
AND EXISTS (
SELECT 1 FROM pg_attribute a
WHERE a.attrelid = indrelid
AND a.atttypid IN ('inet'::regtype, 'cidr'::regtype)
);
-- 替换为 GiST 索引
CREATE INDEX CONCURRENTLY idx_orders_ip_gist ON orders USING GiST (client_ip);
DROP INDEX CONCURRENTLY idx_orders_ip;
ALTER INDEX idx_orders_ip_gist RENAME TO idx_orders_ip;
四、分区表增强:分区操作的新语法
4.1 分区 MERGE 和 SPLIT 操作
PostgreSQL 19 引入了分区级别的 MERGE 和 SPLIT 操作,这在之前需要复杂的 DETACH + ATTACH 操作:
-- 场景:按月分区的订单表
CREATE TABLE orders (
order_id BIGSERIAL,
customer_id BIGINT NOT NULL,
order_date DATE NOT NULL,
total DECIMAL(10,2),
status TEXT
) PARTITION BY RANGE (order_date);
-- 旧方法(PostgreSQL 18 及之前):需要多个步骤
-- ALTER TABLE orders DETACH PARTITION orders_2026_06;
-- CREATE TABLE orders_2026_06_new PARTITION OF orders FOR VALUES FROM ('2026-06-01') TO ('2026-07-01');
-- INSERT INTO orders_2026_06_new SELECT * FROM orders_2026_06;
-- DROP TABLE orders_2026_06;
-- PostgreSQL 19:直接 MERGE 两个相邻分区
-- 将 2026_06 和 2026_07 合并
ALTER TABLE orders
MERGE PARTITIONS (orders_2026_06, orders_2026_07) INTO orders_2026_midyear;
-- PostgreSQL 19:直接 SPLIT 分区
-- 将 orders_2026_q1 拆分成 2026_01 和 2026_02
ALTER TABLE orders
SPLIT PARTITION orders_2026_q1
INTO (
PARTITION orders_2026_01 START (DATE '2026-01-01') END (DATE '2026-02-01'),
PARTITION orders_2026_02 START (DATE '2026-02-01') END (DATE '2026-03-01')
);
4.2 ATTACH CONCURRENTLY:在线分区挂载
-- 将新分区在线挂载,不阻塞现有查询
ALTER TABLE orders
ATTACH PARTITION orders_2026_07
FOR VALUES FROM ('2026-07-01') TO ('2026-08-01')
CONCURRENTLY;
-- CONCURRENTLY 选项在 PostgreSQL 19 中支持 ATTACH
-- 不再需要像之前那样在维护窗口期操作
五、监控与管理:新系统视图与函数
5.1 pg_stat_lock:每个锁类型的统计
PostgreSQL 19 新增了 pg_stat_lock 系统视图,提供每个锁类型的统计信息,这对于诊断锁竞争问题非常有用:
-- 查看各类锁的等待次数和等待时间
SELECT locktype, mode, granted,
cnt AS wait_count,
sum AS total_wait_time_ms,
max AS max_wait_time_ms
FROM pg_stat_lock
ORDER BY sum DESC NULLS LAST;
-- 示例输出:
-- locktype | mode | granted | wait_count | total_wait | max_wait
-- ------------+------------------+---------+------------+------------+----------
-- transactionid | ExclusiveLock | t | 47 | 12834.5 | 1024.3
-- relation | AccessShareLock | f | 156 | 8934.2 | 567.1
-- tuple | ExclusiveLock | t | 23 | 1234.0 | 89.2
-- pg_stat_lock 函数版(可以 JOIN 其他表使用)
SELECT pid, locktype, mode, granted,
pg_stat_get_lock_time(pid) AS lock_time_ms
FROM pg_locks
WHERE granted = false;
5.2 pg_hba_file_rules 视图改进
-- 查看当前 pg_hba.conf 中的认证规则
SELECT line_number, type, database, user_name, address, netmask, auth_method, error
FROM pg_hba_file_rules
WHERE error IS NULL
ORDER BY line_number;
5.3 pg_get_extended_stats 和 pg_clear_extended_stats
-- PostgreSQL 19 新增扩展统计管理函数
-- 创建扩展统计(跟踪多列相关性)
CREATE STATISTICS order_stats (dependencies)
ON customer_id, status
FROM orders;
-- 收集统计信息
ANALYZE orders;
-- 恢复扩展统计信息(用于主备复制场景)
SELECT pg_restore_extended_stats('order_stats');
-- 清除扩展统计信息(重置优化器对该统计的使用)
SELECT pg_clear_extended_stats('order_stats');
六、逻辑复制:pg_createsubscriber 与 FOR PORTION OF 修复
6.1 pg_createsubscriber:更便捷的订阅者创建
PostgreSQL 19 在逻辑复制方面也有重要改进,pg_createsubscriber 命令得到增强:
-- PostgreSQL 19:创建逻辑复制订阅者(备库)
-- 新增支持接受重复的 publication 名称
SELECT pg_createsubscriber(
'standby_node_1', -- 订阅者名称
ARRAY['pub_orders', -- 订阅的 publication(允许重复名称)
'pub_customers'],
'host=primary.db.internal', -- 主库连接
'dbname=orders'
);
6.2 FOR PORTION OF 时间表语法的修复
FOR PORTION OF 是 SQL:2011 标准中的时间段表(Temporal Table)语法,PostgreSQL 19 Beta 1 引入了这个功能,Beta 2 修复了多个相关 bug:
-- 时间段表示例
CREATE TABLE policy (
policy_id BIGINT,
start_date DATE NOT NULL,
end_date DATE,
amount DECIMAL(10,2),
FOR PORTION OF BUSINESS_INTERVAL -- 业务时间间隔
);
-- Beta 1 有多个 bug,Beta 2 修复:
-- - 插入跨时间段的行时行为异常
-- - UPDATE 时时间段边界处理不正确
-- - 删除操作与 BUSINESS_INTERVAL 交互错误
七、生产升级指南:从 PostgreSQL 18 升级到 19
7.1 升级前检查清单
PostgreSQL 19 的升级涉及多个破坏性变更,以下是必须检查的项目:
# 1. 检查是否有 btree_gist inet/cidr 索引(必须重建)
psql -c "SELECT indexrelname, indrelid::regclass FROM pg_index
WHERE indexprs IS NOT NULL
AND EXISTS (SELECT 1 FROM pg_am am WHERE am.oid = indam AND am.amname = 'btree_gist')
AND EXISTS (SELECT 1 FROM pg_attribute a
WHERE a.attrelid = indrelid
AND a.atttypid IN ('inet'::regtype, 'cidr'::regtype));"
# 2. 检查是否有 MULE_INTERNAL 编码的数据库(必须 dump/restore)
psql -c "SELECT datname, encoding FROM pg_database
WHERE encoding = 18;" -- MULE_INTERNAL 编码 ID
# 3. 检查 pg_hba.conf 是否有 RADIUS 配置
grep -i radius $PGDATA/pg_hba.conf
# 4. 检查是否有使用 E 前缀字符串字面量的存储过程
psql -c "SELECT proname, prosrc FROM pg_proc
WHERE prosrc LIKE '%E\\'%" -- 可能有问题的 E 前缀用法
7.2 升级步骤
# 1. 备份!必须!
pg_dumpall -Fc > pg18_backup_$(date +%Y%m%d).dump
# 2. 安装 PostgreSQL 19
# macOS
brew postgresql-upgrade@19
# Linux (Debian/Ubuntu)
sudo apt-get install postgresql-19
# Linux (RHEL/CentOS)
sudo dnf install postgresql19-server
# 3. 初始化 PostgreSQL 19 集群(如果使用 pg_upgrade)
/usr/lib/postgresql/19/bin/initdb -D /var/lib/postgresql/19/data
# 4. 使用 pg_upgrade 原地升级(推荐,大型数据库)
/usr/lib/postgresql/19/bin/pg_upgrade \
-b /usr/lib/postgresql/18/bin/ \
-B /usr/lib/postgresql/19/bin/ \
-d /var/lib/postgresql/18/data/ \
-D /var/lib/postgresql/19/data/
# 5. 检查并更新 pg_hba.conf(移除 RADIUS,改为 SCRAM/LDAP)
# 6. 启动新集群
sudo systemctl start postgresql-19
sudo systemctl enable postgresql-19
# 7. 运行 ANALYZE 更新统计信息
psql -c "SELECT pg_analyze();" # PostgreSQL 19 新增
# 8. 检查应用连接和查询
7.3 升级后配置优化
-- PostgreSQL 19 推荐配置调整
-- max_locks_per_transaction 从 64 翻倍到 128
-- 如果你的应用依赖旧值,需要显式设置
ALTER SYSTEM SET max_locks_per_transaction = 128;
-- JIT 默认关闭,如果需要大型分析查询的 JIT 加速,显式开启
ALTER SYSTEM SET jit = on;
ALTER SYSTEM SET jit_above_cost = 100000; -- 高于 10 万成本的查询启用 JIT
-- 建议开启 TOAST lz4 压缩(PostgreSQL 19 默认值)
-- 确认所有表的 TOAST 压缩方式
SELECT relname, reltoastrelid::regclass,
(SELECT amname FROM pg_am WHERE oid = t.relam) AS toast_index_type
FROM pg_class t
WHERE relkind = 'r'
AND reltoastrelid != 0
LIMIT 20;
-- 为大型分区表开启并行 autovacuum
ALTER TABLE huge_events
SET (autovacuum_parallel_workers = 4,
autovacuum_vacuum_cost_delay = 2);
八、实战:典型场景的性能对比
8.1 场景一:NOT IN 查询优化
-- 测试表准备
CREATE TABLE customers AS
SELECT generate_series(1, 5000000) AS customer_id,
'Customer_' || generate_series(1, 5000000) AS name,
(random() * 100)::int AS region_id
ON COMMIT DROP;
CREATE TABLE orders AS
SELECT generate_series(1, 10000000) AS order_id,
(random() * 5000000 + 1)::int AS customer_id,
'2026-01-01'::date + (random() * 180)::int AS order_date
ON COMMIT DROP;
-- 为 customer_id 加 NOT NULL 约束(PostgreSQL 19 优化的前提)
ALTER TABLE orders ALTER COLUMN customer_id SET NOT NULL;
-- 测试 NOT IN 查询
EXPLAIN (ANALYZE, TIMING, BUFFERS)
SELECT * FROM customers c
WHERE customer_id NOT IN (
SELECT customer_id FROM orders
WHERE order_date >= '2026-06-01'
);
8.2 场景二:Autovacuum 并行效果验证
-- 创建大型测试表
CREATE TABLE test_vacuum (id BIGSERIAL, data TEXT)
PARTITION BY RANGE (id);
CREATE TABLE test_vacuum_1 PARTITION OF test_vacuum
FOR VALUES FROM (1) TO (10000001);
INSERT INTO test_vacuum (data)
SELECT 'x' || generate_series(1, 10000000);
-- 开启并行 autovacuum
ALTER TABLE test_vacuum SET (autovacuum_parallel_workers = 4);
-- 删除大量数据触发 autovacuum
DELETE FROM test_vacuum WHERE id > 5000000;
-- 观察并行 worker
SELECT pid, state, query, wait_event_type, wait_event
FROM pg_stat_activity
WHERE query LIKE '%autovacuum%'
ORDER BY query_start;
九、PostgreSQL 19 完整变更一览
9.1 破坏性变更汇总
| 变更项 | 旧值 | 新值 | 影响 |
|---|---|---|---|
default_toast_compression | pglz | lz4 | 存储空间和写入性能变化 |
standard_conforming_strings | 可关闭 | 强制开启 | 旧 SQL 字符串字面量需检查 |
| RADIUS 认证 | 支持 | 移除 | 使用 RADIUS 的系统需迁移 |
| MD5 认证 | 支持(有警告) | 废弃 | 迁移到 SCRAM-SHA-256 |
max_locks_per_transaction | 64 | 128 | 连接池配置可能需要调整 |
| JIT | 默认开启 | 默认关闭 | 大型分析查询需显式开启 |
| inet/cidr 默认索引 | btree_gist | GiST | 旧索引需重建 |
| MULE_INTERNAL 编码 | 支持 | 移除 | 需 dump/restore 迁移 |
9.2 新增配置参数
# PostgreSQL 19 新增参数(postgresql.conf)
password_expiration_warning_threshold = '7d' # 密码过期前警告天数
md5_password_warnings = on # MD5 警告开关
io_min_workers = 1 # 异步 I/O 最小 worker 数
io_max_workers = 8 # 异步 I/O 最大 worker 数
io_worker_idle_timeout = '500ms' # I/O worker 空闲超时
io_worker_launch_interval = '10ms' # I/O worker 启动间隔
timing_clock_source = 'gettimeofday' # 计时精度来源
autovacuum_max_parallel_workers = 8 # Autovacuum 最大并行数
default_toast_compression = 'lz4' # TOAST 默认压缩算法
十、总结与展望
PostgreSQL 19 是近年来变化幅度最大的一个版本之一。它的核心思路可以概括为三点:
性能优先:查询优化器的系统性重构(Semijoin/Antijoin优化、聚合前推、Memoize扩展)将大量慢查询场景的运行时间从分钟级压缩到秒级甚至毫秒级。TOAST 压缩算法切换、并行 Autovacuum 和 SIMD COPY FROM 则从基础设施层面全面提升了数据库的吞吐能力。
安全升级:MD5 认证废弃、RADIUS 支持移除、standard_conforming_strings 强制开启——这些都是数据库安全的基本功。PostgreSQL 19 在保持向后兼容的同时,逐步清除了历史遗留的安全隐患。
运维友好:分区 MERGE/SPLIT 语法、pg_stat_lock 新视图、pg_createsubscriber 增强,这些改进让 DBA 的日常运维工作更高效,也让业务开发者的 SQL 表达更简洁。
PostgreSQL 19 正式版预计将在 2026 年 9-10 月发布,GA 前建议在测试环境中充分验证 Beta 2 版本,提前处理上述破坏性变更。
选题来源:PostgreSQL 全球开发组 2026 年 7 月 16 日发布 PostgreSQL 19 Beta 2,来源:https://www.postgresql.org/about/news/postgresql-19-beta-2-released-3350/
关键词:PostgreSQL 19 | Beta 2 | 查询优化 | ANTI JOIN | 并行 Autovacuum | TOAST lz4 | MD5 废弃 | SCRAM 认证 | 分区 MERGE SPLIT | pg_stat_lock