灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

    • MySQL 运维知识地图:从入门配置到高可用排障
    • MySQL8 配置文件 my.cnf 重要参数解读
    • MySQL 导出 CSV 中文乱码:字符集链路从头讲一遍
    • MySQL 角色管理
    • MySQL网络抓包审计
      • 方式一:tcpdump + 文本还原(零依赖,适合临场)
      • 方式二:专用 sniffer 工具(能解析协议,输出更规整)
        • 2.1 mysql-sniffer(360,需编译)
        • 2.2 vc-mysql-sniffer(VividCortex,下载即用)
      • 坑与边界
    • MySQL 性能压测:Sysbench 1.0 实战
    • MySQL Router 实现读写分离
    • Gh-ost重建表,清除表碎片率
    • MySQL MGR配合MySQL-router实现innodb-cluster
    • MySQL 快速分析binlog定位问题
    • MySQL执行计划分析
    • DBA常用SQL和命令整理备查
    • 单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」
    • MySQL的事务隔离级别
    • MySQL存储过程批量生成数据
    • MySQL insert on duplicate key update,replace into , insert ignore的理解
    • MySQL不同字符集之间的区别和选择
    • MySQL为什么有时候会选错索引
    • MySQL死锁问题
    • MySQL使用SQL语句查重去重
    • MySQLdump逻辑备份
    • MySQL 基于 GTID 主从复制:跳过异常事务的正确姿势
    • MySQL8快速克隆插件使用指南
    • MySQL8双1设置保障安全
    • MySQL锁
    • innodb cluster安装
    • OPTIMIZE TABLE 和 ANALYZE TABLE 的区别:用实测数据说话
    • MySQLReplicaSet 安装
    • MySQL 的 Left join、Right join 和 Inner join 的区别
    • ORDER BY 配合 LIMIT 触发的索引选择陷阱
  • Redis

  • 高性能KV

  • TiDB

  • Elasticsearch

  • 数据管道

  • 其他数据库

  • 数据库
  • MySQL
灯下哥谭
2022-03-10
目录

MySQL网络抓包审计

写在前面:抓包审计是排查手段,不是审计方案。要长期留存审计记录,用 MySQL 企业版审计插件、MariaDB Audit Plugin 或 Percona 的 audit_log;抓包只适合「现在就要看到这台机器上正在跑什么 SQL、且不方便改配置重启」的临场排查。

另外三条前提,动手前先确认:

  • 抓包会拿到明文 SQL 和其中的业务数据(手机号、身份证、订单号都在里面)。这是敏感操作,要有授权,抓下来的文件也要按敏感数据处置。
  • 连接开了 TLS 就抓不到明文。MySQL 8.0 默认对客户端启用 TLS,能抓到明文往往意味着这条链路根本没加密——那本身是个应当上报的问题。
  • 高 QPS 实例上抓包会占用可观的 CPU 和磁盘,-w 写文件时更要控制时长和大小,别把磁盘打满。

版本说明

本文写于 2022-03。
tcpdump/MySQL 协议抓包分析思路未变,经 2026-07 复核仍适用。

# 方式一:tcpdump + 文本还原(零依赖,适合临场)

网卡名(bond0)和端口(3366)要换成你自己的,先用 ip -br link 和 netstat -lntp | grep mysqld 确认:

#!/bin/bash
# 抓 MySQL 入向流量并还原出 SQL 文本
# -i bond0    抓哪块网卡,按实际改
# -s 0        抓完整包,不截断(漏了它长 SQL 会被切断)
# -l          行缓冲,配合管道才能实时输出
# -w -        写到标准输出交给后面的管道
# dst port    只抓发往 MySQL 的方向,即客户端发来的语句
tcpdump -i bond0 -s 0 -l -w - dst port 3366 | 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.=" $_";
    }
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

这个 perl 片段做的事是:把 strings 抽出的文本行按 SQL 关键字开头合并成完整语句(一条 SQL 可能被拆在多个 TCP 包里)。它是尽力还原,不解析 MySQL 协议,所以预处理语句(prepared statement)、压缩协议、TLS 加密的流量它都还原不出来。

想留存下来事后分析,把 -w - 改成写文件、控制好大小:

tcpdump -i bond0 -s 0 -w /tmp/mysql.pcap -C 100 -W 5 dst port 3366
# -C 100 每个文件 100MB,-W 5 最多滚动 5 个,合计上限 500MB,不会撑爆磁盘
1
2

验证:另开一个终端连上去跑一条 SELECT 1;,抓包侧应当立刻打印出这条语句。抓不到先查三件事:网卡名对不对、端口对不对(很多实例不是 3306)、连接是不是走了 TLS 或 unix socket(走 socket 的本地连接根本不经过网卡,抓不到,这是最常见的"抓不到"原因)。

# 方式二:专用 sniffer 工具(能解析协议,输出更规整)

有两个名字相近但完全不同的工具,网上的教程经常把它们混在一起写,导致「按 A 的步骤编译,却对着 B 的参数敲命令」:

工具 来源 获取方式
mysql-sniffer 奇虎 360 开源,C 写的 源码编译,产物是 mysql-sniffer
vc-mysql-sniffer VividCortex(现 SolarWinds)出的闭源二进制 官网下载现成二进制,不需要编译

下面两节分别对应这两个,别混着用。

# 2.1 mysql-sniffer(360,需编译)

yum install cmake
yum install  libpcap-devel
yum install  glib2-devel
yum install  libnet-devel
1
2
3
4
git clone https://github.com/Qihoo360/mysql-sniffer.git
cd mysql-sniffer
mkdir proj && cd proj
cmake ../
make
# 产物在 bin/ 目录下:mysql-sniffer
1
2
3
4
5
6

用法(注意它的参数和下面 vc- 那个完全不一样):

./bin/mysql-sniffer -i bond0 -p 3366     # -i 网卡  -p 端口
1

# 2.2 vc-mysql-sniffer(VividCortex,下载即用)

这个是预编译二进制,不用上面那套 cmake/make 步骤。它按 /proc/net/tcp 里的 bind 地址来定位要监听的端口:

$ sudo ./vc-mysql-sniffer --binding="[::]:3366" --output=/tmp/queries.log

$ sudo ./vc-mysql-sniffer  --help
vc-mysql-sniffer is a utility from VividCortex to monitor query activity and write results to a file.
See --license for the terms governing your usage of this program.

  -binding="[::]:3306"         This is a list of comma separated bind strings as seen in /proc/net/tcp
  -help="false"                Show this usage message
  -help-json="false"           Show this usage message as JSON
  -license="false"             Print the usage terms of this program
  -output=""                   Filepath to output queries to. Defaults to stdout if none specified.
  -show-database="false"       Include a 'USE `database`' for every statement. Supersedes show-database-changes.
  -show-database-changes="true"
                               Include a 'USE `database`' every time the database is changed.
  -verbose="false"             Enable logging on program startup to stderr
  -version="false"             Show version and exit

  Flag                         Current value
--------------------------------------------
  -binding                     "[::]:3306"
  -help                        "true"
  -help-json                   "false"
  -license                     "false"
  -output                      ""
  -show-database               "false"
  -show-database-changes       "true"
  -verbose                     "false"
  -version                     "false"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 坑与边界

  • 本地连接抓不到。客户端用 -h localhost 时走的是 unix socket,不经过网络栈,tcpdump 抓不到任何东西。要抓本地连接必须让客户端用 -h 127.0.0.1(走 TCP 回环),并把 -i 改成 lo。
  • TLS 加密的连接只能抓到密文。MySQL 8.0 默认对客户端连接启用 TLS,抓包看到乱码是正常的,不是工具坏了。判断方法:SELECT * FROM performance_schema.session_ssl_status; 看会话有没有加密。
  • 预处理语句抓到的是占位符。用 ? 参数化的语句(绝大多数应用框架的默认行为),抓包看到的 SQL 里参数是分开传的二进制值,文本还原的方式拼不回完整语句。这种场景应该用 performance_schema.events_statements_summary_by_digest 或慢日志,而不是抓包。
  • 抓包不是零开销。高 QPS 下 tcpdump 本身会吃掉一个核,-s 0 抓全包写盘更是 I/O 大户。抓完立刻停,别留着跑。
  • 要看「哪些 SQL 慢/频繁」,抓包不是最优解。慢查询日志临时把 long_query_time 设成 0 记录全量语句,再用 pt-query-digest 聚合,比抓包准确得多也轻得多(见 MySQL执行计划分析 末节)。抓包的不可替代之处只有一个:不需要改数据库任何配置、不需要任何数据库权限。
#可观测性#MySQL
上次更新: 9/11/2026

← MySQL 角色管理 MySQL 性能压测:Sysbench 1.0 实战→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式