Announcement

👇Official Account👇

Welcome to join the group & private message

Article first/tail QR code

Skip to content

PostgreSQL 17 实战指南:增量备份、逻辑复制故障转移、JSON_TABLE 与 pgvector

别被"小版本更新"骗了

PostgreSQL 17(2024 年 9 月发布)看起来是一次"成熟度"更新,不像 14 那样有 copy_to 大新闻,也不像 15 那样有 MERGE。但如果你还停在 PG 15 / 16,这些特性单拎出来就值得你动手升级:

  1. 原生增量备份——大库备份从"全天"变成"半小时"
  2. 逻辑复制故障转移——replica 升主不再断复制,不用重做全量同步
  3. JSON_TABLE()——终于跟得上 SQL/JSON 标准
  4. MERGE RETURNING——upsert 终于有返回值了

这篇文章不讲全量 changelog,只讲生产上真正影响你的那几个,外加 2026 年怎么用 PostgreSQL 一库打天下(pgvector + TimescaleDB + PostGIS)。

特性一:原生增量备份(PG 17 最大的运营红利)

PG 17 之前,pg_basebackup 只能做全量备份。PG 17 加了增量备份原生支持,思路是把数据库按 block 粒度记录哪些块变了,然后只备份这些块。

配置前置条件(最容易踩的坑):

增量备份依赖 WAL 摘要(WAL summarization),必须在第一次全量备份之前就打开:

ini
# postgresql.conf
summarize_wal = on

DANGER

summarize_wal 只对开启之后产生的 WAL 生成摘要。如果你开了它之后立刻做增量备份,会失败——因为"上次全量备份到现在"这段 WAL 没有摘要覆盖。

顺序必须是:先开 summarize_wal → 做一次全量备份 → 再开始增量链。用 pg_wal_summary_stats 确认摘要在生成。

全量 + 增量命令:

bash
# 全量备份(作为基线)
pg_basebackup -D /backup/full --manifest-checksums=SHA256

# 增量备份(引用昨天的 manifest,只拷变更的块)
pg_basebackup -D /backup/incr-2026-03-20 \
  --incremental=/backup/full/backup_manifest

# 恢复:pg_combinebackup 把全量 + 增量合并
pg_combinebackup /backup/full /backup/incr-2026-03-20 -o /restore

这个特性对 100GB 以上的库是决定性的。社区有报道说,TB 级库的每日备份从 8 小时降到 30 分钟——因为绝大多数 block 每天都没变。合成全量(synthetic full)还能在不重新全备的情况下重建基线。

恢复单个库/表怎么办? 增量备份是物理备份,恢复仍然要 pg_restore 或逻辑导出做细粒度恢复。物理备份承担"防灾难",逻辑备份承担"找回一条数据",两者互补不冲突。

特性二:逻辑复制故障转移(终于不断流)

逻辑复制最大的痛点:主库挂了,replica 被 promote,逻辑复制槽不会跟着过去。订阅端要重连、可能要全量重同步——2 小时的活。

PG 17 加了故障转移复制槽(failover slots)

sql
-- 在发布端创建可故障转移的逻辑复制槽
SELECT pg_create_logical_replication_slot(
    'my_subscription_slot',
    'pgoutput',
    false,  -- temporary
    true    -- failover = true(PG 17 新增)
);

-- 查看 failover 状态
SELECT slot_name, slot_type, failover, active
FROM pg_replication_slots;

每个 standby 上要开同步:

ini
# postgresql.conf(standby 上)
sync_replication_slots = on
hot_standby_feedback = on

主库失败、standby promote 后,新主带着和订阅端一致的 LSN,复制无缝恢复,不用全量重同步。实测数据(PG 17)里,模拟 failover 后订阅端 3 秒内重连恢复;PG 17 之前同样的场景要 drop + recreate 订阅,2 小时全表同步。

逻辑复制的两阶段提交也补上了:

sql
CREATE PUBLICATION my_pub FOR TABLE orders, order_items
  WITH (two_phase = true);

CREATE SUBSCRIPTION my_sub
  CONNECTION 'host=primary port=5432 dbname=mydb'
  PUBLICATION my_pub
  WITH (two_phase = enable);

这笔交易对跨订阅端分布式事务、多租户 SaaS 数据隔离意义重大。

特性三:JSON_TABLE()——写 JSON 查询终于不吐了

PG 16 及之前,把 JSONB 数组展开成行要靠 jsonb_array_elements + LATERAL,SQL 又长又绕。PG 17 实现了 SQL/JSON 标准的 JSON_TABLE()

sql
-- 旧写法(PG 16 及以下)
SELECT e->>'id' AS id,
       e->>'name' AS name,
       e->>'email' AS email
FROM orders o,
     LATERAL jsonb_array_elements(o.metadata->'contacts') AS e
WHERE o.order_id = 123;

-- 新写法(PG 17,JSON_TABLE)
SELECT jt.id, jt.name, jt.email
FROM orders o,
     JSON_TABLE(
       o.metadata,
       '$.contacts[*]'
       COLUMNS (
         id     INTEGER PATH '$.id',
         name   TEXT   PATH '$.name',
         email  TEXT   PATH '$.email'
       )
     ) AS jt
WHERE o.order_id = 123;

JSON 负载重的系统,JSON_TABLE 能把应用层那堆解析代码删掉,查询逻辑收进 SQL 里。

特性四:MERGE RETURNING——upsert 终于有前列腺

MERGE 从 PG 15 就有,但 PG 17 加了 RETURNINGWHEN NOT MATCHED BY SOURCE 这两个关键能力:

sql
MERGE INTO orders_summary t
USING new_orders s
  ON t.order_id = s.order_id
WHEN MATCHED AND s.deleted = true THEN
  DELETE
WHEN MATCHED THEN
  UPDATE SET total = s.total, updated_at = NOW()
WHEN NOT MATCHED THEN
  INSERT (order_id, total, created_at)
  VALUES (s.order_id, s.total, NOW())
RETURNING t.order_id, merge_action() AS action;
-- merge_action() 返回 'INSERT' / 'UPDATE' / 'DELETE'

数据同步(CDC、ETL)里这套写法干净得多,merge_action() 让你知道每行到底走了哪条路。

其他值得注意的 PG 17 细节

  • 内存友好的 VACUUM:重写的 VACUUM 减少内存占用,_io_ pacing 让它和高并发 OLTP 共存更好
  • pg_stat_io:新增的 I/O 统计视图,能按后端类型拆分读写,排查 IO 瓶颈必备
  • B-tree 对 IN 列表的扫描优化:多个值查询更快
  • COPY ... ON_ERROR ignore:批量导入遇到坏行能继续
  • sslnegotiation=direct:直连 TLS 握手,省一轮往返

2026 年:PostgreSQL 一库打天下

PG 17 的定位不单是关系库,而是数据平台。配合扩展,一个库能同时干 RDBMS、向量检索、时序、GIS 的活:

pgvector:把 RAG 塞进 PG

pgvector(Andrew Kane 2021 年作品)加 vector 类型 + L2/内积/余弦距离 + HNSW/IVFFlat 索引。2026 年 5 月最新版到 0.8

它成了 RAG 事实标准——OpenAI/Anthropic 生态的团队大量用它在 PG 里直接做嵌入检索,嵌入和关系元数据同库,少运维一个服务。对 <100M 向量的负载,召回/延迟表现跟专用 vector DB 有得比。

sql
CREATE EXTENSION IF NOT EXISTS vector;

-- HNSW 索引
CREATE INDEX ON embeddings USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 100);

-- 带元数据过滤的相似检索
SELECT id, title, 1 - (embedding <=> $query) AS similarity
FROM embeddings
WHERE tenant_id = 42            -- 预过滤
ORDER BY embedding <=> $query    -- 余弦距离
LIMIT 5;

TIP

如果想再进一步,pgvectorscale(Timescale 出品)提供了流式索引(StreamingDiskANN)。2026 年 4 月有基准:50M 个 1536 维向量上,99% 召回目标下 pgvectorscale 跑到约 471 QPS,同硬件 Qdrant 约 41 QPS——量级差异,但高度依赖配置,别当真理,用它提醒你"PG 能做的比你以为的多"。

TimescaleDB:吃掉时序市场

TimescaleDB 的 time_bucketfirst/last/lag、gap fill、以及 2024 年引入的 hypercore(混合列存+行存)让它正面跟 InfluxDB、Prometheus 竞争。

授权是双轨的:核心 Apache 2.0,进阶特性走 Timescale License(对非 AWS SaaS 有限制)。

PostGIS + pgRouting:地理标配

PostGIS(3.5,2026 年 5 月)加了 GEOMETRY/GEOGRAPHY 类型和 3000+ 空间函数,几乎所有 GIS 栈的默认底座。pgRouting 做路径规划。

运维生态

  • pgBackRest:物理备份事实标准,S3/GCS/Azure 直传、PITR、加密
  • pg_cron:RDS/GCP Cloud SQL/Azure 默认内置,VACUUM/REINDEX/分区清理全在库里排
  • pg_repack:无锁重建索引、清 bloat
  • pglogical:跨大版本逻辑复制(9.4→16 都能跳)

要不要升级?一张表说清楚

因素升级权重
大库(>500GB)高——增量备份单独就值回票价
重度逻辑复制高——故障转移槽彻底去痛点
复杂 upsert / 数据同步中——MERGE RETURNING 好香
重度 JSON 负载中——JSON_TABLE 删掉应用层解析
内存受限实例中——VACUUM 内存改进
小库、简单查询低——不急,但值得排期

升级路径:

  • 最小停机pg_upgrade(PG 16→17 直连),大库务必加 --link 硬链接,480GB 从 3 小时压到 4 分钟
  • 零停机:新建 PG 17 实例 → 逻辑复制过去 → catch up 后切流量。升级到 PG 17 还能用 pg_createsubscriber 把物理 standby 转成逻辑订阅者,更顺

WARNING

PG 14 会在 2026 年 11 月 EOL。还在 PG 14 及以下的,现在就该排升级了,不是"要不要",是"什么时候"。

结论

PG 17 是一场"成熟度更新",但增量备份、逻辑复制故障转移、JSON_TABLE、MERGE RETURNING 每一个都是生产刚需。而 2026 年的 PostgreSQL 早就不只是关系库——pgvector 让它能跑 RAG,TimescaleDB 让它能吃时序,PostGIS 让它覆盖 GIS。对大多数团队,"先住在 PG 里,扛不住了再搬专库"依然是最理性的起点。

TIP

先开 summarize_wal 再全备再走增量链。别在没开摘要时就急着做增量备份,那只会静默退化成全量备份,你还以为自己在省钱。

上次更新于: