MySQL主版本升级必须停机,所有未提交事务强制回滚;InnoDB事务状态依赖内存和redo log,无法延续;升级前需显式处理事务,无可靠自动延续机制。

MySQL升级时活跃事务会直接失败
MySQL主版本升级(如5.7→8.0)必须停机,所有未提交的事务在服务停止瞬间被强制回滚。这是由MySQL的存储引擎层决定的——InnoDB 的事务状态完全依赖内存中的trx_sys结构和redo log物理位置,升级过程无法延续这些运行时上下文。
- 执行
mysqld --upgrade或替换二进制文件前,MySQL必须已完全关闭,此时所有连接断开,活跃TRX_STATE为TRX_STATE_ACTIVE的事务全部丢弃 - 即使使用
--skip-grant-tables启动也无法恢复旧事务;新实例加载的是全新事务系统 - 唯一“延续”可能仅存在于极少数场景:若升级是in-place且版本兼容(如8.0.30→8.0.33),且未触发
mysql_upgrade,部分事务日志可能被重放,但这不构成可靠保障
升级前必须显式处理事务状态
不能依赖自动等待或超时机制。MySQL不会在SHUTDOWN命令中等待事务完成,默认行为是快速终止。
- 手动执行
SET GLOBAL innodb_fast_shutdown = 0(推荐),确保ib_logfile和ibdata1处于可恢复状态,但不改变事务中断事实 - 通过
SELECT * FROM information_schema.INNODB_TRX检查是否有长事务,对TIME_STARTED较早的记录,应主动KILL或协调业务侧提交/回滚 - 避免在升级窗口期开启新事务,可在升级前设置
max_connections = 1并只留DBA连接,再用FLUSH TABLES WITH READ LOCK阻塞写入(注意:该锁不阻塞事务内DML,仅对DDL和部分DML生效)
从库升级可降低业务影响,但主库事务仍会中断
如果采用主从架构,先升级从库再切换主从角色,能减少业务停机时间,但原主库上的事务依然会在其停机时中断——这和是否启用复制无关。
- GTID模式下,从库升级后
START SLAVE会从中继日志中重放未执行的事务,但这些是已提交的事务,不是原主库正在执行中的事务 - 半同步复制不能防止主库事务中断;
rpl_semi_sync_master_timeout只影响提交返回时机,不影响升级时的强制终止逻辑 - 若使用MGR,节点退出集群即触发
view_change,本地未提交事务同样被回滚,不可恢复
替代方案:滚动升级不适用于MySQL单实例
MySQL官方不支持单实例热升级。所谓“平滑升级”实际指应用层配合的灰度迁移,而非数据库自身能力。
- 真正可行路径是搭建新版本实例 → 用
mysqldump或mydumper导出逻辑数据 → 导入新实例 → 切换DNS或代理层流量 - 使用
Percona XtraBackup做物理备份+恢复,可缩短RTO,但仍需业务停写窗口来保证一致性点(--slave-info+CHANGE MASTER TO可辅助构建从库,但主库事务仍中断) - 有些团队误以为
ALTER INSTANCE ROTATE INNODB MASTER KEY或RESTART命令能绕过中断,实际这些操作不涉及版本变更,与升级无关
事务中断这件事本身没有取巧办法。关键是把“哪些事务会丢”“丢之前能不能通知业务”“丢了之后业务怎么兜底”想清楚,而不是寄希望于数据库在升级时保持事务连续性。










