主从切换是最稳妥的不停机升级路径,前提是已有主从复制架构且延迟可控;必须启用row格式与gtid,停sql线程后再升级从库,通过master_pos_wait校验位点,配合proxysql动态路由实现无感切换。

主从切换是最稳妥的不停机升级路径
生产环境 MySQL 不停机升级,核心不是“怎么升”,而是“怎么切”。主从切换是目前最成熟、风险最低的方案,前提是已有主从复制架构且延迟可控。
- 必须确保
binlog_format = ROW和gtid_mode = ON,否则切换后可能出现数据不一致或无法回切 - 升级前先停掉待升级从库的
SQL_THREAD(STOP SLAVE SQL_THREAD),避免升级过程中写入中断导致 relay log 断链 - 新版本启动后,用
SELECT MASTER_POS_WAIT(...)精确校验同步位点,比只看Seconds_Behind_Master = 0更可靠 - 切换瞬间需配合应用层重连机制——VIP漂移、DNS TTL调低至5秒、或 ProxySQL 的
mysql_query_rules动态停用写规则
ProxySQL 动态路由能控制读流量灰度迁移
ProxySQL 不是升级工具,但它是让升级过程“无感”的关键调度层。它把“升级”变成一组可观察、可回退的路由变更。
- 严禁直接
UPDATE mysql_servers SET hostgroup_id = 10手动切主——健康检查会在5秒内覆盖该值,导致写请求发到只读节点,报错ERROR 1290 (HY000): The MySQL server is running with the --read-only option - 正确做法是:先将节点加入
offline_hostgroup,再执行LOAD MYSQL SERVERS TO RUNTIME;恢复时用weight控制读流量比例,等max_replication_lag检查通过后再提升权重 - 必须开启
transaction_persistent = 1,否则事务中跨节点的读会落到不同从库,破坏一致性
MySQL Shell AdminAPI 适合 InnoDB Cluster 场景
如果你用的是官方 InnoDB Cluster(MGR),mysqlsh 的 AdminAPI 是唯一推荐的自动化滚动升级入口,但它对配置和状态极其敏感。
- 升级前必须运行
cluster.checkInstanceConfiguration(),它会检查enforce_gtid_consistency=ON、binlog_checksum=NONE(8.0.26+ 要求为CRC32)等硬性条件 -
cluster.upgradeMetadata()只更新集群元数据版本,不触碰数据;真正的二进制替换必须手动停服、换文件、再以mysqld --upgrade=MINIMAL启动 - 升级中任意节点失败,AdminAPI 会自动暂停并标记状态为
ERROR,此时不能强行继续——要先cluster.rejoinInstance()或人工修复
跨大版本升级必须提前清理三类隐形兼容问题
5.7 → 8.0 升级失败,90% 不是因为启动不起来,而是因为某些表/语句/配置在旧版本里“能跑”,到了新版本直接卡死或静默出错。
- 查
MyISAM表:SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM',8.0 已移除 MyISAM 系统表支持,必须ALTER TABLE ... ENGINE=InnoDB - 查保留字冲突:
util.checkForServerUpgrade()会报Column name 'rank' is a reserved keyword,这类字段名在 8.0 中必须加反引号或重命名 - 删掉
my.cnf里的old_passwords=1、explicit_defaults_for_timestamp=OFF、sql_mode=NO_AUTO_CREATE_USER——这些参数会让mysqld启动直接失败,日志里只显示 “Starting MySQL…” 然后卡住
caching_sha2_password 插件与老客户端的兼容性。哪怕所有 SQL 和配置都改完了,只要应用还在用 mysql-connector-java 或 <code>PyMySQL ,连接就会报 <code>Authentication plugin 'caching_sha2_password' cannot be loaded,而这个错误不会出现在 mysqld 日志里,只在应用侧抛出。











