Aurora PostgreSQL 大版本升级实战:从 PG 14 到 PG 16 的蓝绿部署方案、踩坑记录与性能基线对比

Aurora PostgreSQL 14 的 EOL 越来越近了,但很多团队还在观望。怕升级出问题?怕业务中断?这篇把升级前的准备、三种升级方案对比、蓝绿部署实操步骤和常见坑都讲清楚。

为什么现在必须动了

Aurora PostgreSQL 跟社区版 PostgreSQL 的大版本生命周期是绑定的。PG 14 的社区 EOL 是 2026 年 11 月,Aurora 的支持窗口也在逐步收紧。

更现实的压力:如果你不主动升级,亚马逊云科技会在 EOL 后强制升级,而且是在维护窗口自动执行。自己不升,系统帮你升——但时间点和方式你说了不算。

我去年底把三个生产集群从 14.9 升到了 16.4,踩了不少坑。诵实话升之前心里也没底,毕竟是有状态服务,出了问题可不是重启就能解决的。这篇完整记录一下整个过程。

升级前必做:建立性能基线

这步很多人跳过,但它是升级后验证"有没有变慢"的关键依据。

1. 开启 pg_stat_statements

-- 检查是否已加载
SHOW shared_preload_libraries;

-- 如果没有,需要修改参数组(需要重启实例)
-- 在 AWS 控制台的参数组中添加 pg_stat_statements 到 shared_preload_libraries

-- 创建扩展
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- 查看 Top SQL
SELECT
    substring(query, 1, 80) AS short_query,
    calls,
    round(total_exec_time::numeric, 2) AS total_ms,
    round(mean_exec_time::numeric, 2) AS avg_ms,
    rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;

2. 导出基线数据

# 把当前的 Top SQL 导出来,升级后对比
psql -h your-aurora-cluster.xxx.rds.amazonaws.com -U postgres -d mydb \
  -c "SELECT query, calls, total_exec_time, mean_exec_time, rows \
      FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 50" \
  --csv > baseline_before_upgrade.csv

3. 关键查询的执行计刓

挑 5-10 个核心业务 SQL,手动跑 EXPLAIN (ANALYZE, BUFFERS) 并保存。升级后对比执行计划有没有变化。

-- 示例:保存执行计划
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT o.id, o.status, c.name
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE o.created_at > now() - interval '7 days'
  AND o.status = 'pending';

为什么要保存执行计划? PG 大版本升级后优化器行为可能变化。我们升到 16 后有一条 JOIN 查询的执行计划从 Hash Join 变成了 Merge Join,性能反而好了。但也有团队遇到过回退的情况。

三种升级方案对比

方案 停机时间 复杂度 适用场景
蓝绿部署 ~1 分钟 大多数场景推荐
原地升级 10-30 分钟 可以接受短停机
Clone + DMS 接近零 超大库、零停机要求

方案一:蓝绿部署(推荐)

这是亚马逊云科技为 Aurora 内置的能力,不需要自己搞复制。原理是:

  1. 系统在后台创建一个新版本集群(绿环境)
  2. 绿环境从蓝环境持续复制数据
  3. 你测试验证绿环境没问题
  4. 执行切换,DNS 端点自动指向绿环境
  5. 切换过程约 1 分钟

操作步骤

# 第一步:创建蓝绿部署
aws rds create-blue-green-deployment \
  --blue-green-deployment-name "pg14-to-pg16" \
  --source "arn:aws:rds:us-east-1:123456789012:cluster:my-aurora-cluster" \
  --target-engine-version "16.4" \
  --target-db-parameter-group-name "aurora-pg16-params" \
  --target-db-cluster-parameter-group-name "aurora-pg16-cluster-params"

等绿环境创建好(通常 10-30 分钟,取决于数据量):

# 查看状态
aws rds describe-blue-green-deployments \
  --blue-green-deployment-identifier "bg-xxxxx" \
  --query 'BlueGreenDeployments[0].Status'

在绿环境上跑验证:

# 连接到绿环境的端点
psql -h green-cluster.xxx.rds.amazonaws.com -U postgres -d mydb

# 跑一遍关键业务 SQL
# 对比 pg_stat_statements 的执行计划
# 检查应用连接池是否正常

确认没问题后执行切换:

# 切换!约 1 分钟停机
aws rds switchover-blue-green-deployment \
  --blue-green-deployment-identifier "bg-xxxxx" \
  --switchover-timeout 300

蓝绿部署的注意事项

  1. 参数组要提前建好:PG 16 的参数组跟 14 不一样,有些参数改名或移除了
  2. Extension 版本:升级后某些 Extension 需要手动 ALTER EXTENSION ... UPDATE
  3. 连接池:切换后应用的连接池需要重建。如果用 PgBouncer,它会自动重连
  4. 切换窗口:选业务低峰期,虽然只有约 1 分钟,但这 1 分钟内所有写操作会失败

方案二:原地升级

直接在现有集群上升级,适用可以接受 10-30 分钟停机的场景。

aws rds modify-db-cluster \
  --db-cluster-identifier my-aurora-cluster \
  --engine-version "16.4" \
  --db-cluster-parameter-group-name "aurora-pg16-cluster-params" \
  --apply-immediately

优点:操作简单,一条命令。
缺点:不能回滚。升级后发现问题只能恢复快照。

一定要在升级前打快照:

aws rds create-db-cluster-snapshot \
  --db-cluster-identifier my-aurora-cluster \
  --db-cluster-snapshot-identifier "pre-pg16-upgrade-snapshot"

方案三:Clone + DMS(大库方案)

对于 TB 级别的库,或者需要零停机的场景:

  1. Clone 现有集群
  2. 在 Clone 上做原地升级
  3. 用 DMS 做持续复制
  4. 切流量到新集群

这个方案复杂度高,要处理 DMS 的 CDC 配置、Schema 差异、序列值同步等问题。除非你有强零停机需求,否则蓝绿部署就够了。

Extension 升级——最容易被忽略的坑

大版本升级后,Extension 的版本可能不匹配。升级完第一件事:

-- 检查所有 Extension
SELECT extname, extversion FROM pg_extension;

-- 更新到新版本
ALTER EXTENSION pg_stat_statements UPDATE;
ALTER EXTENSION postgis UPDATE;
ALTER EXTENSION pg_trgm UPDATE;

我遇到过一次升级后 pg_stat_statements 没更新,导致它的视图结构是旧的,查询报错。ALTER EXTENSION ... UPDATE 就好了。

升级前检查 Extension 兼容性

-- 查看目标版本支持哪些 Extension 版本
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE installed_version IS NOT NULL;

如果某个 Extension 在新版本不可用(比如已废弃),需要在升级前做好替代方案。

升级后验证 Checklist

#!/bin/bash
# post_upgrade_check.sh

echo "=== 1. 版本确认 ==="
psql -c "SELECT version();"

echo "=== 2. Extension 状态 ==="
psql -c "SELECT extname, extversion FROM pg_extension;"

echo "=== 3. Top SQL 对比 ==="
psql -c "SELECT substring(query,1,60), calls, round(mean_exec_time::numeric,2) as avg_ms
         FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;"

echo "=== 4. 连接数 ==="
psql -c "SELECT count(*) FROM pg_stat_activity WHERE state = 'active';"

echo "=== 5. 复制状态(如有只读副本)==="
psql -c "SELECT * FROM aurora_replica_status();"

常见问题排查

升级后查询变慢

大版本升级后优化器统计信息可能不准确,先跑一遍 ANALYZE:

-- 全库更新统计信息
ANALYZE VERBOSE;

-- 或者针对关键表
ANALYZE orders;
ANALYZE customers;

如果 ANALYZE 后还是慢,对比新旧执行计划。PG 16 的优化器在某些场景下会选择不同的 Join 策略,可以通过 SET enable_hashjoin = off 临时验证是不是 Join 类型的问题。

升级后报「function does not exist」

通常是 Extension 没更新。ALTER EXTENSION xxx UPDATE; 解决。如果某个自定义函数依赖了旧版 Extension 的内部函数,需要重新创建。

蓝绿切换后应用报连接错误

切换会改变底层 IP,连接池里的旧连接全部失效。确保应用有重试逻辑,或者在切换前把连接池的 idle 超时调短。

我的升级经验总结

  1. 先建性能基线——不建基线就升级,等于蒙着眼过马路
  2. 蓝绿部署是首选——1 分钟切换,可回滚到蓝环境
  3. 参数组提前建——别等创建绿环境的时候才发现参数不对
  4. Extension 升完记得 UPDATE——这是最常见的遗漏
  5. 选低峰期操作——虽然蓝绿只停 1 分钟,但这 1 分钟里写请求会报错
  6. 升级不是终点——升完之后持续观察 1-2 周的 pg_stat_statements

Aurora PG 14 的 EOL 倒计时已经开始。与其被动等强制升级,不如现在就找个非生产环境练一遍。蓝绿部署的体验确实很丝滑,试过一次就有信心了。


参考资料:

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐