应先关联v$filestat与dba_data_files按tablespace_name分组,计算phyrds/phywrts及(readtim*10)/NULLIF(phyrds,0)得平均读延迟(毫秒),再结合AVGIOTIM>20ms与MAXIOWTM>100ms识别热点表空间,注意单位换算与RAC需用gv$filestat。

查 v$filestat 与 dba_data_files 关联获取每个表空间的IO吞吐
Oracle 没有直接按表空间聚合 I/O 的视图,必须手动关联 v$filestat(含物理读写次数、耗时)和 dba_data_files(含文件归属表空间)。关键不是加总 phyrds,而是把每个文件的 phyrds、phywrts、readtim、writetim 按 tablespace_name 分组后换算成有意义的吞吐与延迟。
-
readtim和writetim单位是厘秒(centiseconds),不是毫秒;算平均延迟时要 ×10 得到毫秒值 - 吞吐量用
(phyrds × 8192) / 1024 / 1024粗略估算 MB/s(假设标准块大小 8KB),但仅作趋势参考——真实吞吐受 OS 层缓存、ASM 条带、多路径影响极大 - 别用
dba_tablespace_usage_metrics:它只报容量,不带任何 I/O 统计 - RAC 环境下必须查
gv$filestat并用inst_id分组,否则会漏掉其他节点的负载
用 AVGIOTIM 和 MAXIOWTM 判断响应延迟是否异常
v$filestat 中的 AVGIOTIM 是自实例启动以来的平均单次 I/O 响应时间(单位毫秒),但它容易被长尾延迟拉高。真正要盯的是 MAXIOWTM(最大单次写耗时)和持续性:如果某表空间对应文件的 AVGIOTIM > 20 且 MAXIOWTM > 100,同时该值在最近 2 小时内稳定高于其他文件 3 倍以上,基本可判定为热点。
-
AVGIOTIM是累计值,不能反映瞬时抖动;若实例刚重启,数值偏低会误导判断 - SYSTEM 或 UNDOTBS1 表空间出现高
AVGIOTIM,优先查硬解析 SQL 或未提交事务,而不是立刻怀疑磁盘 - 不要单独看
AVGIOTIM:需同步查phywrts是否也异常高;若写多但延迟低,可能是顺序写优化生效;若写少但延迟高,大概率是随机写争用或存储队列堆积
结合 dba_hist_filestatxs 追溯历史延迟趋势
实时视图只能看当前状态,而 AWR 中的 dba_hist_filestatxs 可回溯 7 天内每个数据文件的 phyrds、phywrts、readtim、writetim,适合定位周期性毛刺(如夜间备份、归档切换引发的延迟飙升)。
- 查询前务必加时间过滤:
s.begin_interval_time BETWEEN SYSDATE-7 AND SYSDATE,否则全库扫描极慢 -
readtim / NULLIF(phyrds, 0)才是有效平均读延迟;漏掉NULLIF会导致除零错误并中断查询 - 结果中
avg_read_ms超过基线(SSD ≤3ms、SAS ≤10ms、NL-SAS ≤15ms)且连续 3 个快照都超标,才构成告警依据 - 注意:该视图中
readtim同样是厘秒,必须 ×10 换算
避免把操作系统层指标误当作表空间级指标
iostat 或 /proc/diskstats 输出的是物理设备或 LUN 级别的吞吐与 await,无法映射到 Oracle 表空间。例如一个 LUN 上放了 5 个表空间的数据文件,iostat 显示 %util > 90%,但你不知道是哪个表空间在猛刷。
- Linux 下若
disk_asynch_io=true但/proc/sys/fs/aio-max-nr不足,I/O 会静默退化为同步模式,导致所有表空间延迟集体升高——此时v$filestat全部变慢,但 iostat 可能看不出异常 - ASM 环境中,
v$asm_disk_iostat比 iostat 更贴近真实卷表现,但依然无法精确到表空间;必须通过v$datafile→v$asm_alias→v$asm_disk逐层反查才能定位 - Exadata 上
cellcli -e list metriccurrent输出的 IO% 是存储单元级,和 Oracle 表空间无直接对应关系
实际监控中最容易被忽略的一点:表空间本身不产生 I/O,文件才产生。 所有“表空间 IO”都是人工聚合结果,一旦文件跨 ASM 磁盘组、或使用了不同条带宽度、或混布了 OLTP 与归档日志,聚合后的数字就失去诊断价值。真要定位瓶颈,永远从单个文件出发,再向上归因到表空间。


















