AWR不直接显示表空间I/O瓶颈,需查DBA_HIST_FILESTATXS(文件级)和DBA_HIST_TABLESPACE_STAT(表空间级)视图;关键看READTIM/WRITETIM与PHYRDS/PHYWRTS比值,注意READTIM单位为百分之一秒;快照ID须一致,历史默认仅保留8天;用SQL查avg_read_ms>20ms的异常数据文件。
看懂 AWR 里 DBA_HIST_FILESTATXS 和 DBA_HIST_TABLESPACE_STAT 的 I/O 数据
awr 报告本身不直接展示表空间级 i/o 瓶颈,得自己查历史视图。关键不是看“总读写次数”,而是比对 phyrds/phywrts 和 readtim/writetim——时间占比高但次数少,大概率是单次 i/o 大(比如全表扫描);次数多但时间短,可能是小块随机读(索引查找)。注意 readtim 单位是百分之一秒,不是毫秒,直接除 phyrds 得到平均延迟会错。
-
DBA_HIST_FILESTATXS按数据文件粒度统计,能定位到具体FILE#和TS#,适合排查某几个文件异常 -
DBA_HIST_TABLESPACE_STAT按表空间聚合,缺失文件名信息,但能看出SYSAUX或USERS这类逻辑单元是否整体承压 - 两个视图的快照时间必须对齐(用相同
SNAP_ID),否则对比无意义 - 默认只保留 8 天历史,
DBA_HIST_SNAPSHOT查下实际保留窗口,别白查
用 SQL 快速识别 I/O 延迟最高的数据文件
别翻 AWR HTML 报告里的“IO Stat by Filetype”那几页,慢还容易漏。直接跑这个:
SELECT ts.name ts_name, df.name file_name,
f.phyrds, f.readtim, ROUND(f.readtim/f.phyrds,2) avg_read_ms,
f.phywrts, f.writetim, ROUND(f.writetim/f.phywrts,2) avg_write_ms
FROM dba_hist_filestatxs f
JOIN v$tablespace ts ON f.ts# = ts.ts#
JOIN v$datafile df ON f.file# = df.file#
WHERE f.snap_id = &snap_id
AND f.phyrds > 0 AND f.phywrts > 0
ORDER BY f.readtim DESC, f.writetim DESC
FETCH FIRST 10 ROWS ONLY;重点看 avg_read_ms 超过 20 的文件——正常 OLTP 下机械盘应 readtim 高但 phyrds 很低,说明是偶发大块读(比如备份或导出),不是持续瓶颈。
- 替换
&snap_id为两次采样中问题时段的任意一个快照 ID - 加
AND f.file# IN (1,3,5)可聚焦系统表空间文件(SYSTEM、SYSAUX) - 别信
AVG_READ_MS平均值,要结合PHYRDS看分布:100 次读里有 1 次 200ms,平均才 2ms,但应用可能就卡在这 1 次
Tablespace 统计里 PHYSICAL_READS 和 PHYSICAL_WRITES 不等于文件级之和
这是最常被误解的一点:DBA_HIST_TABLESPACE_STAT.PHYSICAL_READS 是从 V$TABLESPACE 动态性能视图采样来的瞬时值,本质是自实例启动以来的累计值做差,而 DBA_HIST_FILESTATXS 是每个文件单独采样。两者口径不同,数值对不上很正常。
- 表空间视图里没有
READTIM字段,无法算延迟,纯看吞吐量意义有限 - 如果发现某个表空间
PHYSICAL_READS暴增,但下属所有文件的PHYRDS都不高,大概率是临时表空间(TEMP)在做排序/哈希,得去查V$SORT_SEGMENT - 监控脚本里混用这两个视图做环比,结果可能完全失真
别跳过 DBA_HIST_IOSTAT_DETAIL 直接下结论
DBA_HIST_FILESTATXS 只告诉你“哪个文件慢”,但不告诉你“为什么慢”。DBA_HIST_IOSTAT_DETAIL 按设备类型(TYPE = 'Data File' / 'Log File' / 'Control File')拆分了 I/O 类型(SMALL_READ_MEGABYTES, LARGE_WRITE_REQS 等),能判断是不是归档日志写满、控制文件争用,或者大量 LARGE_READ_REQS(典型全表扫描)。
- 查
TYPE = 'Data File'且FUNCTION_NAME = 'db file sequential read'的等待,对应索引单块读,延迟高说明缓存没起作用 -
LARGE_READ_REQS比平时高 3 倍,先看执行计划里有没有没走索引的大查询,别急着加磁盘 - 这个视图默认不采集,确认
STATISTICS_LEVEL是TYPICAL或ALL,否则为空
真正卡住的从来不是“平均响应时间”,而是长尾延迟和 I/O 类型错配。比如 SYSTEM 表空间里出现大量 db file scattered read,基本可以断定有未绑定变量的硬解析风暴在刷共享池。


















