129 lines
6.9 KiB
Markdown
129 lines
6.9 KiB
Markdown
# 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
|
||
<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 错误日志反复出现:
|
||
|
||
```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 逐步恢复。
|
||
|
||
本次完成的是原因排查;异常流量及服务负载未由本次操作消除。
|