# 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` 连接此数据库。 ```sql 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。相关现有索引包括: ```text newslist (news_status, news_cid, news_addtime) news_cid_list(news_status, news_cid) ``` 上述 SQL 的 EXPLAIN: ```text type: ref key: newslist key_len: 1 estimated rows:32800 Extra: Using where; Using filesort ``` 因此不是完全没有使用索引,而是只利用了状态筛选,未解决按时间排序的问题。查询没有约束中间的 `news_cid`,当前三列索引不能有效满足该排序需求。EXPLAIN 的 32,800 是估算值,慢日志的 72,352 是实际执行计数,两者口径不同。 已定位服务器首页模板: ```text /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'); ``` ## 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 错误日志反复出现: ```text 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. 建议处理顺序(尚未执行) 1. **先控制异常流量。** 优先在 WAF/CDN/入口层对 `www.txiaw.com` 开启 CC 防护;结合该域名首页、随机 `r` 参数、无 User-Agent 等特征做有范围的规则,并配置请求速率保护。来源分散,规则应避免仅依赖少量 IP,也要验证对合法访问的影响。Nginx 支持按指定键限制请求速率,具体阈值需要结合合法流量设定:[Nginx limit_req 官方文档](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html)。 2. **降低这条 SQL 的单次成本。** 评估增加 `(news_status, news_addtime)` 联合索引,保留现有分类列表索引;执行前核对备份、重复索引、DDL 方式和负载,执行后用 EXPLAIN 与慢查询验证。这里只提出候选索引,未在生产创建,也未验证创建后的性能。索引列的连续性和等值条件如何影响 ORDER BY,可参阅 [MySQL ORDER BY 优化说明](https://dev.mysql.com/doc/refman/26.7/en/order-by-optimization.html)。 3. **缓存首页这份固定列表。** 给查询结果设置合理 TTL;若确认 `r` 对正常业务无意义,避免让它产生无限不同的首页缓存键,并防止并发失效时集中回源数据库。当前实际证据表明这条固定查询仍在大量重复执行。 4. **减少多站点相互拖累。** 后续评估独立 PHP 池和资源限制。MySQL 连接数、PHP 并发、缓冲池与服务器规格应在流量恢复后按实测调整。 验收应观察:异常请求量下降、PHP socket 不再队列满、各站点 502 明显减少、排序查询并发和慢查询增速下降,以及 2 核服务器 CPU 与 load 逐步恢复。 本次完成的是原因排查;异常流量及服务负载未由本次操作消除。