free buffer waits高但DBWR CPU低说明I/O路径阻塞:存储响应慢、异步I/O未启用或DBWR配置不足;需查v$sysstat、db file parallel write平均等待、iostat指标及fast_start_mttr_target设置。
DBWR写慢的直接证据:free buffer waits 高但 DBWR 进程 CPU 使用率低
这说明不是 dbwr 没在干活,而是它被卡在 i/o 路径上——常见于存储响应慢、异步 i/o 未启用或单个 dbwr 进程扛不住脏块生成速率。free buffer waits 不是 dbwr 自身慢的“症状”,而是它没及时刷出脏块导致前台进程等空闲 buffer 的结果。真因得往 i/o 子系统和 dbwr 配置里挖。
实操建议:
- 查
v$sysstat确认free buffer waits是否持续 > 100 ms/second(不是总量高就行,要看每秒等待时间) - 用
top -H -p $(pgrep -f "ora_dbw")或v$process+v$session查 DBWR 线程实际 CPU 占用——若 - 对比
io_wait_time和write_time在v$bgprocess或 AWR 的 “Background Wait Events” 部分是否显著偏高
异步 I/O 必须开启,否则 DBWR 实际是同步写
Oracle 默认在 Linux 上不自动启用异步 I/O(AIO),哪怕文件系统支持。DBWR 启用 AIO 后才能真正并发提交多个写请求,避免串行阻塞。没开 AIO 时,db_writer_processes 设再多也白搭,因为每个写操作都得等前一个完成。
实操建议:
- 确认
disk_asynch_io = TRUE(show parameter disk_asynch_io),且操作系统级 AIO 已加载:lsmod | grep aio - 检查数据文件所在文件系统是否支持 AIO:
mount输出中含async(如 XFS 默认支持,ext4 需挂载选项barrier=1,commit=30并配内核参数) - 若用 ASM,确保
asm_diskstring指向的设备支持 AIO(如 /dev/oracleasm/* 下设备需 udev 规则设OPTIONS="aio")
db_writer_processes 和 dbwr_io_slaves 别乱调,先看 I/O 吞吐瓶颈在哪
增加 db_writer_processes 只在多 CPU 且 I/O 子系统能并行处理时有效;盲目加到 8 或 16,反而引发 LGWR 与 DBWR 争抢 latch(如 cache buffers lru chain)。而 dbwr_io_slaves 是为单 DBWR 进程无法发足够异步 I/O 请求时的补救方案,本质是让 slave 进程代发 write(),但会增加上下文切换开销。
实操建议:
- 先查 AWR 中 “I/O Profile” 部分的
Physical writes和Write requests比值:若Write requests远低于Physical writes(比如 1:5),说明每次写请求包含大量 block,I/O 合并良好,此时加 DBWR 进程收益小 - 若
Write requests接近Physical writes(1:1),说明写请求细碎,优先考虑调大db_block_size或优化应用批量逻辑,而不是堆 DBWR - 启用
dbwr_io_slaves前,确认db_writer_processes = 1,否则 slave 不生效(官方文档明确说明)
AWR 中真正该盯的三个指标:不是 free buffer waits,而是它背后的 I/O 延迟链
free buffer waits 是果,不是因。分析时必须顺藤摸瓜:从等待事件 → DBWR 写延迟 → 存储响应时间。AWR 报告里容易被忽略的是 “Instance Activity Stats” 下的 physical writes 和 “Wait Event Histogram” 中 db file parallel write 的 1–16ms、16–32ms 区间占比——如果 >30% 的写落在 32ms 以上,基本可断定存储层有延迟毛刺或队列堆积。
实操建议:
- 在 AWR 的 “Top 5 Timed Foreground Events” 里,若
free buffer waits排前三,立刻翻到 “Background Wait Events”,重点看db file parallel write的平均等待时间(Avg wait (ms))是否 > 20ms - 对比同一时段的 OS 层 iostat:
iostat -x 1中%util是否持续 > 90%,await是否 > 25ms,svctm是否接近await(说明非队列问题,是磁盘本身慢) - 检查
v$iostat_file,看 datafile 对应的small_write_reqs和large_write_reqs是否严重倾斜——大量 small write 通常意味着 buffer cache 命中率低或 checkpoint 频繁
最常被跳过的一步:确认 fast_start_mttr_target 是否设得太小,导致 Oracle 被迫高频 checkpoint,把本可合并的写打散成大量小写。这个参数调高一点,有时比调 DBWR 更管用。


















