当前位置: 首页 > 科技观察

MySQL链接查杀方法全集

时间:2023-03-11 23:44:54 科技观察

前言:在数据库运维过程中,我们经常会关注数据库链接的状态,比如总共有多少链接,有多少活跃链接是否存在,是否存在执行时间过长的链接。数据库的各种异常也可以通过连接状态间接反映出来,尤其是当数据库出现死锁或者严重卡顿的时候,首先要检查数据库是否存在异常连接,将这些异常连接kill掉。本文将主要介绍如何查看数据库链接以及如何杀死异常链接。1、查看数据库链接查看数据库链接最常用的语句是showprocesslist。该语句可以查看数据库中存在的线程状态。普通用户只能查看当前用户发起的链接,具有PROCESS全局权限的用户可以查看所有用户的链接。showprocesslist结果中的Info字段只显示每条语句的前100个字符,如果需要显示更多信息,可以使用showfullprocesslist。同样,查看information_schema.processlist表可以看到数据库链接状态信息。#普通用户只能看到当前用户发起的链接mysql>selectuser();+--------------------+|user()|+------------------+|testuser@localhost|+----------------+1rowinset(0.00sec)mysql>showgrants;+--------------------------------------------------------------------+|Grantsfortestuser@%|+--------------------------------------------------------------------+|GRANTUSAGEON*.*TO'testuser'@'%'||GRANTSELECT,INSERT,UPDATE,DELETEON`testdb`.*TO'testuser'@'%'|+------------------------------------------------------------------+2rowsinset(0.00sec)mysql>showprocesslist;+--------+--------+-----------+------+--------+------+----------+-----------------+|Id|User|Host|db|Command|Time|State|Info|+--------+--------+-----------+--------+--------+------+--------+------------------+|769386|testuser|localhost|NULL|Sleep|201||NULL||769390|testuser|localhost|testdb|Query|0|starting|showprocesslist|+--------+------------+------------+--------+--------+------+----------+------------------+2rowsinset(0.00sec)mysql>select*frominformation_schema.processlist;+--------+--------+-----------+--------+--------+------+------------+-------------------------------------------+|ID|USER|HOST|DB|命令|时间|状态|信息|+--------+--------+------------+--------+----------+--------+------------+------------------------------------------+|769386|testuser|localhost|NULL|Sleep|210||NULL||769390|testuser|localhost|testdb|Query|0|executing|select*frominformation_schema.processlist|+------+----------+----------+--------+------------+------+------------+---------------------------------------------+2rowsinset(0.00sec)#授予PROCESS权限后,可以看到所有用户链接mysql>grantprocesson*.*to'testuser'@'%';QueryOK,0rowsaffected(0.01sec)mysql>flushprivileges;QueryOK,0rowsaffected(0.00sec)mysql>showgrants;+-----------------------------------------------------------------------+|Grantsfortestuser@%|+-------------------------------------------------------------------+|GRANTPROCESSON*.*TO'testuser'@'%'||GRANTSELECT,INSERT,UPDATE,DELETEON`testdb`.*TO'testuser'@'%'|+----------------------------------------------------------------+2rowsinset(0.00sec)mysql>showprocesslist;+--------+-----------+------------------+--------+--------+--------+--------+----------------+|Id|User|Host|db|Command|Time|State|Info|+--------+------------+--------------------+--------+---------+------+------------+----------------+|769347|root|localhost|testdb|睡眠|53||NULL||769357|root|192.168.85.0:61709|NULL|睡眠|521||NULL||769386|testuser|localhost|NULL|睡眠|406||NULL||769473|testuser|localhost|testdb|Query|0|starting|showprocesslist|+--------+--------+------------------+--------+--------+-----+--------+-------------------+4rowsinset(0.00sec)通过showprocesslist的结果,我们可以清楚的了解到每个线程链接的详细信息。具体字段的含义比较容易理解。下面我详细解释一下每个字段代表的含义:Id:是这个链接的唯一标识,用kill命令加上这个Id值就可以杀掉这个链接。用户:指发起该链接的用户名。Host:记录了发送请求的客户端的IP和端口号,可以定位到是哪个客户端的哪个进程发送了请求。db:当前正在执行的命令在哪个数据库上。如果未指定数据库,则值为NULL。命令:指线程链接此刻正在执行的命令。时间:表示线程链接处于当前状态的时间。State:线程的状态,对应Command。Info:记录线程执行的具体语句。当数据库链接过多时,过滤有用信息就变得很麻烦。例如,我们只想查看某个用户或某个状态的链接。这时候使用showprocesslist会发现一??些我们不需要的信息。这时候使用information_schema.processlist来过滤就会变得简单很多。下面是一些常见的过滤需求:#只查看某个ID的链接信息select*frominformation_schema.processlistwhereid=705207;#过滤掉某个用户的链接select*frominformation_schema.processlistwhereuser='testuser';#过滤掉所有非空闲链接select*frominformation_schema.processlistwherecommand!='Sleep';#过滤出空闲时间在600秒以上的链接select*frominformation_schema.processlistwherecommand='Sleep'andtime>600;#筛选出某个状态下的链接select*frominformation_schema.processlistwherestate='Sendingdata';#筛选出某个客户端IP的链接select*frominformation_schema.processlistwherehostlike'192.168.85.0%';2、杀死数据库连接如果数据库连接异常,我们可以通过kill语句杀死连接。kill的标准语法是:KILL[CONNECTION|QUERY]processlist_id;KILL允许使用可选的CONNECTION或QUERY修饰符:KILLCONNECTION与不带修饰符的KILL相同,它将终止进程相关链接。KILLQUERY终止链接当前正在执行的语句,但保持链接本身不变。是否能杀链接取决于SUPER权限:没有SUPER权限,只能杀掉当前用户发起的链接。具有SUPER权限的用户可以杀死所有链接。在紧急情况下,需要批量kill链接时,可以通过拼接SQL获取kill语句,然后执行,会方便很多。分享几个可能用来杀链接的SQL:#杀掉空闲时间超过600秒的链接,拼接得到kill语句selectconcat('KILL',id,';')frominformation_schema.`processlist`wherecommand='sleep'andtime>600;#kill某个状态下的链接,拼接得到kill语句selectconcat('KILL',id,';')frominformation_schema.`processlist`wherestate='Sendingdata';selectconcat('KILL',id,';')frominformation_schema.`processlist`wherestate='Waitingfortablemetadatalock';#kill一个用户发起拼接得到kill语句selectconcat('KILL',id,';')frominformation_schema.`processlist`user='testuser';这里提醒一下,kill语句一定要慎用!特别是这个链接执行update语句或者表结构改变语句的时候,kill掉这个链接回滚操作可能需要很长时间。摘要:本文介绍如何查杀数据库链接。如果怀疑数据库有问题,可以第一时间检查数据库链接。