mysql数据库的并发连接数与系统配置

max_connections是MySQL服务端允许同时建立的客户端连接数上限,不是能稳定处理的并发请求数或实际QPS;它仅是连接层门禁,设过高易致OOM或线程崩溃,需配合系统资源、ulimit、内核参数及连接池优化。

MySQL 的 max_connections 是什么,又不是什么

max_connections 是 MySQL 服务端允许同时建立的客户端连接数上限,它不等于“能稳定处理的并发请求数”,更不等于“系统能承受的实际 QPS”。这个值只是连接层的门禁开关,设得太高而没配好系统资源,反而会触发 OOM 或线程调度崩溃。

  • 默认值通常为 151(MySQL 5.7+),生产环境往往需调高,但不能盲目翻倍
  • 每个连接至少占用几 MB 内存(含线程栈、网络缓冲、临时表空间等),max_connections = 2000 可能直接吃掉 4~6 GB 内存
  • Linux 进程级限制(ulimit -n)必须 ≥ max_connections + 预留文件描述符(如 binlog、redo log、socket 监听等),否则 MySQL 启动失败或运行中报 Too many open files

Linux 系统侧必须同步调整的三个关键项

MySQL 不会自动绕过内核限制。只改 my.cnf 里的 max_connections,90% 的高并发场景会卡在系统层。

  • /etc/security/limits.conf 中为 mysql 用户设置:
    mysql soft nofile 65535
    mysql hard nofile 65535
  • /etc/systemd/system/mysqld.service.d/override.conf(若用 systemd)中追加:
    [Service]
    LimitNOFILE=65535
  • 确认内核参数:sysctl net.core.somaxconn 建议 ≥ 1024,避免 TCP 连接堆积在 SYN_QUEUE

如何判断当前连接数是否真成瓶颈

别只看 SHOW STATUS LIKE 'Threads_connected'。真实压力来自活跃查询、锁等待和 IO 阻塞。

  • 检查长期空闲连接:SELECT ID, USER, HOST, COMMAND, TIME, STATE FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' OR TIME > 60;
  • 识别连接泄漏:应用端未调用 connection.close(),导致 Threads_connected 持续缓慢上涨,且 Threads_running 始终很低
  • 对比 Aborted_connectsConnection_errors_* 状态变量,突增说明是认证失败或握手超时,而非连接数不足

连接池比调大 max_connections 更有效

多数 Web 应用的并发请求远高于数据库能健康承载的连接数。硬扛不如收敛——把连接复用做扎实。

  • Java 应用优先用 HikariCP,maximumPoolSize 建议设为 CPU 核数 × (2~4),而非照搬 QPS
  • Python 的 pymysqlmysql-co

    nnector-python
    必须启用 pool_size,禁用 autocommit=True 以外的长事务
  • 避免在事务中混入 HTTP 调用、文件读写等阻塞操作,否则连接被独占时间远超 SQL 执行本身
实际压测中,常看到 DBA 把 max_connections 从 500 改到 2000,结果 innodb_row_lock_time_avg 翻了 3 倍——问题不在连接数,而在没拆分热点行更新或缺少合适的索引。连接数配置永远要和慢查、锁、IO 能力一起看。