6.9 KiB
MySQL 高负载排查报告
服务器:47.106.181.28。排查时间:2026-08-31 14:54–15:05,北京时间。
本次仅做只读检查,包括系统采样、读取日志与代码、SHOW 状态/索引和 EXPLAIN。未重启服务、终止业务查询、添加索引、修改配置或封禁 IP。SSH 已断开。本报告不包含密码。
结论
www.txiaw.com 遭遇高度符合 CC 攻击特征的首页刷请求:大量不同来源 IP 请求 /?r=随机值,几乎全部没有 User-Agent。首页每次渲染会执行一条缺少合适排序索引的文章列表 SQL,造成大量扫描和排序。并发查询耗尽 CPU,PHP 5.6 的处理队列随之饱和,影响同一 PHP 服务上的多个网站。
证据支持的调用链为:
分布式首页刷请求 → 首页模板查询 → 大量并发扫描/排序 → MySQL CPU 饱和、PHP 队列满 → 多站点 502
攻击者身份及各来源 IP 的实际操作者未核验;请求形态及流量异常是日志事实。随机参数具有缓存穿透/绕过的常见特征,但本次未完整验证所有缓存层的缓存键规则。
1. 异常流量
来源日志:服务器 /www/wwwlogs/www.txiaw.com.log。
15:02:48–15:02:55 的最近 10,000 条记录样本:
| 项目 | 结果 |
|---|---|
| 来源 IP | 117 个 |
| 首页 GET 请求 | 9,996 条 |
| 无 User-Agent | 9,996 条 |
| HTTP 502 | 9,925 条 |
| HTTP 499 | 75 条 |
另一批随后取得的 10,000 条记录中,首页请求 9,999 条,全部带 r 参数、全部没有 User-Agent,且 9,999 个完整首页 URL 各不相同。两批样本不同,不应混用分母。
第一批样本的较多来源包括:138.19.36.111(375 条)、113.10.168.213(317 条)、218.103.151.242(296 条)、112.119.100.62(291 条)。这些是日志中的来源地址,不代表已核验的攻击主体,也不是完整封禁清单。
2. 直接消耗 MySQL 的查询
实际数据库为 xiaxia,连接账号为 juanshu,MySQL 版本为 5.6.50-log。应用配置确认 www.txiaw.com 连接此数据库。
SELECT news_id, news_cid, news_name
FROM xiaxia.gxl_news
WHERE news_status = 1
ORDER BY news_addtime DESC
LIMIT 100;
实时 SHOW FULL PROCESSLIST 样本中,该账号可见 80 个连接,其中 77 个正在执行上述 SQL,状态均为 Creating sort index。这些连接来自本机。全局状态采样为 Threads_connected=80、Threads_running=79。
这里的 Creating sort index 是查询执行时的排序状态,并非有人正在运行 CREATE INDEX。
服务器 /www/server/data/mysql-slow.log 尾部 512 KiB 样本,按日志 SET timestamp 字段统计:
| 项目 | 结果 |
|---|---|
| 时间范围 | 15:02:12–15:04:50,158 秒 |
| 上述 SQL 的记录数 | 1,776 次 |
| 平均耗时 | 6.479 秒 |
| 最短 / 最长耗时 | 3.013 / 14.024 秒 |
| 每次 Rows_examined | 72,352 |
| 每次返回行数 | 100(抽查原始记录) |
| 最大 Lock_time | 0.000295 秒 |
慢日志仅记录超过阈值的查询,不能据此推算全部业务请求量。短时全局计数差分还显示,每秒约新增 12.4 次慢查询;这是另一段约 3 秒的采样。
Innodb_row_lock_current_waits=0,Table_locks_waited=0。证据指向并发排序的 CPU 开销,未观察到锁等待风暴。
3. 索引与代码定位
表为 InnoDB。相关现有索引包括:
newslist (news_status, news_cid, news_addtime)
news_cid_list(news_status, news_cid)
上述 SQL 的 EXPLAIN:
type: ref
key: newslist
key_len: 1
estimated rows:32800
Extra: Using where; Using filesort
因此不是完全没有使用索引,而是只利用了状态筛选,未解决按时间排序的问题。查询没有约束中间的 news_cid,当前三列索引不能有效满足该排序需求。EXPLAIN 的 32,800 是估算值,慢日志的 72,352 是实际执行计数,两者口径不同。
已定位服务器首页模板:
/www/wwwroot/www.txiaw.com/Tpl/icp/gxl_index.html:24
<php>$jishu =gxl_mysql_news('field:news_id,news_cid,news_name;limit:100;order:news_addtime desc');</php>
4. 资源与连带影响
14:54 起的系统采样:
- 2 个 CPU 核心,约 3.5 GiB 物理内存。
- 系统 load average 为
67.85 / 73.58 / 68.81。 - 连续 vmstat 样本 CPU idle 为 0,约 88%–90% 用户态,磁盘等待约为 0。
- mysqld 的 3 秒 pidstat 样本平均占用 136.33% CPU,约 1.36 个核心。该指标与 ps 中的进程长期平均值口径不同。
- Swap 已使用约 1 GiB,但当时未观察到持续换入换出;可用内存约 1.3 GiB。
- 根分区使用率 66%,不是磁盘空间耗尽。
- TCP established 约 7,240 条,这是整机 TCP 连接数,不是 MySQL 连接数。
15:02:55 的 Nginx 错误日志反复出现:
connect() to unix:/tmp/php-cgi-56.sock failed
(11: Resource temporarily unavailable) while connecting to upstream
www.txiaw.com、www.xxiaw.com 等网站出现上述错误。配置显示多个站点共用 PHP 5.6,包括 www.txiaw.com、www.xxiaw.com、m.xxiaw.com、www.bchongw.com、m.bchongw.com、down.bchongw.com、m.txuaw.com。其他网站近期样本也有大量 502,说明影响已经扩散。
5. 建议处理顺序(尚未执行)
- 先控制异常流量。 优先在 WAF/CDN/入口层对
www.txiaw.com开启 CC 防护;结合该域名首页、随机r参数、无 User-Agent 等特征做有范围的规则,并配置请求速率保护。来源分散,规则应避免仅依赖少量 IP,也要验证对合法访问的影响。Nginx 支持按指定键限制请求速率,具体阈值需要结合合法流量设定:Nginx limit_req 官方文档。 - 降低这条 SQL 的单次成本。 评估增加
(news_status, news_addtime)联合索引,保留现有分类列表索引;执行前核对备份、重复索引、DDL 方式和负载,执行后用 EXPLAIN 与慢查询验证。这里只提出候选索引,未在生产创建,也未验证创建后的性能。索引列的连续性和等值条件如何影响 ORDER BY,可参阅 MySQL ORDER BY 优化说明。 - 缓存首页这份固定列表。 给查询结果设置合理 TTL;若确认
r对正常业务无意义,避免让它产生无限不同的首页缓存键,并防止并发失效时集中回源数据库。当前实际证据表明这条固定查询仍在大量重复执行。 - 减少多站点相互拖累。 后续评估独立 PHP 池和资源限制。MySQL 连接数、PHP 并发、缓冲池与服务器规格应在流量恢复后按实测调整。
验收应观察:异常请求量下降、PHP socket 不再队列满、各站点 502 明显减少、排序查询并发和慢查询增速下降,以及 2 核服务器 CPU 与 load 逐步恢复。
本次完成的是原因排查;异常流量及服务负载未由本次操作消除。