在线升级仅支持同一大版本内小版本平滑迭代(如8.0.33→8.0.34),跨大版本(如5.7→8.0)或含MyISAM表必须离线升级;离线升级需停服、替换二进制、重初始化数据目录、迁移并清理配置;主从与组复制需按兼容顺序滚动升级,并严格校验插件、参数及GTID一致性。
在线升级只适用于小版本平滑迭代
MySQL 官方只保证同一大版本内的小版本在线升级可行,比如 8.0.33 → 8.0.34;跨大版本(如 5.7 → 8.0)或含 MyISAM 表的实例,mysqld --upgrade 会直接失败,甚至损坏元数据。这是因为 8.0 彻底重构了数据字典,mysql 系统库中 user、db 等表已移除,全部由内部 dictionary 管理,5.7 的系统表空间无法识别。
- 必须使用相同构建方式:都是官方二进制包,或都是源码编译,混用会导致 ABI 不兼容
- 启用插件(如
audit_log、keyring)前需确认新版是否支持对应 ABI 版本,否则启动即报错 - 在线升级后仍需手动验证:字符集默认值变化(
utf8mb4_0900_as_cs)、JSON 索引行为、慢日志字段新增、sql_mode默认收紧等
离线升级是跨版本和生产环境的唯一稳妥路径
所谓“离线”,本质是停服 + 替换二进制 + 重初始化数据目录 + 迁移配置,不是简单覆盖安装。很多人跳过关键检查点,结果 service mysql start 启动失败,排查半天才发现是配置项残留或初始化未完成。
- 备份前务必运行:
mysqlcheck --all-databases --check-upgrade,它会明确指出哪些表需ALTER TABLE ... UPGRADE PARTITIONING - 替换
mysqld二进制后,先别急着启动服务,用测试命令验证初始化:mysqld --initialize-insecure --datadir=/var/lib/mysql --basedir=/usr/local/mysql-8.0 -
my.cnf中必须清理废弃参数,例如query_cache_type、explicit_defaults_for_timestamp,否则 8.0 启动直接报unknown variable
主从集群下如何最小化升级窗口
高可用环境不能全量停机,得靠角色切换实现“伪在线”:先升级从库 → 提升为新主 → 再升级原主。但 GTID 和复制过滤器的兼容性稍有不慎就会中断复制。