mysqlrouter --bootstrap 不自动实现读写分离,仅生成基础配置;必须手动添加[metadata_cache:mycluster]、[routing:read_write]和[routing:read_only]三段,并通过不同端口区分读写流量。

mysqlrouter --bootstrap 不能自动实现读写分离,它只生成基础配置框架;真正的读写路由必须靠你手动补全两组 [routing] 段并让应用连不同端口。
为什么 bootstrap 不等于自动读写分离
执行 mysqlrouter --bootstrap root@10.0.1.10:3306 后,生成的 mysqlrouter.conf 默认只包含一个 [routing:default] 段,绑在 6446 端口,所有流量都走 PRIMARY——这本质是「高可用连接池」,不是读写分离。
Router 从不解析 SQL,也不看你是发 SELECT 还是 INSERT,它只认端口和配置里的 role=PRIMARY 或 role=SECONDARY。
必须手动补全的三个核心 section
缺一不可,且名字、引用、角色值必须严格一致:
-
[metadata_cache:mycluster]:名字要和后面 routing 段里写的完全一样;bootstrap_server_addresses至少填一个在线节点地址,如mysql://10.0.1.10:3306;ttl=5推荐(太长会延迟故障感知) -
[routing:read_write]:绑定端口建议用6446;destinations=metadata-cache://mycluster/default?role=PRIMARY——注意必须是PRIMARY,写MASTER或WRITABLE都无效 -
[routing:read_only]:绑定端口建议用6447;destinations=metadata-cache://mycluster/default?role=SECONDARY——Router 不识别SLAVE或READ_ONLY
应用层连错端口 = 读写分离失效
Router 不拦截、不重写、不判断你的 SQL。它只做一件事:你连 localhost:6446,它就转发到 PRIMARY;你连 localhost:6447,它才转到 SECONDARY。
- 写操作(含事务)必须固定连
6446,否则可能写到从库,造成数据不一致 - 读操作连
6447,但 Router 不检查复制延迟——如果从库 lag 2 秒,你照样读到旧数据 - Spring Boot 等 ORM 必须配多数据源,比如用
@Primary标写库,@Qualifier("readDataSource")标读库,不能只靠一个spring.datasource.url
元数据权限和网络连通性常被忽略
Router 启动时若报 Failed to fetch cluster metadata,大概率是这两件事没做:
- 配置中指定的 MySQL 用户(如
router_user)必须有权限查performance_schema.replication_group_members和mysql_innodb_cluster_metadata表;只给SELECT权限不够,还得显式授权:GRANT SELECT ON performance_schema.* TO 'router_user'@'%'; - Router 所在机器必须能直连所有 MySQL 实例的业务端口(如
3306)和组复制端口(默认33061);云环境常见防火墙/安全组没放开33061,导致元数据拉不到,fallback 全走 PRIMARY
Router 的「自动化」仅限于节点发现和故障转移,读写路由逻辑完全静态、由配置驱动。最容易被绕过的点是:以为配了 mode=read-write-split 就万事大吉——这个参数在 8.2+ 版本已废弃,实际生效的是 [routing] 段里的 destinations 字符串。


















