Architecture
To fully understand the STATSPACK architecture, we have to look at the basic nature of the STATSPACK utility. The STATSPACK utility is an outgrowth of the Oracle UTLBSTAT and UTLESTAT utilities, which have been used with Oracle since the very earliest versions.
The BSTAT-ESTAT utilities capture information directly from the Oracle's in-memory structures and then compare the information from two snapshots in order to produce an elapsed-time report showing the activity of the database. If we look inside utlbstat.sql and utlestat.sql, we see the SQL that samples directly from the view: V$SYSSTAT;
insert into stats$begin_stats select * from v$sysstat; insert into stats$end_stats select * from v$sysstat;
![]()
When a snapshot is executed, the STATSPACK software will
sample from the RAM in-memory structures inside the SGA and transfer the values
into the corresponding STATSPACK tables. These values are then available for
comparing with other snapshots.
![]()
Note that in most cases, there is a direct correspondence
between the v$ view in the SGA and the corresponding STATSPACK table. For
example, we see that the stats$sysstat table is similar to the
v$sysstat view.
SQL> desc v$sysstat; Name Null?
Type ----------------------------------------- --------
----------------------- STATISTIC#
NUMBER NAME
VARCHAR2(64) CLASS
NUMBER VALUE
NUMBER STAT_ID
NUMBER
SQL> desc stats$sysstat; Name Null?
Type ----------------------------------------- --------
----------------------- SNAP_ID NOT NULL
NUMBER DBID NOT NULL
NUMBER INSTANCE_NUMBER NOT NULL
NUMBER STATISTIC# NOT NULL
NUMBER NAME NOT NULL
VARCHAR2(64) VALUE
NUMBER
It is critical to your understanding of the
STATSPACK utility that you realize the information captured by a STATSPACK
snapshot is accumulated values. The information from the V$VIEWS collects
database information at startup time and continues to add the values until the
instance is shutdown. In order to get a meaningful elapsed-time report, you must
run a STATSPACK report that compares two snapshots as shown above. It is
critical to understand that a report will be invalid if the database is shut
down between snapshots. This is because all of the accumulated values will be
reset, causing the second snapshot to have smaller values than the first
snapshot.
Installing and Configuring STATSPACK
Create PERFSTAT Tablespace
The STATSPACK utility requires an isolated
tablespace to obtain all of the objects and data. For uniformity, it is
suggested that the tablespace be called PERFSTAT, the same name as the schema
owner for the STATSPACK tables. It is important to closely watch the STATSPACK
data to ensure that the stats$sql_summary table is not taking an inordinate
amount of space.
SQL> CREATE TABLESPACE
perfstat DATAFILE
'/u01/oracle/db/AKI1_perfstat.dbf' SIZE
1000M REUSE EXTENT MANAGEMENT LOCAL UNIFORM SIZE
512K SEGMENT SPACE MANAGEMENT AUTO PERMANENT
ONLINE;
Run the Create Scripts
Now that the tablespace exists, we can begin
the installation process of the STATSPACK software. Note that you must have
performed the following before attempting to install STATSPACK.
-
Run catdbsyn.sql as
SYS
-
Run dbmspool.sql as
SYS
$ cd $ORACLE_HOME/rdbms/admin $ sqlplus "/ as sysdba" SQL>
start spcreate.sql
Choose the PERFSTAT user's
password ----------------------------------- Not specifying a password
will result in the installation FAILING
Enter value for
perfstat_password: perfstat
Choose the Default tablespace for the
PERFSTAT user --------------------------------------------------- Below is
the list of online tablespaces in this database which can store user data.
Specifying the SYSTEM tablespace for the user's default tablespace will
result in the installation FAILING, as using SYSTEM for performance data is
not supported.
Choose the PERFSTAT users's default tablespace. This is
the tablespace in which the STATSPACK tables and indexes will be
created.
TABLESPACE_NAME CONTENTS STATSPACK DEFAULT
TABLESPACE ------------------------------ ---------
---------------------------- PERFSTAT PERMANENT SYSAUX PERMANENT
* USERS PERMANENT
Pressing <return> will result in STATSPACK's
recommended default tablespace (identified by *) being used.
Enter
value for default_tablespace: PERFSTAT
Choose the Temporary tablespace for the
PERFSTAT user ----------------------------------------------------- Below
is the list of online tablespaces in this database which can store temporary
data (e.g. for sort workareas). Specifying the SYSTEM tablespace for the
user's temporary tablespace will result in the installation FAILING, as using
SYSTEM for workareas is not supported.
Choose the PERFSTAT user's
Temporary tablespace.
TABLESPACE_NAME CONTENTS DB DEFAULT TEMP
TABLESPACE ------------------------------ ---------
-------------------------- TEMP TEMPORARY *
Pressing <return>
will result in the database's default Temporary tablespace (identified by *)
being used.
Enter value for temporary_tablespace: TEMP
..... ..... Creating Package
STATSPACK...
Package created.
No errors. Creating Package Body
STATSPACK...
Package body created.
No
errors.
NOTE: SPCPKG complete. Please check spcpkg.lis for any
errors.
Check the Logfiles: spcpkg.lis, spctab.lis,
spcusr.lis
Adjusting the STATSPACK Collection
Level
STATSPACK has two types of collection options,
level and threshold. The level parameter controls the type of data
collected from Oracle, while the threshold parameter acts as a filter for
the collection of SQL statements into the stats$sql_summary
table.
SQL> SELECT * FROM
stats$level_description ORDER BY snap_level;
| Level 0 |
This level captures general
statistics, including rollback segment, row cache, SGA, system events,
background events, session events, system statistics, wait statistics, lock
statistics, and Latch information. |
| Level 5 |
This level includes capturing high
resource usage SQL Statements, along with all data captured by lower
levels. |
| Level 6 |
This level includes capturing SQL
plan and SQL plan usage information for high resource usage SQL Statements,
along with all data captured by lower levels. |
| Level 7 |
This level captures segment level
statistics, including logical and physical reads, row lock, itl and buffer busy
waits, along with all data captured by lower levels. |
| Level 10 |
This level includes capturing Child
Latch statistics, along with all data captured by lower
levels. |
You can change the default level of a snapshot
with the statspack.snap function. The
i_modify_parameter =>
'true' changes the level permanent for all
snapshots in the future.
SQL> exec
statspack.snap(i_snap_level => 6, i_modify_parameter
=> 'true');
Create, View and Delete
Snapshots
sqlplus perfstat/perfstat SQL> exec
statspack.snap; SQL> select
name,snap_id,to_char(snap_time,'DD.MM.YYYY:HH24:MI:SS') "Date/Time" from
stats$snapshot,v$database;
NAME SNAP_ID
Date/Time --------- ---------- ------------------- AKI1 4
14.11.2004:10:56:01 AKI1 1
13.11.2004:08:48:47 AKI1 2
13.11.2004:09:00:01 AKI1 3
13.11.2004:09:01:48
SQL>
@?/rdbms/admin/sppurge; Enter the Lower and Upper
Snapshot ID
Create the Report
sqlplus perfstat/perfstat SQL>
@?/rdbms/admin/spreport.sql
Statspack at a Glance
What if you have this long STATSPACK report and you want to
figure out if everything is running smoothly? Here, we will review what we look
for in the report, section by section. We will use an actual STATSPACK report
from our own Oracle 10g system.
STATSPACK report
for
DB Name DB Id Instance Inst Num Release RAC
Host ------------ ----------- ------------ -------- ----------- ---
---------------- AKI1 2006521736 AKI1 1 10.1.0.2.0
NO akira
Snap Id Snap Time Sessions Curs/Sess
Comment --------- ------------------ -------- ---------
------------------- Begin Snap: 5 14-Nov-04 11:18:00 15
14.3 End Snap: 6 14-Nov-04 11:33:00 15 10.2
Elapsed: 15.00
(mins)
Cache Sizes
(end) ~~~~~~~~~~~~~~~~~ Buffer Cache: 24M Std
Block Size: 4K Shared Pool Size: 764M Log
Buffer: 1,000K
Note that this section may appear slightly different
depending on your version of Oracle. For example, the Curs/Sess column, which
shows the number of open cursors per session, is new with Oracle9i (an 8i
Statspack report would not show this data).
Here, the item we are most interested in is the elapsed
time. We want that to be large enough to be meaningful, but small enough to
be relevant (15 to 30 minutes is OK). If we use longer times, we begin to
lose the needle in the haystack.
Load
Profile ~~~~~~~~~~~~ Per Second Per
Transaction ---------------
--------------- Redo size: 425,649.84
16,600,343.64 Logical reads: 1,679.69
65,508.00 Block changes: 2,546.17
99,300.45 Physical reads: 77.81
3,034.55 Physical writes: 78.35
3,055.64 User calls: 0.24
9.55 Parses: 2.90
113.00 Hard
parses: 0.16 6.27 Sorts:
0.76 29.82 Logons:
0.01 0.36 Executes: 4.55
177.64 Transactions:
0.03
% Blocks changed per Read:
151.59 Recursive Call %: 99.56 Rollback per transaction %:
0.00 Rows per Sort: 65.61
Here, we are interested in a variety of things, but if we
are looking at a "health check", three items are important:
- The Hard parses (we want very few of them)
- Executes (how many statements we are executing per
second / transaction)
- Transactions (how many transactions per second we
process).
This gives an overall view of the load on the server.
In this case, we are looking at a very good hard parse number and a fairly light
system load (1 - 4 transactions per second is low).
Next, we move onto the Instance Efficiency Percentages
section, which includes perhaps the only ratios we look at in any
detail:
Instance Efficiency
Percentages (Target
100%) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Buffer
Nowait %: 100.00 Redo NoWait %: 99.99 Buffer Hit %:
95.39 In-memory Sort %: 100.00 Library Hit %: 99.42 Soft Parse %:
94.45 Execute to Parse %: 36.39 Latch Hit %: 100.00 Parse CPU to Parse Elapsd %:
59.15 % Non-Parse CPU: 99.31
Shared Pool Statistics Begin
End ------ ------ Memory
Usage %: 10.28 10.45 % SQL with executions>1: 70.10 71.08
% Memory for SQL w/exec>1: 44.52 44.70
The three in bold are the most important: Library Hit, Soft
Parse % and Execute to Parse. All of these have to do with how well the shared
pool is being utilized. Time after time, we find this to be the area of greatest
payback, where we can achieve some real gains in performance.
Here, in this report, we are quite pleased with the Library
Hit and the Soft Parse % values. If the library Hit ratio was low, it
could be indicative of a shared pool that is too small, or just as
likely, that the system did not make correct use of bind variables in the
application. It would be an indicator to look at issues such as
those.
OLTP System
The Soft Parse % value is one of the most important
(if not the only important) ratio in the database. For a typical OLTP system,
it should be as near to 100% as possible. You quite simply do not hard
parse after the database has been up for a while in your typical transactional /
general-purpose database. The way you achieve that is with bind
variables. In a regular system like this, we are doing many executions per
second, and hard parsing is something to be avoided.
Data Warehouse
In a data warehouse, we would like to generally see the
Soft Parse ratio lower. We don't necessarily want to use bind variables in a
data warehouse. This is because they typically use materialized views,
histograms, and other things that are easily thwarted by bind variables. In a
data warehouse, we may have many seconds between executions, so hard parsing is
not evil; in fact, it is good in those environments.
The moral of this is ...
... to look at these ratios and look at how the system
operates. Then, using that knowledge, determine if the ratio is okay given the
conditions. If we just said that the execute-to-parse ratio for your system
should be 95% or better, that would be unachievable in many web-based systems.
If you have a routine that will be executed many times to generate a page, you
should definitely parse once per page and execute it over and over, closing the
cursor if necessary before your connection is returned to the connection
pool.
Moving on, we get to the Top 5 Timed Events section (in
Oracle9i Release 2 and later) or Top 5 Wait Events (in Oracle9i Release 1 and
earlier).
Top 5 Timed
Events ~~~~~~~~~~~~~~~~~~
% Total Event Waits Time (s)
Call Time -------------------------------------------- ------------
----------- --------- CPU
time 122
91.65 db file sequential read 1,571
2 1.61 db file scattered read
1,174 2 1.59 log file
sequential read 342 2
1.39 control file parallel write 450
2 1.39
------------------------------------------------------------- Wait Events
DB/Inst: AKI1/AKI1 Snaps: 5-6
-> s - second -> cs -
centisecond - 100th of a second -> ms - millisecond - 1000th of a
second -> us - microsecond - 1000000th of a second -> ordered by
wait time desc, waits desc (idle events last)
This section is among the most important and relevant
sections in the Statspack report. Here is where you find out what events
(typically wait events) are consuming the most time. In Oracle9i Release 2, this
section is renamed and includes a new event: CPU time.
- CPU time is not really a wait event (hence, the new
name), but rather the sum of the CPU used by this session, or the amount of CPU
time used during the snapshot window. In a heavily loaded system, if the CPU
time event is the biggest event, that could point to some CPU-intensive
processing (for example, forcing the use of an index when a full scan should
have been used), which could be the cause of the bottleneck.
- Db file sequential read - This wait event will be
generated while waiting for writes to TEMP space generally (direct loads,
Parallel DML (PDML) such as parallel updates. You may tune the PGA AGGREGATE
TARGET parameter to reduce waits on sequential reads.
- Db file scattered read - Next is the db file
scattered read wait value. That generally happens during a full scan of a
table. You can use the Statspack report to help identify the query in
question and fix it.
Here you will find the most CPU-Time consuming
SQL statements
SQL ordered by Gets
DB/Inst: AKI1/AKI1 Snaps: 5-6 -> Resources reported for PL/SQL code
includes the resources used by all SQL statements called by the
code. -> End Buffer Gets Threshold: 10000 Total Buffer Gets:
720,588 -> Captured SQL accounts for 3.1% of Total Buffer Gets ->
SQL reported below exceeded 1.0% of Total Buffer
Gets
CPU
Elapsd Old Buffer Gets Executions Gets per Exec %Total Time (s)
Time (s) Hash Value --------------- ------------ -------------- ------
-------- --------- ---------- 16,926 1 16,926.0
2.3 2.36 3.46 1279400914 Module: SQL*Plus create table test as select * from
all_objects
Tablespace ------------------------------
Av Av Av Av Buffer Av Buf Reads
Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms) --------------
------- ------ ------- ------------ -------- ---------- ------ TAB
1,643 4 1.0 19.2 16,811 39 0
0.0 UNDO 166 0 0.5 1.0 5,948 14 0
0.0 SYSTEM 813 2 2.5 1.6 167 0 0
0.0 STATSPACK 146 0 0.3 1.1 277 1 0
0.0 SYSAUX 18 0 0.0 1.0 29 0 0
0.0 IDX 18 0 0.0 1.0 18 0 0
0.0 USER 18 0 0.0 1.0 18 0 0
0.0
-------------------------------------------------------------
->A high value for "Pct
Waits" suggests more rollback segments may be required ->RBS stats may not
be accurate between begin and end snaps when using Auto Undo managment, as
RBS may be dynamically created and dropped as needed
Trans
Table Pct Undo Bytes RBS No Gets Waits Written
Wraps Shrinks Extends ------ -------------- ------- ---------------
-------- -------- -------- 0 8.0 0.00
0 0 0 0 1 3,923.0 0.00
14,812,586 15 0 14 2 5,092.0 0.00
19,408,996 19 0 19 3 295.0 0.00
586,760 1 0 0 4 1,312.0 0.00
4,986,920 5 0 5 5 9.0
0.00 0 0 0 0 6 9.0
0.00 0 0 0 0 7 9.0
0.00 0 0 0 0 8 9.0
0.00 0 0 0 0 9 9.0
0.00 0 0 0 0 10 9.0
0.00 0 0 0 0
-------------------------------------------------------------
->Optimal Size should
be larger than Avg Active
RBS No Segment Size Avg Active
Optimal Size Maximum Size ------ --------------- ---------------
--------------- --------------- 0 364,544
0 364,544 1 17,952,768
8,343,482 17,952,768 2 25,292,800
11,854,857 25,292,800 3 4,321,280
617,292 6,418,432 4 8,515,584
1,566,623 8,515,584 5
126,976 0 126,976 6
126,976 0 126,976 7
126,976 0 126,976 8
126,976 0 126,976 9
126,976 0 126,976 10
126,976 0 126,976
-------------------------------------------------------------
Generate Execution Plan for given SQL
statement
If you have identified one or more problematic
SQL statement, you may want to check the execution plan. Remember the "Old Hash
Value" from the report above (1279400914), then execute the scrip to generate
the execution plan.
sqlplus perfstat/perfstat SQL>
@?/rdbms/admin/sprepsql.sql Enter the Hash Value,
in this example: 1279400914
SQL
Text ~~~~~~~~ create table test as select * from all_objects
Known
Optimizer Plan(s) for this Old Hash
Value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Shows all known
Optimizer Plans for this database instance, and the Snap Id's they were first
found in the shared pool. A Plan Hash Value will appear multiple times if
the cost has changed -> ordered by Snap Id
First
First Plan Snap Id Snap Time Hash Value
Cost --------- --------------- ------------ ---------- 6 14 Nov 04
11:26 1386862634 52
Plans in shared pool between Begin and End
Snap Ids ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Shows the
Execution Plans found in the shared pool between the begin and end snapshots
specified. The values for Rows, Bytes and Cost shown below are those which
existed at the time the first-ever snapshot captured this plan - these values
often change over time, and so may not be indicative of current values ->
Rows indicates Cardinality, PHV is Plan Hash Value -> ordered by Plan Hash
Value
-------------------------------------------------------------------------------- |
Operation | PHV/Object Name | Rows | Bytes| Cost
| -------------------------------------------------------------------------------- |CREATE
TABLE STATEMENT |----- 1386862634 ----| | | 52
| |LOAD AS SELECT | | |
| | | VIEW | | 1K|
216K| 44 | | FILTER | |
| | | | HASH JOIN |
| 1K| 151K| 38 | | TABLE ACCESS FULL
|USER$ | 29 | 464 | 2 | | TABLE ACCESS
FULL |OBJ$ | 3K| 249K| 35 | | TABLE
ACCESS BY INDEX ROWID |IND$ | 1 | 7 | 2 | |
INDEX UNIQUE SCAN |I_IND1 | 1 | | 1
| | NESTED LOOPS | | 5 | 115 |
16 | | INDEX RANGE SCAN |I_OBJAUTH1 | 1 | 10
| 2 | | FIXED TABLE FULL |X$KZSRO | 5 |
65 | 14 | | FIXED TABLE FULL |X$KZSPR | 1
| 26 | 14 | | FIXED TABLE FULL |X$KZSPR
| 1 | 26 | 14 | | FIXED TABLE FULL
|X$KZSPR | 1 | 26 | 14 | | FIXED TABLE
FULL |X$KZSPR | 1 | 26 | 14 | | FIXED
TABLE FULL |X$KZSPR | 1 | 26 | 14 | |
FIXED TABLE FULL |X$KZSPR | 1 | 26 | 14
| | FIXED TABLE FULL |X$KZSPR | 1 | 26 |
14 | | FIXED TABLE FULL |X$KZSPR | 1 | 26
| 14 | | FIXED TABLE FULL |X$KZSPR | 1 |
26 | 14 | | FIXED TABLE FULL |X$KZSPR | 1
| 26 | 14 | | FIXED TABLE FULL |X$KZSPR
| 1 | 26 | 14 | | FIXED TABLE FULL
|X$KZSPR | 1 | 26 | 14 | | FIXED TABLE
FULL |X$KZSPR | 1 | 26 | 14 | | FIXED
TABLE FULL |X$KZSPR | 1 | 26 | 14 | |
FIXED TABLE FULL |X$KZSPR | 1 | 26 | 14
| | FIXED TABLE FULL |X$KZSPR | 1 | 26 |
14 | | FIXED TABLE FULL |X$KZSPR | 1 | 26
| 14 | | FIXED TABLE FULL |X$KZSPR | 1 |
26 | 14 | | FIXED TABLE FULL |X$KZSPR | 1
| 26 | 14 | | FIXED TABLE FULL |X$KZSPR
| 1 | 26 | 14 | | VIEW
| | 1 | 13 | 2 | | FAST
DUAL | | 1 | | 2
| --------------------------------------------------------------------------------
Resolving Your Wait Events
The following are 10 of the most common causes
for wait events, along with explanations and potential
solutions:
This generally indicates waits related to
full table scans. As full table scans are pulled into memory, they rarely
fall into contiguous buffers but instead are scattered throughout the buffer
cache. A large number here indicates that your table may have missing or
suppressed indexes. Although it may be more efficient in your situation to
perform a full table scan than an index scan, check to ensure that full table
scans are necessary when you see these waits. Try to cache small tables to avoid
reading them in over and over again, since a full table scan is put at the cold
end of the LRU (Least Recently Used) list.
This event generally indicates a single block
read (an index read, for example). A large number of waits here could indicate
poor joining orders of tables, or unselective indexing. It is normal for
this number to be large for a high-transaction, well-tuned system, but it can
indicate problems in some circumstances. You should correlate this wait
statistic with other known issues within the Statspack report, such as
inefficient SQL. Check to ensure that index scans are necessary, and check join
orders for multiple table joins. The DB_CACHE_SIZE will also be a determining
factor in how often these waits show up. Problematic hash-area joins should show
up in the PGA memory, but they're also memory hogs that could cause high wait
numbers for sequential reads. They can also show up as direct path read/write
waits.
This indicates your system is waiting for a
buffer in memory, because none is currently available. Waits in this category
may indicate that you need to increase the DB_BUFFER_CACHE, if all your
SQL is tuned. Free buffer waits could also indicate that unselective SQL is
causing data to flood the buffer cache with index blocks, leaving none for this
particular statement that is waiting for the system to process. This normally
indicates that there is a substantial amount of DML (insert/update/delete) being
done and that the Database Writer (DBWR) is not writing quickly enough; the
buffer cache could be full of multiple versions of the same buffer, causing
great inefficiency. To address this, you may want to consider accelerating
incremental checkpointing, using more DBWR processes, or increasing the
number of physical disks.
This is a wait for a buffer that is being used
in an unshareable way or is being read into the buffer cache. Buffer busy
waits should not be greater than 1 percent. Check the Buffer Wait Statistics
section (or V$WAITSTAT) to find out if the wait is on a segment header. If this
is the case, increase the freelist groups or increase the pctused to
pctfree gap. If the wait is on an undo header, you can address this by
adding rollback segments; if it's on an undo block, you need to reduce the data
density on the table driving this consistent read or increase the DB_CACHE_SIZE.
If the wait is on a data block, you can move data to another block to avoid this
hot block, increase the freelists on the table, or use Locally Managed
Tablespaces (LMTs). If it's on an index block, you should rebuild the index,
partition the index, or use a reverse key index. To prevent buffer busy waits
related to data blocks, you can also use a smaller block size: fewer records
fall within a single block in this case, so it's not as "hot." When a DML
(insert/update/ delete) occurs, Oracle Database writes information into the
block, including all users who are "interested" in the state of the block
(Interested Transaction List, ITL). To decrease waits in this area, you can
increase the initrans, which will create the space in the block to allow
multiple ITL slots. You can also increase the pctfree on the table where
this block exists (this writes the ITL information up to the number specified by
maxtrans, when there are not enough slots built with the initrans
that is specified).
Latches are low-level queuing mechanisms
(they're accurately referred to as mutual exclusion mechanisms) used to protect
shared memory structures in the system global area (SGA). Latches are like locks
on memory that are very quickly obtained and released. Latches are used to
prevent concurrent access to a shared memory structure. If the latch is
not available, a latch free miss is recorded. Most latch problems are related to
the failure to use bind variables (library cache latch), redo generation
issues (redo allocation latch), buffer cache contention issues (cache buffers
LRU chain), and hot blocks in the buffer cache (cache buffers chain). There are
also latch waits related to bugs; check MetaLink for bug reports if you suspect
this is the case. When latch miss ratios are greater
than 0.5 percent, you should investigate the issue.
An enqueue is a lock that protects a shared
resource. Locks protect shared resources, such as data in a record, to prevent
two people from updating the same data at the same time. An enqueue includes a
queuing mechanism, which is FIFO (first in, first out). Note that Oracle's
latching mechanism is not FIFO. Enqueue waits usually point to the ST enqueue,
the HW enqueue, the TX4 enqueue, and the TM enqueue. The ST enqueue is used for
space management and allocation for dictionary-managed tablespaces. Use LMTs, or
try to preallocate extents or at least make the next extent larger for
problematic dictionary-managed tablespaces. HW enqueues are used with the
high-water mark of a segment; manually allocating the extents can circumvent
this wait. TX4s are the most common enqueue waits. TX4 enqueue waits are usually
the result of one of three issues. The first issue is duplicates in a unique
index; you need to commit/rollback to free the enqueue. The second is multiple
updates to the same bitmap index fragment. Since a single bitmap fragment may
contain multiple rowids, you need to issue a commit or rollback to free the
enqueue when multiple users are trying to update the same fragment. The third
and most likely issue is when multiple users are updating the same block.
If there are no free ITL slots, a block-level lock could occur. You can easily
avoid this scenario by increasing the initrans and/or maxtrans to
allow multiple ITL slots and/or by increasing the pctfree on the table.
Finally, TM enqueues occur during DML to prevent DDL to the affected object. If
you have foreign keys, be sure to index them to avoid this general
locking issue.
This wait occurs because you are writing the
log buffer faster than LGWR can write it to the redo logs, or because log
switches are too slow. To address this problem, increase the size of the log
files, or increase the size of the log buffer, or get faster disks to write to.
You might even consider using solid-state disks, for their high
speed.
All commit requests are waiting for "logfile
switch (archiving needed)" or "logfile switch (Checkpoint. Incomplete)." Ensure that the archive disk is not full or slow.
DBWR may be too slow because of I/O. You may need to add more or larger redo
logs, and you may potentially need to add database writers if the DBWR is the
problem.
When a user commits or rolls back data, the
LGWR flushes the session's redo from the log buffer to the redo logs. The log
file sync process must wait for this to successfully complete. To reduce wait
events here, try to commit more records (try to commit a batch of 50 instead
of one at a time, for example). Put redo logs on a faster disk, or alternate
redo logs on different physical disks, to reduce the archiving effect on LGWR.
Don't use RAID 5, since it is very slow for applications that write a lot;
potentially consider using file system direct I/O or raw devices, which are very
fast at writing information.
There are several idle wait events listed after
the output; you can ignore them. Idle events are generally listed at the bottom
of each section and include such things as SQL*Net message to/from client and
other background-related timings. Idle events are listed in the stats$idle_event
table.
Remove STATSPACK from the Database
After a STATSPACK session you want to remove
the STATSPACK tables.
sqlplus "/ as sysdba" SQL>
@?/rdbms/admin/spdrop.sql SQL> DROP TABLESPACE perfstat
INCLUDING CONTENTS AND DATAFILES;
|