使用 mysql-sniffer 查看MySQL当前执行的语句

MySQL
前言

在某些特定的问题排查场景下,或者需要复现问题,我们可能需要开启general log 来查看 MySQL 实时运行的 SQL 语句,以此来缩小问题的范围。general log 会记录所有的SQL语句,无论语句是否正确执行或者是由于语法错误而终止执行。同时开启 general log 在实例负载比较大的情况下了能会对服务器性能产生影响,这里推荐一个好用的工具,它基于 MySQL 协议的抓包工具,实时抓取 MySQL Server 端的请求,并格式化输出。

工具安装

安装必要的依赖

yum install gcc gcc-c++ cmake libpcap-devel glib2-devel libnet-devel -y

安装命令

git clone https://github.com/Qihoo360/mysql-sniffer.git

cd mysql-sniffer

(base) [root@ip-10-0-0-22 mysql-sniffer]# ll
total 20
-rw-r--r-- 1 root root  272 Jan 23 08:58 CMakeLists.txt
drwxr-xr-x 2 root root   20 Jan 23 08:58 include
drwxr-xr-x 2 root root  126 Jan 23 08:58 lib
drwxr-xr-x 4 root root  321 Jan 23 08:58 libnids-1.24
-rw-r--r-- 1 root root 1066 Jan 23 08:58 LICENSE
drwxr-xr-x 4 root root  100 Jan 23 09:01 proj
-rw-r--r-- 1 root root 4298 Jan 23 08:58 README_CN.md
-rw-r--r-- 1 root root 2611 Jan 23 08:58 README.md
drwxr-xr-x 2 root root  242 Jan 23 09:01 src

(base) [root@ip-10-0-0-22 mysql-sniffer]# cd src/

(base) [root@ip-10-0-0-22 src]# ls
CMakeLists.txt  mysql-dissector.c  session.cpp  sniff-config.cpp  sniff-log.cpp  util.c
main.c          mysql-dissector.h  session.h    sniff-config.h    sniff-log.h    util.h

修改 CMakeLists.txt


ADD_EXECUTABLE(mysql-sniffer ${SRC_LIST})
TARGET_LINK_LIBRARIES(mysql-sniffer optimized
    libnidstcpreasm.a
    libpthread.so.0 #添加这一行
    libnet.a 
    libpcap.a
    libglib-2.0.a 
    libgthread-2.0.a
    librt.so)
   
TARGET_LINK_LIBRARIES(mysql-sniffer debug
    libnidstcpreasm-dbg.a
    libpthread.so.0 #添加这一行
    libnet.a 
    libpcap.a
    libglib-2.0.a
    libgthread-2.0.a
    librt.so)

然后执行下面的命令:


mkdir proj

cd proj

cmake ../

make

如何使用

查看帮助

(base) [root@ip-10-0-0-22 bin]# pwd
/root/mysql-sniffer/proj/bin

(base) [root@ip-10-0-0-22 bin]# ./mysql-sniffer -h
Usage ./mysql-sniffer [-d] -i eth0 -p 3306,3307,3308 -l /var/log/mysql-sniffer/ -e stderr
         [-d] -i eth0 -r 3000-4000
         -d daemon mode.
         -s how often to split the log file(minute, eg. 1440). if less than 0, split log everyday
         -i interface. Default to eth0
         -p port, default to 3306. Multiple ports should be splited by ','. eg. 3306,3307
            this option has no effect when -f is set.
         -r port range, Don't use -r and -p at the same time
         -l query log DIRECTORY. Make sure that the directory is accessible. Default to stdout.
         -e error log FILENAME or 'stderr'. if set to /dev/null, runtime error will not be recorded
         -f filename. use pcap file instead capturing the network interface
         -w white list. dont capture the port. Multiple ports should be splited by ','.
         -t truncation length. truncate long query if it's longer than specified length. Less than 0 means no truncation
         -n keeping tcp stream count, if not set, default is 65536. if active tcp count is larger than the specified count, mysql-sniffer will remove the oldest one

实时抓取某端口信息并打印到屏幕

(base) [root@ip-10-0-0-22 bin]# ./mysql-sniffer -i eth0 -p 3306

查看 MySQL 中真实执行的SQL 语句

mysql> shw databases; # 即使错误的语句也会被记录
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'shw databases' at line 1
mysql> show databases;
+-----------------------+
| Database              |
+-----------------------+
| information_schema    |
| dr                    |
| geek                  |
| mydumper              |
| mysql                 |
| performance_schema    |
| rudonx                |
+-----------------------+
7 rows in set (0.04 sec)

mysql> use rudonx
Reading table information for completion of table 
……


Database changed
mysql> show tables;
+------------------+
| Tables_in_rudonx |
+------------------+
| gk_37            |
| rudonx           |
| t1               |
| t11              |
| test             |
+------------------+
5 rows in set (0.04 sec)

查看 sniffer 输出

2022-01-23 17:50:36      rudonx  10.0.0.22       NULL            34ms             1      select @@version_comment limit 1
2022-01-23 17:50:47      rudonx  10.0.0.22       NULL            34ms             0      shw databases
2022-01-23 17:50:51      rudonx  10.0.0.22       NULL            35ms            12      show databases
2022-01-23 17:50:55      rudonx  10.0.0.22       NULL            35ms             1      SELECT DATABASE()
2022-01-23 17:50:55      rudonx  10.0.0.22       rudonx          34ms             0      use rudonx
2022-01-23 17:50:55      rudonx  10.0.0.22       rudonx          35ms            12      show databases
2022-01-23 17:50:55      rudonx  10.0.0.22       rudonx          35ms             5      show tables
2022-01-23 17:51:03      rudonx  10.0.0.22       rudonx          34ms             5      show tables

:输出格式为:时间,访问用户,来源 IP,访问 Database,命令耗时,返回数据行数,执行语句。

抓取某端口信息并打印到文件

运行命令如下:

(base) [root@ip-10-0-0-22 bin]# ./mysql-sniffer -i eth0 -p 3306 -l /tmp

查看文件输出:

(base) [root@ip-10-0-0-22 tmp]# tail -f 3306.log 
2022-01-23 18:00:06      rudonx  10.0.0.22       NULL            31ms             1      select @@version_comment limit 1
2022-01-23 18:00:18      rudonx  10.0.0.22       NULL            30ms             1      select 1
2022-01-23 18:00:30      rudonx  10.0.0.22       NULL            38ms            12      show databases
2022-01-23 18:00:48      rudonx  10.0.0.22       NULL            31ms             1      select * from rudonx.rudonx
2022-01-23 18:01:13      rudonx  10.0.0.22       NULL            31ms            61      show tables

:-l 指定日志输出路径,日志文件将以 port.log 命名

实时抓取多个端口信息并打印到文件

示例命令如下:

(base) [root@ip-10-0-0-22 bin]# ./mysql-sniffer -i eth0 -p 3306,3307,3310 -l /tmp

注::-l 指定日志输出路径,-p 指定需要抓取的端口列表逗号分割。日志文件将以各自 port.log 命名。

使用注意事项
  1. 先运行./mysql-sniffer 命令,然后在连接MySQL,才可以抓取的到相关信息。
  2. 使用该工具有一定的丢包几率。

如果您有其他问题,欢迎您联系火山引擎技术支持服务

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论