使pt-kill和pt-query-digest工具兼容TiDB

MySQL DBA 对 percona toolkit再熟悉不过了,其中pt-kill和pt-query-digest是日常运维中经常使用到的工具。但是这些原生工具对TiDB兼容性不是特别好,限制了在TiDB上的使用我们对pt-kill和pt-query-digest进行了简单的修改,使其能够在TiDB上正常使用,不需要再重新造轮子,大大降低了TiDB运维人员的学习成本。我们将修改后的工具放到了GitHub上,方便大家更好的运维TiDB,为TiDB社区贡献一份力量。接下来会简单介绍这两个工具使用方法。

pt-kill工具用来批量kill指定条件的数据库中的连接,从而达到过载保护作用。该工具会发送KILL xxx 语句来实现该功能,但是TiDB默认情况下参数compatible-kill-query为false,即KILL xxx不起作用,需要发送KILL TiDB xxx才实际起作用。TiDB这样的设计充分考虑了当使用负载均衡或代理连接TiDB时,当用户按下Ctrl+C时,会导致误杀其他连接的问题。而然,这样的设计,也导致了TiDB默认参数情况下,pt-kill工具失效。

因此我们修改了pt-kill,增加了参数–tidb,当需要KILL TiDB上的连接时,只需要添加该参数,pt-kill便会发送KILL TIDB xxx命令,从而可以KILL掉TiDB上的指定连接。当然,为了防止误杀其他连接,pt-kill也需要直连TiDB使用。由于pt-kill工具大家非常了解,且网上用法的介绍非常多,下面仅简单列举一个使用例子:

##按照执行时间kill, 杀掉执行时间超过5秒的所有查询
pt-kill 
--no-version-check 
--host 127.0.0.1 
--charset utf8 
--match-command Query 
--busy-time 5 
--kill 
--victims all 
--interval 10 
--tidb 

pt-query-digest工具是用来分析MySQL日志的首选工具,一些有名的慢日志系统也基于该工具开发。然而,TiDB(3.0.0)的慢日志记录的时间格式与MySQL格式略有不同,因此该工具也无法正常的分析TiDB的慢日志。

-- TiDB 3.0.0 slow log 格式
# Time: 2019-05-24-11:33:43.112342888 +0800
# Txn_start_ts: 0
# User: admin@127.0.0.1
# Conn_ID: 810559
# Query_time: 10.000232849
# DB: test
# Is_internal: false
# Digest: b4dae6a771c1d84157dcc302bef38cbff77a7a8ff89ee38302ac3324485454a3
select sleep(10);

-- MySQL5.7  slow log 格式
# Time: 2019-05-24T03:58:59.355559Z
# User@Host: root[root] @ localhost []  Id:  2222
# Query_time: 0.000033  Lock_time: 0.000000 Rows_sent: 0  Rows_examined: 0
SET timestamp=1556078339;

虽然TiDB也支持了一些查看慢日志的方法,诸如内存表,和一些admin命令,如下所示。但是远远没有pt-query-digest功能强大。

## 查询内存表
/* 查询所有用户执行的SQL,且按执行消耗时间排序 */
tidb > select `Query_time`, query from INFORMATION_SCHEMA.`SLOW_QUERY` where `Is_internal`=false order by `Query_time` desc limit 2;
+--------------+------------------------------------------------------------------+
| Query_time   | query                                                            |
+--------------+------------------------------------------------------------------+
| 12.77583857  | select * from t_slim, t_wide where t_slim.c0=t_wide.c0;          |
|  0.734982725 | select t0.c0, t1.c1 from t_slim t0, t_wide t1 where t0.c0=t1.c0; |
+--------------+------------------------------------------------------------------+
2 rows in set
Time: 0.012s

## 使用admin命令
admin show slow recent N
admin show slow top [internal | all] N
admin show slow recent 10

因此,我们对pt-query-digest进行了简单修改,使其兼容了TiDB(3.0.0+)的慢日志,从而可以像分析MySQL慢日志一样分析TiDB(3.0.0+)慢日志。同样,pt-query-digest工具大家已经非常熟悉,且网上用法的介绍非常多,下面仅简单列举几个使用例子:

# 直接分析慢查询
pt-query-digest slow.log > result.log

# 最近12小时
pt-query-digest  --since=12h  slow.log > result.log

# 时间范围
pt-query-digest slow.log --since '2019-06-18 09:30:00' --until '2019-06-18 10:00:00' > result.log

# 按照SQL类型查询
pt-query-digest --filter '$event->{fingerprint} =~ m/^select/i' slow.log > result.log

# 按用户查询
pt-query-digest --filter '($event->{User} || "") =~ m/^superadmin/i'  test.log > slow.log

# 只查询客户端发送的SQL
pt-query-digest --filter '($event->{Is_internal} || "") =~ m/^false/i'  test.log > slow.log

# 访问特定DB的SQL
pt-query-digest --filter '($event->{DB} || "") =~ m/^test1/i'  test.log > slow.log

# 某个连接发送过来的SQL
pt-query-digest --filter '($event->{Conn_ID} || "") =~ m/^810559/i'  test.log > slow.log

# 查看属性信息
pt-query-digest test.log --filter 'print Dumper $event' --no-report

## 输出json (可以分析是否一条SQL走了不同的索引等等)
pt-query-digest test.log --output=json

更详细的用法,详见GitHub,地址:https://github.com/MyTiDBA/TiDB-toolkit

欢迎大家使用和交流~

3赞

:+1::+1::+1:

1赞

:+1: :+1: :+1:

太给力了,疯狂点赞:+1:

干得漂亮!

功德无量!

:+1::+1::+1: