数据库频繁落盘导致磁盘阻塞的本质是写I/O压力集中爆发,表现为%util≥95%、w_await>50ms、avgqu-sz升高、CPU使用率低;排查需聚焦“谁在写、写什么、为什么这么写”,通过top查%wa、iostat -dx 1看写指标、iotop -oP定位mysqld/postgres进程,再结合innodb_flush_log_at_trx_commit、wal_level等配置分析根因。

数据库频繁落盘导致磁盘阻塞,本质是写 I/O 压力集中爆发——不是空间满了,而是磁盘处理不过来请求。这类问题常表现为 MySQL/PostgreSQL 响应变慢、事务提交延迟高、监控显示 %util 接近 100%、await > 50ms、avgqu-sz 显著升高,而 CPU 使用率却不高。排查要聚焦“谁在写”、“写什么”、“为什么这么写”三层。
确认是否为数据库落盘引发的 IO 瓶颈
先排除误判:运行 top 查看 %wa(iowait) 是否持续 > 30%。若高,说明 CPU 正在等磁盘;再执行 iostat -dx 1,重点观察:
- %util ≥ 95% → 磁盘已饱和,大概率是瓶颈所在
- avgqu-sz > 2(HDD)或 > 4(SSD) → 队列堆积,请求排队严重
- w_await 远高于 r_await(如 w_await=200ms,r_await=5ms)→ 写操作拖慢整体响应
- w/s 和 wkB/s 异常高 → 直接指向写密集型行为,与数据库日志刷盘强相关
定位具体数据库进程及其写行为
用 iotop -oP(仅显示活跃进程,非线程)找出写速率最高的进程。常见目标包括:
-
mysqld或postgres主进程(PID 可通过ps aux | grep -E "(mysql|postgres)"确认) - 若看到
mysqld的 DISK WRITE 占比超 70%,基本可锁定 - 用
lsof -p PID | grep -E "(ib_logfile|ibdata|pg_wal|base/.*\.dat)"查看它正在写的文件 → 通常是 redo log(MySQL)、WAL(PostgreSQL)或数据文件
分析数据库落盘激增的根源
高频落盘不是凭空产生,需结合数据库配置与负载特征判断原因:
-
MySQL 场景:检查
innodb_flush_log_at_trx_commit=1(每次事务都刷盘)+ 大量小事务 → 导致大量随机写;或sync_binlog=1+ binlog 写入频繁 -
PostgreSQL 场景:关注
wal_level = logical、max_wal_size过小触发频繁 checkpoint、或大量INSERT/UPDATE未批量提交 - 共性诱因:定时任务批量导入、应用未使用连接池导致短连接高频建连/提交、SQL 未加索引引发全表更新并写大量 undo/redo
验证与临时缓解措施
定位后不建议直接 kill 数据库进程。可尝试安全干预:
- 对非核心业务会话,用数据库命令限流(如 MySQL 的
KILL QUERY PID终止慢写事务) - 临时调大 PostgreSQL 的
checkpoint_timeout或 MySQL 的innodb_log_file_size(需重启,仅评估后操作) - 观察
iostat中 w_await 和 avgqu-sz 是否回落 → 若明显下降,印证判断准确 - 慎用
echo 3 > /proc/sys/vm/drop_caches,它不解决写压力,只清读缓存,对落盘无直接帮助











