点击上方“IT那活儿”,关注后了解更多精彩内容!!
一

问题描述
注:MySQL版本8.0.16
mysql的连接数是有上限,如果到达上限就会报错。报错信息如下:
ERROR 1203 (42000): User vvv already has more than 'max_user_connections' active connections
△上:单用户的连接数到达max_user_connections的值。
ERROR 1040 (HY000): Too many connections
△上:所有用户的连接总数到达max_connections的值。
△当连接返回这些报错的时候意味着数据库的连接数到达上限,新的连接请求是无法连接到数据库的。
注意:在连接数涨满之后,拥有all privileges权限的用户是可以连接数据库的。
二

解决方案
step1 首先查看mysql的max_connections,max_user_connections的值。

step2 可以看到Threads_connected的值已经到达连接数的上限。Threads_running的值为4说明所有连接都不是空闲连接。

step3 可以查看该值与max_user_connections/max_connections的差,如果差越小说明,大多数连接都在等待获取锁。

接下来我们着手解决问题。
step4 调整连接数上限
△一个连接本身只会占用少量的内存,关键还是看当前数据库的QPS/TPS是否接近压力测试的值。如果QPS/TPS并不高可以选择将连接数上限增大。
△如果thread_running的值与threads_connected相比非常的低说明大多数连接都是空闲连接,可以选择将连接数上限增大。
set global max_connections=40;set global max_user_connections=40;
△上:使用上面两条命令将数据库的连接数上限设置增大。
注意:如果数据库发生重启此次设置将会失效,要想永久生效需要在my.cnf文件当中将值写进去。
step5 调整超时时间
a. 连接超时
如果thread_running的值与threads_connected相比非常的低说明大多数连接都是空闲连接,可以选择将空闲连接的超时时间降低,快速释放连接。
set global wait_timeout=10;
△上:将非交互模式的空闲连接超时时间设置为10秒。
b. 锁等待超时
Innodb_row_lock_current_waits的值非常高可以说明有非常多的锁等待。可以进一步通过sys库的innodb_lock_waits视图来查看锁等待时间,通过设置锁等待超时将这些长时间等待的连接释放掉。

set global innodb_lock_wait_timeout=2;
△上:设置锁等待超时为一个较短的时间来释放连接数。
注意:如果数据库发生重启此次设置将会失效,要想永久生效需要在my.cnf文件当中将值写进去。
step6 杀死线程
△如果thread_running的值非常高,代表当前数据库繁忙。如果出现连接数满可以选择将执行时间长的线程杀掉,来释放连接。
pt-kill --busy-time 20 --host 192.168.56.11 --port 3306 --user=pt_test --password=pt_test --interval 1 --print --kill

△上:这里推荐使用precona公司的pt-kill工具来进行杀掉线程的工作。凡是执行时间超过20秒的线程就会被杀掉。
△pt-kill也可以用于杀死空闲连接以及针对特定的用户线程来进行查杀。
本 文 原 创 来 源:IT那活儿微信公众号(上海新炬王翦团队)






