Free Buffer Waits本质是在等DBWR从LRU链“拉出”脏块腾出空闲缓冲区,而非等待磁盘写完成;其根本原因是DBWR处理速度跟不上前台进程消耗buffer的节奏,高free buffer inspected/free buffer requested比值(>3~5)表明LRU扫描效率低下、DBWR滞后,比值接近1则指向buffer cache过小或低效SQL引发的物理读爆炸。
Free Buffer Waits到底在等什么
它不是在等磁盘写完,而是在等dbwr从lru链上“拉出”足够多的脏块,腾出free buffer。关键区别在于:free buffer waits反映的是dbwr跟不上前台进程“消耗buffer”的节奏,而不是磁盘本身慢——后者会先表现为db file parallel write高延迟或write complete waits飙升。
先看v$sysstat里两个关键指标比值
执行:
SELECT name, value FROM v$sysstat WHERE name IN ('free buffer requested', 'free buffer inspected');
如果free buffer inspected ÷ free buffer requested > 3~5,说明前台进程反复扫描LRU却找不到可重用buffer,DBWR确实滞后;如果比值接近1,问题更可能是buffer cache太小或SQL物理读爆炸,加DBWR进程毫无意义。
- 比值高 → 优先查
db file parallel write平均等待时间:超过15ms就锁定I/O子系统瓶颈 - 比值低 → 直接查
v$sql中disk_reads高、buffer_gets低的语句,比如全表扫描没统计信息、批量INSERT未分批、延迟块清除严重的表被高频扫描 - 别只盯着
db_writer_processes:Oracle 11g默认按CPU数自动配DBWR(每8核1个),硬设为8或16反而可能引发latch争用
WRITE COMPLETE WAITS共现时,90%是存储配置翻车
当free buffer waits和write complete waits同时高发,且write complete waits平均等待超20ms,基本可断定是存储层卡住。常见真凶:
- Exadata上开了“自动磁盘擦洗”,征期高峰IO被吃光
- FlashCache配置成
WriteThrough模式,脏块必须刷到机械盘才返回,绕过了闪存加速 - 多路径配置不当或存储控制器队列深度设得太低,
dd if=/dev/zero of=/dev/raw_device bs=1M count=1024 oflag=direct测裸设备IOPS才能确认是不是Oracle层之外的问题 - 文件系统缓存未关闭,导致Oracle写请求被二次缓冲,实际落盘延迟不可控
_db_block_max_scan_pct调高是饮鸩止渴
这个隐含参数控制前台进程扫描LRU链的上限百分比(11g默认40%)。设成60%看似能多扫一段再唤DBWR,但实际只是把压力推迟爆发——脏块总量没变,单次查找时间变长,还可能把冷数据块也卷进扫描范围。更危险的是,它不解决根本吞吐,只转移争用位置:ASH里若发现free buffer waits的p3(set-id#)集中在某几个buffer pool set,说明已出现局部热点,此时调参会让问题从全局蔓延成局部雪崩。
真正该盯住的,永远是那几条disk_reads爆表却buffer_gets很低的SQL,它们才是buffer cache的黑洞。











