使用tcpdump 抓包功能 跟踪mysql sql语句执行速度

之前写过一个mysql 5.6如何跟踪在毫秒级记录sql日志的问题,当时是通过为输出全局日志加时间的方式来实现的,不是很精确。采用tcpdump的方式从网络层抓包记录的时间更精确。而且还有ip和端口记录

原理

使用tcpdump的网络抓包功能,从mysql客户端和服务器交互的网络数据中,直接输出sql语句,和网络包的相关信息。

实现功能

1、跟踪sql语句

可以输出所有客户端请求的sql

2、记录sql语句时间

可以输出微秒级的时间

3、分析sql语句的请求和应答时间

通过跟踪同一个原端口发送sql语句和接收数据包的间隔,可以实时跟踪分析sql语句的执行时间。与mysql profiling相比可以实时跟踪程序实际执行情况。

4、确认发起sql语句的进程

可以根据客户端源端口结合在客户端执行lsof 命令确认发起sql的进程

 

 

前提

mysql客户端和服务器之间不要开启加密传输,一般内网都不开。
在服务器有tcpdump权限

实现方式

使用perl写的解析脚本,直接帖就可以用,不需要保存。

#只输出sql
tcpdump -i eth1 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
    if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL)/i)
    {
        if (defined $q) { print "$q\n"; }
        $q=$_;
    } else {
        $_ =~ s/^[ \t]+//; $q.=" $_";
    }
}'

#记录时间,源和目的ip地址端口,tcp标志和sql
tcpdump -i eth0 -Annn -s 0 -l port 3306 | strings | perl -e '
while(<>) { 
    chomp;
    if(/^\d\d:\d\d:\d\d.\d{6} IP.+$/){
        print "\n$_\t";
    }
    if(/((SELECT|UPDATE|DELETE|INSERT|SET |COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL).+$)/i)
    {
        print "$1";
    }else{
    } 
}'

进阶

如果想更进一步解析,可以参考 https://github.com/nlitsme/xpcapperl 的项目 或者用perl的cpan包
Net::Packet::Dump
Net::Analysis
Net::TcpDumpLog
我简单搜了一下,这几个都可以试试。

© 2018, 新之助meow. 原创文章转载请注明: 转载自http://www.xinmeow.com

0.00 avg. rating (0% score) - 0 votes
点赞