应关闭tcp_slow_start_after_idle(设为0)以避免长连接空闲后吞吐骤降;合理调大tcp_rmem/tcp_wmem(如4096 262144 16777216)提升大结果集传输效率;高延迟场景优选BBR拥塞控制;代理层启用tcp_tw_reuse并适当调低tcp_fin_timeout缓解端口耗尽。

tcp_slow_start_after_idle 导致连接复用时吞吐骤降
MySQL 在长连接空闲后重建传输窗口,tcp_slow_start_after_idle 默认开启会强制重走慢启动,对短突发查询很不友好。比如应用层用连接池维持长连接,但每分钟只发几条语句,实际带宽可能长期卡在初始 10KB/s。
- 检查当前值:
sysctl net.ipv4.tcp_slow_start_after_idle(Linux 4.1+ 默认为 1) - 生产环境建议关闭:
sysctl -w net.ipv4.tcp_slow_start_after_idle=0,并写入/etc/sysctl.conf - 注意:该参数仅影响已建立连接的空闲恢复行为,不影响新建连接的初始 cwnd
net.ipv4.tcp_rmem 和 net.ipv4.tcp_wmem 设置不合理
MySQL 的大结果集(如 SELECT * FROM huge_table)或批量插入常受 TCP 缓冲区限制,tcp_rmem 过小会导致接收方频繁 ACK,tcp_wmem 过小则发送端无法攒够 MSS,降低单次传输效率。
- 典型错误配置:
4096 16384 65536—— 最大值 64KB 对千兆网太保守 - 推荐值(万兆内网):
4096 262144 16777216(min/default/max,单位字节) - 必须配合
net.core.rmem_max和net.core.wmem_max调高,否则系统会截断到其上限 - 修改后需重启 MySQL 或至少重连客户端才生效(内核参数作用于 socket 层)
net.ipv4.tcp_congestion_control 选错算法影响高延迟链路
跨机房或云厂商间 MySQL 主从同步、ProxySQL 转发等场景,RTT 常超 20ms,传统 cubic 易激进扩窗导致丢包;而 reno 又过于保守。这时 bbr 是更稳的选择,但要注意兼容性。
- 确认内核支持:
sysctl net.ipv4.tcp_available_congestion_control(需含bbr) - 启用:
sysctl -w net.ipv4.tcp_congestion_control=bbr - 关键限制:BBR 不兼容某些老旧交换机的 ECN 行为,若出现大量
TCP retransmission或dup ack,切回cubic - MySQL 自身不感知拥塞算法,但主从延迟、LOAD DATA 网络耗时直接受影响
net.ipv4.tcp_fin_timeout 和 net.ipv4.tcp_tw_reuse 配合不当引发端口耗尽
连接数高的 MySQL 代理或短连接应用(如 PHP-FPM 每请求建连),FIN_WAIT_2 状态堆积 + TIME_WAIT 占用端口,容易触发 Cannot assign requested address 错误。
-
tcp_fin_timeout控制 FIN_WAIT_2 超时(默认 60s),可降至30,但低于 20s 可能丢 ACK -
tcp_tw_reuse必须设为1(仅对客户端有效),MySQL 服务端不走此路径,所以代理层或应用服务器才需要它 - 真正治本的是让应用复用连接,调低
tcp_fin_timeout只是缓解手段 - 别碰
tcp_tw_recycle—— 已被 Linux 4.12+ 移除,且 NAT 环境下必出问题
这些参数不是调得越大越快,也不是改完就生效。真实瓶颈常藏在网卡中断分布、RSS 队列绑定、甚至交换机 buffer 设置里——内核 TCP 参数只是其中一环,动之前先用 ss -i 看连接的实际 cwnd、rtt、retrans、qsize,比盲目调参靠谱得多。


















