Oracle 10g Datafile I/O Statistics
Mike Ault, Harry Conway and Don Burleson
The Oracle10g database significantly improves the I/O
subsystem through the addition of such features as the
Automatic Storage Management (ASM) facility. However, it is
important to constantly monitor the I/O workload on the
database because in a well tuned application, I/O remains a
bound factor that can cause significant wait times in data
access. I/O layout design is a complex process and includes
the consideration of the following points:
Sufficient disk capacity for business needs.
Appropriate data protection level using RAID levels, hardware,
LVM, etc.
Sufficient I/O throughput that does not exceed disk I/O
bandwidth.
The AWR has several views that can be used to isolate datafile
I/O related statistics as well as tablespace space usage
statistics.
The dba_hist_filestatxs and dba_hist_tempstatxs views display
information about I/O activity for data and temporary database
files, respectively:
SQL> desc DBA_HIST_FILESTATXS
Name Null? Type
----------------- -------- -------------
SNAP_ID NUMBER
DBID NUMBER
INSTANCE_NUMBER NUMBER
FILE# NUMBER
CREATION_CHANGE# NUMBER
FILENAME VARCHAR2(513)
TS# NUMBER
TSNAME VARCHAR2(30)
BLOCK_SIZE NUMBER
PHYRDS NUMBER
PHYWRTS NUMBER
SINGLEBLKRDS NUMBER
READTIM NUMBER
WRITETIM NUMBER
SINGLEBLKRDTIM NUMBER
PHYBLKRD NUMBER
PHYBLKWRT NUMBER
WAIT_COUNT NUMBER
TIME NUMBER
The view, dba_hist_tempstatxs, has the identical structure.
Both views can be queried to monitor overall database I/O
activity for a particular snapshot interval grouped by
tablespaces using the query db_tbsp_io_10g.sql:
db_tbsp_io_10g.sql
-- *************************************************
-- Copyright © 2005 by Rampant TechPress
-- This script is free for non-commercial purposes
-- with no warranties. Use at your own risk.
--
-- To license this script for a commercial purpose,
-- contact [email protected]
-- *************************************************
select tbsp “Tablespace”
, ios "I/O Activity"
From (
select e.tsname tbsp
, sum (e.phyrds - nvl(b.phyrds,0)) +
sum (e.phywrts - nvl(b.phywrts,0)) ios
from dba_hist_filestatxs e
, dba_hist_filestatxs b
where b.snap_id(+) = &pBgnSnap
and e.snap_id = &pEndSnap
and b.dbid(+) = &pDbId
and e.dbid = &pDbId
and b.dbid(+) = e.dbid
and b.instance_number(+) = &pInstNum
and e.instance_number = &pInstNum
and b.instance_number(+) = e.instance_number
and b.file# = e.file#
and ( (e.phyrds - nvl(b.phyrds,0) ) +
(e.phywrts - nvl(b.phywrts,0)) ) > 0
group by e.tsname
union
select e.tsname tbsp
, sum (e.phyrds - nvl(b.phyrds,0)) +
sum (e.phywrts - nvl(b.phywrts,0)) ios
from dba_hist_tempstatxs e
, dba_hist_tempstatxs b
where b.snap_id(+) = &pBgnSnap
and e.snap_id = &pEndSnap
and b.dbid(+) = &pDbId
and e.dbid = &pDbId
and b.dbid(+) = e.dbid
and b.instance_number(+) = &pInstNum
and e.instance_number = &pInstNum
and b.instance_number(+) = e.instance_number
and b.file# = e.file#
and ( (e.phyrds - nvl(b.phyrds,0) ) +
(e.phywrts - nvl(b.phywrts,0) ) ) > 0
group by e.tsname
)
The script allows users to look at the I/O activity per
tablespace basis, locate hot tablespaces that experienced a
large workload and may be candidates for further tuning
consideration:
SQL> @db_tbsp_io.sql
Tablespace I/O Activity
------------------------------ ------------
SYSAUX 9630
SYSTEM 3658
UNDOTBS1 1104
USERS 14
The WISE tool offers the following I/O related reports that
build time-series charts for I/O database activity:
I/O by datafiles.
I/O by tablespaces.
Total database I/O activity.
Total tablespace I/O activity.
The screenshots below, Figures 2.3, 2.4 and 2.5), demonstrate
the sample chart reports available in WISE. These screenshots
show database I/O activity by particular datafiles, tablespaces,
or total database I/O. WISE also allows the viewing of I/O
statistics averaged by hour of day, day of week, or month of
year.
Figure 2.3: AWR I/O by datafiles chart in WISE.
Figure 2.4: AWR Total Tablespace I/O Activity chart in
WISE.
Figure 2.5: AWR Total Database I/O Activity chart in WISE.
The following script, wait_time_detail_10g.sql, compares the
wait event values from dba_hist_waitstat and
dba_hist_active_sess_history. This script quickly allows the
identification of the exact objects that are experiencing wait
events:
wait_time_detail_10g.sql
-- *************************************************
-- Copyright © 2005 by Rampant TechPress
-- This script is free for non-commercial purposes
-- with no warranties. Use at your own risk.
--
-- To license this script for a commercial purpose,
-- contact [email protected]
-- *************************************************
prompt
prompt This will compare values from dba_hist_waitstat with
prompt detail information from dba_hist_active_sess_history.
prompt
set pages 999
set lines 80
break on snap_time skip 2
col snap_time heading 'Snap|Time' format a20
col file_name heading 'File|Name' format a40
col object_type heading 'Object|Type' format a10
col object_name heading 'Object|Name' format a20
col wait_count heading 'Wait|Count' format 999,999
col time heading 'Time' format 999,999
select
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi') snap_time,
-- file_name,
object_type,
object_name,
wait_count,
time
from
dba_hist_waitstat wait,
dba_hist_snapshot snap,
dba_hist_active_sess_history ash,
dba_data_files df,
dba_objects obj
where
wait.snap_id = snap.snap_id
and
wait.snap_id = ash.snap_id
and
df.file_id = ash.current_file#
and
obj.object_id = ash.current_obj#
and
wait_count > 50
order by
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi'),
file_name
;
This script is also enabled to join into the dba_data_files view to get the file
names associated with the wait event. This is a very powerful script that can
be used to quickly drill-in to find the cause of specific waits. The following is a
sample output from this script:
SQL> @wait_time_detail_10g
Copyright 2005 by Donald K. Burleson
This will compare values from dba_hist_waitstat with
detail information from dba_hist_active_sess_hist.
Snap Object Object Wait
Time Type Name Count Time
-------------------- ---------- -------------------- -------- --------
2005-02-28 01:00 TABLE ORDOR 4,273 67
INDEX PK_CUST_ID 12,373 324
INDEX FK_CUST_NAME 3,883 17
INDEX PK_ITEM_ID 1,256 967
2005-02-29 03:00 TABLE ITEM_DETAIL 83 69
2005-03-01 04:00 TABLE ITEM_DETAIL 1,246 45
2005-03-01 21:00 TABLE CUSTOMER_DET 4,381 354
TABLE IND_PART 117 15
2005-03-04 01:00 TABLE MARVIN 41,273 16
TABLE FACTOTUM 2,827 43
TABLE DOW_KNOB 853 6
TABLE ITEM_DETAIL 57 331
TABLE HIST_ORD 4,337 176
TABLE TAB_HIST 127 66
This example demonstrates how the AWR and ASH data can
be used to create an almost infinite number of sophisticated
custom performance reports.
A sample custom AWR query can be created by starting with a
simple query to plot the “user I/O wait time” statistic for each
AWR snapshot. The phys_reads.sql script shows that it is easy
to extract the physical read counts from the AWR:
phys_disk_reads_10g.sql
-- *************************************************
-- Copyright © 2005 by Rampant TechPress
-- This script is free for non-commercial purposes
-- with no warranties. Use at your own risk.
--
-- To license this script for a commercial purpose,
-- contact [email protected]
-- *************************************************
break on begin_interval_time skip 2
column phyrds format 999,999,999
column begin_interval_time format a25
select
begin_interval_time,
filename,
phyrds
from
dba_hist_filestatxs
natural join
dba_hist_snapshot
;
The results below show a running total of Oracle physical
reads from phys_reads.sql. The snapshots are collected every
half-hour in this example, and many DBAs will increase the
default collection frequency of AWR snapshots. Starting from
this script, a where clause criteria could easily be added to
create a unique time-series exception report:
SQL> @phys_reads
BEGIN_INTERVAL_TIME FILENAME PHYRDS
------------------------- ---------------------------------------- ------------
24-FEB-04 11.00.32.000 PM E:\ORACLE\ORA92\FSDEV10G\SYSTEM01.DBF 164,700
E:\ORACLE\ORA92\FSDEV10G\UNDOTBS01.DBF 26,082
E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 472,008
E:\ORACLE\ORA92\FSDEV10G\USERS01.DBF 1,794
E:\ORACLE\ORA92\FSDEV10G\T_FS_LSQ.ORA 2,123
The simple script called rpt_10g_sysstat.sql displays a time-
series exception report for any statistic in dba_hist_sysstat.
This script accepts the statistics number and the value
threshold for the exception report as supplied parameters:
rpt_10g_sysstat.sql
-- *************************************************
-- Copyright © 2005 by Rampant TechPress
-- This script is free for non-commercial purposes
-- with no warranties. Use at your own risk.
--
-- To license this script for a commercial purpose,
-- contact [email protected]
-- *************************************************
prompt
prompt This will query the dba_hist_sysstat view to display all values
prompt that exceed the value specified in
prompt the "where" clause of the query.
prompt
set pages 999
break on snap_time skip 2
accept stat_name char prompt 'Enter Statistic Name: ';
accept stat_value number prompt 'Enter Statistics Threshold value: ';
col snap_time format a19
col value format 999,999,999
select
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi') snap_time,
value
from
dba_hist_sysstat
natural join
dba_hist_snapshot
where
stat_name = '&stat_name'
and
value > &stat_value
order by
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi')
;
The rpt_sysstat script should now be run. It will prompt the
DBA for the statistic name and threshold value:
SQL> @rpt_sysatst
Copyright 2005 by Donald K. Burleson
This will query the dba_hist_sysstat view to display all values
that exceed the value specified in
the "where" clause of the query.
Enter Statistic Name: physical writes
Enter Statistics Threshold value: 200000
SNAP_TIME VALUE
------------------- ------------
2005-02-21 08:00 200,395
2005-02-27 08:00 342,231
2005-02-29 08:00 476,386
2005-03-01 08:00 277,282
2005-03-02 08:00 252,396
2005-03-04 09:00 203,407
The listing above indicates a repeating trend in which physical
writes seem to be high at 8:00 a.m. on certain days. This
powerful script will allow the DBA to quickly extract exception
conditions from any instance-wide Oracle metric and view the
values change over time.
Another example quickly writes a custom exception report. In
the following report called hot_write_files_10g.sql, the
dba_hist_filestatxs table can be queried to identify “hot write”
datafiles in which the file consumed more than 25% of the
total physical writes for the instance.
By taking a closer look at the query, it can be noted that the
query compares the physical writes, the phywrts column of
dba_hist_filestatxs, with the instance-wide physical writes,
statistic# = 55 from dba_hist_sysstat.
This simple yet powerful script allows the Oracle professional
to track hot-write datafiles over time, thereby gaining
important insights into the status of the I/O sub-system.
hot_write_files_10g.sql
-- *************************************************
-- Copyright © 2005 by Rampant TechPress
-- This script is free for non-commercial purposes
-- with no warranties. Use at your own risk.
--
-- To license this script for a commercial purpose,
-- contact [email protected]
-- *************************************************
prompt
prompt This will identify any single file who's write I/O
prompt is more than 25% of the total write I/O of the database.
prompt
set pages 999
break on snap_time skip 2
col filename format a40
col phywrts format 999,999,999
col snap_time format a20
select
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi') snap_time,
filename,
phywrts
from
dba_hist_filestatxs
natural join
dba_hist_snapshot
where
phywrts > 0
and
phywrts * 4 >
(
select
avg(value) all_phys_writes
from
dba_hist_sysstat
natural join
dba_hist_snapshot
where
stat_name = 'physical writes'
and
value > 0
)
order by
to_char(begin_interval_time,'yyyy-mm-dd hh24:mi'),
phywrts desc
;
The sample output from this script is useful because it shows
the high-write datafiles and those times when they are hot:
SQL> @hot_write_files
This will identify any single file who's write I/O
is more than 25% of the total write I/O of the database.
SNAP_TIME FILENAME PHYWRTS
-------------------- ---------------------------------------- ------------
2005-02-20 23:30 E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 85,540
2005-02-21 01:00 E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 88,843
2005-02-21 08:31 E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 89,463
2005-02-22 02:00 E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 90,168
2005-02-22 16:30 E:\ORACLE\ORA92\FSDEV10G\SYSAUX01.DBF 143,974
E:\ORACLE\ORA92\FSDEV10G\UNDOTBS01.DBF 88,973
This type of time-series exception reporting is extremely
useful for detecting those times when the Oracle10g database
is experiencing I/O related stress. Many Oracle professionals
will schedule these types of exception reports using
dbms_scheduler and send the report via automatic e-mail
every day.
The above article is an excerpt from the new book “Oracle
Tuning Power Scripts: With 100+ High Performance SQL
Scripts” by Mike Ault, Harry Conway and Don Burleson. You
can buy the book and download the Oracle powerscripts at
this link.