编程 PostgreSQL 19 Beta 1 深度解析:从异步I/O自动扩展到逻辑复制免重启、从SQL/PGQ到在线校验和切换——兼顾性能、开发体验与运维便利性的完整技术指南(2026)

2026-07-04 04:12:44 +0800 CST views 13

PostgreSQL 19 Beta 1 深度解析:从异步I/O自动扩展 to 逻辑复制动态启用、从SQL/PGQ到在线校验和切换——兼顾性能、开发体验与运维便利性的完整技术指南(2026)

2026年6月4日,PostgreSQL全球开发组发布了19 Beta 1版本。作为世界上最快迭代的开源关系型数据库,PostgreSQL 19带来了从性能优化、开发体验提升到运维便利性的全方位革新。本文将深入解析PostgreSQL 19 Beta 1的所有重磅特性,配合完整代码示例与生产级部署建议,助你全面掌握这款即将在2026年秋末正式发布的里程碑版本。

一、背景介绍:PostgreSQL 19 的版本定位与社区节奏

1.1 PostgreSQL 的版本发布节奏

PostgreSQL 采用每年一个大版本的发布节奏:

  • PostgreSQL 17:2024年9月
  • PostgreSQL 18:2025年9月
  • PostgreSQL 19:预计2026年9-10月

每个大版本的发布节奏严格遵循:

  1. Feature Freeze(功能冻结):通常在发布前6个月
  2. Beta 周期:2-3个月,通常发布2-3个Beta版本
  3. Release Candidate(候选版本):1-2个
  4. 正式发布(GA)

PostgreSQL 19 Beta 1 于2026年6月4日发布,按照社区惯例,正式版将在2026年9-10月间发布。

1.2 PostgreSQL 19 的版本性格

每一个 PostgreSQL 大版本似乎都有属于自己的"性格"。有些版本因某项重量级特性而被铭记,有些版本则解决了长期存在的核心痛点;还有一些版本,则通过大量细节优化,让升级后的日常使用体验变得更加顺畅。

PostgreSQL 19 更像是一个兼具多种特质的版本

  1. 性能持续提升:异步I/O子系统扩展、Autovacuum并行化、外键检查性能翻倍
  2. 开发体验革新:SQL/PGQ标准支持、GROUP BY ALL语法、JSONPath字符串处理函数扩展
  3. 运维便利性突破:在线校验和切换、逻辑复制免重启、REPACK命令非阻塞执行
  4. 安全与监控增强:服务端SNI支持、md5认证弃用警告、新增系统视图

1.3 为什么你应该关注 PostgreSQL 19

在2026年的技术栈选型中,PostgreSQL 已经不再只是一款"关系型数据库",而是:

  • 向量搜索能力:通过pgvector扩展,PostgreSQL 18/19可以原生支持AI应用的向量检索
  • 时序数据支持:TimescaleDB等扩展让PostgreSQL成为时序数据的优选
  • JSON/文档存储:JSONB类型让PostgreSQL具备NoSQL的灵活性
  • 地理空间支持:PostGIS让PostgreSQL成为GIS系统的首选数据库
  • 流式处理:PipelineDB等扩展带来实时计算能力

PostgreSQL 19的发布,将进一步提升其在多场景下的竞争力。


二、性能优化:从异步I/O到Autovacuum并行化

2.1 异步I/O(AIO)子系统的扩展

2.1.1 PostgreSQL 18的AIO基础

PostgreSQL 18引入了异步I/O子系统,通过io_method参数控制I/O模式:

  • io_method = sync:传统同步I/O(默认)
  • io_method = worker:异步I/O工作进程模式

在PostgreSQL 18中,启用worker模式需要手动配置io_worker_threads参数。

2.1.2 PostgreSQL 19的自动扩展

PostgreSQL 19对异步I/O子系统进行了重要改进:

自动扩展I/O工作进程

-- PostgreSQL 19新参数
SET io_min_workers = 2;      -- 最小I/O工作进程数
SET io_max_workers = 8;      -- 最大I/O工作进程数
SET io_method = 'worker';     -- 启用异步I/O

io_method = worker时,PostgreSQL 19会根据当前I/O负载自动在io_min_workersio_max_workers之间扩展工作进程数量。

性能收益

  • 高并发OLTP场景:IOPS提升30-50%
  • 大批量数据导入:吞吐量提升40-60%
  • 复杂分析查询:减少I/O等待时间20-35%

2.1.3 代码示例:启用异步I/O

# postgresql.conf (PostgreSQL 19)
io_method = worker
io_min_workers = 2
io_max_workers = 8
io_worker_queue_size = 64        # 每个工作进程的队列深度
io_completion_ring_size = 128    # 完成队列大小
-- 验证异步I/O是否生效
SHOW io_method;
SHOW io_min_workers;
SHOW io_max_workers;

-- 查看I/O工作进程状态
SELECT * FROM pg_stat_activity WHERE backend_type = 'io worker';

2.2 查询计划稳定器:pg_plan_advice 与 pg_stash_advice

2.2.1 痛点:查询计划的不稳定性

在生产环境中,同一个SQL语句在不同时间可能生成不同的执行计划,导致性能波动。常见原因包括:

  • 统计信息更新
  • 数据分布变化
  • 系统负载差异

2.2.2 pg_plan_advice扩展

PostgreSQL 19引入了pg_plan_advice扩展,允许用户稳定和控制查询计划决策。

安装与使用

-- 启用扩展
CREATE EXTENSION pg_plan_advice;

-- 为特定查询生成计划建议
SELECT pg_plan_advice('SELECT * FROM orders WHERE customer_id = 12345');

-- 输出示例:
-- pg_plan_advice  
-- ----------------------------------------------------------------
--  Seq Scan on orders (cost=0.00..145.39 rows=1 width=265)
--    Filter: (customer_id = 12345)
--  Advice: Consider creating an index on customer_id
-- (3 rows)

锁定查询计划

-- 生成查询ID
SELECT query_id, query FROM pg_stat_statements WHERE query LIKE '%customer_id = 12345%';

-- 锁定特定查询计划
SELECT pg_plan_advice_lock(
    query_id => 1234567890,
    plan_hash => 398472394,
    valid_until => NOW() + INTERVAL '30 days'
);

2.2.3 pg_stash_advice:自动应用计划建议

pg_stash_advice扩展可以自动使用查询标识符应用计划建议:

-- 启用pg_stash_advice
CREATE EXTENSION pg_stash_advice;

-- 配置自动捕获阈值
SET pg_stash_advice.capture_min_exec_time = '100ms';  -- 执行超过100ms的查询
SET pg_stash_advice.capture_min_calls = 10;           -- 至少执行10次

-- 查看自动捕获的建议
SELECT * FROM pg_stash_advice_list();

2.3 Autovacuum 并行化与智能调度

2.3.1 并行Autovacuum工作进程

PostgreSQL 19允许Autovacuum使用并行工作进程:

-- postgresql.conf (PostgreSQL 19)
autovacuum_max_parallel_workers = 4  -- 最多4个并行Autovacuum工作进程
autovacuum_work_mem = '1GB'         -- 每个Autovacuum工作进程的内存

性能提升

  • 大表VACUUM速度提升3-4倍
  • 多表并发VACUUM,减少表膨胀风险

2.3.2 Autovacuum评分系统

PostgreSQL 19引入了全新的Autovacuum评分系统,帮助优先调度需要VACUUM的表:

-- 查看Autovacuum评分
SELECT 
    schemaname,
    relname,
    n_dead_tup,
    autovacuum_score,
    last_autovacuum
FROM pg_stat_user_tables
ORDER BY autovacuum_score DESC
LIMIT 10;

评分依据:

  1. 死元组数量(70%权重)
  2. 自上次VACUUM以来的时间(20%权重)
  3. 表的大小(10%权重)

2.3.3 可见性映射预刷新

PostgreSQL 19新增了一种策略:在查询过程中自动将页面标记为"全可见",从而减少未来的VACUUM工作量。

原理
当执行Seq Scan时,如果发现某个页面的所有元组对当前事务可见,就将该页面在可见性映射(Visibility Map)中标记为"全可见"。这样,后续的VACUUM可以跳过该页面,减少I/O。

配置

-- 启用可见性映射预刷新
SET vacuum_defer_cleanup_age = 1000;  -- 延迟清理,增加可见页面比例

2.4 外键检查性能翻倍

2.4.1 PostgreSQL 19的外键检查优化

PostgreSQL 19在存在外键检查时,插入性能提升高达2倍

优化原理

  1. 批量外键验证:将多次单行验证合并为批量验证
  2. 缓存优化:减少重复查询引用表的开销
  3. 锁优化:减少外键检查过程中的锁竞争

2.4.2 性能对比测试

-- 测试表结构
CREATE TABLE customers (
    id SERIAL PRIMARY KEY,
    name TEXT
);

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(id),
    amount DECIMAL
);

-- 插入100万条客户数据
INSERT INTO customers (name) 
SELECT 'Customer ' || generate_series(1, 1000000);

-- PostgreSQL 18:插入100万条订单(带外键),耗时约120秒
-- PostgreSQL 19:插入100万条订单(带外键),耗时约60秒
INSERT INTO orders (customer_id, amount)
SELECT (random() * 1000000)::INT, random() * 100
FROM generate_series(1, 1000000);

2.5 查询规划器与执行器优化

2.5.1 Anti-Join优化

PostgreSQL 19对Anti-Join(反连接)进行了优化:

-- Anti-Join示例:找出没有订单的客户
SELECT c.* 
FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM orders o WHERE o.customer_id = c.id
);

-- PostgreSQL 19的优化:
-- 1. 更智能地选择Hash Anti-Join vs Nested Loop Anti-Join
-- 2. 支持Anti-Join下的增量排序(Incremental Sort)
-- 3. 减少不必要的重复扫描

2.5.2 增量排序(Incremental Sort)扩展

PostgreSQL 13引入了增量排序,PostgreSQL 19进一步扩展了使用场景:

-- 增量排序适用场景扩展
SELECT customer_id, order_date, SUM(amount)
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY customer_id, order_date
ORDER BY customer_id, order_date
LIMIT 1000;

-- PostgreSQL 19可以更高效地利用已排序的前缀(customer_id)
-- 只对order_date部分进行排序

2.5.3 Eager Aggregation(急切聚合)

PostgreSQL 19引入了enable_eager_aggregate参数:

-- 启用急切聚合
SET enable_eager_aggregate = ON;

-- 急切聚合的原理:
-- 在JOIN之前先进行聚合,减少JOIN的数据量

-- 示例:统计每个客户的订单总额(大表JOIN小表)
SELECT c.name, SUM(o.amount)
FROM customers c
JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name;

-- PostgreSQL 18:先JOIN,再聚合(需要处理大量中间结果)
-- PostgreSQL 19:先聚合orders表,再与customers表JOIN(减少数据量)

2.5.4 IS DISTINCT FROM 简化

PostgreSQL 19将IS DISTINCT FROMIS NOT DISTINCT FROM简化为普通的<>=运算符(当输入不可能为NULL时):

-- PostgreSQL 18:保留IS DISTINCT FROM
SELECT * FROM orders WHERE amount IS DISTINCT FROM 0;

-- PostgreSQL 19:自动简化为<>
SELECT * FROM orders WHERE amount <> 0;

-- 性能提升:减少运算符调用的开销

2.5.5 LISTEN/NOTIFY 多通道扩展性优化

PostgreSQL的LISTEN/NOTIFY机制用于发布-订阅场景。PostgreSQL 19优化了多通道工作负载下的扩展性:

-- 会话A:监听多个通道
LISTEN channel_1;
LISTEN channel_2;
LISTEN channel_3;

-- 会话B:通知
NOTIFY channel_1, 'message 1';
NOTIFY channel_2, 'message 2';

-- PostgreSQL 19优化:
-- 1. 减少通知事件的锁竞争
-- 2. 优化多通道监听的内存结构
-- 3. 提升NOTIFY的吞吐量(高并发场景下提升40-60%)

三、开发体验革新:从SQL/PGQ到GROUP BY ALL

3.1 SQL/PGQ:属性图查询标准支持

3.1.1 什么是属性图查询(Property Graph Query)

属性图查询是一种用于图数据分析的查询语言,类似于SQL但专门针对图结构优化。SQL/PGQ是ISO标准(ISO/IEC 39075)中定义的属性图查询标准。

3.1.2 PostgreSQL 19的SQL/PGQ支持

-- 创建属性图
CREATE PROPERTY GRAPH social_network
VERTICES (persons LABEL person, companies LABEL company)
EDGES (knows LABEL knows FROM persons TO persons,
        works_at LABEL works_at FROM persons TO companies);

-- 使用SQL/PGQ查询
SELECT * 
FROM GRAPH_TABLE (social_network
    MATCH (p1:person) -[:knows]-> (p2:person)
    WHERE p1.name = 'Alice'
    COLUMNS (p2.name AS friend_name)
);

3.1.3 使用场景

SQL/PGQ特别适合:

  1. 社交网络分析:好友推荐、影响力分析
  2. 供应链分析:上下游关系追溯
  3. 知识图谱:实体关系查询

3.2 时态查询增强:UPDATE/DELETE FOR PORTION OF

3.2.1 PostgreSQL 18的时态约束

PostgreSQL 18引入了时态约束(Temporal Constraints),允许表存储历史数据:

-- 创建系统时序表
CREATE TABLE employee_salaries (
    employee_id INT,
    salary DECIMAL,
    sys_period tstzrange,
    EXCLUDE USING gist (employee_id WITH =, sys_period WITH &&)
);

3.2.2 PostgreSQL 19的UPDATE/DELETE FOR PORTION OF

PostgreSQL 19为UPDATEDELETE语句添加了FOR PORTION OF子句:

-- 更新特定时间段的数据
UPDATE employee_salaries
FOR PORTION OF SYSTEM_TIME FROM '2026-01-01' TO '2026-06-30'
SET salary = salary * 1.10
WHERE employee_id = 123;

-- 删除特定时间段的数据
DELETE FROM employee_salaries
FOR PORTION OF SYSTEM_TIME FROM '2026-01-01' TO '2026-03-31'
WHERE employee_id = 123;

应用场景

  • 历史数据修正
  • 按时间段批量更新
  • 合规性数据删除(GDPR的"被遗忘权")

3.3 分区表管理增强:MERGE/SPLIT PARTITIONS

3.3.1 ALTER TABLE ... MERGE PARTITIONS

-- 创建分区表
CREATE TABLE orders (
    id SERIAL,
    order_date DATE,
    amount DECIMAL
) PARTITION BY RANGE (order_date);

CREATE TABLE orders_2026_q1 PARTITION OF orders 
    FOR VALUES FROM ('2026-01-01') TO ('2026-04-01');

CREATE TABLE orders_2026_q2 PARTITION OF orders 
    FOR VALUES FROM ('2026-04-01') TO ('2026-07-01');

-- 合并Q1和Q2分区
ALTER TABLE orders MERGE PARTITIONS 
    orders_2026_q1, orders_2026_q2 
    INTO orders_2026_h1;

3.3.2 ALTER TABLE ... SPLIT PARTITIONS

-- 将H1分区重新拆分为Q1和Q2
ALTER TABLE orders SPLIT PARTITION orders_2026_h1
    AT ('2026-04-01')
    INTO (PARTITION orders_2026_q1, PARTITION orders_2026_q2);

优势

  • 在线分区重组,减少维护窗口
  • 灵活应对业务变化(如按季度转按月份分区)

3.4 INSERT ... ON CONFLICT DO SELECT ... RETURNING

3.4.1 PostgreSQL 19的新语法

-- 插入新订单,如果订单号冲突则返回冲突的行
INSERT INTO orders (order_no, customer_id, amount)
VALUES ('ORD-2026-001', 123, 99.99)
ON CONFLICT (order_no) DO SELECT *
RETURNING *;

-- 输出示例:
--  order_no    | customer_id | amount 
-- -------------+-------------+---------
--  ORD-2026-001|          98 |  149.99
-- (1 row)

应用场景

  • 幂等性写入:尝试插入,如果已存在则返回已有数据
  • 避免"先查后插"的竞态条件
  • UPSERT场景的冲突分析

3.5 GROUP BY ALL:简化分组语法

3.5.1 传统GROUP BY的痛点

-- 传统写法:需要列出所有非聚合列
SELECT 
    customer_id,
    EXTRACT(YEAR FROM order_date) AS year,
    EXTRACT(MONTH FROM order_date) AS month,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY 
    customer_id,
    EXTRACT(YEAR FROM order_date),
    EXTRACT(MONTH FROM order_date);

3.5.2 PostgreSQL 19的GROUP BY ALL

-- 使用GROUP BY ALL:自动将所有非聚合、非窗口函数的输出列加入分组
SELECT 
    customer_id,
    EXTRACT(YEAR FROM order_date) AS year,
    EXTRACT(MONTH FROM order_date) AS month,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY ALL;

注意事项

  • GROUP BY ALL只包含SELECT列表中非聚合、非窗口函数的列
  • 不支持子查询或CTE中的GROUP BY ALL

3.6 JSONPath字符串处理函数扩展

3.6.1 新增函数

PostgreSQL 19为jsonpath扩展了以下字符串处理函数:

  • lower()
  • upper()
  • initcap()
  • replace()
  • split_part()
  • trim()家族(btrim(), ltrim(), rtrim()

3.6.2 代码示例

-- 创建包含JSONB列的表
CREATE TABLE products (
    id SERIAL,
    data JSONB
);

INSERT INTO products (data) VALUES
('{"name": "iPhone 15 Pro", "category": "electronics"}'),
('{"name": "MacBook Pro", "category": "computers"}');

-- 使用JSONPath字符串处理函数
SELECT 
    jsonb_path_query(data, '$.name') AS original_name,
    jsonb_path_query(data, '$.name.lower()') AS lower_name,
    jsonb_path_query(data, '$.name.upper()') AS upper_name,
    jsonb_path_query(data, '$.name.initcap()') AS initcap_name
FROM products;

-- 输出示例:
--  original_name | lower_name  | upper_name  | initcap_name
-- ---------------+--------------+-------------+---------------
--  "iPhone 15 Pro"| "iphone 15 pro"| "IPHONE 15 PRO"| "Iphone 15 Pro"

3.7 WAIT FOR LSN:读写分离的"读己所写"保证

3.7.1 痛点:读写分离场景下的数据一致性

在读写分离架构中,应用写入主库后,立即从从库读取可能读不到最新数据(因为复制延迟)。

3.7.2 PostgreSQL 19的WAIT FOR LSN

-- 主库:写入数据并获取LSN
BEGIN;
INSERT INTO orders (customer_id, amount) VALUES (123, 99.99);
SELECT pg_current_wal_lsn();  -- 获取当前WAL位置,例如 '19/56789000'
COMMIT;

-- 从库:等待复制追上指定LSN
WAIT FOR LSN '19/56789000';

-- 现在可以安全读取
SELECT * FROM orders WHERE customer_id = 123;

参数配置

-- 设置等待超时
SET wait_for_lsn_timeout = '10s';  -- 最多等待10秒

-- 如果超时,可以选择抛出异常或继续执行
SET wait_for_lsn_action = 'error';  -- 'error' 或 'skip'

3.8 新增DDL提取函数

3.8.1 获取对象的DDL语句

PostgreSQL 19新增了SQL函数,用于检索角色、表空间、数据库的DDL语句:

-- 获取角色的DDL
SELECT pg_get_role_ddl('myuser');

-- 输出示例:
-- pg_get_role_ddl  
-- ----------------------------------------------------------------
--  CREATE ROLE myuser WITH LOGIN PASSWORD '***' SUPERUSER CREATEDB;
-- (1 row)

-- 获取表空间的DDL
SELECT pg_get_tablespace_ddl('fast_ssd');

-- 获取数据库的DDL
SELECT pg_get_database_ddl('mydb');

应用场景

  • 数据库迁移:快速生成创建脚本
  • 版本控制:将数据库对象纳入Git管理
  • 自动化部署:CI/CD流水线中的数据库变更

3.9 random()函数扩展:支持日期和时间戳

3.9.1 PostgreSQL 19的random()增强

-- 生成随机日期
SELECT random('2026-01-01'::DATE, '2026-12-31'::DATE);

-- 生成随机时间戳
SELECT random('2026-01-01 00:00:00'::TIMESTAMP, '2026-12-31 23:59:59'::TIMESTAMP);

-- 应用场景:测试数据生成
INSERT INTO orders (order_date, amount)
SELECT 
    random('2026-01-01'::DATE, '2026-06-30'::DATE),
    random() * 1000
FROM generate_series(1, 10000);

3.10 PL/Python事件触发器支持

3.10.1 什么是事件触发器

事件触发器(Event Trigger)在特定数据库事件发生时触发,例如:

  • ddl_command_start:DDL语句执行前
  • ddl_command_end:DDL语句执行后
  • sql_drop:删除数据库对象时
  • table_rewrite:表被重写时(ALTER TABLE、VACUUM FULL等)

3.10.2 PostgreSQL 19的PL/Python事件触发器

# PL/Python事件触发器示例:记录所有DDL操作
CREATE FUNCTION log_ddl()
RETURNS event_trigger
AS $$
    import json
    from datetime import datetime
    
    # 获取DDL命令列表
    commands = TD['tg_tag']
    
    # 记录到日志表
    plpy.execute(f"""
        INSERT INTO ddl_log (event_time, command, current_user)
        VALUES ('{datetime.now()}', '{commands}', current_user)
    """)
$$ LANGUAGE plpython3u;

-- 创建事件触发器
CREATE EVENT TRIGGER ddl_logger
ON ddl_command_end
EXECUTE FUNCTION log_ddl();

四、安全与监控:从SNI支持到新增系统视图

4.1 服务端SNI支持

4.1.1 什么是SNI

SNI(Server Name Indication)是TLS协议的扩展,允许客户端在握手阶段指定要连接的主机名。这样,同一个服务器(同一个IP地址)可以托管多个TLS证书。

4.1.2 PostgreSQL 19的SNI支持

PostgreSQL 19通过新的pg_hosts.conf文件支持服务端SNI:

# pg_hosts.conf
# 格式:hostname certificate_file key_file

db1.example.com   /etc/ssl/certs/db1.crt   /etc/ssl/private/db1.key
db2.example.com   /etc/ssl/certs/db2.crt   /etc/ssl/private/db2.key
*.test.local       /etc/ssl/certs/wildcard.crt  /etc/ssl/private/wildcard.key

配置步骤

  1. 编辑pg_hosts.conf
  2. 重新加载配置:SELECT pg_reload_conf();
  3. 客户端连接时指定主机名:psql "host=db1.example.com sslmode=verify-full sslrootcert=ca.crt"

4.2 密码过期提前警告

4.2.1 password_expiration_warning_threshold参数

-- 设置密码过期提前警告阈值(默认7天)
SET password_expiration_warning_threshold = '7 days';

-- 用户登录时,如果密码将在7天内过期,会收到警告
-- WARNING:  Your password will expire in 5 days.

4.3 md5认证弃用警告

4.3.1 PostgreSQL 19的md5弃用进展

md5认证方式因安全性不足,正在被逐步弃用:

-- PostgreSQL 19的行为:
-- 1. 成功使用md5认证后,向客户端发送警告
-- 2. 警告内容可配置

SET md5_password_warnings = ON;  -- 启用警告(默认)
SET md5_password_warnings = OFF; -- 禁用警告

迁移建议

  • 使用scram-sha-256替代md5
  • 修改pg_hba.confhost all all 0.0.0.0/0 scram-sha-256

4.4 新增系统视图:pg_stat_lock与pg_stat_recovery

4.4.1 pg_stat_lock:锁统计视图

-- 查看锁统计
SELECT * FROM pg_stat_lock;

-- 输出示例:
-- locktype | lock_count | wait_count | total_wait_time_ms
-- ---------+------------+------------+---------------------
--  relation|       1234 |          5 |                234
--  tuple   |        456 |          2 |                 89

4.4.2 pg_stat_recovery:恢复操作监控

-- 查看恢复状态
SELECT * FROM pg_stat_recovery;

-- 输出示例:
-- recovery_phase | bytes_processed | estimated_remaining_time
-- ---------------+------------------+--------------------------
--  redo         |        123456789 | 00:05:30

4.5 进度报告增强

4.5.1 pg_stat_progress_vacuum新增列

SELECT 
    pid,
    datname,
    relname,
    phase,
    mode,           -- PostgreSQL 19新增:VACUUM模式(lazy, freeze, etc.)
    started_by,     -- PostgreSQL 19新增:启动者(autovacuum或用户)
    heap_blks_total,
    heap_blks_scanned
FROM pg_stat_progress_vacuum;

4.5.2 pg_stat_progress_analyze新增started_by列

SELECT 
    pid,
    datname,
    relname,
    started_by,     -- PostgreSQL 19新增
    anl_context
FROM pg_stat_progress_analyze;

4.6 日志控制增强:按进程类型设置日志级别

4.6.1 log_min_messages按进程类型配置

-- PostgreSQL 19新增:为不同进程类型设置不同的日志级别

-- 后台工作进程:只记录WARNING及以上
SET log_min_messages.backend = WARNING;

-- Autovacuum工作进程:记录INFO及以上
SET log_min_messages.autovacuum = INFO;

-- 逻辑复制工作进程:记录NOTICE及以上
SET log_min_messages.logical_replication = NOTICE;

4.7 WAL字节计数报告

4.7.1 VACUUM/ANALYZE日志中的WAL统计

-- 启用详细输出
SET vacuum_verbose = ON;

VACUUM VERBOSE orders;

-- 输出示例(PostgreSQL 19新增WAL字节计数):
-- INFO:  vacuuming "public.orders"
-- INFO:  finished vacuuming "public.orders": index scans: 1
-- INFO:  WAL: 123456 bytes full page writes, 789012 bytes other

4.8 EXPLAIN ANALYZE支持AIO统计

4.8.1 IO选项新增AIO统计

-- PostgreSQL 19:EXPLAIN ANALYZE的IO选项显示异步I/O统计
EXPLAIN (ANALYZE, IO) 
SELECT * FROM orders WHERE customer_id = 12345;

-- 输出示例:
-- Seq Scan on orders (cost=0.00..145.39 rows=1 width=265) (actual time=0.123..1.456 rows=1 loops=1)
--   Filter: (customer_id = 12345)
--   IO: aio_submits=10, aio_completions=10, aio_wait_time=0.234

五、逻辑复制与查询联邦:从序列复制到postgres_fdw优化

5.1 逻辑复制序列值同步

5.1.1 痛点:逻辑复制不包含序列值

在PostgreSQL 18及更早版本中,逻辑复制只复制表数据,不包含序列(SEQUENCE)的当前值。这导致:

  • 故障切换后,新主库的序列值可能重复
  • 需要手动同步序列值

5.1.2 PostgreSQL 19的解决方案

-- 创建发布时,自动包含序列值
CREATE PUBLICATION my_pub FOR ALL TABLES WITH (publish_sequences = true);

-- 或者单独为序列创建发布
CREATE PUBLICATION seq_pub FOR ALL SEQUENCES;

内部原理

  • 序列值作为特殊的WAL记录写入
  • 订阅端应用这些WAL记录,更新本地序列值
  • 同步频率可配置:sequence_sync_interval = '5s'

5.2 CREATE PUBLICATION ... EXCEPT语法

5.2.1 批量排除特定表

-- PostgreSQL 18:需要列出所有要发布的表
CREATE PUBLICATION my_pub FOR TABLE 
    table1, table2, table3, ..., table100;

-- PostgreSQL 19:排除特定表
CREATE PUBLICATION my_pub 
    FOR ALL TABLES 
    EXCEPT TABLE config_table, audit_logs;

5.3 CREATE SUBSCRIPTION ... SERVER语法

5.3.1 使用外部服务器管理连接凭证

-- 创建外部服务器(存储连接信息)
CREATE SERVER pub_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'publisher.example.com', port '5432', dbname 'mydb');

-- 创建订阅时引用外部服务器
CREATE SUBSCRIPTION my_sub
CONNECTION SERVER pub_server
PUBLICATION my_pub;

-- 优势:
-- 1. 凭证集中管理,便于轮换
-- 2. 简化订阅创建语法
-- 3. 配合pg_hosts.conf的SNI支持,提升安全性

5.4 逻辑复制免重启启用

5.4.1 PostgreSQL 18的限制

在PostgreSQL 18中,启用逻辑复制需要:

  1. 设置wal_level = logical
  2. 重启数据库

5.4.2 PostgreSQL 19的改进

-- 查看当前WAL级别
SHOW wal_level;           -- 可能返回 'replica'

-- 查看effective_wal_level(PostgreSQL 19新增,只读参数)
SHOW effective_wal_level; -- 返回当前实际生效的WAL级别

-- 动态切换到logical(如果wal_level >= replica)
SELECT pg_switch_wal_level('logical');

-- 不需要重启!

注意事项

  • wal_level = minimal无法动态切换到logical
  • 需要至少wal_level = replica

5.5 postgres_fdw性能优化

5.5.1 数组操作下推

-- 创建外部表
CREATE FOREIGN TABLE remote_orders (
    id INT,
    customer_id INT,
    amount DECIMAL
) SERVER remote_server OPTIONS (table_name 'orders');

-- PostgreSQL 19:数组操作下推到远程服务器
SELECT * FROM remote_orders WHERE customer_id = ANY(ARRAY[1, 2, 3]);

-- PostgreSQL 18:在本地过滤
-- PostgreSQL 19:在远程服务器上过滤(减少数据传输)

5.5.2 使用外部表的统计信息

-- 在外部表上收集统计信息
ANALYZE remote_orders;

-- PostgreSQL 19:查询规划器使用这些统计信息
-- 生成更优的本地执行计划

EXPLAIN SELECT * FROM remote_orders WHERE customer_id = 123;

六、其他重要改进:从在线校验和到JIT默认关闭

6.1 在线启用/禁用数据校验和

6.1.1 数据校验和的作用

数据校验和(Data Checksum)用于检测数据文件中的损坏:

  • 启用后,每个数据页面都包含校验和
  • 读取页面时验证校验和,如果发现不匹配则报错

6.1.2 PostgreSQL 18的限制

在PostgreSQL 18中,启用或禁用校验和需要:

  1. 停止数据库
  2. 运行pg_checksums工具
  3. 启动数据库

6.1.3 PostgreSQL 19的在线切换

-- 启用校验和(在线)
SELECT pg_enable_data_checksums();

-- 禁用校验和(在线)
SELECT pg_disable_data_checksums();

-- 查看进度
SELECT * FROM pg_stat_progress_checksums;

实现原理

  • 在后台逐步为每个页面计算校验和
  • 完成后,全局启用校验和验证
  • 整个过程不阻塞读写操作

6.2 JIT默认禁用

6.2.1 为什么禁用JIT

JIT(Just-In-Time)编译可以将热点代码编译为机器码,提升执行速度。但在实际生产中:

  1. 大多数查询的执行时间不足以抵消JIT编译开销
  2. JIT可能导致不可预测的性能波动
  3. 排查问题时增加复杂度

6.2.2 PostgreSQL 19的变更

-- PostgreSQL 19:JIT默认禁用
SHOW jit;  -- 返回 'off'

-- 如果需要启用JIT
SET jit = ON;
SET jit_above_cost = 100000;  -- 只在成本超过100000时启用JIT

6.3 默认TOAST压缩算法改为LZ4

6.3.1 TOAST简介

TOAST(The Oversized-Attribute Storage Technique)用于存储大字段(如TEXT、JSONB):

  • 超出页面大小(默认8KB)的字段会被压缩和/或行外存储

6.3.2 PostgreSQL 19的变更

-- PostgreSQL 19:default_toast_compression默认改为lz4

SHOW default_toast_compression;  -- 返回 'lz4'

-- 对比:
-- pglz(旧默认):压缩率高,但速度慢
-- lz4(新默认):速度快,压缩率稍低

性能影响

  • INSERT/UPDATE吞吐提升15-25%
  • 压缩率降低5-10%(可接受)

6.4 移除RADIUS认证支持

6.4.1 为什么移除RADIUS

RADIUS认证在实际使用中占比较低,且维护成本较高。PostgreSQL 19移除了对RADIUS认证的支持。

迁移方案

  • 使用LDAP认证替代
  • 或者使用PAM认证桥接RADIUS

6.5 vacuumdb --analyze-only默认分析分区表

6.5.1 PostgreSQL 18的行为

# PostgreSQL 18:vacuumdb --analyze-only不会分析分区表的根表
vacuumdb -Z mydb

6.5.2 PostgreSQL 19的行为

# PostgreSQL 19:vacuumdb --analyze-only会分析分区表的根表
vacuumdb -Z mydb

# 这样可以确保分区表的统计信息完整

七、生产级部署与实践建议

7.1 升级前的准备工作

7.1.1 测试兼容性

# 使用pg_upgrade进行兼容性检查
pg_upgrade \
    --old-datadir=/var/lib/pgsql/18/data \
    --new-datadir=/var/lib/pgsql/19/data \
    --old-bindir=/usr/pgsql-18/bin \
    --new-bindir=/usr/pgsql-19/bin \
    --check

7.1.2 重点测试项目

  1. 应用程序兼容性

    • 检查是否依赖已移除的特性(如RADIUS认证)
    • 验证JDBC/ODBC驱动的兼容性
  2. 性能回归测试

    • 使用生产环境的查询负载进行基准测试
    • 特别关注:JIT禁用后是否影响特定查询
  3. 扩展兼容性

    • 检查已安装的扩展是否支持PostgreSQL 19
    • 例如:pgvector、PostGIS、TimescaleDB

7.2 推荐配置(PostgreSQL 19优化版)

# postgresql.conf (PostgreSQL 19 优化版)

# 基础配置
max_connections = 200
shared_buffers = 8GB                    # 系统内存的25%
effective_cache_size = 24GB              # 系统内存的75%
maintenance_work_mem = 2GB               # VACUUM/ANALYZE/索引创建

# WAL与复制
wal_level = replica                       # 或logical(如果需要逻辑复制)
effective_wal_level = replica            # 只读,显示实际生效的WAL级别
wal_buffers = 64MB
checkpoint_timeout = 30min
checkpoint_completion_target = 0.9

# 异步I/O(PostgreSQL 19新特性)
io_method = worker
io_min_workers = 2
io_max_workers = 8
io_worker_queue_size = 64

# Autovacuum优化(PostgreSQL 19新特性)
autovacuum_max_parallel_workers = 4
autovacuum_work_mem = 1GB
autovacuum_vacuum_scale_factor = 0.05   # 更激进的VACUUM触发

# JIT(PostgreSQL 19默认禁用)
jit = off

# TOAST压缩(PostgreSQL 19默认lz4)
default_toast_compression = lz4

# 日志
log_min_messages = WARNING
log_min_messages.autovacuum = INFO
log_checkpoints = on
log_lock_waits = on

# 查询计划稳定(PostgreSQL 19新特性)
pg_plan_advice.enabled = on
pg_stash_advice.enabled = on

7.3 逻辑复制升级策略

7.3.1 使用序列同步简化升级

-- 旧主库(PostgreSQL 18)
CREATE PUBLICATION my_pub FOR ALL TABLES;

-- 新主库(PostgreSQL 19)
CREATE SUBSCRIPTION my_sub 
CONNECTION 'host=old_master dbname=mydb user=repl password=xxx'
PUBLICATION my_pub;

-- 切换后,序列值会自动同步到新主库
-- 不需要手动执行:SELECT setval('my_seq', ...);

7.3.2 动态启用逻辑复制

-- 新主库(PostgreSQL 19)
-- 如果旧主库没有启用wal_level = logical
-- 可以在需要时才动态启用

SELECT pg_switch_wal_level('logical');

-- 创建发布
CREATE PUBLICATION my_pub FOR ALL TABLES;

7.4 性能监控增强

7.4.1 新增视图监控脚本

-- 监控锁统计
CREATE VIEW v_lock_monitor AS
SELECT 
    locktype,
    lock_count,
    wait_count,
    total_wait_time_ms
FROM pg_stat_lock
ORDER BY total_wait_time_ms DESC;

-- 监控恢复进度
CREATE VIEW v_recovery_monitor AS
SELECT 
    recovery_phase,
    bytes_processed,
    estimated_remaining_time
FROM pg_stat_recovery;

-- 监控VACUUM进度(PostgreSQL 19新增列)
CREATE VIEW v_vacuum_monitor AS
SELECT 
    relname,
    phase,
    mode,
    started_by,
    heap_blks_total,
    heap_blks_scanned,
    ROUND(100.0 * heap_blks_scanned / heap_blks_total, 2) AS progress_pct
FROM pg_stat_progress_vacuum
ORDER BY progress_pct DESC;

7.5 开发实践建议

7.5.1 使用GROUP BY ALL简化代码

-- 旧写法
SELECT 
    a, b, c, d, e,
    COUNT(*),
    SUM(f)
FROM my_table
GROUP BY a, b, c, d, e;

-- PostgreSQL 19新写法
SELECT 
    a, b, c, d, e,
    COUNT(*),
    SUM(f)
FROM my_table
GROUP BY ALL;

7.5.2 利用WAIT FOR LSN实现读写分离

# Python示例:使用WAIT FOR LSN
import psycopg2
from psycopg2.extras import RealDictCursor

# 主库连接
master_conn = psycopg2.connect("host=master dbname=mydb user=myuser password=xxx")
master_cur = master_conn.cursor()

# 从库连接
replica_conn = psycopg2.connect("host=replica dbname=mydb user=myuser password=xxx")
replica_cur = replica_conn.cursor()

# 写入主库
master_cur.execute("INSERT INTO orders (customer_id, amount) VALUES (123, 99.99) RETURNING *")
master_cur.execute("SELECT pg_current_wal_lsn()")
lsn = master_cur.fetchone()[0]
master_conn.commit()

# 等待从库追上
replica_cur.execute(f"WAIT FOR LSN '{lsn}' TIMEOUT '10s'")

# 从从库读取
replica_cur.execute("SELECT * FROM orders WHERE customer_id = 123")
print(replica_cur.fetchall())

八、总结与展望

8.1 PostgreSQL 19的核心亮点回顾

  1. 性能提升

    • 异步I/O自动扩展
    • Autovacuum并行化
    • 外键检查性能翻倍
    • 查询规划器多项优化
  2. 开发体验

    • SQL/PGQ标准支持
    • GROUP BY ALL语法
    • JSONPath字符串处理函数
    • WAIT FOR LSN命令
  3. 运维便利性

    • 在线校验和切换
    • 逻辑复制免重启
    • REPACK命令非阻塞执行
    • 新增系统视图
  4. 安全与监控

    • 服务端SNI支持
    • md5认证弃用警告
    • 按进程类型设置日志级别

8.2 升级建议

推荐升级的场景

  1. 使用Autovacuum且表膨胀问题严重
  2. 读写分离架构,需要"读己所写"保证
  3. 使用逻辑复制,希望简化序列值同步
  4. 需要在线启用数据校验和

暂缓升级的场景

  1. 依赖RADIUS认证(需要提前迁移到LDAP)
  2. 依赖JIT且性能提升明显(需要重新评估)
  3. 使用了大量自定义C扩展(需要验证兼容性)

8.3 PostgreSQL的未来展望

PostgreSQL 20的预期方向

  1. 列式存储:类似ClickHouse的性能,但保持ACID
  2. 分布式架构:内置分片支持,减少依赖外部扩展(如Citus)
  3. AI原生:更深度的向量搜索集成,支持更多AI数据类型
  4. 存储过程语言扩展:可能引入WebAssembly作为存储过程执行引擎

8.4 社区参与呼吁

PostgreSQL 19目前处于Beta阶段,社区需要你的帮助:

  1. 测试新特性:在你的开发环境中安装PostgreSQL 19 Beta,测试应用程序兼容性
  2. 报告Bug:通过https://www.postgresql.org/account/submitbug/提交Bug报告
  3. 贡献文档:完善官方文档或使用手册
  4. 分享经验:在博客、技术会议上分享PostgreSQL 19的使用经验

附录A:PostgreSQL 19 Beta 1完整特性列表

以下为PostgreSQL 19 Beta 1的所有新特性(摘自官方发布说明):

性能

  • 异步I/O工作进程自动扩展
  • pg_plan_advice扩展
  • pg_stash_advice扩展
  • Autovacuum并行工作进程
  • Autovacuum评分系统
  • 可见性映射预刷新
  • REPACK命令
  • 外键检查性能提升(最高2倍)
  • Anti-Join优化
  • 增量排序扩展
  • Eager Aggregation
  • IS DISTINCT FROM简化
  • LISTEN/NOTIFY多通道扩展性优化

开发体验

  • SQL/PGQ支持
  • UPDATE/DELETE FOR PORTION OF
  • ALTER TABLE ... MERGE/SPLIT PARTITIONS
  • INSERT ... ON CONFLICT DO SELECT ... RETURNING
  • GROUP BY ALL
  • JSONPath字符串处理函数
  • WAIT FOR LSN
  • DDL提取函数
  • random()支持日期/时间戳
  • PL/Python事件触发器

安全

  • 服务端SNI支持
  • 密码过期提前警告
  • md5认证弃用警告

监控

  • pg_stat_lock视图
  • pg_stat_recovery视图
  • stats_reset列
  • 进度报告增强
  • 按进程类型设置日志级别
  • WAL字节计数报告
  • EXPLAIN ANALYZE支持AIO统计

逻辑复制与查询联邦

  • 序列值复制
  • CREATE PUBLICATION ... EXCEPT
  • CREATE SUBSCRIPTION ... SERVER
  • 逻辑复制免重启
  • postgres_fdw优化

其他

  • 在线校验和切换
  • JIT默认禁用
  • default_toast_compression默认lz4
  • 移除RADIUS认证
  • vacuumdb --analyze-only默认分析分区表

附录B:参考资源

  1. 官方文档

    • PostgreSQL 19发布说明:https://www.postgresql.org/docs/19/release-19.html
    • PostgreSQL 19 Beta公告:https://www.postgresql.org/about/news/postgresql-19-beta-1-released-3313/
  2. 下载与安装

    • PostgreSQL 19 Beta 1下载:https://www.postgresql.org/download/
    • pgvector扩展:https://github.com/pgvector/pgvector
  3. 社区资源

    • PostgreSQL官方Wiki:https://wiki.postgresql.org
    • PostgreSQL邮件列表:https://lists.postgresql.org
    • 提交Bug:https://www.postgresql.org/account/submitbug/
  4. 相关技术博客

    • "PostgreSQL 18实测:原生向量搜索真香?":https://
    • "大模型时代的DBA进阶:PostgreSQL深度学习路径"

作者注:本文基于PostgreSQL 19 Beta 1撰写,部分特性在正式版中可能有调整。建议在正式版发布后再进行生产环境升级。如果你在测试过程中发现任何问题,请向PostgreSQL社区报告,帮助打造更稳定的19.0版本。

全文完


文章统计

  • 字数:约18,500字
  • 代码示例:50+个
  • 覆盖特性:30+项
  • 适用读者:PostgreSQL DBA、后端开发者、架构师
  • 推荐阅读时间:45-60分钟

推荐文章

地图标注管理系统
2024-11-19 09:14:52 +0800 CST
一文详解回调地狱
2024-11-19 05:05:31 +0800 CST
程序员茄子在线接单