Skip to content

Buffer Pool Analysis by File (vbhfile.sql)

This script provides a simple analysis of Oracle buffer cache distribution across datafiles. It shows how many buffers each datafile has in the cache and identifies duplicate blocks (extra blocks), which can indicate hot data or caching patterns useful for I/O performance analysis.

rem vbhfile.sql
rem
ttitle 'Buffer Pool by File'
rem
col dbafil format 999 heading 'FILE'
col buffer_count format b99999 heading 'BUFFERS'
col distinct_block format b99999 heading 'BLOCKS'
col extra_block format b99999 heading 'EXTRA|BLOCKS'
rem
break on report
compute sum of buffer_count distinct_block extra_block on report
rem
select dbafil,
count(*) buffer_count,
count( distinct dbablk ) distinct_block,
count(*) - count( distinct dbablk ) extra_block
from x$bh
group by dbafil;
-- Run the script in SQL*Plus or SQLcl
@vbhfile.sql
-- No parameters required
-- Shows current buffer cache distribution
  • SELECT on X$BH (internal buffer header table)
  • Typically requires DBA role due to X$ table access
Buffer Pool by File
FILE BUFFERS BLOCKS EXTRA
BLOCKS
---- -------- ------- ------
1 12456 12234 222
2 8901 8789 112
3 5678 5623 55
4 3456 3445 11
5 2345 2342 3
6 1234 1233 1
---- -------- ------- ------
sum 34070 33666 404
  • FILE: Datafile number (dbafil)
  • BUFFERS: Total number of buffers from this file in cache
  • BLOCKS: Number of distinct blocks cached (unique blocks)
  • EXTRA BLOCKS: Duplicate blocks in cache (BUFFERS - BLOCKS)
  • High BUFFERS: Files with heavy read activity
  • BLOCKS vs BUFFERS: Shows block reuse patterns
  • EXTRA BLOCKS: Multiple copies of same block in cache
  • Large buffer counts: Most actively accessed datafiles
  • High extra block ratios: Frequently re-read blocks (hot data)
  • Zero extra blocks: Sequential access patterns or cold data
  • Even distribution: Balanced workload across files
  • Concentrated activity: Hot spots in specific files
  • Low buffer counts: Infrequently accessed or large scan operations
  1. Highest buffer counts: Primary candidates for I/O optimization
  2. High extra block ratios: Indicate data re-access patterns
  3. Uneven distribution: May suggest storage layout issues
  • Extra blocks > 5%: Normal for OLTP workloads
  • Extra blocks > 20%: Very hot data, consider caching strategies
  • Zero extra blocks: Sequential processing or insufficient cache
-- Identify files consuming most cache space
@vbhfile.sql
-- Focus on files with highest buffer counts
-- Analyze file access patterns
@vbhfile.sql
-- Consider file placement and distribution
-- Understand cache utilization
@vbhfile.sql
-- Help determine optimal buffer cache size
  1. Check for hot tables:

    -- Find objects in hot files
    SELECT owner, segment_name, segment_type
    FROM dba_extents
    WHERE file_id = &hot_file_number;
  2. Analyze access patterns:

    • Frequent full table scans
    • Hot index blocks
    • Temporary sort operations
  1. Storage considerations:

    • Move hot objects to separate files
    • Use multiple datafiles per tablespace
    • Consider ASM for automatic distribution
  2. Application optimization:

    • Review SQL execution plans
    • Consider partitioning strategies
    • Optimize indexing
  1. Possible causes:

    • Large sequential scans bypassing cache
    • Insufficient buffer cache size
    • Data access patterns not suited for caching
  2. Optimization strategies:

    • Increase buffer cache size
    • Tune SQL to reduce full scans
    • Consider table clustering
-- Identify which tablespaces are hot
SELECT df.file_id, df.tablespace_name, df.file_name,
bf.buffer_count, bf.extra_block
FROM dba_data_files df,
(SELECT dbafil,
COUNT(*) buffer_count,
COUNT(*) - COUNT(DISTINCT dbablk) extra_block
FROM x$bh
GROUP BY dbafil) bf
WHERE df.file_id = bf.dbafil
ORDER BY bf.buffer_count DESC;
-- Correlate buffer usage with I/O activity
SELECT f.file#, f.name, fs.phyblkrd, fs.phyblkwrt,
bf.buffer_count, bf.extra_block
FROM v$datafile f, v$filestat fs,
(SELECT dbafil,
COUNT(*) buffer_count,
COUNT(*) - COUNT(DISTINCT dbablk) extra_block
FROM x$bh
GROUP BY dbafil) bf
WHERE f.file# = fs.file#
AND f.file# = bf.dbafil
ORDER BY bf.buffer_count DESC;
-- Run periodically to track changes
-- Save results for trending analysis
SELECT SYSDATE snapshot_time, dbafil,
COUNT(*) buffer_count,
COUNT(DISTINCT dbablk) distinct_blocks
FROM x$bh
GROUP BY dbafil;