Vous êtes sur la page 1sur 43

Interpret Statspack Report

Introduction

The utlbstat.sql and utlestat.sql are Oracle provided


scripts which are included with Oracle 7, 8 and 8i. These
scripts lay the foundation for most tuning efforts and
are executed as sys or internal from within svrmgrl(UNIX)
or svrmgr23 (on NT). While no two DBA's generally agree
on an assessment of every statistics reported from
utlestat.sql and it's report.txt output, they should
agree on the meaning of the main statistics, which is
what I'll discuss here.

Getting Started

You should be familiar with some basic nomenclature,


utilities and parameters before getting started.

 TIME_STATISTICS=TRUE Set in the init.ora, it enables


capturing of internal timing statistics on the
database.
 utlbstat.sql Oracle supplied script to initialize
internal statistics capturing, I'll refer to this
simply as bstat.
 utlestat.sql Oracle supplied script to end internal
statistics capturing and generate the report.txt
output. I'll refer to this script as estat.
 report.txt The output from the execution of the
estat script which is spooled to its current
directory
 cron The UNIX job scheduler (see the main pages if
your not familiar with this utility)
 svrmgrl The line mode version of server manager, the
DBA interface used to accomplish maintenance of the
database, available after the 7.1 release of Oracle.

To be able to run the utlbstat.sql and utlestat.sql


script, (normally found in the $ORACLE_HOME/rdbms/admin
subdirectory in an OFA installation), you must first set
TIMED_STATISTICS=TRUE in your init.ora and shutdown and
restart the database, or you will need to ALTER SESSION
SET TIMED_STATISTICES =TRUE from svrmgrl.

Prepared by: Ramesh 1


Interpret Statspack Report

Next, you have two choices; you can either set up a cron
job to execute the two scripts during peak or scheduled
times; or launch the scripts interactively from within
svrmgrl. I'll discuss the interactive approach first,
followed by a couple of cron scenarios you can use.

Running bstat and estat interactively

After assuring TIMED_STATISTICS=TRUE is set for your


database;

select substr(name,1,30),value

from v$parameter

where name = 'timed_statistics'; *** Note lower case for


timed_statistics

timed_statistics TRUE *** Should be the result from the


query

Log into svrmgrl as SYSDBA, SYS or INTERNAL. Next, run


@$ORACLE_HOME/rdbms/admin/utlbstat. This will create the
temporary tables and views that will be used to collect
the beginning statistics that will be saved in these
tables. All of these tables contain BEGIN in their name.

If your not still logged into svrmgrl, log in again as


SYSDBA, SYS or INTERNAL. Run the utlestat.sql script as
@$ORACLE_HOME/rdbms/admin/utlestat from the svrmgrl
command prompt. The estat script will collect the ending
statistics, and create an additional set of temporary
tables which it will use to format the output for the
report.txt statistics report. As you might guess, these
tables will contain END in their name. The report.txt
output, is what you are actually interested in, and it is
this output which you will be doing your assessment from
and making tuning decisions for your database.

The duration of time between running bstat and estat is a


matter of personal choice, however it should be long
enough to collect sufficient statistics for the results

Prepared by: Ramesh 2


Interpret Statspack Report

to be meaningful. Generally, no less than 30 minutes


should be used, and, it should also be run during a
period of peak activity. You may also to choose to run it
for specific tuning sessions when performance on the
database is not optimal and you are troubleshooting a
particular issue, which may or may not coincide with
"peak activity".

Running bstat and estat from UNIX cron

I typically choose to run these utilities from cron at


selected periods and for set duration during the normal
business day. My reason for this approach is it gives me
an excellent historical view of the performance of the
database. This enables me to easily compare a period of
poor performance today, with the same period of time
previously when there were no performance problems. Also,
as tuning is an iterative process, tuning changes I made
recently are hopefully having a positive impact on the
performance of the database, and by having historical
reports to go back to, I can readily establish
comparative numbers validating the changes which were
made. The comparison of the two or more reports may also
show, we went to far one way or the other and have
introduced performance degradation as a result of the
changes. (Yes this does happen)

There are three methods I employ at any given time for a


particular database in collecting statistics; every two
hours during the normal business day; start and end of
the business day; and, start of week through end of week.

Let's look at each method individually. When I'm tuning a


"technologically challenged" database, which is
exhibiting less than optimal performance, I use the
following cron entries to collect continuous 2 hour
snapshots of performance which I can later manually
review, or grep specific sections or lines out of.

##################################################

# Run the utlbstat and utlestat reports Mon - Fri

##################################################

Prepared by: Ramesh 3


Interpret Statspack Report

05 00,02,04,06,08,10,12,14,16,18,20,22 * * 1,2,3,4,5
/u01/oracle/scripts/utlbstat.sh sid

00 02,04,06,08,10,12,14,16,18,20,22 * * 1,2,3,4,5
/u01/oracle/scripts/utlestat.sh sid

15 06 * * * /bin/find /u01/oracle/admin/sid/reports -
mtime +17 -exec rm {} \;

The above cron listing runs the bstat script every 2


hours at 5 minutes after the hour, and the estat script
every two hours on the hour. The 5 minute difference
gives the estat script time to complete, and generate the
report.txt output. The shell scripts, which call the
utlbstat.sql and utlestat.sql script, are listed below.

##################################################

# Run the utlbstat.sql script for a specific instance

##################################################

#!/bin/sh

ORACLE_SID=$1 ;export ORACLE_SID

ORACLE_HOME=/u01/oracle/product/7.3.4;export ORACLE_HOME

$ORACLE_HOME/bin/svrmgrl < /tmp/bstat.log 2>


/tmp/bstat.log

connect internal

set termout off

@$ORACLE_HOME/rdbms/admin/utlbstat

exit

The above script accepts the sid as an input argument and


sets the environment variables appropriately to run
utlbstat against the specified instance.

Prepared by: Ramesh 4


Interpret Statspack Report

The next script runs the utlestat script against the


specified instance to complete the statistics collection
process for the instance. It also uses the system date
and time to append to the report.txt name to save the
report for the specific time frame within which it was
run. It also moves the renamed report to the holding
directory for estat reports which is located at
$ORACLE_BASE/admin/sid/reports.

##################################################

# Run the utlestat.sql script for a specific instance

# Rename the report.txt file and move it to a dedicated


directory

##################################################

#!/bin/sh

ORACLE_SID=$1 ;export ORACLE_SID

ORACLE_HOME=/u01/oracle/product/7.3.4;export ORACLE_HOME

file=`date +%y%m%d`_`date +%H%M`

cd /u01/oracle/admin/${ORACLE_SID}/reports

$ORACLE_HOME/bin/svrmgrl < /tmp/estat.log 2>


/tmp/estat.log

connect internal

set termout off

@$ORACLE_HOME/rdbms/admin/utlestat

exit

mv report.txt report_$file.txt

The last line in the cron listing above, is a maintenance


line to clean up estat reports that are over 17 days old.

Prepared by: Ramesh 5


Interpret Statspack Report

The other two methods that I may run on a regular cron


schedule are once a day, and once a week as shown in the
following two cron listings are also used primarily when
troubleshooting poor performance and I want a longer term
view of the statistics.

##################################################

# Run the utlbstat and utlestat reports during the


business day.

##################################################

05 06 * * 1,2,3,4,5 /u01/oracle/scripts/utlbstat.sh sid

00 18 * * 1,2,3,4,5 /u01/oracle/scripts/utlestat.sh sid

15 06 * * * /bin/find /u01/oracle/admin/sid/reports -
mtime +17 -exec rm {} \;

##################################################

# Run the utlbstat and utlestat reports for a Week at a


time

##################################################

05 06 * * 1 /u01/oracle/scripts/utlbstat.sh sid

00 18 * * 5 /u01/oracle/scripts/utlestat.sh sid

15 06 * * * /bin/find /u01/oracle/admin/sid/reports -
mtime +17 -exec rm {} \;

Once the database has achieved a reasonably stable state,


and performance is acceptable, I will generally alter the
timings of the bstat and estat to only run once a week
during a typical period of activity after the databases
have been up and active for a period of time. In my
experience, Thursday is typically a good choice for once
a week monitoring of stable databases.

Prepared by: Ramesh 6


Interpret Statspack Report

##################################################

# Run the utlbstat and utlestat reports once a Week

##################################################

05 06 * * 4 /u01/oracle/scripts/utlbstat.sh sid

00 18 * * 4 /u01/oracle/scripts/utlestat.sh sid

15 06 * * * /bin/find /u01/oracle/admin/sid/reports -
mtime +17 -exec rm {} \;

Assessing the output

Now that you have the report.txt output in your hands,


it's time to dig into what it is telling you. In this
section, I'll step through each area of the report in the
order it is output from estat. Although there is
significant information in each section, I will
concentrate on those statistics and their meanings, which
are most often the culprits in performance degradation on
an Oracle database.

It should also be noted, if you ask two performance-


tuning specialists their opinions on what is "acceptable
performance" in any given statistic, they may or may not
agree, although they will certainly offer an opinion. In
general though, they should be in agreement on the major
statistics that I'll discuss in this paper. Also, the
applications being run against the particular database
may introduce performance degradation that can make it
extremely difficult, if not impossible to tune for.

Tuning is an iterative process. As you make changes to


one area or parameter, it will certainly effect another
requiring the potential for additional tuning changes to
offset or take further advantage of the ones you just
made. As I mentioned earlier, you can also go the wrong
way, or too far, in making a change to a parameter by
accident or intentionally, ultimately requiring a
reversal of the previous change. What ever you do, don't
be afraid to say "that didn't work" or "I made a mistake
on that one" and correct the situation promptly.

Prepared by: Ramesh 7


Interpret Statspack Report

Report.txt output

The report.txt output is broken into several sections as


follows:

 Shared Pool Statistics


 System Wide Statistics
 Dirty Buffer Write Queue
 System Wide Wait Events
 Latches Willing to Wait
 Latches Not Willing to Wait
 Buffer Busy Statistics
 Rollback Segment Statistics
 Init.ora Parameters which are NOT default
 Dictionary Cache Statistics
 Tablespace I/O Statistics
 Data File I/O Statistics

Shared Pool Statistics

The query executed by utlestat.sql for reporting shared


pool statistics

SVRMGR> Rem Select Library cache statistics. The pin hit


rate should be high.

SVRMGR> select namespace library,

2> gets,

3>
round(decode(gethits,0,1,gethits)/decode(gets,0,1,gets),3
)

4> gethitratio,

5> pins,

6>
round(decode(pinhits,0,1,pinhits)/decode(pins,0,1,pins),3
)

7> pinhitratio,

Prepared by: Ramesh 8


Interpret Statspack Report

8> reloads, invalidations

9> from stats$lib;

The output from the utlestat.sql script

LIBRARY GETS GETHITRATI PINS PINHITRATI


RELOADS INVALIDATI

------------ ---------- ---------- ---------- ----------


---------- ----------

BODY 7876 1 7876 1


0 0

CLUSTER 0 1 0 1
0 0

INDEX 0 1 0 1
0 0

OBJECT 0 1 0 1
0 0

PIPE 0 1 0 1
0 0

SQL AREA 612476 .784 1565878 .814


23402 596

TABLE/PROCED 284224 .998 941952 .999


535 0

TRIGGER 2189 .999 2189 .996


5 0

8 rows selected.

Library - The particular section of the shared pool.

Gets - The number of requests made for an object in the


library.

Gethitratio - The percentage of time the requested object


was found in the library. It is calculated by dividing

Prepared by: Ramesh 9


Interpret Statspack Report

the number of gethits by the number of gets. This value


should always be as close to 1 as possible.

Pins - The number of times a requested object in the


cache was executed.

Pinhitratio - The number of times a requested object


being executed (pinning) is found in the cache.

Reloads - The number of times a requested objects was in


memory, but had since been aged out, and must now be
reloaded in order to be executed.

Invalidations - The number of times an object in the


library became invalid.

In reviewing the above section of the report, the


following checks should be made:

 Gethitratio - As close to 1 as possible for all


libraries

 Pinhitratio - As close to 1 as possible for all


libraries.

 Reloads - As close to 0 as possible for all


libraries

 Invalidations - As close to 0 as possible for all


libraries

 Ratios below 95% for either the pinhitratio or


gethitratio are generally indicative of the shared
pool being undersized. In some cases, the nature of
the application and poorly formed adhoc queries, the
lack of bind variable usage can contribute to lower
hit ratios, and may not be correctable by simply
enlarging the shared pool. In these cases, the
applications themselves need to be tuned, as well as
the potential for training issues in the area of
adhoc queries.

System Wide Statistics

The query executed by utlestat.sql

Prepared by: Ramesh 10


Interpret Statspack Report

SVRMGR> select n1.name "Statistic",

2> n1.change "Total",

3> round(n1.change/trans.change,2) "Per


Transaction",

4> round(n1.change/logs.change,2) "Per Logon",

5> round(n1.change/(to_number(to_char(end_time,
'J'))*60*60*24 -

6> to_number(to_char(start_time,
'J'))*60*60*24 +

7> to_number(to_char(end_time, 'SSSSS'))


-

8> to_number(to_char(start_time,
'SSSSS')))

9> , 2) "Per Second"

10> from stats$stats n1, stats$stats trans,


stats$stats logs, stats$dates

11> where trans.name='user commits'

12> and logs.name='logons cumulative'

13> and n1.change != 0

14> order by n1.name;

The output from the utlestat.sql query above:

Statistic Total Per Transact Per


Logon Per Second

--------------------------- ------------ ------------ ---


--------- ------------

CPU used by this session 899362 30.56


99.27 130.25

Prepared by: Ramesh 11


Interpret Statspack Report

CPU used when call started 894035 30.38


98.68 129.48

CR blocks created 15831 .54


1.75 2.29

Current blocks converted fo 118 0


.01 .02

DBWR buffers scanned 3446717 117.12


380.43 499.16 (1)

DBWR checkpoints 662 .02


.07 .1 (2)

DBWR free buffers found 3009437 102.26


332.17 435.83 (1)

DBWR lru scans 34638 1.18


3.82 5.02

DBWR make free requests 30813 1.05


3.4 4.46 (3)

DBWR summed scan depth 3446761 117.12


380.44 499.17

DBWR timeouts 955 .03


.11 .14

SQL*Net roundtrips to/from 1379937 46.89


152.31 199.85

SQL*Net roundtrips to/from 72 0


.01 .01

background checkpoints comp 3 0


0 0 (4)

background checkpoints star 5 0


0 0 (4)

background timeouts 7019 .24


.77 1.02

Prepared by: Ramesh 12


Interpret Statspack Report

bytes received via SQL*Net 223523173 7595.08


24671.43 32371.21

bytes received via SQL*Net 20822 .71


2.3 3.02

bytes sent via SQL*Net to c 249685662 8484.05


27559.12 36160.12

bytes sent via SQL*Net to d 5105 .17


.56 .74

calls to get snapshot scn: 693610 23.57


76.56 100.45

calls to kcmgas 32615 1.11


3.6 4.72

calls to kcmgcs 2060 .07


.23 .3

calls to kcmgrs 1084275 36.84


119.68 157.03

change write time 1245 .04


.14 .18

cleanouts and rollbacks - c 1927 .07


.21 .28

cleanouts only - consistent 787 .03


.09 .11

cluster key scan block gets 774611 26.32


85.5 112.18

cluster key scans 33517 1.14


3.7 4.85

commit cleanout failures: b 5 0


0 0

commit cleanout failures: c 11 0


0 0

Prepared by: Ramesh 13


Interpret Statspack Report

commit cleanout number succ 243791 8.28


26.91 35.31

consistent changes 31070 1.06


3.43 4.5 (6)

consistent gets 88854698 3019.19


9807.36 12868.17 (5)

cursor authentications 426627 14.5


47.09 61.79

data blocks consistent read 30823 1.05


3.4 4.46

db block changes 1348892 45.83


148.88 195.35 (7)

db block gets 1824046 61.98


201.33 264.16 (5)

deferred (CURRENT) block cl 30937 1.05


3.41 4.48

dirty buffers inspected 38 0


0 .01 (9)

enqueue conversions 5856 .2


.65 .85

enqueue releases 90671 3.08


10.01 13.13

enqueue requests 90812 3.09


10.02 13.15

enqueue timeouts 152 .01


.02 .02 (10)

enqueue waits 41 0
0 .01

execute count 726176 24.67


80.15 105.17

Prepared by: Ramesh 14


Interpret Statspack Report

free buffer inspected 975 .03


.11 .14 (8)

free buffer requested 10373888 352.49


1145.02 1502.37 (8)

immediate (CR) block cleano 2714 .09


.3 .39

immediate (CURRENT) block c 162355 5.52


17.92 23.51

logons cumulative 9060 .31


1 1.31

logons current -7 0
0 0

messages received 63064 2.14


6.96 9.13

messages sent 63064 2.14


6.96 9.13

no work - consistent read g 74939901 2546.38


8271.51 10852.99

opened cursors cumulative 146719 4.99


16.19 21.25

opened cursors current -85 0


-.01 -.01

parse count 613674 20.85


67.73 88.87

parse time cpu 174268 5.92


19.23 25.24

parse time elapsed 244363 8.3


26.97 35.39

physical reads 10519313 357.44


1161.07 1523.43 (5)

Prepared by: Ramesh 15


Interpret Statspack Report

physical writes 313406 10.65


34.59 45.39

process last non-idle time 2.158799E+12 73353689.71


238278045.06 312642880.27

recursive calls 600623 20.41


66.29 86.98 (11)

recursive cpu usage 7491 .25


.83 1.08

redo blocks written 178106 6.05


19.66 25.79

redo buffer allocation retr 0 0


0 0 (12)

redo entries 755215 25.66


83.36 109.37 (13)

redo log space requests 4 0


0 0 (14)

redo log space wait time 253 .01


.03 .04

redo size 166250052 5649


18349.9 24076.76 (15)

redo small copies 6504 .22


.72 .94 (16)

redo synch time 166637 5.66


18.39 24.13

redo synch writes 30680 1.04


3.39 4.44

redo wastage 12987034 441.29


1433.45 1880.82

redo write time 127144 4.32


14.03 18.41

Prepared by: Ramesh 16


Interpret Statspack Report

redo writer latching time 82 0


.01 .01

redo writes 31444 1.07


3.47 4.55

rollback changes - undo rec 1767 .06


.2 .26

rollbacks only - consistent 14089 .48


1.56 2.04

session connect time 2.158799E+12 73353675.76


238277999.74 312642820.8

session logical reads 90474197 3074.22


9986.11 13102.71

session pga memory 736599976 25028.88


81302.43 106676.32

session pga memory max 754312840 25630.75


83257.49 109241.54

session uga memory 26003552 883.57


2870.15 3765.9

session uga memory max 314734576 10694.35


34738.92 45580.68

sorts (disk) 85 0
.01 .01 (17)

sorts (memory) 56951 1.94


6.29 8.25 (17)

sorts (rows) 38258494 1299.98


4222.79 5540.69

summed dirty queue length 22 0


0 0

table fetch by rowid 23901562 812.15


2638.14 3461.49 (18)

Prepared by: Ramesh 17


Interpret Statspack Report

table fetch continued row 9292 .32


1.03 1.35 (19)

table scan blocks gotten 25613353 870.31


2827.08 3709.39

table scan rows gotten 790999372 26877.31


87306.77 114554.58

table scans (long tables) 1037 .04


.11 .15 (20)

table scans (short tables) 177260 6.02


19.57 25.67 (20)

total number commit cleanou 245600 8.35


27.11 35.57

transaction rollbacks 40 0
0 .01

transaction tables consiste 8 0


0 0

transaction tables consiste 237 .01


.03 .03

user calls 1373453 46.67


151.6 198.91 (11)

user commits 29430 1


3.25 4.26

user rollbacks 54 0
.01 .01

write requests 14858 .5


1.64 2.15

1. Calculate the percentage of time DBWR found free


buffers on the LRU list by dividing DBWR free
buffers found by DBWR make free requests. (1 - DBWR
make free requests / DBWR free buffers found ). A
value of 95% or better is desired with as close to
100% as possible the goal.

Prepared by: Ramesh 18


Interpret Statspack Report

2. DBWR checkpoints should be kept to a minimum.


Normally, you only want to see checkpoints at log
switch, so setting LOG_CHECKPOINT_TIMEOUT to 0
(infinity) and LOG_CHECKPOINT_INTERVAL to a value
greater than your log size will allow checkpoints
only at log switch.

3. DBWR make free requests are an indication if


DB_BLOCK_BUFFERS is tuned correctly. A make free
request is issued each time insufficient space is
available in the buffer cache without removing items
from the least recently used end of the LRU list.
High numbers here are indicative of insufficient
buffers in the buffer cache.

4. Background checkpoints completed and background


checkpoints started should never be more than 1
apart. This number should closely match the number
of log switches shown in the alert log during the
time the statistics are being gathered. A number
higher than the number of log switches is showing a
need to tune the checkpoint interval with
LOG_CHECKPOINT_INTERVAL and LOG_CHECKPOINT_TIMEOUT.
If these statistics, in addition to the number of
log switches are both high yet correlate closely to
each other, perhaps even 1 to 1, you probably need
to increase the size of your redo logs to slow down
the frequency of log switches.

5. Consistent gets plus db block gets is the total for


logical reads for the period. Physical reads divided
by logical reads + physical reads gives you the
database buffer cache hit ratio. Any value below 90%
should be considered unacceptable and certainly
contributory to poor database performance. You
should strive to keep this statistic above 95% with
a goal of 98 - 99% being reasonable. A consistent
get is done for any select statement provided there
is no FOR UPDATE clause attached. A db block get is
done for INSERT, UPDATE, DELETE and SELECT FOR
UPDATE statements.

6. Consistent changes are the number of times a block


was changed, or a rollback segment had to be read
for transaction read consistency. A high number here

Prepared by: Ramesh 19


Interpret Statspack Report

could indicate jobs doing large updates are being


run during your statistics-gathering window.

7. Db block changes are the number of blocks in the


buffer cache which were modified requiring their
being written to the online redo logs. Hence, this
value is the amount of redo generated during the
statistics gathering period. This value can help you
properly size your online redo logs for maximum
performance and log switch times. Even if multiple
rows in a block are modified, this still only counts
as one block change.

8. Free buffers inspected and free buffers requested


give an indication of adequate sizing of the
database buffer cache. Free buffers inspected is the
number of buffers skipped in the buffer cache to
find an available free buffer. Dividing this
statistic by the free buffers requested statistic
would give you the percentage of the time a free
buffer was found immediately. Again, the closer to
100% you can get, the better the indicator that your
database buffer cache is sized correctly.

9. Dirty buffers inspected is the number of modified or


dirty buffers which were aged out on the LRU list.
Any value here indicates the DBWR is not keeping up
and adding additional DBWR's should help alleviate
the problem. Also, making the redo log sizes
smaller, or reducing the value of
LOG_CHECKPOINT_INTERVAL can cause writes to occur
more frequently reducing the load on the DBWR
process.

10. A value greater than 0 here indicates the


ENQUEUE_RESOURCES parameter needs to be increased. A
timeout occurs when an enqueue lock was requested,
and one was not available.

11. Generally, there should be less than 4


recursive classes per process. If the number of
classes exceeds 4 per process, you should check the
dictionary cache hit ratio and also check for tables
or indexes with a large number of extents. Also, the
ratio of recursive calls to user calls should be
less than 10%. The primary exception to the 10% rule

Prepared by: Ramesh 20


Interpret Statspack Report

would be if there is a large amount of PL/SQL being


executed on the database.

12. A value other than 0 for redo buffer allocation


retries indicates the log writer is not keeping up.
This value is the number of times a request for
space allocation in the redo buffer was made and
space was not available. Tuning the values for
LOG_CHECKPOINT_INTERVAL and LOG_CHECKPOINT_TIMEOUT
can help improve this number. In Oracle8, you can
also increase the number of LGWR processes by
adjusting the values for LGWR_IO_SLAVES and
ARCH_IO_SLAVES. Problems in this area can be caused
by checkpoints or log switches. During a log switch
or checkpoint, (a checkpoint also occurs at log
switch), the buffer is "frozen" while the redo
blocks are written to the online redo logs. If a
checkpoint is occurring too frequently, processes
can be forced to wait while the checkpoint
completes.

13. The number of redo entries made during the


duration of statistics collection.

14. A value other than 0 here indicates that a user


had to wait for space in the redo buffer. This is
generally caused during a log switch. Increasing the
size of your redo buffer can help improve this
statistic. This is set via the LOG_BUFFER parameter
in the init.ora for your instance. You can also
reduce the number of log switches by increasing the
size of your online redo logs.

15. Redo size is the amount of redo information


written to the online redo logs during the
statistics collection period.

16. Redo small copies are the number of redo


entries which were written to the redo buffer using
the redo allocation latch. The ratio of redo small
copies to redo entries should be less than 10% in
most cases. Tuning the LOG_SMALL_ENTRY_MAX_SIZE
parameter in the init.ora will allow you to manage
the number of redo entries, which use the redo
allocation latch vs. the redo copy latch. To
increase the number of redo entries that use the

Prepared by: Ramesh 21


Interpret Statspack Report

redo allocation latch reduce the value for


LOG_SMALL_ENTRY_MAX_SIZE.

17. Sorts (disk and memory) indicate the accuracy


of the SORT_AREA_SIZE parameter in the init.ora. The
sorts (disk) divided by sorts (memory) should not be
above 5% (sorts(disk) / (sorts(memory) +
sorts(disks)). A sort to disk requires the creation
of a temporary segment to perform the sort
generating I/O overhead in the processing of the
sort action. It's also important to remember that
SORT_AREA_SIZE is an area of memory that is
allocated outside of the SGA and is on a per-user
basis. Make sure the system has adequate physical
memory before increasing your SORT_AREA_SIZE
parameter.

18. Table fetch by rowid is the number of rows


which were accessed via an index, or by use of the
'where ROWID=' statement.

19. Table fetch by continued row is indicative of


chained or migrated rows requiring more than a
single block read to return the row. Chained and
migrated rows can cause acute performance
degradation and should be corrected immediately if
they are being reported.

20. Table scans long and table scans short are


reports of how full table scans are being done
across your instance. Short tables are tables that
are less than 5 blocks in size. As Oracle reads a
minimum of 5 blocks, short tables will always be
read into memory completely with a single I/O
operation. Hence, any indexes on short tables are
forcing Oracle to do two I/O's to complete the same
request for data. Long tables on the other hand, are
those that are more than 5 blocks in size. When
looking at these two numbers, you should see high
numbers for short table scans and comparatively low
numbers for long table scans.

Dirty Buffer Write Queue Length

The statistics shown in this section indicate whether or

Prepared by: Ramesh 22


Interpret Statspack Report

not there are more dirty blocks in the buffer cache than
can be written to disk in a single I/O pass. Multiple
I/O's to write dirty blocks causes modified blocks to
wait in the queue to be written. Increasing the
DB_FILE_SIMULTANEOUS_WRITES parameter allows more than
one write to a data file at a given time. In general, you
should set this to the number of disks used in the stripe
set for optimal performance.

This is the query as taken from the estat, report.txt


output.

SVRMGR> select queue.change/writes.change "Average Write


Queue Length"

2> from stats$stats queue, stats$stats writes

3> where queue.name = 'summed dirty queue length'

4> and writes.name = 'write requests';

Average Write Queue Length

---------------------------

.00148068380670345941580293

1 row selected.

The result of the above query should be less than the


value of: (db_files * db_file_simultaneous_writes) /2or¼
of db_block_bufferswhich ever is smaller.

If the average write queue length is larger than the


above calculation, you can increase the
DB_FILE_SIMULTANEOUS_WRITES or DB_FILES parameters in the
init.ora. You also want to look for disks that are doing
significantly more I/O's than others.

System Wide Wait Events for Non-Background Processes

The system-wide wait events are extracted from the


V$SESSION_EVENT and V$SYSTEM_EVENT. The V$SESSION view is
a real time view you can use to view the events as the

Prepared by: Ramesh 23


Interpret Statspack Report

are occuring. The following excerpt from a production


database illustrates the type of wait events you may see.
The first extract is for non-background events, the
second is for background events coming from PMON, SMON
etc.

The query shown is the one run by the utlestat.sql


utility program to generate ending statistics and the
report.txt output.

SVRMGR> select n1.event "Event Name",

2> n1.event_count "Count",

3> n1.time_waited "Total Time",

4> round(n1.time_waited/n1.event_count, 2) "Avg


Time"

5> from stats$event n1

6> where n1.event_count > 0

7> order by n1.time_waited desc;

Event Name Count Total Time


Avg Time

-------------------------------- ------------- ----------


--- -------------

SQL*Net message from client 1399888


64337107 45.96

parallel query dequeue wait 13744


2762547 201

db file scattered read 1301752


1459435 1.12

rdbms ipc message 224


1380151 6161.39

db file sequential read 753874


1275223 1.69

Prepared by: Ramesh 24


Interpret Statspack Report

log file sync 30717


166532 5.42

latch free 625942


73230 .12

SQL*Net more data from client 10999


7829 .71

rdbms ipc reply 645


6075 9.42

SQL*Net message from dblink 72


5337 74.13

buffer busy waits 2942


5225 1.78

enqueue 44
4029 91.57

SQL*Net message to client 1399892


1118 0

SQL*Net more data to client 41694


676 .02

library cache pin 814


519 .64

write complete waits 15


222 14.8

log file switch completion 3


206 68.67

switch logfile command 3


123 41

SQL*Net break/reset to client 1795


72 .04

control file sequential read 4442


37 .01

Prepared by: Ramesh 25


Interpret Statspack Report

SQL*Net more data from dblink 2


21 10.5

SQL*Net message to dblink 72


0 0

22 rows selected.

While many of the above waits are considered normal


processing waits, there are definitely some you don't
want to see; free buffer waits, buffer busy waits and
enqueue waits. A couple of others which may indicate
performance problems include db file scattered read, db
file sequential read, log file sync.

The free buffer waits statistic indicates that either the


DBWR processes cannot keep up, or you may need to adjust
the frequency of your checkpoints by tuning the
CHECK_POINT_TIMEOUT and CHECK_POINT_INTERVAL parameters
in the init.ora.

The buffer busy waits statistic is indicating contention


for a buffer in the SGA. You may need to increase the
INITRANS parameter for a specific table or index if the
event is identified as belonging to either a table or
index. Querying V$SESSIOIN_WAIT will give you the file id
of the segment and the block ID causing the contention.
Using these two values, you can query DBA_EXTENTS to
identify the offending table or index.

Enqueue waits generally are indicating there are too many


DML or DDL lock, or, there may be a large number of
sequences. Increasing the ENQUEUE_RESOURCES parameter in
the init.ora will help reduce these.

The db file scattered read statistic is indicating either


disk contention or a significant number of full table
scans is occuring. The db file sequential read is also
indicative of disk contention on index reads.

Log file syncs occur each time LGWR flushes a buffer to


the on-line redo logs as a session issues a COMMIT. A
user session cannot continue while the sync process is
occurring, so times spent waiting here can show up in
application performance degradation. It may be necessary

Prepared by: Ramesh 26


Interpret Statspack Report

to review application code here and reduce the number of


commits issued.

System Wide Wait Events for Background Processes

The next report taken from report.txt is wait events for


the background processes ( PMON, SMON, etc.) Waits in any
of these areas except rdbms ipc message should be tuned.
The rdbms ipc message is indicating the system is mostly
idle as to the timer waits and can generally be ignored.
The same general guidelines from above also apply to
these waits.

SVRMGR> select n1.event "Event Name",

2> n1.event_count "Count",

3> n1.time_waited "Total Time",

4> round(n1.time_waited/n1.event_count, 2) "Avg


Time"

5> from stats$bck_event n1

6> where n1.event_count > 0

7> order by n1.time_waited desc;

Event Name Count Total Time


Avg Time

-------------------------------- ------------- ----------


--- -------------

Null event 156570


13028707 83.21

rdbms ipc message 54037


3278288 60.67

pmon timer 2765


690321 249.66

Prepared by: Ramesh 27


Interpret Statspack Report

smon timer 69
679979 9854.77

log file parallel write 31462


127199 4.04

db file parallel write 14884


24969 1.68

log file sync 57


2473 43.39

db file scattered read 460


1669 3.63

db file sequential read 345


1242 3.6

control file parallel write 264


378 1.43

db file single write 207


337 1.63

enqueue 2
200 100

rdbms ipc reply 16


139 8.69

latch free 103


100 .97

log file switch completion 1


47 47

control file sequential read 94


34 .36

log file sequential read 4


28 7

log file single write 8


22 2.75

Prepared by: Ramesh 28


Interpret Statspack Report

buffer busy waits 4


0 0

19 rows selected.

A couple of the wait events to pay attention to are in


the log file related event categories. The log file
parallel write is the time spent waiting for the multi-
plexed redo logs to be written to. The log file
sequential read wait occurs as redo records are being
read from the redo log are being read. The log file
single write events occur when during writes to the log
file header when log members are being added, SCN
information is being written, hot backup status is being
written, etc. If these event numbers are high, tune the
log file writes to assure they are occuring as rapidly as
possible.

In the DBWR category are db file parallel write event


which occurs while files are being written to in
parallel, db file scattered read events which occur as
multiple blocks are being read during full table scans
and full index scans. This is going to be directly
effected by the setting for
DB_FILE_MULTIBLOCK_READ_COUNT. Large numbers here may
indicate fragmentation on the physical device as a multi-
block read is not necessarily a contiguous read on the
physical device, but rather a logical multi-block read of
Oracle blocks. V$DATAFILE can be queried to determine
filename of the file being read. Looking at
V$SYSTEM_EVENT view gives detailed information on the
blocks being read and the starting point of the read. db
file sequential read events occur during regular reads of
datafiles by the foreground processes. These may include
reads which are not full table/index scans such as index
lookups etc. One other event is the db file single write
event which occurs when file headers or other individual
blocks are being written. The long and short of data file
wait events is that you need to take a hard look at your
file system layout and physical storage architecture.

Latch Statistics - Willing to Wait

These waits belong to processes who are trying to acquire

Prepared by: Ramesh 29


Interpret Statspack Report

a latch, but are willing to wait if it's not available,


sleep for a while, and retry to acquire the latch. Unlike
locks, which are used to manage physical objects, latches
are used to manage memory, and in effect are a lock on
memory or a memory buffer. V$LATCH is the underlying view
from which this information is gathered. The query
executed by utlestat.sql and the output from report.txt
follows.

SVRMGR> select name latch_name, gets, misses,

2> round((gets-misses)/decode(gets,0,1,gets),3)

3> hit_ratio,

4> sleeps,

5> round(sleeps/decode(misses,0,1,misses),3)
"SLEEPS/MISS"

6> from stats$latches

7> where gets != 0

8> order by name;

LATCH_NAME GETS MISSES HIT_RATIO


SLEEPS SLEEPS/MISS

------------------ ----------- ----------- ----------- --


--------- -----------

archive control 2 0 1
0 0

cache buffer handl 2307 0 1


0 0

cache buffers chai 198298540 18986 1


146 .008

cache buffers lru 389699 437 .999


32 .073

Prepared by: Ramesh 30


Interpret Statspack Report

dml lock allocatio 99885 2 1


1 .5

enqueue hash chain 187382 6 1


2 .333

enqueues 274500 37 1
2 .054

global transaction 220 0 1


0 0

global tx free lis 6 0 1


0 0

global tx hash map 22 0 1


0 0

ktm global data 189 0 1


0 0

latch wait list 1206748 562 1


52 .093

library cache 13774514 31644 .998


16212 .512

library cache load 2338 0 1


0 0

list of block allo 68676 1 1


0 0

loader state objec 167 0 1


0 0

messages 325821 510 .998


33 .065

modify parameter v 9058 1 1


1 1

multiblock read ob 2862151 1169 1


75 .064

Prepared by: Ramesh 31


Interpret Statspack Report

process allocation 5505 0 1


0 0

redo allocation 895961 546 .999


18 .033

redo copy 12 12 0
5 .417

row cache objects 19060877 74255 .996


18952 .255

sequence cache 27365 0 1


0 0

session allocation 176058 39 1


10 .256

session idle bit 2816650 100 1


8 .08

session switching 479 0 1


0 0

shared pool 6025558 558239 .907


589968 1.057

sort extent pool 69 0 1


0 0

system commit numb 2197515 646 1


76 .118

transaction alloca 101417 2 1


0 0

undo global data 123204 4 1


0 0

user lock 15390 2 1


1 .5

33 rows selected.

Prepared by: Ramesh 32


Interpret Statspack Report

Fortunately, evaluating this section of the report is


much easier than the earlier sections. The primary
indicator of problems is a low hit ratio for a given
latch. Your goal should be for all hit ratios to be as
close to 1 as possible. Any numbers below .99 should be
looked at. Also, any sleeps/miss statistics that are
higher than 1 should also be assessed as this indicates
the process had to sleep more than once to obtain a
latch.

Latch Statistics - Not Willing to Wait

The main difference in the two latch statistic sections


is the next section of latch's will not sleep and wait
for a latch to become free. These latches either succeed
or fail on the first attempt. The utlestat.sql query and
the report.txt output follow. One thing which will be
obvious when you look at the report.txt output, is there
is a bug in the utlestat.sql query which is not reporting
the hit ratio correctly. The correct query should look as
follows:

select name latch_name,

immed_gets nowait_gets,

immed_miss nowait_misses,

round(immed_gets/(immed_gets+immed_miss), 3)

nowait_hit_ratio

from stats$latches

where immed_gets + immed_miss != 0

order by name;

Note the difference in the parenthesis placement on line


4 of the query.

SVRMGR> select name latch_name,

2> immed_gets nowait_gets,

Prepared by: Ramesh 33


Interpret Statspack Report

3> immed_miss nowait_misses,

4> round((immed_gets/immed_gets+immed_miss), 3)

5> nowait_hit_ratio

6> from stats$latches

7> where immed_gets + immed_miss != 0

8> order by name;

LATCH_NAME NOWAIT_GETS NOWAIT_MISSES


NOWAIT_HIT_RATIO

------------------ ---------------- ---------------- ----


------------

cache buffers chai 19158912 236


237

cache buffers lru 20995499 13143


13144

library cache 462576 3827


3828

process allocation 5505 0


1

redo copy 1251593 42


43

row cache objects 56223 960


961

session idle bit 4 0


1

7 rows selected.

In this case you will have to do the calculation from the


numbers you do have, or, as I did, fix the utlestat.sql
script to produce the correct output and statistics which
should have looked like this.

Prepared by: Ramesh 34


Interpret Statspack Report

LATCH_NAME NOWAIT_GETS NOWAIT_MISSES


NOWAIT_HIT_RATIO

------------------ ---------------- ---------------- ----


------------

cache buffers chai 19158912 236


1

cache buffers lru 20995499 13143


1

library cache 462576 3827


.99

process allocation 5505 0


1

redo copy 1251593 42


1

row cache objects 56223 960


1

session idle bit 4 0


1

7 rows selected.

You can refer to the Oracle 8 Server Reference Manual for


a comprehensive discussion of all wait events and their
meaning.

Buffer Busy Waits

When access to a buffer is denied by Oracle because it is


busy, it generates a buffer busy wait for each class of
buffer which had waits. The following query and
report.txt output from utlestat.sql shows those that were
present at the time I ran this report on a production
database. In addition, the view V$WAITSTAT also shows all
waits which have occurred since the instance was started.

Prepared by: Ramesh 35


Interpret Statspack Report

By accessing V$SESSION_WAIT you can get the actual


address of the block causing the problem.

SVRMGR> select * from stats$waitstat

2> where count != 0

3> order by count desc;

CLASS COUNT TIME

------------------ ---------------- ----------------

data block 2930 5227

undo header 13 2

undo block 1 0

3 rows selected.

If the count/time is high for a given class of buffers,


this section will help you identify what needs tuning. If
undo headers and/or blocks are showing high waits, adding
more rollback segments can help. If the problem is with
data blocks, increasing the size of the database buffer
cache can reduce these waits. Segment header waits
generally point to the need to add freelists to the
effected table.

Rollback Segment Statistics

Statistics for each rollback segment are shown in this


section. I look at a number of the statistic columns in
tuning rollback segments. Trans_table_waits should be as
close to 0 as possible. A value here indicates a request
for space in a rollback segment had to wait. Increasing
the number of rollback segments will help tuning this
statistic. Shrinks/wraps should be as close to 0 as
possible. Optimally, they should be 0. Any time a
rollback segment wraps, it is physically allocating an
additional extent which requires I/O overhead due to
transaction which will not fit in the initial extent. On
the other side of the coin, wraps occur because a

Prepared by: Ramesh 36


Interpret Statspack Report

rollback segment wrapped (extended) beyond optimal, and


when a second transaction caused it to wrap a second
time, Oracle will shrink the segment back to it's optimal
size again generating I/O overhead. This
allocation/deallocation of extents in rollback segments
is very expensive in terms of overhead on the Oracle
database and should be avoided through tuning.

SVRMGR> select * from stats$roll;

Non-Default init.ora Parameters

Any parameter in the init.ora which is not the default


for Oracle will be listed in this section. The remainder
of the parameters can be viewed by querying V$PARAMETER.
I've only listed a few as an example of the output in the
report.

always_anti_join NESTED_LOOPS

audit_trail DB

background_dump_dest
/u01/oracle/admin/sid/bdump

cache_size_threshold 9765

checkpoint_process TRUE

compatible 7.3.4.0

control_files
/onln/oradata/sid/control01.ctl, /u

core_dump_dest
/u01/oracle/admin/sid/cdump

cpu_count 8

db_block_buffers 97656

db_block_lru_latches 8

db_block_size 8192

Prepared by: Ramesh 37


Interpret Statspack Report

Dictionary Cache Statistics

Unfortunately, under Oracle7, you cannot tune the


dictionary cache portion of the Shared Pool, nor can you
tune the library cache portion. Your only option is to
increase the size of the Shared Pool in the init.ora If
any of the statistics (which you will have to calculate)
is below 95% after the database has been running for a
day or so, you need to increase the size of the
SHARED_POOL parameter in the init.ora. Another indication
of the library cache's being too small is a high number
of recursive calls which is shown in the system wide
statistics session of the report discussed earlier.
Following is the query, and report.txt output from a
production database I support.

SVRMGR> select * from stats$dc 2> where get_reqs !=


0 or scan_reqs != 0 or mod_reqs != 0;

NAME GET_REQS GET_MISS SCAN_REQ SCAN_MIS


MOD_REQS COUNT CUR_USAG

--------------- -------- -------- -------- -------- -----


--- -------- --------

dc_tablespaces 4347 25 0 0
40 44 42

dc_free_extents 7583 3982 632 0


5138 2339 2338

dc_segments 1044563 135 0 0


724 2098 2096

dc_rollback_seg 2958 0 0 0
0 35 22

dc_used_extents 1278 632 0 0


1278 368 103

dc_tablespace_q 8 1 0 0
8 9 6

Prepared by: Ramesh 38


Interpret Statspack Report

dc_users 75786 4 0 0
0 70 68

dc_users 14347 4 0 0
0 70 51

dc_user_grants 38206 4 0 0
0 63 62

dc_objects 283415 83 0 0
1 1904 1899

dc_tables 389821 52 0 0
2 1409 1404

dc_columns 13894139 697 543240 53


0 22091 22090

dc_table_grants 149911 31 0 0
0 943 942

dc_indexes 819875 33 224337 24


0 1389 1388

dc_constraint_d 6945748 358 268030 22


0 11956 11955

dc_constraint_d 0 0 13950 29
0 1 0

dc_synonyms 7270 7 0 0
0 120 118

dc_usernames 19145 5 0 0
0 72 63

dc_object_ids 4384554 31 0 0
0 1367 1366

dc_sequences 443 0 0 0
442 3 1

dc_tablespaces 636 0 0 0
636 10 9

Prepared by: Ramesh 39


Interpret Statspack Report

dc_profiles 9700 0 0 0
0 4 2

dc_database_lin 14 0 0 0
0 7 2

dc_histogram_de 605489 110 0 0


0 3213 3211

dc_truncates 2 0 0 0
2 20 4

25 rows selected.

One way to calculate the hit ratios is to look at the


dictionary cache as a whole by running the following
query:

select sum(gets), sum(getmisses),

(1-(sum(getmisses) / (sum(gets) ))) * 100 HitRate

from v$rowcache;

SUM(GETS) SUM(GETMISSES) HitRatio

844248809 984071 99.8834383

Tablespace and File System I/O Statistics

I'm choosing to combine the last two sections of the


report as their tuning is very much intertwined, and the
same principles apply in both sections. I've also only
included a couple of lines from each section to
illustrate the information contained in each, and how to
read it in tuning the I/O on the database. It's important
to know upfront the two most important parameters in
tuning this section are DB_FILE_MULTIBLOCK_READ_COUNT and
DB_FILE_SIMULTANEOUS_WRITES.
DB_FILE_MULTIBLOCK_READ_COUNT is the parameter Oracle
will go to when accessing a table via a full table scan.
It specifies the number of blocks that can be read in one
I/O when a full table scan is being done. It is very
important to recognize that the blocks being read are not
necessarily contiguous on the physical disk device, but

Prepared by: Ramesh 40


Interpret Statspack Report

in fact are very likely scattered on one or more physical


disks. This is where reviewing statistics discussed
earlier, in particular db file scattered read waits, db
file sequential read waits, db file single write waits
and db file parallel write waits can also help in tuning
I/O which is being challenged by poor disk subsystem
layouts.

In looking at the following tablespace statistics there


are some immediately noticeable items which jump out at
you.

TABLE_SPACE READS BLKS_READ


READ_TIME WRITES BLKS_WRT WRITE_TIME MEGABYTES

---------------------------------------------------------
---------------------- ---------- ---------- ----------

AMAPP 21 21
135 2 2 1 67

AMLARGE 6101 48261


6538 9 9 11 2566

APAPP 59353 469443


143179 28 28 22 537

APLARGE 849118 6517712


492194 104 104 134 1887

ARAPP 29 29
103 0 0 0 67

ARLARGE 1630 2077


6094 36 36 43 67

First, dividing the blocks read column by the number of


reads is an immediate indication that full table scans
are occuring if the ratio is higher than 1 to 1. As an
example, the AMLARGE tablespace as a ratio of 7.91:1
indicating that for each physical I/O which Oracle makes,
it is reading an average of 7.9 blocks of data. You will
see similar ratios on the other tablespaces which are
experiencing numerous full table scans. If the ratio was
exactly 8:1 this would be indicative of every I/O

Prepared by: Ramesh 41


Interpret Statspack Report

operation against the tablespace being executed as a full


table scan, as opposed to using an index first. Adding to
this equation is knowing that the
DB_FILE_MULTIBLOCK_READ_COUNT is set to 8, which is the
number of blocks Oracle can read in a single I/O
operation further supports this conclusion. Looking at
the ARLARGE tablespace, you see the ratio is closer to
1.27 which means an index is being used for a majority of
the access to tables in this tablespace. Other statistics
which you glean from a quick overview, is the proportion
of reads to writes across the tablespaces, which can help
you determine if your database block size is set
correctly to support your application. Again looking at
the AMLARGE tablespace, you will notice only 9 writes
occurred during the duration of the statistics gathering
period compared to 6101 reads. This could be the result
of normal day to day operations which are primarily OLAP
(On Line Analytical Processing), or DSS (Decision Support
Systems) vs. what we would normally expect to see in OLTP
(On-line Transaction Processing) systems which is many
small insert, update and delete operations. In the above
listing, we are clearly looking at a read intensive
application. Contrary to what the developers or users may
think, the above database is virtually 100% read vs.
write. This can drastically effect how you architect and
tune your database, including database block size, file
system layout, datafile distribution, stripe sizes,
number of disks to include in stripe sets, disk speeds
and sizes, and this is just to mention a few of the
issues. The following listing is from the same database
after the DB_FILE_MULTIBLOCK_READ_COUNT was increase from
8 which was used above to 16 where it currently is set.
The decision to increase it from 8 to 16 was made as a
direct result of the above statistics.

TABLE_SPACE READS BLKS_READ


READ_TIME WRITES BLKS_WRT WRITE_TIME MEGABYTES

---------------------------------------------------------
---------------------- ---------- ---------- ----------

AMAPP 21 29
57 0 0 0 67

Prepared by: Ramesh 42


Interpret Statspack Report

AMLARGE 13064 179329


280526 0 0 0 2566

APAPP 9850 148961


295711 27 27 52 537

APLARGE 157324 1914333


1391982 56 56 337 1887

ARAPP 13 13
37 0 0 0 67

ARLARGE 917 1077


4843 6 6 0 67

What should standout in the new listing just above is the


change in the ratios on the same tables mentioned above,
AMLARGE and ARLARGE. Where the ratios on them earlier
where 7.9:1 and 1.3:1 respectively, they are now 13.73:1
and 1.17:1. This represents a reduction in I/O necessary
to return the requested data on AMLARGE by over 75%.

The last section of the report is almost identical to the


tablespace I/O report. The same techniques described
above can be used to assess this section also and should
provided excellent guidance in balancing load across your
storage subsystems.

Prepared by: Ramesh 43

Vous aimerez peut-être aussi