back_log控制TCP未完成三次握手的SYN队列长度,受net.core.somaxconn限制,与max_connections无关;调大它仅缓解瞬时建连丢包,不能提升并发处理能力。

MySQL 的 back_log 参数控制的是 TCP 连接请求在进入 MySQL 服务前、由操作系统内核维护的“未完成三次握手连接队列”(SYN Queue)的最大长度。它不直接决定 MySQL 能处理多少并发连接,而是影响高并发瞬时建连时是否被内核丢包——这是很多突发流量下“连接拒绝(Connection refused)”或“Too many connections”误报的底层原因之一。
back_log 的真实作用和常见误解
很多人以为调大 back_log 就能提升 MySQL 并发能力,其实不然:
- 它不是连接池,也不影响已建立连接的处理能力:只作用于 TCP 握手阶段,即客户端发了 SYN、MySQL 还没完成三次握手的“半连接”状态;
-
它的上限受操作系统限制:Linux 内核参数
net.core.somaxconn是硬性天花板,back_log设置再大,超过somaxconn也会被自动截断; -
它和
max_connections完全无关:后者管的是已认证、已分配线程的活跃连接数,前者管的是还没进来的排队请求。
判断是否真需要调大 back_log
不要盲目调优。先确认问题根源:
- 观察 MySQL 错误日志中是否有
Aborted connection ... because of empty packet或Got timeout reading communication packets等提示(间接线索); - 检查系统级指标:
netstat -s | grep -i "listen overflows"或ss -lnt | grep -E "(Recv-Q|Send-Q)",若Recv-Q长期非零且接近设置值,说明队列积压; - 对比应用层报错:大量客户端出现
Connection refused(非Connection timed out),尤其集中在秒级流量尖峰开始时刻。
安全有效的调优步骤
调优需“系统参数 + MySQL 参数”协同,顺序不能错:
-
先调操作系统:修改
/etc/sysctl.conf,确保net.core.somaxconn = 65535(或更高,如 131072),然后执行sysctl -p生效; -
再设 MySQL back_log:在
my.cnf的[mysqld]段中设置back_log = 65535(建议 ≤somaxconn,通常设为相同值即可); - 重启 MySQL 生效:注意该参数是只读的,必须重启;
-
验证是否生效:登录 MySQL 执行
SHOW VARIABLES LIKE 'back_log';,同时用ss -lnt | grep :3306查看对应端口的Recv-Q是否有容纳空间。
配套必须做的几件事
单调 back_log 很难根治问题,还需配合以下措施:
- 启用连接复用:应用侧使用连接池(如 HikariCP、Druid),避免每请求都新建 TCP 连接;
-
缩短握手耗时:关闭
skip_name_resolve避免 DNS 反查;必要时禁用 SSL/TLS 握手(测试环境),或启用 TLS session resumption; - 前置负载均衡缓冲:在 MySQL 前加 LVS、HAProxy 或 ProxySQL,它们自带连接队列和重试机制,可吸收瞬时洪峰;
-
监控与告警:对
Aborted_connects状态变量、内核 listen overflows、以及应用建连失败率做聚合监控,设置阈值告警。
不复杂但容易忽略:back_log 是高并发建连链路的第一道缓冲阀,调对了不会提升吞吐,但能防止第一波流量就崩掉入口。真正承载高并发,靠的是连接池、查询优化、读写分离和合理的资源配比,back_log 只是让这些策略有机会起作用。


















