HAProxy 配置 MySQL 读写分离必须使用 mode tcp,frontend 和 backend 均需显式声明;禁用 option httpchk,改用 option mysql-check user haproxy_check;主库 backend 应去掉 check 或延长检查间隔,从库用只读账号检查;balance leastconn 更适读负载,事务请求须绑定同一节点;监听端口如 3307 需绕过 SELinux/ufw 限制,并验证 ss -tlnp 监听状态。

HAProxy 配置 MySQL 读写分离时,mode tcp 是硬性要求
MySQL 协议不是 HTTP,不支持 mode http 下的路径、头信息解析。用错模式会导致连接直接被拒绝,或者握手失败后静默断开。
常见错误现象:Access denied for user(实际密码正确)、客户端卡在连接阶段、ERROR 2013 (HY000): Lost connection to MySQL server。
- 必须在
frontend和backend中都显式设置mode tcp - 禁用
option httpchk—— 它只对 HTTP 有效,TCP 模式下会报配置错误 - 健康检查改用
option mysql-check user haproxy_check,且需提前在 MySQL 中创建该用户并授权USAGE
MySQL 后端节点不能全设为 check,主库要避开健康检查干扰写操作
HAProxy 默认每 5 秒发一次 mysql-check,若主库也开启检查,可能在大事务或锁表期间误判为宕机,触发不必要的故障转移。
使用场景:主从架构中,主库只写不读,从库承担读请求;HAProxy 本身不判断 SQL 类型,读写分离需靠应用层或中间件配合。
- 主库 backend 中去掉
check,或加inter 30s拉长检查间隔 - 从库 backend 保留
check,但user必须是只读账号(避免检查语句意外修改数据) - 不要依赖
backup关键字做主备切换——HAProxy 不感知 MySQL 主从状态,它只看端口连通性和登录是否成功
balance roundrobin 在从库间分发读请求,但要注意连接复用和事务粘性
默认轮询策略看似公平,但 MySQL 连接有状态(比如临时表、用户变量、事务),跨节点转发会导致 ERROR 1317 (70100): Query execution was interrupted 或数据不一致。
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
性能影响:短连接 + 高频查询下,轮询没问题;长连接 + 显式事务下,必须绑定到同一节点。
- 对读请求,可用
balance leastconn减少单节点压力 - 若应用用了
START TRANSACTION,应在事务开始前通过sql_hint或连接串指定直连某从库,别依赖 HAProxy 转发 - 避免在
backend中混用主库和从库地址——即使加了weight,HAProxy 也无法区分读写意图
真实部署时,bind *:3307 这类监听端口最容易被防火墙或 SELinux 拦截
HAProxy 默认监听 3307(避开 MySQL 原生 3306),但 CentOS/RHEL 上 SELinux 会阻止非标准端口的网络绑定,Ubuntu 则常因 ufw 默认拒绝新端口。
常见错误现象:HAProxy 启动无报错,但 netstat -tlnp | grep :3307 查不到监听,telnet 通不过。
- 先确认
haproxy -c -f /etc/haproxy/haproxy.cfg配置语法通过 - CentOS 执行
semanage port -a -t haproxy_port_t -p tcp 3307 - Ubuntu 执行
ufw allow 3307,再systemctl restart ufw - 务必用
ss -tlnp | grep :3307验证监听状态,别只信 HAProxy 日志里的 “starting”
复杂点在于:MySQL 客户端驱动(尤其是旧版 Connector/J)可能缓存 DNS 或连接池地址,换 HAProxy 地址后需要重启应用,否则流量还在直连原库。

















