mysql binlog默认不记录user@host信息,需启用binlog_rows_query_log_events=on(仅row/mixed有效,5.7.2+支持)并重启服务,否则mysqlbinlog -v无法显示操作者及ip。

查不到 User@Host 就别硬找 IP
MySQL 的 DROP DATABASE 或 DELETE 操作本身不会在 binlog 里存用户名和 IP,除非你提前开启了 binlog_rows_query_log_events = ON。这个配置是唯一能让 mysqlbinlog 输出 # User@Host: 注释行的开关——没开就永远看不到是谁连的、从哪来的。ROW 模式下不加它,mysqlbinlog -v 只会显示变更数据,不会附带连接上下文。
-
binlog_rows_query_log_events = ON必须写进my.cnf并重启 MySQL 才生效,动态 SET 不起作用 - 该参数仅对 ROW/MIXED 格式有效,STATEMENT 格式下即使开了也无用
- 5.7.2+ 版本才支持,低于这个版本无论怎么配都看不到
User@Host
用 mysqlbinlog 抓高频 DELETE 的真实命令
批量删除通常表现为短时间内密集的 DELETE 语句(不是单条大事务),重点不是看“删了多少行”,而是看“同一类 SQL 出现频率”。直接用 mysqlbinlog 解析 + grep 最快:
- 先定位时间范围:
mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v --start-datetime="2026-07-01 10:00:00" --stop-datetime="2026-07-01 11:00:00" mysql-bin.000123 | grep -A 2 -B 1 "DELETE FROM.*WHERE" - 注意大小写和空格变体:
delete from、DELETEFROM、换行或反引号包裹的表名都得覆盖 - 如果看到大量
DELETE FROM `orders` WHERE id IN (...或DELETE FROM `log_202606` WHERE create_time ,基本可判定是脚本或归档任务
靠 thread_id 关联真实客户端 IP(需配合 performance_schema)
即便没开 binlog_rows_query_log_events,也能通过 thread_id 反查连接来源——但前提是那个线程还没断开,且 performance_schema 相关 instrumentation 已启用:
- 从 binlog 里提取
thread_id=12345(在Query事件头行里) - 立刻执行:
SELECT THREAD_ID, PROCESSLIST_HOST, PROCESSLIST_USER, PROCESSLIST_INFO FROM performance_schema.threads WHERE THREAD_ID = 12345; - 若返回为空,说明连接已断;此时只能靠历史 slow log 或 general_log(如果开着)交叉验证
-
PROCESSLIST_HOST是客户端声明的 host,经代理/NAT 后可能失真,不能完全等同于真实出口 IP
my2sql 统计 DELETE 行为分布比手动 grep 更准
人工 grep 容易漏掉跨 binlog 文件、被事务包裹、或带子查询的 DELETE。用 my2sql 做聚合统计更可靠:
- 命令示例:
./my2sql -user reader -password xxx -port 3306 -work-type stats -databases app_db -start-file mysql-bin.000120 --stop-datetime "2026-07-01 12:00:00" -output-dir /tmp/stats - 输出的
stats_summary.txt里会按表、SQL 模板、QPS 分组统计,一眼看出哪个DELETE FROM t_order WHERE status=0占了 90% 的 DML 流量 - 注意:
my2sql不解析User@Host,但它能告诉你“哪条 SQL 在高频执行”,结合业务部署信息(比如只有订单服务连t_order)就能快速圈定责任方
真正难的不是找到那几条 DELETE,而是确认它们是否属于预期行为——比如定时归档任务没加限流、监控告警没覆盖到慢 delete、或者某 SDK 自动触发的级联清理。IP 和线程 ID 只是线索,最终得回到业务逻辑层闭环验证。











