mysql的在线升级与离线升级方式的选择

来源:这里教程网 时间:2026-02-28 20:39:09 作者:

在线升级是否可行,取决于 MySQL 版本跨度和存储引擎

MySQL 官方只保证

GA
(General Availability)版本之间的**小版本在线升级**(如
8.0.33 → 8.0.34
),且要求使用相同构建方式(如都是官方二进制包或都用源码编译)。跨大版本(如
5.7 → 8.0
)或混合引擎(尤其含
MyISAM
表)时,
mysqld --upgrade
会失败或产生不兼容元数据。

InnoDB
表在 8.0+ 中默认启用
innodb_file_per_table=ON
和新数据字典格式,5.7 的系统表空间无法直接识别
mysql
系统库结构在 8.0 彻底重构,
user
db
等表被移除,依赖
data dictionary
,离线迁移时必须执行
mysql_upgrade
(8.0.16+ 已弃用,改由
mysqld --upgrade
自动触发)
若实例启用了
audit_log
keyring
插件,插件 ABI 不兼容会导致启动失败,需提前确认插件版本支持情况

离线升级的标准操作流程与关键检查点

离线升级是跨大版本或生产环境的推荐路径,核心是「停服 → 替换二进制 → 初始化数据目录 → 迁移配置」。容易被跳过的检查点往往导致启动失败。

备份前先运行
mysqlcheck --all-databases --check-upgrade
,它会报告具体哪些表需
ALTER TABLE ... UPGRADE PARTITIONING
或修复
替换
mysqld
二进制后,不要直接
service mysql start
;应先用
mysqld --initialize-insecure --datadir=/var/lib/mysql --basedir=/usr/local/mysql-8.0
验证初始化是否成功(仅测试用,生产环境用
--initialize
my.cnf
中废弃参数如
query_cache_type
explicit_defaults_for_timestamp
必须删除,否则 8.0 启动报错
unknown variable
mysqld --defaults-file=/etc/my.cnf --datadir=/var/lib/mysql --basedir=/usr/local/mysql-8.0 --upgrade=FORCE

主从架构下如何最小化升级窗口

对高可用集群,可利用主从角色切换实现“伪在线”升级:先升级从库,再提升为新主,最后升级原主。但要注意 GTID 和复制过滤器的兼容性。

5.7 开启了
gtid_mode=ON
,8.0 升级后必须保持
enforce_gtid_consistency=ON
,否则复制中断
若从库配置了
replicate-ignore-db
,8.0 中该参数已被移除,需改用
replication-filter
语法并重启生效
升级从库前,先在主库执行
STOP SLAVE IO_THREAD
,等
Seconds_Behind_Master = 0
后再停服务,避免 relay log 断层

升级后必须验证的三项实际行为

很多团队只检查

SELECT VERSION()
就认为完成,但以下三类问题常在业务高峰暴露:

字符集隐式转换:5.7 默认
utf8mb4
但排序规则是
utf8mb4_general_ci
,8.0 改为
utf8mb4_0900_as_cs
ORDER BY
结果可能变化,需重跑关键查询对比
JSON 字段索引失效:5.7 建的
VIRTUAL
列索引在 8.0 中仍可用,但若字段定义含
AS (json_extract(...)) STORED
,需确认
INFORMATION_SCHEMA.STATISTICS
中索引状态为
active
慢日志格式变更:8.0 的
slow_query_log_file
默认用新格式(含 query_time 微秒精度),旧解析脚本会丢字段,建议用
mysqldumpslow -s t
而非自定义 awk 脚本

最易被忽略的是权限模型变化:8.0 的

CREATE USER
不再隐式赋权,所有账号需显式
GRANT
,升级后应用连不上时,先查
SELECT user,host,account_locked FROM mysql.user
确认账号未被锁且权限完整。

相关推荐