不能直接原地升级单机为InnoDB Cluster,必须停写、导出、重建集群再导入;因二者架构本质不同——单机为独立进程,集群依赖Group Replication协议、分布式元数据及MySQL Shell的dba API管理,无in-place路径。

不能直接“平滑”升级单机为 InnoDB Cluster——必须停写、导出、重建集群,再导入。所谓“平滑”只体现在应用层切换可控制在分钟级,而非数据库层无感知。
为什么不能原地升级?
MySQL 单机实例和 InnoDB Cluster 是两种完全不同的运行模式:前者是独立进程,后者依赖 Group Replication 协议、分布式元数据(mysql_innodb_cluster_metadata 库)、以及 MySQL Shell 的 dba API 管理。没有 in-place 升级路径,dba.createCluster() 必须在空实例或已同步的干净节点上执行。
- 试图在已有业务数据的单机上直接
dba.createCluster()会失败,报错类似Instance is not empty and cannot be used to bootstrap a cluster - Group Replication 要求所有节点初始状态一致,而单机的 binlog position、GTID set、server_uuid 都是孤立的,无法直接加入集群
- 集群元数据表(如
clusters,instances)必须由dba.createCluster()初始化,不能手动构造
迁移前必须做的三件事
跳过任何一项,后续大概率卡在 c.status() 显示 MISSING 或 OFFLINE:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 源库设为只读:
SET GLOBAL read_only = ON;(不是super_read_only,避免误锁管理账号) - 确认源库开启 GTID:
SELECT @@gtid_mode, @@enforce_gtid_consistency;必须为ON,否则util.dumpInstance(..., consistent: true)会降级为加全局读锁 - 目标集群所有节点需预配置一致:
server_id唯一、binlog_format=ROW、default_authentication_plugin=mysql_native_password(8.0+ 默认 caching_sha2_password 与旧客户端/部分工具不兼容)
用 util.dumpInstance 和 util.loadDump 迁移时的关键参数
这两个函数是 MySQL Shell 8.0+ 提供的原生迁移工具,比 mysqldump 更适配集群场景,但参数选错会导致导入失败或性能极差:
-
consistent: true:依赖 GTID,生成一个全局一致快照;若 GTID 关闭,则退化为FLUSH TABLES WITH READ LOCK,需确保源库能承受该锁 -
threads: N:导出时建议 ≤ 源库 CPU 核数;导入时设为 16–32(取决于目标主节点 I/O 和内存),但注意loadDump的线程数会并发创建表,可能触发max_connections不足 -
deferTableIndexes: 'all':强烈建议开启,否则大表导入时索引构建会拖慢 3–5 倍;导入完成后再批量建索引更高效 -
loadUsers: true:仅当导出时包含@.users.sql(即未设includeUsers: false)才有效;否则用户权限不会恢复,应用连不上
集群初始化后最容易被忽略的验证点
很多人跑完 c.status() 看到 "status": "OK" 就以为完成了,其实还有三个隐性依赖没检查:
- 检查各节点
performance_schema.replication_group_members是否全部MEMBER_STATE = ONLINE,而非仅靠c.status()表面状态 - 确认主节点的
group_replication_single_primary_mode为ON(多主模式需额外评估,生产环境慎用) - 应用连接串必须指向集群的 Router(如 MySQL Router 8.0+)或使用
--cluster模式连接,不能直连某个 IP:Router 会自动路由写请求到 PRIMARY,读请求按策略分发

















