真正卡住 MySQL 并发能力的往往是操作系统层面的资源限制:需调大文件描述符(nofile)、listen 队列(somaxconn)、线程数(nproc)并禁用或降低 swap 倾向,修改后须重启 mysqld 并验证生效。

MySQL 启动后报错或响应迟缓,十有八九不是配置写错了,而是操作系统层面的资源限制卡住了它——尤其是 max_connections 拉不上去、Threads_created 暴涨、连接直接被拒绝,这类现象基本都指向系统级限制没放开。
检查并放宽 Linux 文件描述符限制
MySQL 每个连接至少占用 1 个 socket 文件描述符,max_connections = 2000 时,实际需要远超这个数(含日志、临时文件等)。默认的 ulimit -n 通常只有 1024,必然不够。
- 临时生效:运行
ulimit -n 65535(当前会话),再启动 MySQL 测试是否缓解 - 永久生效:在
/etc/security/limits.conf中添加两行:mysql soft nofile 65535mysql hard nofile 65535 - 注意:systemd 管理的 MySQL(如 Ubuntu 22.04+/CentOS 7+)还需额外在
/etc/systemd/system/mysqld.service.d/override.conf中加LimitNOFILE=65535,否则 limits.conf 不生效
确认并调整内核参数 net.core.somaxconn
该参数控制 listen 队列长度,直接影响新连接能否及时被 accept。若大量连接卡在 SYN_RECV 或 TIME_WAIT,且 SHOW STATUS LIKE 'Aborted_connects' 持续增长,大概率是它太小。
- 查看当前值:
sysctl net.core.somaxconn(常见默认值为 128 或 4096) - 建议设为 65535:
sysctl -w net.core.somaxconn=65535 - 写入配置持久化:
echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf - 该值应 ≥ MySQL 的
back_log参数(默认 50),否则 backlog 配置无效
避免 swap 干扰 MySQL 内存分配
当 innodb_buffer_pool_size 设得较大(比如 12G),而系统启用 swap 时,Linux 可能将部分 buffer pool 换出到磁盘。一旦发生 page-in,查询延迟飙升,表现为“CPU 不高但响应极慢”,且 vmstat 显示 si/so 非零。
- 临时禁用:
swapoff -a - 永久禁用:注释掉
/etc/fstab中 swap 分区行,或执行sudo systemctl disable dphys-swapfile(树莓派等) - 验证:
free -h中 swap 行应全为 0;cat /proc/swaps应为空 - 补充:即使保留 swap,也建议设
vm.swappiness = 1(而非默认 60),大幅降低换出倾向
线程创建失败?检查 RLIMIT_NPROC 是否不足
MySQL 每个连接对应一个线程(非线程池模式下),若 Threads_created 持续上升、Threads_connected 却上不去,或错误日志出现 Pthread_create returned error code 11,说明进程/线程数已达用户级上限。
- 查看当前限制:
ulimit -u(普通用户常为 1024,root 可能更高) - 对 mysql 用户提额:在
/etc/security/limits.conf加mysql soft nproc 65535和mysql hard nproc 65535 - systemd 用户需同步在 service override 中加
LimitNPROC=65535 - 注意:该限制独立于文件描述符,两者必须同时调大
真正卡住 MySQL 并发能力的,往往不是 my.cnf 里的数字,而是这些藏在 OS 底层的“隐形天花板”。改完别忘了重启 mysqld 并用 cat /proc/$(pgrep mysqld)/limits 核对生效值——参数写了不等于起效,进程启动时才读取一次限制。


















