1.事情的起源
项目在跑的过程中,突然间报没有可用的连接数。这个时候,服务进程还在,但是只要涉及到数据库的操作都会报错。
2.排查的思路
事件发生后,我们重启服务,监控的Connections数是258个,某台机器就集中了100个线程。在这个过程大概是允许了5天就挂了,这里有一个规律,就是线程是慢慢衰减下去,一直Connections到151,这个时候,08号机器就相当于完全使用不了。
2.1.查询mysql的所有线程
使用超级管理员,通过 information_schema库,然后sql去查询,就能查询mysql的所有的线程:
select * from `PROCESSLIST` e where e.db='fsmp_iot' and e.TIME>0;
可以从查询的数据中,看到连接到具体的数据库中所有的线程数。我们可以观察这些线程数会不会无故消失。消失就代表代码里是有问题的。
2.2.在数据库中具体的线程都操作了哪些sql?
使用超级管理员,通过 performance_schema库,然后sql去查询:
SELECT * FROM threads WHERE PROCESSLIST_ID=3956298;
注意:PROCESSLIST_ID 是PROCESSLIST表中的ID。
2.3. 按客户端 IP 分组,看哪个客户端的链接数最多。
select client_ip,count(client_ip) as client_num from (select substring_index(host,':' ,1) as client_ip from information_schema.processlist ) as connect_info group by client_ip order by client_num desc;
2.mysql本身的存活时间
mysql本身的线程的最大存活时间,默认是8个小时(28800秒),现在已经有一个进程存活了6.7小时了(24343秒 ID:8505094),得出的结果:线程池中创建的线程,然后不能释放掉,重新创建,导致了自创建后,8个小时候,自动被mysql释放掉。然后线程就不断减少,最终没有线程可用。
(目前发现了两个问题:一个是线程创建的存活时间:我们配置了是500秒也就是8分多钟,但官网给出,默认都是30分钟;第二个问题: keepAliveTime 这个参数,默认系统是0,就是没有去扫描,这个值要去配置)