awr中physical reads仅统计oracle进程对数据文件、临时文件及少量元数据的物理读,单位为逻辑块(默认8kb),不含rman、arch、asm、os预读等i/o;而iostat/vmstat统计所有进程对块设备的原始读请求,单位为扇区(512b),覆盖更广且含存储层行为,故数值必然不等。
awr报告里的physical reads和操作系统层面(如iostat、vmstat)看到的磁盘读数不一致,不是数据错了,而是两者统计口径根本不同——awr只算oracle自己发起的、面向数据文件的物理i/o,而os看到的是所有进程对块设备的所有读请求。
Physical Reads在AWR里到底统计了什么
AWR中Physical Reads来自v$sysstat的physical reads计数器,它只包含以下三类I/O:
- Oracle从数据文件(
datafile)读取DB blocks:包括全表扫描、索引快速全扫描、大对象访问等 - 从临时表空间(
tempfile)读取排序/哈希溢出块(仅当使用TEMP时发生物理读) - 从控制文件、联机重做日志中触发的极少量元数据读(可忽略)
它**完全不包含**:归档日志写入(ARCH进程刷archivelog)、RMAN备份读取数据文件、ASM磁盘头校验、操作系统缓存预读、甚至DBWR写脏块时的底层设备读(那是write,不算read)。
OS监控(iostat/vmstat)为什么数值更大
iostat -x 1输出的r/s或rkB/s是块设备驱动层的原始计数,覆盖全部上下文:
- RMAN备份进程直接打开数据文件做
pread(),每一字节都计入 - DBWR后台进程写脏块前,可能需先读取相邻块做合并(
db file parallel write隐含的读) - ASM实例自身维护磁盘组元数据时的读操作(
asm_io) - Linux page cache预读(
readahead)产生的额外READI/O,Oracle完全不知情
尤其在RAC环境,iostat看到的是所有节点对共享存储的总读请求,而AWR报告默认只展示当前实例视角;若用awrgrpt.sql生成全局报告,Physical Reads仍是各实例求和,但OS工具无法区分节点来源。
同一时段对比时最常踩的坑
直接拿AWR里某1小时窗口的Physical Reads总数,和iostat同一小时的r/s累加值比,几乎必然不等。原因包括:
- AWR快照是离散采样(默认每小时1次),
Physical Reads是两个快照间差值;iostat是连续滚动计数,起止毫秒级偏差就会导致数千次I/O误差 - AWR中
Physical Reads单位是“逻辑块数”(默认8KB),而iostat默认按512字节扇区计,换算时若忽略db_block_size,结果差16倍 - 某些存储层(如EMC VMAX、NetApp AFF)开启读缓存后,
iostat看到的r/s会大幅下降,但AWR的Physical Reads不变——因为Oracle仍认为自己发出了读请求
验证方法:在空闲时段手动执行ALTER SYSTEM FLUSH BUFFER_CACHE,再跑一条强制全表扫描SQL,用SELECT name, value FROM v$sysstat WHERE name = 'physical reads'查增量,同时运行iostat -x 1 60抓这60秒数据,二者才具备可比性。
真正该关注的交叉验证点
纠结绝对值差异没有意义,重点看趋势是否同步、瓶颈是否指向同一环节:
- 如果AWR中
Physical Reads突增 +iostat的%util接近100% +await> 20ms,说明确实是I/O子系统过载 - 如果
Physical Reads高但iostat的r/s平稳,大概率是大量小IO被存储缓存吸收,或存在direct path read未计入(检查wait event中是否有该事件) - 对比
AWR → Instance Efficiency Percentages → Buffer Hit Ratio:若低于90%且Physical Reads持续高位,优先查v$db_cache_advice拐点,而不是盯着OS指标调优
最易被忽略的一点:Physical Reads高本身不等于问题,它可能是合理的大批量ETL作业行为;但若伴随db file sequential read平均等待时间超过10ms,才真正说明I/O响应已成瓶颈——这个等待事件的time_waited_micro才是连接AWR与OS性能的真实锚点。











