MySQL主从复制本身不提供负载均衡能力,仅实现单向数据同步;读写分离需依赖应用层或ProxySQL等中间件实现请求分发与延迟感知、写保护校验。

MySQL 主从复制本身不提供负载均衡能力,它只是单向数据同步机制;要实现读写分离式的负载均衡,必须在应用层或中间件层额外引入调度逻辑。
主从复制的默认行为不包含请求分发
MySQL 原生复制只保证 binlog 从主库(master)传输并重放到从库(slave),所有客户端连接仍需自行决定连哪台实例。MySQL 服务器自身不会主动把 SELECT 请求导到从库、把 INSERT/UPDATE/DELETE 导到主库。
- 如果你直接在应用里写死连接
localhost:3306,那永远只打到一台机器上 - 即使配置了多个 IP,在 DNS 或连接字符串里用逗号拼接(如
host1,host2),MySQL 客户端驱动通常也不支持自动读写分离 -
mysqlrouter、proxysql、maxscale这类中间件才是承担路由职责的组件
常见读写分离中间件选型对比
真正起负载均衡作用的是部署在应用和 MySQL 之间的代理层,它们解析 SQL 类型、维护后端节点状态,并按策略转发:
-
ProxySQL:轻量、热配置、支持 SQL 规则匹配(例如匹配^SELECT就走从库),但需要手动维护mysql_servers和mysql_query_rules表 -
MySQL Router:官方出品,集成度高,但仅支持 InnoDB Cluster 场景下的读写分离,对传统主从拓扑支持弱 -
MaxScale:功能全面,支持自动延迟检测、权重轮询,但资源占用略高,配置文件语法较复杂 - 应用内直连(如 Java 的
ShardingSphere-JDBC):不依赖中间件,但耦合度高,升级/调试成本上升
从库延迟导致的负载不均问题
当从库 Seconds_Behind_Master 持续升高时,即使流量被分发过去,查询结果也可能滞后,此时负载均衡反而成了隐患:
- ProxySQL 可通过
monitor_username定期执行SHOW SLAVE STATUS并根据Seconds_Behind_Master动态下线节点 - MaxScale 默认启用
replication lag threshold,超阈值自动剔除该从库 - 若用 DNS 轮询或客户端硬编码列表,必须自己实现心跳 + 延迟探测逻辑,否则“均衡”只是假象
SELECT host, port, status, lag FROM mysql_server_joins WHERE host = 'slave01' AND lag > 30;
写操作误发到从库会直接报错
从库默认开启 read_only=ON,任何非 super 权限用户尝试执行写语句都会收到错误:
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
这意味着——
- 如果中间件未正确识别事务边界或未拦截
BEGIN/COMMIT,可能导致部分写请求落到从库并失败 - 某些 ORM(如 Django)在事务中混用读写,需确保中间件支持会话一致性(sticky session)或显式指定
using='default' - 不要关闭从库的
read_only来“兼容”,这会让数据不一致风险失控
真正的负载均衡不在复制协议里,而在你如何把请求导向正确的节点;而最常被忽略的,是延迟感知和写保护这两层校验是否真正生效。










