从库读写分离失败应先排查从库同步状态、路由规则、read_only配置及网络链路:1.检查seconds_behind_master、sql_delay、gtid一致性;2.确认中间件是否误判sql读写类型;3.验证read_only与super_read_only是否生效;4.用tcpdump抓包确认实际请求目标。

查 SHOW SLAVE STATUS 里关键字段是否为正常值
从库读写分离失败,第一反应不是改应用代码,而是确认从库本身有没有真正在同步。很多人只看 Slave_IO_Running 和 Slave_SQL_Running 是 Yes 就以为万事大吉,其实不够。
真正要盯住的是这三处:
-
Seconds_Behind_Master:持续大于 0 且不断上涨,说明 SQL 线程追不上主库节奏,查询可能读到旧数据 -
SQL_Delay:如果设了延迟复制(比如CHANGE MASTER TO MASTER_DELAY = 3600),从库天然滞后,读请求会命中过期数据 -
Retrieved_Gtid_Set与Executed_Gtid_Set不一致,或Auto_Position=1但 GTID 模式没对齐,会导致主从跳事务、同步中断而不报错
确认中间件或驱动层的路由规则是否匹配当前 SQL 类型
很多故障不是数据库出问题,是路由逻辑把本该走从库的 SELECT 给发到了主库,或者把带 FOR UPDATE 的语句错误放行到从库——后者直接报错 ERROR 1290 (HY000): The MySQL server is running with the --read_only option。
常见路由误判点:
- ORM 自动生成的 SQL 带隐式事务(如 Django 的
select_for_update()),驱动可能未识别为写操作,误发到从库 - SQL 中含子查询或
UNION,某些中间件(如 MyCat、ShardingSphere)默认按最外层判断读写,实际内层有UPDATE却被忽略 - 连接串里没显式指定
readOnly=true(JDBC 场景),即使走的是从库连接池,驱动仍可能发写请求
检查 read_only 是否在从库生效且未被绕过
从库必须设 read_only=ON,否则应用发来的写请求不会被拒绝,而是静默执行,造成主从数据不一致。但这个参数容易被忽略或误配。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
验证和避坑要点:
- 登录从库执行
SELECT @@read_only;,返回1才算生效;仅靠配置文件写了read_only=1不够,得确认运行时值 -
super_read_only=ON要一并开启,否则高权限用户(如 root)仍可写入 - 某些云厂商 RDS 默认关闭
read_only,或提供“只读实例”概念但底层未强制限制,得手动补上
抓包确认实际发往哪个 IP:PORT 的请求
理论配置都对,但请求就是没走从库?别猜,直接看真实流量。尤其在用了连接池、代理、K8s Service 的环境,DNS 缓存、VIP 漂移、iptables 规则都可能导致连接落地地址和预期不符。
快速定位方法:
- 在应用机器上用
tcpdump -i any port 3306 -w mysql.pcap抓包,用 Wireshark 过滤mysql.query,看源 IP 和目标 IP 是否符合从库地址 - 在从库机器上执行
ss -tulnp | grep :3306,确认监听的是0.0.0.0:3306而非127.0.0.1:3306,否则外部连接连不上 - 若用的是 Docker 或 Pod,检查
hostNetwork: true是否缺失,或 Service 的 endpoint 是否漏掉了从库 Pod
路由配置和主从状态只是起点,真正卡住的往往是网络链路那一层没暴露出来——比如你看到 SHOW SLAVE STATUS 全绿,但抓包发现所有 SELECT 都打到了主库的 VIP 上,那问题根本不在数据库侧。










