Aurora PostgreSQL 蓝绿部署升级深度解析:从性能基线建立到切换验证的完整工程实践

一、问题的起点

去年底我接手了一个棘手的任务:把团队三个 Aurora PostgreSQL 14.9 集群升级到 16.4。说实话接到这个活儿的时候心里是拒绝的——数据库是有状态服务,出了问题不是重启一下能搞定的事。

但没得选。PG 14 的社区 EOL 是 2026 年 11 月,亚马逊云科技的支持窗口也在逐步收紧。你不动手,到时候系统会帮你强制升级,时间点和方式你说了不算。与其被动挨打,不如主动出击。

这篇完整记录从基线建立到切换验证的全过程,包括踩过的坑和事后总结。希望能帮到同样面临这个问题的同学。

二、性能基线——升级前的保命操作

这步太多人跳过了,觉得"先升了再说"。但你想想,升完之后老板问"感觉比以前慢了",你怎么回答?"没有啊我觉得挺快的"?不行,得拿数据说话。没有升级前的性能基线,升完后的任何性能讨论都是空对空。

2.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.2 导出基线数据

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 文件就是你升级后的对比基准。建议同时记录导出时间和集群的负载情况,这样对比才有意义。

2.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,性能反而好了 15%。但也见过其他团队遇到回退的情况,有基线才能在 5 分钟内定位问题。

三、方案选型:蓝绿部署为什么是首选

方案 停机时间 可回滚 复杂度 适用场景
蓝绿部署 ~1 分钟 大多数场景
原地升级 10-30 分钟 否(需快照恢复) 可接受停机
Clone + DMS 接近零 TB 级大库

蓝绿部署的核心优势在于可回滚。如果升完发现性能有问题,可以切回蓝环境。原地升级一旦执行就是单程票,出了事只能恢复快照,那个恢复时间可不是分钟级别的了。

Clone + DMS 方案虽然能做到接近零停机,但你得处理 CDC 配置、Schema 差异、序列值同步等一堆问题。除非是 TB 级别的超大库,否则真没必要上这个方案。

四、蓝绿部署完整操作步骤

4.1 提前建好参数组

这步我第一次做的时候差点翻车——创建蓝绿部署的时候才发现没有 PG 16 的参数组。PG 16 有些参数名变了或者直接移除了,不能把 PG 14 的参数组直接复制过来用。

正确做法:导出当前参数组的非默认值 → 在 PG 16 参数组模板上逐一设置 → 在测试环境验证参数有效。

4.2 创建蓝绿部署

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"

绿环境创建耗时取决于数据量,我们 80GB 的库大概花了 18 分钟。这段时间蓝环境完全不受影响,业务照常跑。

4.3 验证绿环境

绿环境就绪后,连上去跑一遍完整验证:

# 连到绿环境的端点
psql -h green-cluster.xxx.rds.amazonaws.com -U postgres -d mydb
-- 更新统计信息
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';

4.4 业务低峰期执行切换

aws rds switchover-blue-green-deployment \
  --blue-green-deployment-identifier "bg-xxxxx" \
  --switchover-timeout 300

我们实测切换耗时 52 秒。DNS 端点自动指向新集群,应用连接字符串不需要改动。

五、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 就好了,但如果你不知道这个套路,debug 半天也找不到原因。

升级前记得检查兼容性:

SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE installed_version IS NOT NULL;

如果某个 Extension 在 PG 16 已废弃,必须在升级前找替代方案。

六、升级后验证脚本

我写了个脚本,切换完立刻跑:

#!/bin/bash
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 VERBOSE 更新统计信息。如果还慢,对比新旧执行计划看是不是 Join 策略变了。可以用 SET enable_hashjoin = off 临时验证。

function does not exist 报错:十有八九是 Extension 没更新。ALTER EXTENSION xxx UPDATE; 解决。如果是自定义函数依赖了旧版 Extension 的内部函数,就需要重建函数了。

连接池断开:蓝绿切换改变了底层 IP,连接池里的旧连接全部失效。PgBouncer 有自动重连,但那 30 秒左右会有少量请求报错。建议切换前把 idle timeout 调短,减少切换时的失效连接数。

八、经验总结

  1. 性能基线是升级的安全网,没有它等于蒙着眼过马路
  2. 蓝绿部署是 500GB 以下库的首选,停机约 1 分钟且可回滚
  3. 参数组提前建好测好,别等建绿环境时才发现不对
  4. Extension 升完一定要 UPDATE,这是踩坑频率排名靠前的问题
  5. 低峰期操作,虽然只停 1 分钟但这段时间写请求会报错
  6. 在非生产环境完整练一遍,记录实际耗时,心里才有底

Aurora PG 14 的 EOL 倒计时已经开始了。与其等着被强制升级,不如现在就动手。蓝绿部署的体验确实丝滑,练过一次就有信心了。


参考资料:

posted @ 2026-05-04 11:41  亚马逊云开发者  阅读(3)  评论(0)    收藏  举报