`pt-kill` 的高级用法:基于正则表达式或阈值自动终止异常连接

🔪 pt-kill 高级用法:让问题连接“猝死”于黎明前

各位观众老爷们,大家好!我是你们的老朋友,人称“Bug终结者”的程序猿老王。今天,咱们来聊聊一个能让你在半夜安心睡觉,不用担心数据库被“熊孩子”连接拖垮的神器—— pt-kill

别看它名字带个“kill”,听起来血腥暴力,其实它是个温柔的“守护天使”,能帮你自动识别并“优雅地”终止那些“不听话”的连接,让你的数据库服务器永远保持最佳状态。

开场白:为什么我们需要 pt-kill

想象一下,凌晨三点,你正做着一夜暴富的美梦,突然被手机的报警声吵醒,迷迷糊糊一看,数据库CPU飙升到100%!你揉着惺忪睡眼,颤抖着手指登录服务器,发现罪魁祸首是一条执行了几个小时还没跑完的巨型SQL,或者是一堆长时间空闲的“僵尸”连接,霸占着宝贵的资源。

这种场景是不是很熟悉?

手动 kill 掉这些连接?效率太低,等你操作完,可能数据库都宕机了。而且,你不可能24小时盯着服务器啊!

这时候,pt-kill 就派上用场了。它就像一个尽职尽责的门卫,时刻监控着数据库的连接,一旦发现“可疑分子”,立刻采取行动,将它们“请”出去,确保数据库的安全和稳定。

pt-kill 基础回顾:先打好地基

在深入高级用法之前,我们先简单回顾一下 pt-kill 的基本用法,确保大家都在同一起跑线上。

pt-kill 是 Percona Toolkit 的一个组件,需要先安装 Percona Toolkit。安装方法根据你的操作系统而异,这里就不赘述了,请自行Google。

安装完成后,就可以开始使用 pt-kill 了。最简单的用法是:

pt-kill --kill --idle-time 300

这条命令会终止所有空闲时间超过 300 秒的连接。

  • --kill:表示执行 kill 操作。
  • --idle-time 300:表示空闲时间超过 300 秒的连接。

当然,pt-kill 还有很多其他选项,比如:

  • --match-user:匹配用户。
  • --match-host:匹配主机。
  • --match-db:匹配数据库。
  • --match-command:匹配命令类型(例如:Query, Sleep, Connect)。
  • --busy-time:匹配繁忙时间。
  • --match-info:匹配 SQL 语句。
  • --print:只打印要 kill 的连接,不实际执行 kill 操作。
  • --victims all:终止所有匹配的连接(默认只终止一个)。

更多选项可以参考 pt-kill --help

高级用法一:正则表达式,让匹配更精准

pt-kill 最强大的功能之一就是支持正则表达式。通过正则表达式,我们可以更精准地匹配到需要终止的连接,避免误杀。

例如,我们要终止所有执行 SELECT * FROM huge_table 语句的连接,可以使用以下命令:

pt-kill --kill --match-info 'SELECT * FROM huge_table'

但是,如果 SQL 语句稍微有些变化,比如大小写不同,或者多了几个空格,上面的命令就失效了。

这时候,正则表达式就派上用场了。我们可以使用以下命令:

pt-kill --kill --match-info '(?i)SELECTs+*s+FROMs+huge_table'
  • (?i):表示忽略大小写。
  • s+:表示一个或多个空格。
  • *:表示匹配 * 字符(需要转义)。

这条命令可以匹配到以下 SQL 语句:

  • SELECT * FROM huge_table
  • select * from huge_table
  • SELECT * FROM huge_table

是不是很强大?😎

再举个例子,我们要终止所有执行时间超过 600 秒,并且 SQL 语句中包含 JOIN 的连接,可以使用以下命令:

pt-kill --kill --busy-time 600 --match-info '(?i)JOIN'

表格:正则表达式常用元字符

元字符 描述
. 匹配任意单个字符,除了换行符。
* 匹配前面的字符零次或多次。
+ 匹配前面的字符一次或多次。
? 匹配前面的字符零次或一次。
^ 匹配字符串的开头。
$ 匹配字符串的结尾。
[] 匹配方括号中的任意一个字符。例如,[abc] 匹配 abc
[^] 匹配不在方括号中的任意一个字符。例如,[^abc] 匹配除了 abc 之外的任何字符。
d 匹配一个数字字符。等价于 [0-9]
D 匹配一个非数字字符。等价于 [^0-9]
w 匹配一个单词字符(字母、数字或下划线)。等价于 [a-zA-Z0-9_]
W 匹配一个非单词字符。等价于 [^a-zA-Z0-9_]
s 匹配一个空白字符(空格、制表符、换行符等)。
S 匹配一个非空白字符。
() 标记一个子表达式的开始和结束位置。子表达式可以被捕获并在后续使用。
| 或。匹配 | 前后任意一个表达式。例如,a|b 匹配 ab
转义字符。用于取消特殊字符的特殊含义。例如,* 匹配 * 字符。
{n} 匹配前面的字符恰好 n 次。例如,a{2} 匹配 aa
{n,} 匹配前面的字符至少 n 次。例如,a{2,} 匹配 aaaaa 等。
{n,m} 匹配前面的字符至少 n 次,但不超过 m 次。例如,a{2,4} 匹配 aaaaaaaaa

熟练掌握正则表达式,可以让你在 pt-kill 的世界里如鱼得水,精准打击。

高级用法二:基于阈值,让监控更智能

除了正则表达式,pt-kill 还可以基于阈值来终止连接。例如,我们可以设置一个阈值,当某个连接的 CPU 使用率超过 80% 时,就自动终止该连接。

但是,pt-kill 本身并没有直接提供 CPU 使用率的监控功能。我们需要借助其他工具,比如 pstop,来获取 CPU 使用率,然后将结果传递给 pt-kill

这里提供一个简单的脚本示例:

#!/bin/bash

while true
do
  # 获取 CPU 使用率超过 80% 的连接 ID
  PID=$(ps -eo pid,pcpu,comm | awk '$2 > 80 {print $1}')

  # 如果有连接的 CPU 使用率超过 80%,则终止该连接
  if [ -n "$PID" ]; then
    pt-kill --kill --busy-time 0 --match-pid "$PID"
    echo "Killed process with PID: $PID"
  fi

  # 每隔 5 秒执行一次
  sleep 5
done

这个脚本会不断循环,每隔 5 秒获取一次 CPU 使用率超过 80% 的连接 ID,然后使用 pt-kill 终止该连接。

  • ps -eo pid,pcpu,comm:获取进程 ID、CPU 使用率和命令。
  • awk '$2 > 80 {print $1}':过滤出 CPU 使用率超过 80% 的进程 ID。
  • pt-kill --kill --busy-time 0 --match-pid "$PID":终止指定 PID 的连接。
  • --busy-time 0 确保即使连接空闲也会被 kill。

当然,这只是一个简单的示例。你可以根据自己的实际需求,修改脚本,添加更多的监控指标和终止条件。

高级用法三:结合 pt-stalk,让排查更深入

pt-kill 主要负责“杀”,而 pt-stalk 则负责“查”。pt-stalk 可以在指定的时间点,收集数据库服务器的各种信息,包括进程列表、线程信息、内存使用情况等等。

我们可以将 pt-killpt-stalk 结合起来使用,当 pt-kill 终止某个连接时,同时使用 pt-stalk 收集服务器信息,方便后续排查问题。

例如,我们可以修改上面的脚本,添加 pt-stalk 的调用:

#!/bin/bash

while true
do
  # 获取 CPU 使用率超过 80% 的连接 ID
  PID=$(ps -eo pid,pcpu,comm | awk '$2 > 80 {print $1}')

  # 如果有连接的 CPU 使用率超过 80%,则终止该连接
  if [ -n "$PID" ]; then
    # 使用 pt-stalk 收集服务器信息
    pt-stalk --dest /tmp/stalk --pid "$PID" --iterations 1 --sleep 1

    pt-kill --kill --busy-time 0 --match-pid "$PID"
    echo "Killed process with PID: $PID"
  fi

  # 每隔 5 秒执行一次
  sleep 5
done
  • pt-stalk --dest /tmp/stalk --pid "$PID" --iterations 1 --sleep 1:收集指定 PID 的进程信息,保存到 /tmp/stalk 目录下,只收集一次,每次间隔 1 秒。

这样,每次 pt-kill 终止一个连接时,都会同时收集服务器信息,方便我们后续分析问题的原因。

表格:pt-stalk 常用选项

选项 描述
--dest 指定收集到的信息保存的目录。
--pid 指定要收集信息的进程 ID。
--iterations 指定收集信息的次数。
--sleep 指定每次收集信息之间的间隔时间(秒)。
--threshold 指定一个阈值,当满足该阈值时,才会收集信息。例如,--threshold=cpu=80 表示只有当 CPU 使用率超过 80% 时,才会收集信息。
--collect-stack 收集线程堆栈信息。
--mysql-status 收集 MySQL 状态信息。
--mysql-vars 收集 MySQL 变量信息。

注意事项:安全第一!

在使用 pt-kill 时,一定要注意安全,避免误杀。

  • 测试环境先行:在生产环境使用之前,一定要先在测试环境进行充分的测试。
  • 谨慎使用 --kill:在没有充分了解的情况下,不要轻易使用 --kill 选项。可以使用 --print 选项先查看要 kill 的连接,确认无误后再执行 kill 操作。
  • 设置合理的匹配条件:设置尽可能精确的匹配条件,避免误杀。
  • 监控 pt-kill 的运行状态:监控 pt-kill 的运行状态,确保它正常工作。

总结:pt-kill,你的数据库守护神

pt-kill 是一个非常强大的工具,可以帮助我们自动终止异常连接,保护数据库的稳定运行。通过结合正则表达式、阈值和 pt-stalk,我们可以构建一个智能的数据库监控和管理系统,让我们的数据库服务器永远保持最佳状态。

希望今天的分享对大家有所帮助。记住,熟练掌握 pt-kill,让你在深夜也能安然入睡,不再被数据库的“熊孩子”连接折磨!

最后,祝大家 Bug 越来越少,代码越来越漂亮!我们下期再见!👋

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注