back_log是tcp监听队列长度,仅缓解连接建立阶段的瞬时洪峰;它不能增加总连接数,也不能解决连接泄漏或max_connections耗尽问题,必须与net.core.somaxconn协同调整才有效。

back_log 是什么,它真能缓解连接风暴吗?
不能。back_log 不是“连接池”,也不增加 MySQL 能接受的总连接数。它只控制 TCP 连接请求在进入 MySQL 服务前,能在操作系统内核的 accept 队列里排队等待的长度。当大量新连接瞬间涌来(比如秒杀、定时任务启动),MySQL 还没来得及调用 accept() 处理,这些请求就先堆在队列里——back_log 就是这个队列的上限。
一旦队列满了,新的 SYN 包会被内核直接丢弃,客户端看到的是“Connection refused”或超时,而不是 “Too many connections”。所以它解决的是“连接被拒”的表层现象,不是连接数打满的根本问题。
怎么查和改 back_log?注意系统级限制
MySQL 启动时会读取系统参数 /proc/sys/net/core/somaxconn,并把 back_log 设为该值和配置值中的较小者。也就是说,你配再大也没用,如果系统限制卡死了。
- 查当前生效值:
SHOW VARIABLES LIKE 'back_log'; - 查系统上限:
cat /proc/sys/net/core/somaxconn(Linux) - 临时调高系统限制:
sudo sysctl -w net.core.somaxconn=2048 - 永久生效:在
/etc/sysctl.conf加一行net.core.somaxconn = 2048,然后sysctl -p - MySQL 配置中设
back_log = 2000(需重启 mysqld 才生效)
注意:back_log 最大只能到系统 somaxconn 的值,超出部分会被静默截断——SHOW VARIABLES 显示的才是真实生效值。
为什么调大 back_log 后还是连不上?常见坑点
调了 back_log 却没效果,大概率踩了这三个坑:
- 没同步调高
somaxconn,MySQL 实际用的还是旧值(比如默认 128) - 应用端重试机制太激进,SYN 重传间隔短、次数多,反而加剧队列拥塞
- 根本问题是应用连接泄漏或连接池爆满,新连接持续打进来,队列永远清不完——这时加
back_log只是把“立刻拒绝”变成“稍等几秒再拒绝”
典型错误现象:netstat -s | grep -i "listen overflows" 输出非零,说明队列确实溢出了;但同时 Threads_connected 远低于 max_connections,证明不是 MySQL 层打满,而是连接压根没进到 MySQL。
back_log 和 max_connections 到底谁该优先调?
优先看监控数据:
- 如果
Threads_connected接近max_connections→ 重点查应用连接泄漏、慢查询阻塞、连接池配置 → 调max_connections是次要动作 - 如果
Threads_connected很低,但客户端报 Connection refused 或大量超时 → 查listen overflows和somaxconn→back_log才是关键
两者不是替代关系,而是分层防御:操作系统队列(back_log)兜底接收,MySQL 连接池(max_connections)负责处理。漏掉任何一层,突发流量都会击穿。











