增加DBWR进程数不一定缓解Free Buffer Waits,因可能引发latch争用或调度开销;需结合v$sysstat中free buffer inspected与requested比值、WRITE COMPLETE WAITS及db file parallel write等待时间诊断I/O瓶颈,并优先优化高disk_reads低buffer_gets的SQL。
为什么增加DBWR进程数不一定能缓解Free Buffer Waits
直接改db_writer_processes参数不是万能解药。oracle 11g默认按cpu数自动计算dbwr数量(每8个cpu配1个dbwr),强行设高可能引发latch争用或调度开销。关键要看v$sysstat里free buffer inspected和free buffer requested的比值:如果前者远大于后者(比如>5倍),说明前台进程在lru链上反复扫描却找不到可用buffer,这时dbwr确实可能跟不上;但如果比值接近1,问题更可能是buffer cache太小或i/o写不下去。
怎么判断是I/O慢导致DBWR写不出脏块
WRITE COMPLETE WAITS平均等待时间超过20ms、且与FREE BUFFER WAITS共现,基本锁定I/O子系统瓶颈。此时查v$system_event中db file parallel write的平均等待时间——若>15ms,说明DBWR写脏块本身就在等磁盘响应。常见陷阱是误以为加SSD就能解决,实际可能卡在存储控制器队列、多路径配置不当或文件系统缓存未关闭。验证方法:用dd直写裸设备测IOPS,绕过Oracle层确认底层吞吐能力。
哪些SQL操作会高频触发Free Buffer Waits
全表扫描、大范围索引快速全扫描、无绑定变量的硬解析SQL,都会导致大量物理读,快速耗尽free buffer。特别注意以下场景:
- 使用
/*+ FULL(t) */但表没有统计信息,优化器误判走全表扫描 - 批量INSERT/UPDATE未分批,一次生成上千个脏块,DBWR来不及刷
- 延迟块清除(delayed block cleanout)严重的表被频繁全扫,每个块都要构造CR并占buffer
查v$sql中disk_reads高且buffer_gets低的语句,优先优化它们比调参数更见效。
调整_db_block_max_scan_pct隐含参数的风险点
这个参数控制前台进程扫描LRU链的上限百分比(11g默认40%)。调高它(如设为60)能让进程多扫一段再唤DBWR,表面减少等待次数,但实际延长了单次查找时间,且可能把本该淘汰的冷数据块也卷进来。更危险的是:它不改变脏块总量,只是推迟了DBWR压力爆发点。生产环境修改前必须做ASH采样确认free buffer waits的p3(set-id#)是否集中在某几个buffer pool set,否则盲目调参可能让争用从全局转为局部热点。











