slow_query_log是dos风险的间接信号源,因攻击者常通过大量低效查询(如全表扫描、无索引查询)拖垮资源,而非洪水式连接;结合threads_running激增、processlist异常状态及错误日志爆破记录可交叉验证。

慢查询日志(slow_query_log)本身不直接记录拒绝服务攻击,但它能暴露被滥用的资源消耗模式——比如大量低效查询在短时间内密集出现,正是DoS或暴力探测的典型副产品。
为什么 slow_query_log 是 DoS 风险的间接信号源
攻击者不一定靠洪水式连接打垮MySQL(那会体现在 Aborted_connects 或 Threads_connected 异常),而是用“合法但低效”的SQL拖垮CPU、IO或内存。这类行为不会触发连接拒绝,却会让正常业务卡死。
- 慢查询日志记录的是执行时间 ≥
long_query_time的语句,而攻击者常批量发送未加索引的SELECT *、全表扫描的WHERE条件、或故意构造高成本子查询 - 如果同一IP或用户在1分钟内集中产生20+条慢查询,且语句结构高度相似(如只变动ID或用户名),大概率是自动化探测或爆破准备阶段
-
log_queries_not_using_indexes = 1开启后,哪怕执行快,也会记录无索引查询——这是更早的预警信号,比long_query_time更敏感
如何从 slow.log 中快速识别可疑模式
别逐行翻日志。用命令直接提取高频、低质量、集中爆发的线索:
- 统计每条慢查询的出现频次(去重SQL文本):
awk '/^# Time/ {if (sql) print sql | "sort | uniq -c | sort -nr"; sql=""} !/^#/ && !/^$/ {sql = sql $0} END {print sql | "sort | uniq -c | sort -nr"}' /var/log/mysql/mysql-slow.log | head -20 - 查某IP在慢日志中出现次数(需日志含
# User@Host行):grep -A 1 'User@Host' /var/log/mysql/mysql-slow.log | grep '192.168.1.100' | wc -l - 筛选“无索引但执行快”的隐患语句(依赖
log_queries_not_using_indexes):grep -A 2 'No_index_used' /var/log/mysql/mysql-slow.log | grep -B 1 'Query_time'
注意:slow_query_log_file 路径以 SHOW VARIABLES LIKE 'slow_query_log_file'; 输出为准;若日志被 logrotate 压缩,需用 zgrep 替代 grep。
单看 slow.log 不够,必须交叉验证的三个点
孤立的慢查询可能是业务问题,但结合以下任一现象,风险等级立刻上升:
-
SHOW STATUS LIKE 'Threads_running';在慢查询高峰时持续 > 50(说明并发执行卡住,不是排队) -
SHOW PROCESSLIST;中大量状态为Sending data或Copying to tmp table的长时间连接,且 Host 字段指向同一网段 - 错误日志(
log_error)里同期出现大量Access denied for user——说明攻击者一边爆破账号,一边试探SQL注入或宽字节绕过
真正危险的不是某条慢SQL,而是它背后那个不断调整参数重试、逐步摸清你表结构和索引弱点的“活体探测过程”。日志本身不会说话,但字段间的时空关联会漏出马脚。











