大版本升级(如5.7→8.0)业务中断可压缩至分钟级,关键前提是启用gtid和row格式;必须同时设置gtid_mode=on与enforce_gtid_consistency=on,binlog_format=row为官方唯一推荐复制格式,否则易引发主从偏差或数据丢失。

大版本升级(如 5.7 → 8.0)不可能完全“零中断”,但业务中断时间可压缩到分钟级——关键不在“能不能停”,而在于“要不要让应用感知到停”。
主从切换升级必须确保 GTID 和 ROW 格式启用
这是整个流程能回切、能验证、能控制延迟的底层前提。如果当前主从没开 GTID 或 binlog_format 不是 ROW,先别急着升级,否则切换后可能丢数据或无法回滚。
-
gtid_mode=ON且enforce_gtid_consistency=ON必须同时生效,缺一不可 -
binlog_format=ROW是唯一被 MySQL 8.0 官方推荐用于复制的格式;STATEMENT 模式在 8.0 中对某些函数(如NOW()、UUID())行为不一致,极易引发主从数据偏差 - 升级前用
SHOW MASTER STATUS和SHOW SLAVE STATUS\G核对Executed_Gtid_Set是否连续、无缺口 - 若现有复制是基于 file/position 的,必须先切换为 GTID 模式(需重启从库并执行
CHANGE MASTER TO ... GET_MASTER_PUBLIC_KEY=1),再进行后续操作
影子库启动失败的常见原因:直接复用旧 datadir
用 MySQL 8.0 启动一个 5.7 的 datadir,99% 会卡在初始化阶段或报错 Table 'mysql.user' doesn't exist——这不是配置问题,是系统表结构和校验逻辑根本变了。
- 正确做法:用目标版本(如
mysqld8.0.46)执行mysqld --initialize-insecure --datadir=/path/to/shadow_datadir,生成全新空实例 - 数据导入不能只靠
mysqldump:它默认忽略authentication_policy字段、角色继承链、JSON CHECK 约束;必须配合mysqlpump或mydumper,并手动处理SHOW CREATE PROCEDURE输出 -
ibdata1、mysql/子目录、performance_schema/全部不能复用;哪怕只是拷贝旧文件进去,也会导致启动时元数据校验失败 - 配置文件中
basedir和datadir必须指向新二进制路径和新数据目录,不能混用旧路径
权限模型变更导致连接成功但查询失败
应用连得上、SELECT 1 能跑通,不代表权限就对了。MySQL 8.0 的 mysql.user 表字段重设计、默认启用密码策略、root@localhost 不再自动拥有所有权限,这些都静默生效。
- 必须验证:用应用账号执行
SELECT * FROM performance_schema.events_statements_summary_by_digest——这需要SYSTEM_VARIABLES_ADMIN权限,5.7 下没有该权限粒度,8.0 下缺失即报错 - 检查
CURRENT_USER()和USER()返回值差异,确认 definer 是否被降权;比如存储过程里写DEFINER='admin'@'%',在 8.0 中若该用户没显式授予SET_USER_ID权限,调用就会失败 -
SELECT * FROM mysql.role_edges和mysql.default_roles这两张表 5.7 没有,但如果你的应用依赖角色继承,就必须在影子库中显式创建并测试生效路径 -
CREATE USER语句行为变化:8.0 默认用caching_sha2_password插件,老应用若没更新 JDBC 驱动(8.0+ required),会直接拒绝连接,错误信息通常是Public Key Retrieval is not allowed
真正容易被忽略的不是命令怎么敲,而是“谁在什么时候用了什么权限去干了什么事”——升级后第一小时,比看 error.log 更重要的是查 mysql.general_log 或开启 audit log,确认每个业务账号的实际行为边界是否与预期一致。











