mysql慢查询日志不记录客户端ip,需通过general_log(临时启用,代价高)或代理层日志(如nginx、proxysql)追溯源ip;推荐优先使用nginx日志结合时间戳与响应时间反查,并联动应用层连接池和sql分析定位根因。

直接看 slow_query_log 无法获取源 IP,得靠 general_log 或代理层日志
MySQL 原生慢查询日志(slow_query_log)只记录 SQL 内容、执行时间、锁等待等,**不记录客户端 IP**。想追溯到具体哪个 IP 发起的高负载查询,不能只依赖它。真正能拿到源 IP 的路径有两条:一是开启 MySQL 的通用日志(general_log),二是从反向代理(如 Nginx)或中间件(如 ProxySQL)日志里查——后者更推荐,因为开 general_log 在生产环境代价太大。
-
general_log会记录每条进来的语句 + 客户端 host,但日志量爆炸,IO 压力陡增,仅适合临时排查(比如持续 5–10 分钟) - Nginx access 日志默认带
$remote_addr,只要后端是 PHP/Java 等走 HTTP 协议访问 MySQL,就能通过请求链路反推(例如:Nginx 日志里某 IP 在 10:23:45 大量刷 /api/order,对应时间点 MySQL 出现大量SELECT * FROM orders WHERE user_id = ?) - 如果用了数据库中间件(如 ProxySQL),它的
mysql_stats.stats表或日志里会存client_host字段,比 MySQL 原生日志更可控
开启 general_log 时必须限制范围,否则可能拖垮磁盘
真要开 general_log,别直接全局打开。先确认当前负载是否允许:
- 用
SHOW VARIABLES LIKE 'general_log%';查看当前状态和文件路径 - 临时开启:执行
SET GLOBAL general_log = 'ON';,同时立刻用tail -f /var/lib/mysql/general.log监控输出,观察每秒写入行数 —— 超过 200 行/秒就该停 - 日志文件务必落在 SSD 分区,且不能和 MySQL data 目录共用同一块磁盘(避免 IO 争抢)
- 关闭后记得清空文件:
TRUNCATE TABLE mysql.general_log;(如果启用了表存储)或手动rm文件并重启 MySQL(如果启用了文件存储)
从 Nginx 日志反查 MySQL 负载源头最稳妥
绝大多数 Web 场景下,MySQL 负载突增都来自上游应用的异常请求,而这些请求必然经过 Nginx。只要你在 Nginx 配置里加了 $upstream_response_time 和自定义 header(如 X-Real-IP),就能把慢请求和 DB 操作对上号:
- 在 Nginx access log format 中加入响应时间与后端地址:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time $upstream_addr'; - 当发现 MySQL 负载飙升时,立刻执行:
awk '$9 > 2 {print $1}' /www/wwwlogs/access.log | sort | uniq -c | sort -nr | head -20(统计响应超 2 秒的请求来源 IP) - 再结合时间窗口过滤 MySQL 慢日志:
mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log | grep -A 2 -B 2 "2026-06-03 10:23",交叉比对时间戳
查到恶意 IP 后别只封 Nginx,要同步检查连接池行为
单纯封掉一个 IP 可能治标不治本。很多“高负载”其实是应用层 bug 导致的连接泄漏或循环重试,比如某个 Java 应用配置了 maxWait=30000 但没设 testOnBorrow,结果连接池不断新建连接打满 MySQL 的 max_connections。这时候看到的“高负载”其实是大量 Sleep 状态连接在耗资源。
- 用
SHOW PROCESSLIST;看是否有大量Sleep连接,且Host列显示的是内网应用服务器 IP(不是终端用户 IP) - 检查应用侧连接池监控指标:比如 Druid 的
ActiveCount是否长期接近MaxActive,HikariCP 的HikariPool-1.ActiveConnections是否持续高位 - 如果确认是应用自身问题,优先调整连接池参数或修复代码逻辑,而不是在防火墙封 IP —— 封错可能导致整个服务不可用
真实场景中,源 IP 往往只是表象;背后是业务接口被爬、前端重试逻辑失控、或缓存击穿引发的雪崩式 DB 请求。盯住 IP 是第一步,但必须马上跳到应用层和 SQL 层交叉验证。











