平滑升级必须走主从滚动路径,不能原地升级主库,否则会因mysql_native_password插件默认禁用、认证协议变更、配置语义调整等问题导致客户端连接失败、复制中断或服务不可用。

直接上结论:平滑升级必须走主从滚动路径,不能停主库、不能全量导出导入、不能原地升级主库——否则必然中断业务或丢失复制状态。
为什么不能原地升级主库
MySQL 8.4 的 caching_sha2_password 已成唯一默认认证插件,mysql_native_password 插件默认不加载。一旦你对主库执行 dnf upgrade mysql-server 或 apt install --only-upgrade mysql-server,服务重启后所有依赖旧插件的客户端(尤其是老版本 JDBC、PHP mysqli、某些监控 exporter)立刻报错 Error 1524 (HY000): Plugin 'mysql_native_password' is not loaded。主库一挂,整个集群写入就断了。
- 原地升级还会触发
mysql_upgrade自动运行(8.4 中已废弃但兼容层仍可能触发),在高负载主库上执行元数据校验可能锁表或拖慢响应 - 配置项如
slave_type_conversions、replica_parallel_type在 8.4 中语义变更,旧配置未清理会导致复制异常 - 8.4 默认禁用
MASTER关键字,只认SOURCE;主库升级后,原有CHANGE MASTER TO语句在从库上会语法报错
滚动升级从库时如何避免复制断裂
核心是让新从库先以 8.4 版本接入现有 8.0 主库,复现全量 + 增量同步,再切换角色。这要求主库保持兼容性输出,且从库能解析旧协议。
- 主库
my.cnf中必须显式启用双认证插件:default_authentication_plugin=caching_sha2_password且mysql_native_password=ON(注意:这是 8.0.29+ 才支持的开关,低于此版本需先小版本升到 8.0.37+) - 新建的 8.4 从库配置里要加
replica_sql_verify_checksum=OFF,否则 8.0 主库生成的 binlog checksum 格式与 8.4 默认不兼容,复制线程启动即报Got fatal error 1236 - 不要用
mysqldump导入后直接CHANGE SOURCE TO—— dump 文件里的SET @@GLOBAL.GTID_PURGED是 8.0 格式,8.4 解析失败;应改用mysqlpump或在 dump 后手动修正 GTID 集合 - 验证复制时,重点查
SHOW REPLICA STATUS\G中的Replica_IO_Running和Replica_SQL_Running是否都为Yes,且Seconds_Behind_Source归零,而非只看Slave_IO_Running
应用连接切换阶段的关键动作
不是简单改 DNS 或 VIP 指向新主库就完事。8.4 对客户端协议、密码协商、字符集处理更严格,很多“看似正常”的连接会在事务提交或长连接保活时突然失败。
- 提前在测试环境用真实流量压测:用
pt-query-digest抓取线上慢查询,重放至 8.4 从库,观察是否出现Truncated incorrect DOUBLE value类隐式转换错误(8.4 严格模式下更常见) - 应用端 JDBC 连接串必须加参数:
&allowPublicKeyRetrieval=true&useSSL=false(若未配 TLS),否则 8.4 的caching_sha2_password握手会卡住 - 切流前,用
SELECT USER(), CURRENT_USER()在新主库上确认账号实际使用的认证插件是caching_sha2_password,而不是靠CREATE USER ... IDENTIFIED WITH mysql_native_password临时绕过——后者在 8.4 中只是兼容写法,下次ALTER USER就会自动转成 sha2 - 务必检查所有定时任务、ETL 工具、备份脚本中硬编码的
mysql命令是否带--defaults-file,其指定的配置文件里有没有残留user=root+ 无密码字段——8.4 默认拒绝空密码登录,即使配置文件里写了也无效
最易被忽略的点:8.4 的 performance_schema 默认采集项更多,如果从库原本没开 performance_schema 或内存限制太紧,复制线程可能因无法写入 instruments 而卡死;上线前得确认 performance_schema=ON 且 performance_schema_max_table_instances 至少设为 10000。


















