DBAtlas · Database operations atlas

High IO wait / disk latency

The system is waiting on disk IO. First we separate whether the load is read- or write-heavy, then drill down to the causes: insufficient buffer cache, full table scans, checkpoint storms, IOPS limits or spills to temporary space.

Is the IO read-heavy or write-heavy?

Use file IO statistics to determine whether the wait is on the read side (data being read from disk) or on the write side (redo/checkpoint/data writes). This splits the tree in two.

SELECT function_name, small_read_reqs+large_read_reqs AS reads, small_write_reqs+large_write_reqs AS writes,
       small_read_megabytes+large_read_megabytes+small_write_megabytes+large_write_megabytes AS mb
FROM v$iostat_function ORDER BY mb DESC;
  • Mostly read IO
  • Mostly write IO

Why is read IO high?

Excessive physical reads come from three main causes: the buffer cache is too small (the working set does not fit in RAM), queries perform full table scans, or large sort/hash operations spill to temporary space.

SELECT ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct
FROM v$sysstat pr, v$sysstat dbg, v$sysstat cg
WHERE pr.name='physical reads' AND dbg.name='db block gets' AND cg.name='consistent gets';
SELECT sql_id, disk_reads, executions FROM v$sql ORDER BY disk_reads DESC FETCH FIRST 10 ROWS ONLY;
  • Buffer cache hit is low, the working set does not fit
  • Queries perform full table scans
  • Large sorts/hashes spill to temporary space

Why is write IO high?

A write-side bottleneck comes either from periodic checkpoints/flushes briefly saturating the disk (checkpoint storm) or from the storage lacking the IOPS/throughput to sustain the load.

SELECT event, total_waits, ROUND(time_waited/100,1) AS sec
FROM v$system_event
WHERE event IN ('log file parallel write','db file parallel write','checkpoint completed')
ORDER BY time_waited DESC;
  • Sudden checkpoint/flush waves (checkpoint storm)
  • Storage cannot keep up with sustained load (IOPS limit)

Root cause: insufficient buffer cache

The frequently accessed data set (working set) does not fit in the buffer cache, so blocks are constantly re-read from disk. The hit ratio is low and physical reads are high.

Root cause: full table scans

Queries scan large tables end to end because there is no suitable index; this both causes many physical reads and pollutes the cache with useless blocks.

Root cause: sorts/hashes spilling to temporary space

Large sort, hash join or group by operations do not fit in working memory and write to temporary space (temp/tempdb), generating heavy read/write IO.

Root cause: checkpoint storm

Dirty pages accumulate for a long time and are written to disk in bulk at short intervals; these sudden write waves periodically saturate IO.

Root cause: insufficient IOPS / throughput

The storage lacks the IOPS or bandwidth to serve the read+write requests the workload requires; queue depth and latency are persistently high.

Open in DBAtlas →