1. 主备架构升级前的关键考量
在Docker环境中升级MySQL主备集群时,最容易被忽视的是数据一致性和服务连续性保障。我曾在生产环境经历过一次失败的升级,导致业务中断6小时。那次教训让我总结出三个核心检查点:
首先确认主备同步状态,执行SHOW SLAVE STATUS\G查看Seconds_Behind_Master是否为0,同时检查Slave_IO_Running和Slave_SQL_Running状态。我曾遇到备库看似正常但实际存在延迟的情况,这种状态下升级会导致数据丢失。
其次检查容器数据持久化配置。通过docker inspect mysql-master确认Volumes映射是否正确。常见错误是误用临时卷(--tmpfs),升级后数据全部丢失。建议使用命名卷或主机目录:
docker volume create mysql_data docker run -v mysql_data:/var/lib/mysql ...最后评估版本兼容性。MySQL 8.0到8.4的升级看似小版本迭代,但某些特性变更会影响复制:
- 默认认证插件从caching_sha2_password变为sha256_password
- 组复制(grou replication)的通信协议版本变化
- 系统表结构变更可能导致备库SQL线程中断
2. 分阶段升级实施策略
2.1 备库先行升级方案
采用"先备后主"的滚动升级策略能最大限度降低风险。具体操作流程:
- 停止备库容器并备份数据目录:
docker stop mysql-slave cp -rp /var/lib/docker/volumes/mysql_slave_data/_data /backup/mysql_slave_$(date +%F)- 修改docker-compose.yml或启动命令,将镜像版本改为8.4:
services: mysql-slave: image: mysql:8.4 # 其他配置保持不变- 启动备库并检查错误日志:
docker start mysql-slave docker logs --tail 50 mysql-slave | grep -i error- 验证复制状态的关键命令:
SELECT @@GLOBAL.slave_parallel_workers; SHOW REPLICA STATUS\G -- 8.4中SHOW SLAVE STATUS的别名2.2 主库升级的特殊处理
主库升级需要安排维护窗口,建议按以下步骤操作:
- 设置主库为只读并刷新日志:
SET GLOBAL read_only = ON; FLUSH BINARY LOGS;- 使用mysqldump创建逻辑备份(物理备份可能不兼容):
docker exec mysql-master \ mysqldump -uroot -p --all-databases --routines --master-data=2 > /backup/full_dump.sql- 修改GTID执行记录(避免主备切换后重复执行):
-- 在主库执行 SELECT @@GLOBAL.gtid_executed; -- 记录结果并在新主库执行 SET @@GLOBAL.gtid_purged='<记录的值>';3. 版本差异与配置调整
3.1 参数变更适配
8.4版本中这些参数需要特别注意:
binlog_transaction_dependency_tracking默认从COMMIT_ORDER改为WRITESETinnodb_dedicated_server现在支持自动配置redo log大小group_replication_consistency新增BEFORE_ON_PRIMARY_FAILOVER选项
建议在my.cnf中添加:
[mysqld] # 保持与8.0相同的行为 binlog_transaction_dependency_tracking=COMMIT_ORDER # 启用新特性 innodb_redo_log_capacity=1G # 替代旧的innodb_log_file_size3.2 认证插件问题处理
升级后常见的连接错误:
Authentication plugin 'caching_sha2_password' cannot be loaded解决方案有两种:
- 修改用户认证方式(推荐):
ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';- 或者在启动容器时指定旧认证插件:
docker run -e default_authentication_plugin=mysql_native_password ...4. 升级后的验证与回滚方案
4.1 功能验证清单
执行以下测试确保升级成功:
- 主备同步延迟测试:
-- 主库创建测试表 CREATE TABLE sync_test(id INT PRIMARY KEY AUTO_INCREMENT); -- 备库立即查询 SELECT * FROM sync_test; # 应能立即看到数据- 性能基准对比:
# 升级前记录QPS mysqlslap --concurrency=100 --iterations=10 --query="SELECT * FROM large_table" # 升级后重复测试- 应用连接测试:
# Python测试脚本示例 import pymysql conn = pymysql.connect(host='mysql-master', user='app_user', password='password', database='app_db') cursor = conn.cursor() cursor.execute("SELECT 1") assert cursor.fetchone()[0] == 14.2 快速回滚机制
准备回滚容器镜像的方法:
# 保留旧版本镜像 docker tag mysql:8.0 mysql:8.0-backup # 回滚命令示例 docker stop mysql-master docker run --rm -v mysql_data:/var/lib/mysql mysql:8.0-backup \ --upgrade=FORCE # 强制降级模式关键注意事项:
- 回滚前必须停止所有应用连接
- 如果使用了新版本特有功能(如GIS函数),需要先清理相关数据
- 回滚后执行
mysql_upgrade --force修复系统表
5. 高可用环境下的特殊处理
对于使用Keepalived或HAProxy的场景:
- 虚拟IP切换策略调整:
# Keepalived配置示例 vrrp_script chk_mysql { script "/usr/bin/mysql --connect-timeout=3 -e 'SELECT 1'" interval 2 fall 2 rise 1 }- 连接池配置更新:
- 增加连接验证查询:
testOnBorrow: SELECT 1 - 设置合理的连接超时:
validationInterval: 30000
- 监控指标适配:
- 新增8.4特有的监控项:
performance_schema.events_errors_summary_global_by_error - 调整告警阈值:
innodb_redo_log_flushed_up_to的波动范围
我在实际升级过程中发现,8.4版本对内存分配做了优化,相同负载下内存占用降低约15%,但需要调整监控的基线值。建议升级后观察24小时再更新告警规则。