pt-kill #
简介 #
pt-kill
- 终止符合特定条件的MySQL查询。
使用方法 #
pt-kill [OPTIONS] [DSN]
pt-kill
用于终止MySQL连接。pt-kill
会连接到MySQL,并从SHOW PROCESSLIST
获取查询信息(如果未指定FILE
)。如果提供了FILE
,它将从一个或多个包含SHOW PROCESSLIST
输出的FILE
中读取查询。如果FILE
为-
,则pt-kill
从标准输入(STDIN)读取内容。
终止运行时间超过60秒的查询:
1pt-kill --busy-time 60 --kill
打印(但不终止)运行时间超过60秒的查询:
1pt-kill --busy-time 60 --print
每10秒检查一次处于睡眠状态的并全部终止:
1pt-kill --match-command Sleep --kill --victims all --interval 10
--victims all
表示将所有匹配条件的都作为被终止的对象
打印所有登录进程:
1pt-kill --match-state login --print --victims all
查看当前进程列表中哪些查询符合条件:
1mysql -e "SHOW PROCESSLIST" > proclist.txt
2pt-kill --test-matching proclist.txt --busy-time 60 --print
描述 #
pt-kill
从SHOW PROCESSLIST
捕获查询,对它们进行过滤,然后选择终止或打印这些查询。在一些场合中,这也被形象地称为“慢查询狙击手”,意指精准定位并处理慢查询。其核心思想是监控可能消耗过多资源的查询,并将其终止。
为了简洁起见,讨论的是终止查询,但根据所提供的选项,查询也可能只是被打印(或者执行其他操作)。
通常,pt-kill
会连接到 MySQL,从SHOW PROCESSLIST
获取查询。或者,它也可以从文件中读取SHOW PROCESSLIST
的输出。在这种情况下,pt-kill
不会连接到MySQL,--kill
选项也不会生效。当读取文件时,应该使用--print
选项。使用--test-matching
读取文件的功能允许捕获 SHOW PROCESSLIST
的输出,并在稍后通过pt-kill
测试,确保匹配规则正确地终止相应查询。在使用过程中需要遵循许多特殊规则,例如“不要终止复制线程”,因此请务必小心避免终止重要进程!
使用该工具时,有两个关键选项尤为重要:--busy-time
和 --victims
。
--busy-time
:大多数匹配/过滤选项与SHOW PROCESSLIST
中对应的值进行匹配(例如,--match-command
会匹配查询的Command值),而--busy-time
则匹配Time
值。此外,请参见--interval
选项。--victims
:控制每个类别中哪些匹配查询会被终止。默认情况下,会终止具有最高Time
值的匹配查询(也就是最旧的查询)。有关更多细节,请参见下一节"GROUP、MATCH 和 KILL"。
通常情况下,需要指定至少一个--match
选项,否则不会匹配任何查询。或者,也可以指定 --match-all
来匹配所有未被 --ignore
选项忽略的查询。
GROUP, MATCH和KILL #
查询需要经过几个步骤来确定最终要终止(或打印)哪些查询。理解这些步骤将帮助我们精确匹配想要的查询。
- 第一步是将查询分组到类(classes)中。
--group-by
选项控制分组。默认情况下,此选项没有值,因此所有查询都分组到一个默认类中。所有类型的匹配和过滤(下一步)都是按类应用的。因此,可能需要对查询进行分组,以便匹配/过滤某些类,而不匹配/过滤其他类。 - 第二步是匹配。匹配意味着过滤,因为如果查询不符合某些标准,则会从其类中删除。匹配发生在每个类中。首先,通过各种“查询匹配”选项(如
--match-user
)从其类中过滤查询。然后,通过各种“类匹配”选项(如--query-count
)过滤整个类。 - 第三步是选择victim(受害者),即在每个类中要终止哪些匹配的查询。这由
--victims
选项控制。虽然一个类中可能有许多查询匹配,但你可能只想终止最旧的查询,或所有查询等。 - 第四个也是最后一个步骤是对所有类中的所有匹配查询执行某些操作。“操作”选项指定将执行哪些操作。在此步骤中,不再有类,只有一个要终止、打印等的查询列表。
pt-kill
将终止匹配任何指定条件(逻辑或)的所有查询。例如,使用:
1--busy-time 114 --match-command 'Query|Execute'
将终止所有busy-time > 114
或命令为Query
或Execute
的查询。
如果只想终止busy-time>114
且命令为Query
或Execute
的查询,则需要使用–kill-busy-commands
:
1--busy-time 114 --kill-busy-commands 'Query|Execute'
OUTPUT #
如果只给出--kill
,则没有输出。如果只给出--print
,则会为每个本应被终止的查询打印一个带时间戳的KILL语句,例如:
# 2009-07-15T15:04:01 KILL 8 (Query 42 sec) SELECT * FROM huge_table
该行显示了时间戳、查询的ID (8)、其Time (42 sec) 和其Info(通常是查询 SQL)。
如果同时给出 --kill
和 --print
,则会终止匹配的查询,并为每个查询打印一行,如上所示。
由--execute-command
执行的任何命令都负责其自身的输出和日志记录。执行后,pt-kill
不再控制或与其交互。
OPTIONS #
具体OPTIONS见的OPTIONS。
下面列出一些常用的,且前面的内容中没有介绍的:
--ask-pass
连接到 MySQL 时提示输入密码。
--log-dsn
参数类型:DSN。将每个被终止的查询存储在这个DSN中。
该参数指定一个用于存储所有被终止查询的表。传入的DSN必须包含数据库 (D) 和表 (t) 选项。该表必须至少包含以下列。可以为了特殊目的添加更多列,但它们不会被pt-kill
使用。以下CREATE TABLE
定义也用于 --create-log-table
。
1CREATE TABLE kill_log (
2 kill_id int(10) unsigned NOT NULL AUTO_INCREMENT,
3 server_id bigint(4) NOT NULL DEFAULT '0',
4 timestamp DATETIME,
5 reason TEXT,
6 kill_error TEXT,
7 Id bigint(4) NOT NULL DEFAULT '0',
8 User varchar(16) NOT NULL DEFAULT '',
9 Host varchar(64) NOT NULL DEFAULT '',
10 db varchar(64) DEFAULT NULL,
11 Command varchar(16) NOT NULL DEFAULT '',
12 Time int(7) NOT NULL DEFAULT '0',
13 State varchar(64) DEFAULT NULL,
14 Info longtext,
15 Time_ms bigint(21) DEFAULT '0', # NOTE, TODO: currently not used
16 PRIMARY KEY (kill_id)
17) DEFAULT CHARSET=utf8
--match-info
参数类型:字符串;组:查询匹配(Query Matches)
仅匹配processlist的Info与此Perl正则表达式匹配的查询。
processlist的Info列显示正在执行的查询,如果没有正在执行的查询,则显示NULL。
例如: --match-info="(?i-xsm:select)"
--match-user
类型:字符串;组:查询匹配
仅匹配User与此Perl正则表达式匹配的查询。
例如: "--match-user="user1|user2"
--match-host
类型:字符串;组:查询匹配
仅匹配Host与此Perl正则表达式匹配的查询。
Host值通常包含端口,“host:port”。
实用示例 #
打印超过5秒的select #
1pt-kill --match-info="(?i-xsm:select)" \
2 --busy-time 5s --victim all --interval 2\
3 --print \
4 h='127.0.0.1',u='<user>',p='<pwd>',P=3306
1pt-kill --match-info="(?i-xsm:select)" --match-user="<user>" \
2 --busy-time 5s --victim all --interval 2\
3 --print \
4 --ask-pass \
5 h='127.0.0.1',u='<user>',P=3306
kill超过5秒的select #
注意可能会造成误杀
1
2
3pt-kill --match-info="(?i-xsm:select)" \
4 --busy-time 5s --victim all --interval 3 \
5 --kill --print \
6 --ask-pass \
7 h='127.0.0.1',u='<user>',P=3306
1pt-kill --match-info="(?i-xsm:select)" --match-user="<user>" \
2 --busy-time 5s --victim all --interval 3 \
3 --kill --print \
4 --ask-pass \
5 h='127.0.0.1',u='<user>',P=3306
后台运行 #
1pt-kill --match-info="(?i-xsm:select)" --match-user="<user>" \
2 --busy-time 5s --victim all --interval 3 \
3 --kill --print \
4 --daemonize --log ~/kill.log \
5 --ask-pass \
6 h='127.0.0.1',u='<user>',p='<pwd>',P=3306