MySQL不内置读写分离,必须依赖主从复制稳定运行,并通过ProxySQL等中间件或应用层路由实现;主从配置、权限、时间同步及规则加载缺一不可。

MySQL 本身不内置读写分离能力,必须靠外部组件或应用层配合主从复制才能实现。直接改 my.cnf 或执行某条命令无法“开启读写分离”——这是最常见的误解。
主从复制没跑通,读写分离就是空中楼阁
所有读写分离方案都依赖主从复制状态稳定。如果 SHOW SLAVE STATUS\G 中 IO_Running 或 SQL_Running 任一为 No,后续任何代理或路由都无效。
- 检查主库是否启用了
log_bin,且server-id非零(如server-id = 1) - 检查从库
relay_log路径是否有写权限,read_only = 1是否生效(防止误写) - 主从时间不同步会导致 GTID 或位点解析失败,务必先运行
ntpdate ntp.aliyun.com同步时间 - 从库连接主库的账号必须有
REPLICATION SLAVE权限,且 host 要匹配(比如用'repl'@'192.168.10.%'而非'repl'@'%',避免被防火墙拦截)
ProxySQL 是目前最实用的中间件选型
相比已停止维护的 mysql-proxy 或配置复杂的 MaxScale,ProxySQL 对 MySQL 5.7+ 兼容好、热重载配置、自带监控指标,适合中小规模生产环境。
- 安装后默认监听
6032(管理端口)和6033(服务端口),应用只需连6033 - 在
mysql_servers表中把主库权重设为10、从库设为100,再配mysql_replication_hostgroups关联主从组 - 关键是规则匹配:往
mysql_query_rules插入一条match_pattern = '^SELECT'、destination_hostgroup = 2(从库组),并确保apply = 1 - 执行
LOAD MYSQL QUERY RULES TO RUNTIME+SAVE MYSQL QUERY RULES TO DISK生效,不要只 reload 配置文件
应用层直连方式要小心事务和强一致性场景
如果不用中间件,而是让应用自己判断读/写路由,容易踩坑:
-
SELECT语句被路由到从库,但刚执行完INSERT就查,可能因主从延迟读不到最新数据 -
BEGIN开启事务后,所有语句(包括SELECT)必须走主库,否则会报错或数据不一致 - ORM 框架如 MyBatis、Hibernate 默认不识别读写分离,需手动指定
readOnly = true或切换数据源 - 不建议用
mysql -h proxy_ip -P 6033 -u app这类命令行测试读写分离效果——它不模拟应用的真实连接生命周期,容易误判
真正上线前,一定要用真实业务 SQL 压测,观察 ProxySQL 的 stats_mysql_connection_pool 表里各 hostgroup 的 Connections_used 和 Slow_queries,而不是只看 SHOW SLAVE STATUS 的 Yes/No。主从延迟、网络抖动、单点故障这些细节,往往在流量高峰时才暴露。











