运行平稳的数据库,如果遇到CPU狂飙,那很大可能就是慢SQL出现了。DBA首先要保证的是,数据库别跑挂了,所以我们要把那些运行慢的SQL杀死并记录到文件里,以便后面的排查。对于OLTP型业务,主库SELECT类SQL执行不允许超过1s才是合理的;那么对于超过1s的SQL或者对微延迟可以接受查询,理应在从库或者多源库上执行。
那么Percona Tools工具包中也提供了这么一个可以帮你解决这类问题的工具,就是pt-kill。此工具提供了超多选项,其原理就是连接到MySQL并从SHOW PROCESSLIST获取查询并进行过滤,然后执行kill或print动作。需要注意一点的是,在使用pt-kill时,有许多特殊规则要遵循,例如“不要杀死复制线程”,所以要小心不要杀死重要的连接。默认会过滤掉复制线程,请不必担心杀掉复制线程。
其实使用pt-kill大多数情况下,只是想为我们干掉超过一定阈值的SELECT查询并且打印出来(存储到文件或者数据库中),对于DML或者DDL并没有这方面的需求。对于被干掉的SQL可以再做一定的处理,比如报警给相关研发,督促业务改进。
下面是一个以不区分大小写,且以select为前缀的过滤条件来做超时kill。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ pt-kill \ --host=10.10.0.109 \ --port=3306 \ --user=root \ --password=123456 \ --busy-time 5 \ --match-command="Query|Execute" \ --ignore-user="system user" \ --match-info="(?i-xsm:^(select))" \ --victim all \ --interval 1 \ --kill \ --ignore-self \ --print \ --log=/tmp/pt-kill.log |
简单介绍一些相关参数,关于更多详细的参数说明还是看官方网站吧。
批次查询已运行的时间超过这个时间的线程;这里的批次是指pt-kill支持分组处理,如果没有分组那么这里的时间就是单个线程运行的时间。
--match-command
过滤匹配SHOW PROCESSLIST对应的Command字段相关状态的进程,常见状态有Query、Sleep、Binlog Dump、Connect、Delayed insert、Execute、Fetch、Init DB、Kill、Prepare、Processlist、Quit、Reset stmt、Table Dump。与此选项对应的还有--ignore-command
,顾名思义就是匹配相关状态的进程。
--ignore-user
过滤忽略User字段相关用户的进程。与此选项对应的还有--match-user
,顾名思义就是匹配相关用户的进程。
--match-info
过滤匹配Info字段相关的进程,可以使用select、update、insert、delete来进行匹配,并可使用”|”进行多项匹配,如”select|SELECT|delete|DELETE|update|UPDATE”。
默认严格所有选项都是严格区分大小写,但是通过指定像(?i-xsm:select)
这样的正则表达式模式可以使它们不区分大小写,以我上面这种模式写的正则规则 (?i-xsm:^(select))
表示的就是不区分大小写,且以不区分大小写的select开头的查询才匹配。
--daemonize
在后台以守护进程的方式运行。
--victim
用来决定kill那种线程, 默认值为oldest,只杀最老的查询(最先发起的)。这是防止被查杀是不是真的长时间运行的查询,他们只是长期等待。这种匹配按时间查询,杀死一个时间最高值。值为all表示杀掉所有满足的线程;值为all-but-oldest表示杀死所有,但时间最长的保留不杀。
--interval
运行检查query的间隔时间,可以根据实际情况调整。如果不加,只执行一次;加上的话,会在后台不停的执行。
--print
打印满足条件的语句。
--kill
杀死满足条件的语句。加了print后,并且会把杀死的SQL打印出来。
--log
存储满足条件的SQL语句,无论是被kill的还是print的。
最后有个问题没解决,使用发现对于Execute状态的查询pt-kill无法生效,对Query状态的没有问题。目前还不知道什么问题,有知道的麻烦告知一下,谢谢。
也就是这个问题,导致我没法真正使用pt-kill工具。然后自己参考pt-kill使用Python写了一个类似的工具,支持多线程,暂时命名为py-kill,哈哈。代码https://github.com/dongwenpeng/py-kill,需要的可以简单定制化一下。
<参考>
https://github.com/dongwenpeng/py-kill
https://www.percona.com/doc/percona-toolkit/LATEST/pt-kill.html