Aurora 蓝绿部署 Binlog 复制回滚指南

回滚方案对比

当蓝绿部署切换到绿环境后发现问题需要回滚时,有以下几种方案:

方案对比表

方案 回滚时间 数据丢失 复杂度 成本
Binlog 复制 10分钟-2小时 ✅ 无 无额外成本
快照恢复 30分钟-4小时 ⚠️ 快照后的数据 快照存储费用
DMS 同步 20分钟-3小时 ✅ 无 DMS 实例费用
mysqldump 导出导入 数小时-数天 ⚠️ 导出期间的数据

方案选择说明

本文档将聚焦Binlog 复制方案,考虑到以下原因:

  • 速度最快(只同步增量数据,10分钟-2小时,取决于数据量)
  • 零数据丢失(事务级精确同步)
  • 零额外成本(使用 Aurora 原生功能)
  • 可控性强(可随时查看进度、暂停、恢复)

其他方案适合场景:

  • 快照恢复:binlog 已过期时的选择(会丢失快照后的数据)
  • DMS 同步:需要数据转换或过滤时使用(有额外成本和配置复杂度)
  • mysqldump:适合小数据库测试环境(< 10GB)

Binlog 复制原理

Binlog 复制是 MySQL 的标准主从复制功能,Aurora 通过存储过程封装了配置接口。

 

Binlog 复制过程:
  1. 旧蓝环境作为"从库"
  2. 从绿环境读取 binlog(从切换点开始)
  3. 在旧蓝环境回放 binlog 中的变更
  4. 追平后停止复制
  5. 切换应用流量回旧蓝环境

参考: AWS Aurora MySQL 复制存储过程官方文档


前置条件说明

在执行回滚前,必须验证以下条件是否满足:

条件 1: Binlog 可用性验证(最关键)

验证方法:

-- 1. 连接到绿环境(当前生产环境),检查 binlog 保留设置
SELECT @@binlog_retention_hours;

-- 2. 查看可用的 binlog 文件列表
SHOW BINARY LOGS;

判断标准:

binlog 可用 = 切换时间 < (当前时间 - binlog 保留时长)

示例:
- Binlog 保留:72 小时
- 切换时间:2025-12-15 10:00
- 当前时间:2025-12-16 13:00
- 时间差:27 小时
- 结果:✅ 可用(27 < 72)

⚠️如果 binlog 不可用,请跳到"故障排查 - binlog 已过期"章节

条件 2: 复制用户验证

-- 连接到绿环境(当前生产环境)
SELECT user, host FROM mysql.user WHERE user = 'repl_user';

-- 如果不存在,创建复制用户:
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'StrongPassword123!';
-- 注意:权限顺序应该是 REPLICATION CLIENT, REPLICATION SLAVE
GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;

-- 验证权限
SHOW GRANTS FOR 'repl_user'@'%';

权限说明:

  • REPLICATION CLIENT:允许查询主库状态(SHOW MASTER STATUS)
  • REPLICATION SLAVE:允许作为从库连接并读取 binlog

条件 3: 旧蓝环境可访问性验证

# 测试连接旧蓝环境
mysql -h old-blue-cluster.cluster-xxx.us-east-1.rds.amazonaws.com \
  -u admin -p -e "SELECT VERSION();"

# 确认旧蓝环境没有写入
mysql -h old-blue-cluster... -e "SHOW PROCESSLIST;" | grep -i "insert\|update\|delete"

执行回滚步骤

步骤 1: 获取绿环境当前 binlog 位置

#!/bin/bash
# get-green-binlog-position.sh

GREEN_ENDPOINT="green-cluster.cluster-xxx.us-east-1.rds.amazonaws.com"
MYSQL_USER="admin"
MYSQL_PASS="your-password"

echo "=== 获取绿环境 binlog 位置 ==="
mysql -h $GREEN_ENDPOINT -u $MYSQL_USER -p$MYSQL_PASS -e "SHOW MASTER STATUS\G"

# 输出示例:
# File: mysql-bin-changelog.000123
# Position: 154

步骤 2: 在蓝环境配置复制

⚠️ 重要前置条件:必须启用 autocommit

-- 连接到蓝环境(原环境)
-- 1. 首先确认 autocommit 已启用(必须)
SHOW VARIABLES LIKE 'autocommit';
-- 如果显示 OFF,必须启用它
SET autocommit = 1;

-- 2. 根据 Aurora MySQL 版本选择对应的存储过程

-- ============================================
-- Aurora MySQL 3.x 版本(推荐)
-- ============================================
CALL mysql.rds_set_external_source(
  'green-cluster.cluster-xxx.us-east-1.rds.amazonaws.com',  -- 绿环境 endpoint
  3306,                                                       -- 端口
  'repl_user',                                               -- 复制用户
  'StrongPassword123!',                                      -- 密码
  'mysql-bin-changelog.000123',                              -- 切换时的 binlog 文件
  154,                                                       -- 切换时的 binlog 位置
  0                                                          -- 0=不加密, 1=加密
);

-- ============================================
-- Aurora MySQL 2.x 版本
-- ============================================
CALL mysql.rds_set_external_master(
  'green-cluster.cluster-xxx.us-east-1.rds.amazonaws.com',
  3306,
  'repl_user',
  'StrongPassword123!',
  'mysql-bin-changelog.000123',
  154,
  0
);

-- ============================================
-- 如果启用了 GTID(推荐)
-- ============================================
-- Aurora MySQL 3.x
CALL mysql.rds_set_external_source_with_auto_position(
  'green-cluster.cluster-xxx.us-east-1.rds.amazonaws.com',
  3306,
  'repl_user',
  'StrongPassword123!',
  0
);

-- Aurora MySQL 2.x
CALL mysql.rds_set_external_master_with_auto_position(
  'green-cluster.cluster-xxx.us-east-1.rds.amazonaws.com',
  3306,
  'repl_user',
  'StrongPassword123!',
  0
);

步骤 3: 启动复制

-- 启动复制
CALL mysql.rds_start_replication;

-- 立即检查状态
SHOW REPLICA STATUS\G

步骤 4: 监控复制进度

-- 持续监控(每 10 秒执行一次)
SHOW REPLICA STATUS\G

-- 关键指标:
-- Replica_IO_Running: Yes     (必须是 Yes)
-- Replica_SQL_Running: Yes    (必须是 Yes)
-- Seconds_Behind_Master: 0    (应该逐渐减少到 0)
-- Last_IO_Errno: 0            (必须是 0)
-- Last_SQL_Errno: 0           (必须是 0)

CloudWatch 监控(推荐):

Aurora 提供了 AuroraBinlogReplicaLag 指标来监控 binlog 复制延迟:

# 1. 查看 AuroraBinlogReplicaLag 指标
aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name AuroraBinlogReplicaLag \
  --dimensions Name=DBInstanceIdentifier,Value=old-blue-instance-1 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 60 \
  --statistics Average

# 2. 创建告警(当复制延迟超过 60 秒时告警)
aws cloudwatch put-metric-alarm \
  --alarm-name aurora-binlog-replication-lag \
  --alarm-description "Alert when binlog replication lag > 60 seconds" \
  --metric-name AuroraBinlogReplicaLag \
  --namespace AWS/RDS \
  --statistic Average \
  --period 60 \
  --evaluation-periods 2 \
  --threshold 60 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=DBInstanceIdentifier,Value=old-blue-instance-1

关键 CloudWatch 指标说明:

指标名称 说明 单位
AuroraBinlogReplicaLag Binlog 复制延迟(包括外部复制) 毫秒
AuroraReplicaLag Aurora Replica 之间的复制延迟 毫秒
DatabaseConnections 当前数据库连接数 计数
CPUUtilization CPU 使用率 百分比

监控脚本参考:

#!/bin/bash
# monitor-replication.sh - 监控复制进度

BLUE_ENDPOINT="old-blue-cluster.cluster-xxx.us-east-1.rds.amazonaws.com"
MYSQL_USER="admin"
MYSQL_PASS="your-password"

echo "=== 开始监控复制进度 ==="
while true; do
  clear
  echo "监控时间: $(date)"
  echo "================================"
  
  mysql -h $BLUE_ENDPOINT -u $MYSQL_USER -p$MYSQL_PASS -e "SHOW REPLICA STATUS\G" | \
    grep -E "Replica_IO_Running|Replica_SQL_Running|Seconds_Behind_Master|Last_IO_Errno|Last_SQL_Errno"
  
  # 检查是否已追平
  SECONDS_BEHIND=$(mysql -h $BLUE_ENDPOINT -u $MYSQL_USER -p$MYSQL_PASS -sN -e "
    SHOW REPLICA STATUS\G" | grep "Seconds_Behind_Master:" | awk '{print $2}')
  
  if [ "$SECONDS_BEHIND" == "0" ]; then
    echo ""
    echo "✅ 复制已追平!可以停止复制。"
    break
  fi
  
  echo ""
  echo "当前延迟: $SECONDS_BEHIND 秒"
  sleep 10
done

步骤 5: 停止复制并清理

-- 确认已追平后,停止复制
CALL mysql.rds_stop_replication;

-- 再次检查状态
SHOW REPLICA STATUS\G

-- 清理复制配置
-- Aurora MySQL 3.x
CALL mysql.rds_reset_external_source;

-- Aurora MySQL 2.x
CALL mysql.rds_reset_external_master;

-- 验证清理成功
SHOW REPLICA STATUS\G
-- 应该返回空结果或显示 "Empty set"

步骤 6: 切换流量回蓝环境

#!/bin/bash
# switch-back-to-blue.sh

# 1. 停止应用写入绿环境
echo "⚠️  请确保应用已停止写入绿环境"
read -p "按 Enter 继续..."

# 2. 更新应用配置指向蓝环境
echo "更新应用数据库连接字符串..."
# 根据你的部署方式更新(如更新 SSM 参数、环境变量等)

# 3. 重启应用或刷新配置
echo "重启应用服务..."
# kubectl rollout restart deployment/your-app
# 或其他重启命令

# 4. 验证连接
echo "验证应用连接到蓝环境..."

时间估算

阶段 时间 说明
准备配置 5 分钟 获取 binlog 位置、配置复制
启动复制 1 分钟 执行存储过程
数据同步 10 分钟 - 2 小时 取决于数据量和写入速率
停止清理 2 分钟 停止复制、清理配置
应用切换 5-10 分钟 更新配置、重启服务
总计 20 分钟 - 2.5 小时 大部分时间在等待数据同步

故障排查

问题 1: 复制无法启动

-- 检查错误信息
SHOW REPLICA STATUS\G

-- 常见错误:
-- Last_IO_Errno: 1236 - binlog 位置不存在
-- 解决方案:使用下一个 binlog 文件
CALL mysql.rds_next_source_log(123);  -- 123 是当前 binlog 索引
CALL mysql.rds_start_replication;

-- Last_IO_Errno: 1045 - 认证失败
-- 解决方案:检查复制用户密码和权限

问题 2: 复制延迟过大

-- 检查绿环境负载
SHOW PROCESSLIST;

-- 检查蓝环境性能
SHOW ENGINE INNODB STATUS\G

-- 临时增加并行复制线程(Aurora MySQL 3.x)
SET GLOBAL replica_parallel_workers = 4;

问题 3: binlog 已过期

# 如果 binlog 已被清理,只能使用快照恢复
# 1. 停止绿环境写入
# 2. 创建绿环境快照
aws rds create-db-cluster-snapshot \
  --db-cluster-identifier green-cluster \
  --db-cluster-snapshot-identifier green-rollback-snapshot

# 3. 从快照恢复到蓝环境(需要较长时间)
Previous Post
No Comment
Add Comment
comment url