MySQL 连接数:为什么你的服务器总“Too many connections”?连接池的配置和优化

更新日期: 2026-02-02 阅读次数: 16 字数: 903 分类: MySQL

查看 MySQL 的当前连接数是排查性能瓶颈和配置连接池时的基本功。 所以记录一下可能用到的查询命令。以下是基于 MySQL 8.0 的测试:

当前有多少个客户端连着数据库

当前打开的连接数:

> SHOW STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 17    |
+-------------------+-------+
1 row in set (0.01 sec)

查看详细的连接列表

> SHOW FULL PROCESSLIST;
+-------+-----------------+-----------------+----------------+---------+----------+------------------------+-----------------------+
| Id    | User            | Host            | db             | Command | Time     | State                  | Info                  |
+-------+-----------------+-----------------+----------------+---------+----------+------------------------+-----------------------+
|     5 | event_scheduler | localhost       | NULL           | Daemon  | 98589253 | Waiting on empty queue | NULL                  |
| 20740 | user1           | localhost:54994 | database1      | Sleep   |      470 |                        | NULL                  |
| 20741 | user1           | localhost:55450 | database1      | Sleep   |      470 |                        | NULL                  |
| 20918 | user1           | localhost:49080 | database3      | Sleep   |      470 |                        | NULL                  |
| 21858 | user1           | localhost:47582 | database2      | Sleep   |      470 |                        | NULL                  |
| 21859 | user1           | localhost:47734 | database2      | Sleep   |      470 |                        | NULL                  |
| 24081 | user1           | localhost       | db5            | Query   |        0 | init                   | SHOW FULL PROCESSLIST |
+-------+-----------------+-----------------+----------------+---------+----------+------------------------+-----------------------+
18 rows in set (0.00 sec)

字段说明:

  • Command: 连接状态(如 Sleep 表示空闲,Query 表示正在查)
  • Time: 该状态持续的时间(秒)。

可以看到目前的大部分连接处于 Sleep 状态,说明这些连接是空闲的,没有在执行查询。

而且每个独立的数据库都有两个 sleep 状态的连接,说明我的 golang gorm 默认配置是 MaxIdleConns 为 2。 即使没有查询任务,连接池也会保持 2 个空闲连接。但是对于高并发的场景,2 个空闲连接可能不够用。 原因是在高并发结束后,多出来的连接会被立即关闭,等下次请求来时又要重新握手。

当前正在执行查询的连接数

通常远小于 connected,如果这个值很高,说明数据库压力极大

> SHOW STATUS LIKE 'Threads_running';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| Threads_running | 2     |
+-----------------+-------+
1 row in set (0.00 sec)

最大连接数限制

> SHOW VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.00 sec)

默认是 151,可以根据需要调整这个值,避免连接数过多导致拒绝服务。

同时也要对应的限制 golang gorm 的最大连接数,当流量激增时,程序会尝试开启成千上万个连接,直接超出数据库限制,导致报错 Too many connections。

历史最高连接数(峰值)

这个值记录了自 MySQL 启动以来的历史最大并发连接数。如果这个值远低于你的连接池总和,说明你的连接池设置得太大了,浪费资源。

> SHOW STATUS LIKE 'Max_used_connections';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 18    |
+----------------------+-------+
1 row in set (0.00 sec)

一个 mysql 连接会占用多少内存

  • 空闲 (Idle)连接状态:2MB ~ 5MB,仅包含线程栈和基础缓冲区。
  • 普通查询连接状态:5MB ~ 10MB,包含了一些基础的读取缓冲区。
  • 重度查询连接状态(排序/大表关联):32MB ~ 128MB+,如果 SQL 写得烂,且 sort_buffer 设置得大,内存会迅速飙升。

关于作者 🌱

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式