不能。mysql router 本身不解析 sql、不判断读写意图,仅依据后端实例的 primary/secondary 角色做路由,读写分离需应用层或兼容驱动配合实现。

MySQL Router 能不能直接实现读写分离?
不能。MySQL Router 本身不解析 SQL、不判断读写意图,它只是个智能代理——靠后端 MySQL 实例的 role(如 PRIMARY / SECONDARY)做路由决策。真正实现读写分离,得靠应用层把读请求发到只读地址、写请求发到主地址,或者用支持读写分离的驱动(如 MySQL Connector/J 的 loadBalance 模式),Router 只负责把这两个逻辑地址映射到真实实例。
配置 MySQL Router 前必须确认的三件事
Router 不是装上就能用,它依赖底层 MySQL 集群状态准确、网络通、权限对。漏掉任何一项都会导致连接失败或路由错乱:
- MySQL 实例必须启用
group_replication或已配置innodb_cluster(Router 8.0+ 主要对接 InnoDB Cluster);单主从复制环境需手动在mysql_innodb_cluster_metadata库里补全实例角色信息,否则 Router 启动报Failed to fetch cluster metadata - Router 所在机器必须能通过 IP + 端口直连所有 MySQL 实例(包括内部心跳端口,默认
33061),防火墙/安全组常在这里卡住 - 配置中指定的
user必须有SELECT权限访问performance_schema.replication_group_members和mysql_innodb_cluster_metadata库,否则元数据拉不到,Router 默认 fallback 到全部走PRIMARY
router.conf 里最关键的三个 section
Router 的行为几乎全由 mysqlrouter.conf 控制,重点不是写得多,而是这三块配对且语义一致:
-
[routing:read_write]:绑定destinations=metadata-cache://mycluster/default?role=PRIMARY,端口建议设为6446(行业惯例),应用写请求连这个端口 -
[routing:read_only]:绑定destinations=metadata-cache://mycluster/default?role=SECONDARY,端口设6447,应用读请求连这里 -
[metadata_cache:mycluster]:必须和上面两个 routing 段里的名字完全一致;bootstrap_server_addresses要填至少一个在线的 MySQL 实例地址(如mysql://10.0.1.10:3306);ttl建议设5秒,太长会导致故障转移延迟
示例片段:
[metadata_cache:mycluster] bootstrap_server_addresses=mysql://10.0.1.10:3306,mysql://10.0.1.11:3306 cluster_type=gr ttl=5 [routing:read_write] bind_address=0.0.0.0:6446 destinations=metadata-cache://mycluster/default?role=PRIMARY mode=read-write [routing:read_only] bind_address=0.0.0.0:6447 destinations=metadata-cache://mycluster/default?role=SECONDARY mode=read-only
为什么应用连上了但总是写到从库?
这是生产中最容易被忽略的点:Router 的路由逻辑只看后端实例当前 role,不保证事务一致性。如果主库崩溃、新主刚选出来但 SECONDARY 实例还没完成状态同步(比如 RECEIVING 状态),Router 仍会把它当有效只读节点转发读请求——更糟的是,某些旧版 Router(SECONDARY,导致写请求被发到从库并报 ERROR 1290 (HY000): The MySQL server is running with the --read-only option。
应对方式只有两个:第一,在应用层加重试逻辑,捕获该错误后重连 6446 端口;第二,升级 Router 到 8.0.33+,开启 auto_rejoin 并配合 health_check_interval=2 缩短状态感知延迟。











