Aurora PG 14 快 EOL 了,我用蓝绿部署 52 秒切到了 PG 16,聊聊全过程

Aurora PG 14 快 EOL 了,我用蓝绿部署 52 秒切到了 PG 16,聊聊全过程

前两天跟同事吃饭,聊到数据库升级这个话题。他说他们还在 PG 13 上跑,问我升级到底有多麻烦。我说看你用什么方案------如果是亚马逊云科技的 Aurora,蓝绿部署这条路走一遍,你会发现比想象中简单太多。

但"简单"不等于"不需要准备"。我上周刚把生产环境三个集群从 14.9 升到 16.4,停机 52 秒完事。代价是前面花了大概一周时间做准备工作。这篇把整个过程拆开来讲,你看完可以直接照着做。

为什么不能再拖了

PG 14 的社区 EOL 是 2026 年 11 月。你不自己升,亚马逊云科技会在 EOL 后强制升级。强制升级的意思是------在维护窗口自动执行,时间不是你选的,方式不是你定的。

听起来挺省事?但如果恰好赶上你的业务高峰期呢?如果升级后出了优化器回退你都不知道什么时候开始的呢?自己控制节奏总比被动好。

先说结论:我选了蓝绿部署

三种方案我都评估过:

方案 我的体验
蓝绿部署 停机 52 秒,可回滚,推荐
原地升级 简单粗暴但不能回滚,心里没底
Clone + DMS TB 级才需要,我们 80GB 用不上

蓝绿部署的本质:系统在后台创建一个 PG 16 的新集群(绿环境),从旧集群持续同步数据。你验证没问题后执行切换,DNS 端点自动切过去。整个过程中旧集群完全不受影响,业务熇常跑。

原地升级虽然操作简单,但它是单程票------一旦开始就回不了头。出了问题只能恢复快照,那个恢复时间就不是分钟级别了。

升级前的保命操作:性能基线

折腾了三天才学到的教训------不建基线就升级,等于蒙着眼过马路。

开启 pg_stat_statements

sql 复制代码
-- 检查是否已加载
SHOW shared_preload_libraries;

-- 如果没有,需要在 AWS 控制台的参数组中添加(注意:要重启实例)
-- 创建扩展
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- 导出 Top 20 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;

导出 CSV 存档

bash 复制代码
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

这个 CSV 就是你的安全网。升级前后的对比全靠它。建议连同集群当前负载状态一起记录下来。

保存执行计划

挑 5-10 条核心业务 SQL,跑 EXPLAIN (ANALYZE, BUFFERS) 保存。这些是升级后对比优化器行为的关键材料。

sql 复制代码
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';

我们升到 16 后有条 SQL 的执行计划从 Hash Join 变成了 Merge Join。因为有基线,5 分钟就确认了这是正向优化而不是回退。要是没有基线数据,这种变化可能一周后才被发现,那时候再排查就头疼了。

蓝绿部署实操

第一步:建参数组(别跳过!)

这步我差点翻车。PG 16 跟 PG 14 的参数组不完全兼容,有些参数改了名字或者被直接移除了。我第一次创建蓝绿部署的时候才发现没有 PG 16 的参数组,临时建的配置不对,又重来了一遍。白白浪费了两个小时。

血泪教训:参数组一定要提前建好,并在测试环境验证通过。

第二步:创建蓝绿部署

bash 复制代码
aws rds create-blue-green-deployment \
  --blue-green-deployment-name "pg14-to-pg16" \
  --source "arn:aws:rds:us-east-1:123456789012:cluster:my-cluster" \
  --target-engine-version "16.4" \
  --target-db-parameter-group-name "aurora-pg16-params" \
  --target-db-cluster-parameter-group-name "aurora-pg16-cluster-params"

等绿环境就绪,我们 80GB 的库花了 18 分钟:

bash 复制代码
aws rds describe-blue-green-deployments \
  --blue-green-deployment-identifier "bg-xxxxx" \
  --query 'BlueGreenDeployments[0].Status'

第三步:在绿环境上跑验证

连到绿环境端点,把之前保存的核心 SQL 一条条跑一遍。重点看执行计划有没有变化、性能有没有回退。

sql 复制代码
-- 先 ANALYZE 更新统计信息
ANALYZE VERBOSE;

-- 逐一对比核心 SQL 的执行计划
EXPLAIN (ANALYZE, BUFFERS)
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';

第四步:切!

确认没问题后,选了周三凌晨 3 点(业务低谷期)执行切换:

bash 复制代码
aws rds switchover-blue-green-deployment \
  --blue-green-deployment-identifier "bg-xxxxx" \
  --switchover-timeout 300

52 秒完事。DNS 端点不变,应用不用改连接字符串。这段时间内写请求会失败,所以一定要选低峰期。

踩坑实录

坑 1:Extension 没更新

切完发现 pg_stat_statements 查询报错------Extension 版本还是旧的。这个坑出现频率特别高,文档里又不太显眼:

sql 复制代码
ALTER EXTENSION pg_stat_statements UPDATE;
ALTER EXTENSION postgis UPDATE;
ALTER EXTENSION pg_trgm UPDATE;

记住:大版本升级后,Extension 不会自动更新,需要手动执行。

坑 2:连接池短暂断开

切换改了底层 IP,PgBouncer 里的旧连接全部失效。好在 PgBouncer 有自动重连机制,大概 30 秒后恢复正常。但这 30 秒里有少量请求报了连接错误。

改进方案:切换前把连接池的 idle timeout 调到 5 秒,让旧连接提前释放,减少切换时的错误量。

坑 3:个别查询变慢

大部分查询性能持平甚至更好,但有一条聚合查询慢了 20%。对比执行计划发现 PG 16 选了不同的 Join 策略。用 SET enable_hashjoin = off 临时验证确认后,通过 pg_hint_plan 固定了执行计划。

升级后验证清单

bash 复制代码
#!/bin/bash
echo "=== 版本确认 ==="
psql -c "SELECT version();"

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

echo "=== ANALYZE ==="
psql -c "ANALYZE VERBOSE;"

echo "=== 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 "=== 连接数 ==="
psql -c "SELECT count(*) FROM pg_stat_activity WHERE state = 'active';"

我的升级清单总结

  1. 建基线 --- 没有基线数据就别动手
  2. 建参数组 --- 提前建、提前在测试环境验证
  3. 蓝绿部署 --- 创建绿环境 → 验证 → 低峰期切换
  4. Extension UPDATE --- 切完第一件事
  5. ANALYZE --- 切完第二件事
  6. 持续观察 --- 1-2 周内密切关注 pg_stat_statements 数据

原地升级和 Clone + DMS 也说两句

原地升级就一条命令:

bash 复制代码
aws rds modify-db-cluster \
  --db-cluster-identifier my-cluster \
  --engine-version "16.4" --apply-immediately

优点是简单。缺点是停机 10-30 分钟,而且不能回滚。一定要在升级前手动打个快照保底:

bash 复制代码
aws rds create-db-cluster-snapshot \
  --db-cluster-identifier my-cluster \
  --db-cluster-snapshot-identifier "pre-upgrade-snapshot"

Clone + DMS 就不展开了------Clone 现有集群、在 Clone 上原地升级、用 DMS 做 CDC 持续复制、最后切流量。适合 TB 级大库,但 CDC 配置、序列同步这些细节很折腾。80GB 以下的库,蓝绿部署足够了。

PG 14 的倒计时已经开始了。找个非生产环境先练一遍------我第一次在 staging 上做的时候花了 3 小时,第二次生产环境全程 40 分钟就搞定了。熟练度真的很重要。


参考: Aurora PostgreSQL 大版本升级指南 - 亚马逊云科技

相关推荐
zhojiew21 小时前
在AWS中国区实现EKS跨VPC跨区域实现节点加入集群的实践
云计算·aws
认真的薛薛1 天前
Terraform: AWS VPC+可SSH登录EC2
ssh·aws·terraform
认真的薛薛1 天前
Terraform:AWS VPC
云原生·aws·terraform
yyuuuzz1 天前
境外云服务器使用常见问题梳理
运维·服务器·网络·aws
zhojiew3 天前
使用Redis Stream订阅HUATUO发布SSE内核可观测性事件并进行AI分析的数据管道实践
运维·hbase·aws
yyuuuzz5 天前
谷歌云使用的几个常见注意事项
运维·服务器·网络·安全·web安全·云计算·aws
zhojiew5 天前
在AWS中国区的EMR集群中实现基于向量语义搜索的HBase运维诊断系统
运维·hbase·aws
yyuuuzz5 天前
独立开发者线上服务运维的几点实践经验
运维·服务器·网络·云计算·aws
zhojiew5 天前
使用DBT(data build tool)集成AWS Athena完成数据处理的实践
云计算·aws
yyuuuzz7 天前
aws的核心概念与常见使用场景
运维·服务器·网络·云计算·aws