一、问题描述
MySQL 客户端连接显示 1040 - Too many connetions,如下图所示:
二、排查思路
1、当MySQL报告连接数已满(Too many connections
)时,可以通过以下步骤排查问题:
1).查看MySQL的最大连接数配置:
SHOW VARIABLES LIKE 'max_connections';
2).如果设置的偏小,增大mysql连接数
SET GLOBAL max_connections = 新的连接数限制; 或者在my.cnf配置文件中更改最大可打开连接数后,重新启动mysql,使配置生效:
3) .如果设置的已经很大,仍然报错,需查看当前已经建立的连接数:
SHOW STATUS LIKE 'Threads_connected';
3).检查是否有大量挂起的连接或者长时间运行的查询:
SHOW PROCESSLIST;
4).查看连接到本机的具体数量:
netstat -an |grep "123.123.123.123" | wc -l
三、处理建议
1、通过排查确定具体连接的IP地址后,可以通过防火墙,将其隔离在外,防止进行访问
2、并排查此IP的来源,判定连接方是否为正常连接
3、如果为正常连接,需要通知相关干系人进行程序优化,通知其具体哪个用户、哪个数据库进行的连接
4、如果为非正常连接,需要排查其来源IP,并将其在核心入口处进行关闭。
四、命令详解
1、show processlist :show processlist
是显示数据库用户正在运行的线程(注意:1)除了root
用户能看到所有正在运行的线程外,其他用户都只能看到自己正在运行的线程,看不到其它用户正在运行的线程。除非单独个这个用户赋予了PROCESS
权限,2)show processlist
只显示前100条 我们可以通过show full processlist
显示全部)。
show processlist
显示的信息都是来自MySQL
系统库information_schema
中的processlist
表。所以使用下面的查询语句可以获得相同的结果
2、show processlist参数字段详解
参数 | 含义 |
---|---|
Id | 登录mysql后,系统分配的connection_id表示线程的唯一标识,可以使用函数connection_id()查看。当需要kill一个语句的时候会用到。前面我们说了show processlist显示的信息时来自information_schema.processlist表,所以这个Id就是这个表的主键。 |
User | 就是指启动这个线程的用户,如果是system user,它是指由服务器产生的非客户线程,以在内部处理任务。这可能是复制从站或延迟行处理程序使用的I/O或SQL线程。unauthenticated user指的是已经与客户端连接关联但是还没有完成客户机用户的认证的线程。event_scheduler指的是监视预定事件的线程。如果是system user那么在Host列中不会指定主机 。 |
Host | 记录了发送请求的客户端的IP和端口号。通过这些信息在排查问题的时候,我们可以定位到是哪个客户端的哪个进程发送的请求。 |
db | 当前执行的命令是在哪一个数据库上。如果没有指定数据库,则该值为 NULL 。 |
Command | 显示当前连接的执行的命令,一般就是休眠或空闲(sleep),查询(query),连接(connect)。这个很复杂,下面单独解释 |
Time | 表示该线程处于当前状态的时间,单位是秒。 |
State | 显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个 sql语句,已查询为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成 |
Info | 一般记录的是线程执行的语句。默认只显示前100个字符,也就是你看到的语句可能是截断了的,要看全部信息,需要使用 show full processlist。 |