3

pt-kill 输出信息优化

 1 year ago
source link: https://blog.51cto.com/lee90/5804617
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

pt-kill 输出信息优化

精选 原创

我的二狗呢 2022-10-28 13:54:19 博主文章分类:MySQL ©著作权

文章标签 pt-kill mysql 文章分类 Linux 系统/运维 阅读数159

默认情况下,pt-kill (3.3.1版本) 的执行记录如果是输出到log文件的话,日志里面是不会带上 库名、客户端地址的,类似如下:

pt-kill 输出信息优化_mysql

我们可以简单修改下代码, 让其支持该属性的输出。

$ cd /usr/bin/

$ pt-kill --version
pt-kill 3.3.1

$ cp pt-kill pt-kill_20221028_bak

修改前:
foreach my $query ( @queries ) {
if ( $o->get('print') ) {
printf "# %s %s %d (%s %d sec) %s\n",
ts(time), $o->get('kill-query') ? 'KILL QUERY' : 'KILL',
$query->{Id}, ($query->{Command} || 'NULL'), $query->{Time},
($query->{Info} || 'NULL');
}
if ( $o->get('query-id') ) {
my $fp = $qr->fingerprint($query->{'Info'});
my $chksm = Transformers::make_checksum($fp);
print "Query ID: 0x$chksm\n";
}

修改后:
if ( $o->get('print') ) {
printf "# 检测时间: %s ,操作类型: %s ,Query_Id: %d ,用户名: %s ,客户端地址: %s ,库名: %s (%s %d sec) ,SQL明细: %s\n",
ts(time), ($o->get('kill-query') ||$o->get('kill')) ? 'KILL QUERY OR KILL' : 'ONLY_PRINT',
$query->{Id},$query->{User},$query->{Host},($query->{db} ? $query->{db} :'none'),($query->{Command} || 'NULL'), $query->{Time},
($query->{Info} || 'NULL');
}
if ( $o->get('query-id') ) {
my $fp = $qr->fingerprint($query->{'Info'});
my $chksm = Transformers::make_checksum($fp);
print "Query ID: 0x$chksm\n";
}
pt-kill 输出信息优化_pt-kill_02

修改完成后,我们执行下pt-kill命令,如下(演示的过滤条件很暴力):

pt-kill u=dts,h=192.168.31.181,p='dts' --match-info "^(select)" --victims=all --busy-time 1 --interval 1 --no-version-check  --print --kill --match-user "dts"

在控制台的日志大致如下:

pt-kill 输出信息优化_pt-kill_03

生产上,我们通常还会把kill的记录存到表里面,只要额外配置个库表,加点配置如下:

pt-kill u=dts,h=192.168.31.181,p='dts' --match-info "^(select)" --victims=all --busy-time 1 --interval 1 --no-version-check  --print --kill --log-dsn=h=192.168.31.181,u=dts,p='dts',P=3306,D=percona,t=kill_log --match-user "dts"

需要确保这个dsn上的kill_log表是存在的,建表语句如下:

create database percona;

use percona;

CREATE TABLE `kill_log` (
`kill_id` int unsigned NOT NULL AUTO_INCREMENT,
`server_id` bigint NOT NULL DEFAULT '0',
`timestamp` datetime DEFAULT NULL,
`reason` text,
`kill_error` text,
`Id` bigint NOT NULL DEFAULT '0',
`User` varchar(16) NOT NULL DEFAULT '',
`Host` varchar(64) NOT NULL DEFAULT '',
`db` varchar(64) DEFAULT NULL,
`Command` varchar(16) NOT NULL DEFAULT '',
`Time` int NOT NULL DEFAULT '0',
`State` varchar(64) DEFAULT NULL,
`Info` longtext,
`Time_ms` bigint DEFAULT '0',
PRIMARY KEY (`kill_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

kill_log表里面记录类似如下:

pt-kill 输出信息优化_pt-kill_04

经测试,发现 只有当存在 --kill 参数的情况下(即 --print --kill 或者单独的--kill),记录才会存到kill_log数据表里面。但是只要存在--print参数,不管是否有--kill参数,巡检记录都会输出到控制台日志。

在翻看代码的过程中,看到它是通过show full processlist 拿到数据后,在pt-kill内部处理的,而不是通过生产查询sql去查库,避免对数据库造成压力。 如果说不足的话,那就是还缺少一个IM告警的功能,这可能是为了工具的轻量化。

总的而言,pt-kill 可以满足日常的使用的,后续我们可以参考pt-kill的实现思路,用python重构一下增加IM告警能力。

  • 打赏
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK