
MySQL Router 能不能直接做读写分离负载均衡?
不能。MySQL Router 本身不解析 SQL、不判断读写意图,它只按配置做 TCP 连接转发——本质是连接层代理,不是查询路由中间件。
常见错误现象:SELECT 被发到写节点、读节点宕机后连接直接失败,都是因为误以为它能自动识别语义。
- 它只认后端地址列表和角色标签(
role = "read-only"或"read-write"),不看 SQL 内容 - 读写分离必须靠客户端配合:应用连两个不同端口(如
7001写,7002读),Router 分别转发到对应集群 - 如果用单端口(如默认
6446),它只会轮询所有后端,不管是不是只读实例
怎么配 MySQL Router 实现「读节点轮询 + 写节点唯一」?
核心是写两套 [routing] 配置段,绑定不同端口和不同后端角色,再确保后端 MySQL 实例正确标注 group_replication_single_primary_mode 或设置 super_read_only=ON。
示例关键配置片段:
[routing:read] bind_address = 127.0.0.1:7002 destinations = metadata-cache://mycluster/?role=PRIMARY_AND_SECONDARY mode = read-only protocol = classic [routing:write] bind_address = 127.0.0.1:7001 destinations = metadata-cache://mycluster/?role=PRIMARY mode = read-write protocol = classic
-
destinations必须用metadata-cache://协议才能动态感知 MGR 状态;直写 IP 列表会丢失故障转移能力 -
mode = read-only不代表只发SELECT,而是告诉 Router:这个路由只连标为SECONDARY的节点(需后端实例已设super_read_only=ON) - Router 启动时若连不上元数据节点(如
mysql_innodb_cluster_metadata库不存在),会静默失败,日志里只有Failed to connect to metadata server
MySQL Router 和 ProxySQL / MaxScale 比起来差在哪?
差在查询级控制粒度。Router 是连接代理,ProxySQL 是 SQL 代理——后者能匹配 SELECT 前缀、重写语句、缓存结果、限流熔断;前者连慢查询都看不到。
- 性能上 Router 更轻量,CPU 占用低,延迟稳定在
- 兼容性上 Router 对 MySQL 8.0+ MGR 开箱即用;ProxySQL 需手动维护
mysql_servers表,MGR 节点变更要触发脚本同步 - 如果你的应用已用
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:7001/写死写库、:7002读库,换 ProxySQL 反而要改连接逻辑
启动失败常见原因和排查顺序
Router 日志默认极简,出错往往只打印一行,得开 --log-level=DEBUG 才能看到真实卡点。
- 配置文件路径不对:
mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf必须显式指定,它不读/etc/mysqlrouter.conf - 元数据权限不足:连接 MGR 元数据节点的账号缺
SELECT权限在mysql_innodb_cluster_metadata库,报错是Access denied for user 'router'@'%' to database 'mysql_innodb_cluster_metadata' - SSL 强制但未配证书:
ssl_mode = REQUIRED时,Router 默认不校验证书,但后端 MySQL 若设了require_secure_transport=ON,连接直接被拒,现象是Connection refused而非 SSL 错误
最常被忽略的是:Router 进程启动后不会自动重连失效的后端,也不会 reload 配置——改完 .conf 文件必须 kill -USR2 或重启进程,否则新配置永远不生效。











