查看 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式