mysql如何进行无停机时间的版本升级_mysql零停机迁移方法

1次阅读

mysql零停机升级依赖主从切换而非原地升级,需确保版本间复制兼容(如5.7→8.0可行,反向不可),配合AdminAPI可自动化滚动升级,但须严控配置、时区、大小写策略及认证插件等隐性差异。

mysql如何进行无停机时间的版本升级_mysql零停机迁移方法

MySQL 主从切换实现零停机升级

MySQL 本身不支持原地热升级(比如从 5.7 直接升到 8.0),所谓“无停机时间升级”,本质是靠架构切换而非单实例就地升级。最成熟、可控的方式是构建主从复制拓扑,将新版本实例作为从库拉取旧版本主库的 binlog,待数据追平后执行角色切换。

关键前提是:新旧版本间必须满足 replication compatibility。例如:

  • 5.7 → 8.0 支持(但需关闭 sql_mode 中的 NO_AUTO_CREATE_USER 等已移除项)
  • 8.0 → 5.7 不支持(高版本 binlog Event 类型低版本无法解析)
  • 跨大版本时,mysql_upgrade 不可用于在线实例,只能在从库停写后执行(且仅限同版本升级场景)

使用 MySQL Shell 的 AdminAPI 自动化滚动升级

MySQL 8.0.19+ 内置的 AdminAPI(通过 mysqlsh)可管理 InnoDB Cluster,支持对集群节点逐个升级而不中断服务。它底层仍是主从切换逻辑,但封装了状态检查、故障隔离、自动重试等细节。

实操要点:

  • 确保所有节点启用 group_replication 且运行在兼容模式(如 group_replication_consistency=AFTER
  • 升级前用 cluster.checkInstanceConfiguration() 验证目标实例配置(尤其 binlog_format=ROWenforce_gtid_consistency=ON
  • 执行 cluster.upgradeMetadata() 仅更新元数据版本,不触碰数据;真正的二进制升级需先停掉该节点的 mysqld,替换二进制,再以 --upgrade=MINIMAL 启动

pt-online-schema-change 不能用于版本升级

有人误以为 pt-online-schema-changegh-ost 能做版本升级——它们只解决「表结构变更时避免锁表」的问题,和 MySQL 服务进程的二进制替换、系统表迁移、字符集默认行为变更等完全无关。

典型误用后果:

  • 在 5.7 主库上用 gh-ost 迁移一张表,再把该表所在的实例升级到 8.0 → mysql.user 表结构已变,权限系统直接失效
  • 跳过 mysql_upgrade 步骤直接启动 8.0 二进制读取 5.7 数据目录 → 启动失败并报错 table 'mysql.role_edges' doesn't exist
  • 未重放完所有 binlog 就切换流量 → 出现主键冲突或丢失事务

升级后必须验证的三个隐性断裂点

即使切换成功,以下三点极易被忽略,导致后续业务异常:

  • TIMEZONE 行为差异:5.7 默认用系统时区,8.0 默认用 SYSTEM 但首次启动会尝试写入 mysql.time_zone 表;若未加载时区表,NOW()CONVERT_TZ() 结果错乱
  • lower_case_table_names 默认值变化:linux 下 5.7 默认为 0,8.0 默认为 1 —— 若应用硬编码了大小写混用的表名,查询会突然返回空结果
  • default_authentication_plugin:8.0 默认改用 caching_sha2_password,老客户端(如 MySQL 5.6 JDBC driver)连接会报错 Unknown authentication plugin caching_sha2_password

这些不是“升级没完成”,而是“升级完成了但环境没对齐”。上线前必须用真实业务 SQL 在新实例上回放验证,不能只看 SHOW SLAVE STATUSGSeconds_Behind_Master: 0

text=ZqhQzanResources