Wednesday, April 23, 2008

TX Transaction locks - Example wait scenarios (enqueue)

Subject: TX Transaction locks - Example wait scenarios
Doc ID: Note:62354.1 Type: TROUBLESHOOTING
Last Revision Date: 28-FEB-2008 Status: PUBLISHED


Introduction
~~~~~~~~~~~~
This short article gives examples of TX locks and the waits which can
occur in various circumstances. Often such waits will go unnoticed unless
they are of a long duration or when they trigger a deadlock scenario (which
raises an ORA-60 error).

The examples here demonstrate fundamental locking scenarios which should
be understood by application developers and DBA's alike.


Useful SQL statements
~~~~~~~~~~~~~~~~~~~~~
If you encounter a lock related hang scenario the following SQL statements
can be used to help isolate the waiters and blockers:

Show all sessions waiting for any lock:

select event,p1,p2,p3 from v$session_wait
where wait_time=0 and event='enqueue';

Show sessions waiting for a TX lock:

select * from v$lock where type='TX' and request>0;

Show sessions holding a TX lock:

select * from v$lock where type='TX' and lmode>0;


What is a TX lock ?
~~~~~~~~~~~~~~~~~~~
A TX lock is acquired when a transaction initiates its first change and is
held until the transaction does a COMMIT or ROLLBACK. It is used mainly as
a queuing mechanism so that other sessions can wait for the transaction to
complete. The lock name (ID1 and ID2) of the TX lock reflect the transaction
ID of the active transaction.


Example Tables
~~~~~~~~~~~~~~
The lock waits which can occur are demonstrated using the following
tables. Connect as SCOTT/TIGER or some dummy user to set up the test
environment using the following SQL:

DROP TABLE tx_eg;
CREATE TABLE tx_eg ( num number, txt varchar2(10), sex varchar2(10) )
INITRANS 1 MAXTRANS 1;
INSERT into tx_eg VALUES ( 1, 'First','FEMALE' );
INSERT into tx_eg VALUES ( 2, 'Second','MALE' );
INSERT into tx_eg VALUES ( 3, 'Third','MALE' );
INSERT into tx_eg VALUES ( 4, 'Fourth','MALE' );
INSERT into tx_eg VALUES ( 5, 'Fifth','MALE' );
COMMIT;

In the examples below three sessions are required:

Ses#1 indicates the TX_EG table owners first session
Ses#2 indicates the TX_EG table owners second session
DBA indicates a SYSDBA user with access to


The examples covered below include:

Waits due to Row being locked by an active Transaction
Waits due to Unique or Primary Key Constraint enforcement
Waits due to Insufficient 'ITL' slots in the Block
Waits due to rows being covered by the same BITMAP index fragment


Waits due to Row being locked by an active Transaction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a session updates a row in a table the row is locked by the sessions
transaction. Other users may SELECT that row and will see row as it was
BEFORE the UPDATE occurred. If another session wishes to UPDATE the same
row it has to wait for the first session to commit or rollback. The
second session waits for the first sessions TX lock in EXCLUSIVE mode.

Eg:
Ses#1: update tx_eg set txt='Garbage' where num=1;
Ses#2: update tx_eg set txt='Garbage' where num=1;
DBA: select SID,TYPE,ID1,ID2,LMODE,REQUEST
from v$lock where type='TX';

SID TY ID1 ID2 LMODE REQUEST
---------- -- ---------- ---------- ---------- ----------
8 TX 131075 597 6 0
10 TX 131075 597 0 6

> This shows SID 10 is waiting for the TX lock held by SID 8 and it
> wants the lock in exclusive mode (as REQUEST=6).

The select below is included to demonstrate that a session waiting
on a lock will show as waiting on an 'enqueue' in V$SESSION_WAIT
and that the values of P1RAW, P2 and P3 indicate the actual lock
being waited for. When using Parallel Server the EVENT will be
'DFS enqueue lock acquisition' rather than 'enqueue'.
This select will be omitted from the following examples.

DBA: select sid,p1raw, p2, p3
from v$session_wait
where wait_time=0 and event='enqueue';

SID P1RAW P2 P3
---------- -------- ---------- ----------
10 54580006 131075 597
> ~~~~ ~~ ~~~~~~ ~~~
> type|mode id1 id2
> T X 6 131075 597


The next select shows the object_id and the exact row that the
session is waiting for. This information is only valid in V$SESSION
when a session is waiting due to a row level lock. The statement
is only valid in Oracle 7.3 onwards. As SID 10 is the waiter above
then this is the session to look at in V$SESSION:

DBA: select ROW_WAIT_OBJ#,
ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#
from v$session
where sid=10;

ROW_WAIT_O ROW_WAIT_F ROW_WAIT_B ROW_WAIT_R
---------- ---------- ---------- ----------
3058 4 2683 0

> The waiter is waiting for the TX lock in order to lock row 0
> in file 4, block 2683 of object 3058.

Ses#1: rollback;
Ses#2: rollback;


Waits due to Unique or Primary Key Constraint enforcement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a table has a primary key constraint, a unique constraint
or a unique index then the uniqueness of the column/s referenced by
the constraint is enforced by a unique index. If two sessions try to
insert the same key value the second session has to wait to see if an
ORA-0001 should be raised or not.

Eg:
Ses#1: ALTER TABLE tx_eg ADD CONSTRAINT tx_eg_pk PRIMARY KEY( num );
Ses#1: insert into tx_eg values (10,'New','MALE');
Ses#2: insert into tx_eg values (10,'OtherNew',null);
DBA: select SID,TYPE,ID1,ID2,LMODE,REQUEST
from v$lock where type='TX';

SID TY ID1 ID2 LMODE REQUEST
---------- -- ---------- ---------- ---------- ----------
8 TX 196625 39 6 0
10 TX 262155 65 6 0
10 TX 196625 39 0 4

This shows SID 10 is waiting for the TX lock held by SID 8 and it
wants the lock in share mode (as REQUEST=4). SID 10 holds a TX lock
for its own transaction.

Ses#1: commit;
Ses#2: ORA-00001: unique constraint (SCOTT.TX_EG_PK) violated
Ses#2: rollback;


Waits due to Insufficient 'ITL' slots in a Block
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Oracle keeps note of which rows are locked by which transaction in an area
at the top of each data block known as the 'interested transaction list'.
The number of ITL slots in any block in an object is controlled by
the INITRANS and MAXTRANS attributes. INITRANS is the number of slots
initially created in a block when it is first used, while MAXTRANS places
an upper bound on the number of entries allowed. Each transaction which
wants to modify a block requires a slot in this 'ITL' list in the block.

MAXTRANS places an upper bound on the number of concurrent transactions
which can be active at any single point in time within a block.

INITRANS provides a minimum guaranteed 'per-block' concurrency.

If more than INITRANS but less than MAXTRANS transactions want to be
active concurrently within the same block then the ITL list will be extended
BUT ONLY IF THERE IS SPACE AVAILABLE TO DO SO WITHIN THE BLOCK.

If there is no free 'ITL' then the requesting session will wait on one
of the active transaction locks in mode 4.

Eg: Ses#1: update tx_eg set txt='Garbage' where num=1;
Ses#2: update tx_eg set txt='Different' where num=2;
DBA: select SID,TYPE,ID1,ID2,LMODE,REQUEST
from v$lock where type='TX';

SID TY ID1 ID2 LMODE REQUEST
---------- -- ---------- ---------- ---------- ----------
8 TX 327688 48 6 0
10 TX 327688 48 0 4

This shows SID 10 is waiting for the TX lock held by SID 8 and it
wants the lock in share mode (as REQUEST=4).

Ses#1: commit;
Ses#2: commit;
Ses#1: ALTER TABLE tx_eg MAXTRANS 2;
Ses#1: update tx_eg set txt='First' where num=1;
Ses#2: update tx_eg set txt='Second' where num=2;

Both rows update as there is space to grow the ITL list to
accommodate both transactions.

Ses#1: commit;
Ses#2: commit;

Also from 9.2 you can check the ITL Waits in v$segment_statistics
with a query like :
SELECT t.OWNER, t.OBJECT_NAME, t.OBJECT_TYPE, t.STATISTIC_NAME, t.VALUE
FROM v$segment_statistics t
WHERE t.STATISTIC_NAME = 'ITL waits'
AND t.VALUE > 0;

If need be, increase INITTRANS and MAXTRANS.

Waits due to rows being covered by the same BITMAP index fragment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bitmap indexes index key values and a range of ROWIDs. Each 'entry'
in a bitmap index can cover many rows in the actual table.
If 2 sessions wish to update rows covered by the same bitmap index
fragment then the second session waits for the first transaction to
either COMMIT or ROLLBACK by waiting for the TX lock in mode 4.

Eg: Ses#1: CREATE Bitmap Index tx_eg_bitmap on tx_eg ( sex );
Ses#1: update tx_eg set sex='FEMALE' where num=3;
Ses#2: update tx_eg set sex='FEMALE' where num=4;
DBA: select SID,TYPE,ID1,ID2,LMODE,REQUEST
from v$lock where type='TX';

SID TY ID1 ID2 LMODE REQUEST
---------- -- ---------- ---------- ---------- ----------
8 TX 262151 62 6 0
10 TX 327680 60 6 0
10 TX 262151 62 0 4

This shows SID 10 is waiting for the TX lock held by SID 8 and it
wants the lock in share mode (as REQUEST=4).

Ses#1: commit;
Ses#2: commit;


Other Scenarios
~~~~~~~~~~~~~~~
There are other wait scenarios which can result in a SHARE mode wait for a TX
lock but these are rare compared to the examples given above.
Eg: If a session wants to read a row locked by a transaction in a PREPARED
state then it will wait on the relevant TX lock in SHARE mode (REQUEST=4).
As a PREPARED transaction should COMMIT , ROLLBACK or go to an in-doubt
state very soon after the prepare this is not generally noticeable..

Tuesday, April 22, 2008

Finding root blocker (enqueue)

Subject: Detecting Blocking Sessions in RAC and non-RAC (Enqueue Locks) Environments
Doc ID: Note:398519.1 Type: SCRIPT
Last Revision Date: 12-JAN-2007 Status: PUBLISHED

In this Document
Purpose
Software Requirements/Prerequisites
Configuring the Script
Running the Script
Caution
Script
Script Output
References



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



Applies to: Oracle Server - Enterprise Edition - Version: 7.3.4 to 10.2
Information in this document applies to any platform.
PurposeScript and explanation for finding blocking and blocked sessions in both RAC (multi instance) and non-RAC (single instance) environments.
.
Locking Mechanism
Resources (rows, tables, control files ...) represented by enqueues (TX, TM, CF, ...) can be locked in various modes (i.e. shared, exclusive, ...). Concurrent locking requests can conflict as per compatibility rules. Resources (enqueues) are externalized via GV$RESOURCE and lock requests via GV$LOCK views. Details can be found in
'Oracle® Database Concepts' -> chapter 'Data Concurrency and Consistency' (10.2. version)
.
Locking Conflict Types
1. Local locking conflict (block) - conflicting sessions are connected to the same instance (also applies to one instance of RAC)
Drawback: V$LOCK column BLOCK contains value 1 for blocking lock (session)
2. Global locking conflict (block) - conflicting sessions are connected to different instances (multi instance RAC only)
Drawback: V$LOCK column BLOCK contains value 2 to mark potential conflict (value is always 2 in RAC environments unless there is local conflict)
@ as per Bug:3230663 in 10.2 we should be able to detect global conflict (but still reproducible in 10.2.0.2 @ Linux x86 )
.

Script Principle
Display all sessions holding or requesting lock of resource some session is waiting for. Waiting session has non-zero value of column GV$LOCK.REQUEST. Resource is identified by (TYPE,ID1,ID2 columns of GV$LOCK view).
.
We cannot use GV$LOCK.BLOCK in RAC as it always contains value 2 ("potential locking conflict") unless there is local conflict detected.
.
Finding root blocker
Run query provided in Script section and do one of the following.
(1) Find and kill root blockers
a) - Find oldest resource request - row with highest CTIME (this is row L1)
b) - Exists there another row with the same SID as L1? (this is row L2 if exists)
NOT - this is root blocker, kill it
YES - Find row with the same values of ID1,ID2 columns as in L2 where LOCK > 0 (this is row L3)
- Repeat (b) with L3 (L3 becomes L1) until You find root blocker
(2) Or use simple rule (may not be best)
a) Kill oldest blocking session (highest CTIME)
b) Run script again and repeat (a) until blocking session exists
.

Detecting Object of Locking Conflict
Typically problematic conflicts happen with "DML Locks" (transaction - TX and table - TM lock types) and sometimes it is important to find out subject of the conflict (i.e. fix application design error to prevent issue).
Object name for TM lock can be easily identified as V$LOCK.ID1 is matching to DBA_OBJECTS.OBJECT_ID.
select OBJECT_ID, OWNER,OBJECT_NAME from dba_objects o, V$LOCK l
where l.SID=&sid and l.ID1=o.OBJECT_ID;
Contrary there is no easy way (select) to find out which row (TX) is the session waiting for i.e. to match TX request to TM lock (table name). This is due to locking implementation - pointer in database block points to assigned slot in undo segment (transaction id - XID). It is possible to make a guess of table name (using similarity of CTIME column value). I.e. session is waiting for TX lock for 100s and TM lock on table A has been placed 100s ago (this is just a guess as TM lock could have been acquired for earlier update in the same transaction).
Note: For simplicity GV$LOCK is referred as view but actually this is synonym for view GV_$LOCK (the same applies to V$LOCK).
Software Requirements/PrerequisitesSQL*Plus
Configuring the ScriptThere are no steps required.
Running the ScriptConnect as user able to select from GV$LOCK (typically user having DBA role).
sqlplus '/ as sysdba'
@
CautionThis script is provided for educational purposes only and not supported by Oracle Support Services. It has been tested internally, however, and works as documented. We do not guarantee that it will work for you, so be sure to test it in your environment before relying on it.
Proofread this script before using it! Due to the differences in the way text editors, e-mail packages and operating systems handle text formatting (spaces, tabs and carriage returns), this script may not be in an executable state when you first receive it. Check over the script to ensure that errors of this type are corrected.

Script
-- Author: daniel.x.simon@oracle.com
prompt CTIME is in Seconds
set lines 120
col BLOCK for 9
col LMODE for 9
col INST_ID for 9
col REQUEST for 9
col SID for 999999
select INST_ID, SID, TYPE, ID1, ID2, LMODE, REQUEST, CTIME, BLOCK
from gv$lock where (ID1,ID2,TYPE) in
(select ID1,ID2,TYPE from gv$lock where request>0);

Script Output- example output showing two independent root conflicts
- there can be noted oldest conflict (sid 64 vs 38) is not the root as session 38 is blocked by session 67
INST_ID SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
---------- -------- ---------- --------- ------- ---------- ---------- ---------- ----------
2 212 TX 1114116 1399221 6 0 308 2
1 248 TX 1114116 1399221 0 6 304 0
4 67 TX 6225949 1244199 6 0 26 2
1 38 TX 6225949 1244199 0 6 23 0
2 64 TX 131103 2270514 0 6 117 0
1 38 TX 131103 2270514 6 0 171 2




ReferencesKeywords'RAC' 'BLOCKING~LOCKS' 'ENQUEUE' 'V$LOCK' 'V$LOCK'

Thursday, April 10, 2008

Advanced Features of Oracle Net Services

Address List Parameter LOAD_BALANCE(Client Load Balancing):
When set to on, instructs Oracle Net to progress through the list of protocol addresses in a random sequence, balancing the load on the various listeners. When set to off, instructs Oracle Net to try the addresses sequentially until one succeeds.

This is different from runtime connection load balancing feature which is based on load. (This feature is automatically enabled in shared server configuration and uou must use remote_listener to enable this feature in dedicated server configuration)

Transparent Application Failover(TAF) which is also called runtime failover is controlled by parameter failover_mode and connect-time failover is controlled by parameter failover.

Thursday, March 27, 2008

aix/redhat linux 32/64bit

aix
bootinfo -y硬件
bootinfo -K内核

redhat linux
uname -a
Linux DellServ.redhat.com.cn 2.6.9-22.ELsmp #1 Fri Feb 24 16:44:51 EST 2006 i686 i686 i386 GNU/Linux

得到当前运行的内核版本号以及平台,从上面的示例中可以看到当前运行的内核版本为32位(i686 i686 i386表示32bit,X86_64表示64bit)

Monday, March 17, 2008

materialized view(mview) and vpd

1. 当基表有vpd策略(该策略不返回null),不能创建或者刷新mview。
2. 但是基表上的vpd策略(该策略不返回null)可以与mview共存。
3. query rewrite与vpd的关系,“2”的具体回避方法(exempt access policy用户)参照
Oracle® Database Data Warehousing Guide
10g Release 2 (10.2)
Part Number B14223-02
9 Advanced Materialized Views

Monday, February 25, 2008

How to Identify Resource Intensive SQL for Tuning

Subject: How to Identify Resource Intensive SQL for Tuning
Doc ID: Note:232443.1 Type: TROUBLESHOOTING
Last Revision Date: 20-AUG-2006 Status: PUBLISHED

PURPOSE
This article provides guidance on how to identify the most resource intensive SQL statements in a database for tuning purposes.
SCOPE & APPLICATION
The techniques described here can be used when initial diagnosis of a database performance problem suggests that further investigation needs to concentrate on finding and tuning the most resource intensive SQL statements according to specific criteria, e.g.
using the most CPU
performing the most disk I/O operations
having the most executions
taking the longest time to execute (elapsed time)
The article should be of use to Database Administrators, Support Engineers, Consultants and Database Performance Analysts.
WHEN TO LOOK FOR RESOURCE INTENSIVE SQL STATEMENTS
In this section we discuss briefly the reasons that would lead us to look for the most resource intensive SQL statements while investigating a database performance problem.
Response Time Analysis shows that heaviest time consumer is CPU-related e.g. CPU Other or CPU Parse time or an I/O-related Wait Event e.g. db file sequential read or db file scattered read:
This is the method followed by tools such as Statspack.
Extensive information is gathered from the database which shows in detail in what type of activities time is being spent.
It is based on the following equation:
Response Time = Service Time + Wait Time

where Service Time is time spent on the CPU
and Wait Time is the sum of time spent on Wait Events i.e. non-idle time spent waiting for an event to complete or for a resource to become available.
Service Time is comprised of time spent on the CPU for Parsing, Recursive CPU usage (for PLSQL and recursive SQL) and CPU used for execution of SQL statements (CPU Other).

Service Time = CPU Parse + CPU Recursive + CPU Other

The above components of Service Time can be found from the following statistics:
Service Time from CPU used by this session
CPU Parse from parse time cpu
CPU Recursive from recursive cpu usage
From these, CPU Other can be calculated as follows:

CPU other = CPU used by this session - parse time cpu - recursive cpu usage

When CPU Other is a significant component of total Response Time the next step is to find the SQL statements that access the most blocks. Block accesses are also known as Buffer Gets and Logical I/Os.

Statspack lists such SQL statements in section SQL ordered by Gets.

When CPU Parse is a significant component of total Response Time the next step is to find the SQL statements that have the most parses.

Statspack lists such SQL statements in section SQL ordered by Parse Calls.
Note: this is available in Oracle9i and above.

Wait Time is the sum of time waited for non-idle Wait Events. These include I/O waits for reading blocks from disk as measured by the Wait Events db file sequential read for single-block reads and db file scattered read for multi-block reads.

When such Wait Events are found to be significant components of Response Time the next step is to find the SQL statements that read the most blocks from disk.

Statspack lists such SQL statements in section SQL ordered by Reads.

Example from Statspack: (pre-Oracle9i Release 2)
Here is an example where CPU Other was found to be a significant component of total Response Time:

Top 5 Wait Events
~~~~~~~~~~~~~~~~~ Wait % Total
Event Waits Time (cs) Wt Time
-------------------------------------------- ------------ ------------ -------
direct path read 4,232 10,827 52.01
db file scattered read 6,105 6,264 30.09
direct path write 1,992 3,268 15.70
control file parallel write 893 198 .95
db file parallel write 40 131 .63
-------------------------------------------------------------

Statistic Total per Second per Trans
--------------------------------- ---------------- ------------ ------------
CPU used by this session 358,806 130.5 12,372.6
parse time cpu 38 0.0 1.3
recursive cpu usage 186,636 67.9 6,435.7

From these figures we can obtain:
Wait Time = 10,827 x 100% / 52,01% = 20,817 cs
Service Time = 358,806 cs
Response Time = 358,806 + 20,817 = 379,623 cs
CPU Other = 358,806 - 38 - 186,636 = 172,132 cs
If we now calculate percentages for the top Response Time components:
CPU Other = 45.34%
CPU Recursive = 49.16%
direct path read = 2.85%
etc. etc.
CPU Other is a significant component of Response Time, so a possible next step is to look at the SQL ordered by Gets section.
Example from Statspack: (Oracle9i Release 2 & above)
Starting with Oracle9i Release 2, Statspack presents Service Time (obtained from the statistic CPU used by this session ) together with the top Wait Events in a section called Top 5 Timed Events, which replaces the section Top 5 Wait Events of previous releases.
Here is an example:


Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
library cache lock 141 424 76.52
db file scattered read 3,367 96 17.40
CPU time 32 5.79
db file sequential read 161 1 .18
control file parallel write 245 0 .05
-------------------------------------------------------------

Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
CPU used by this session 3,211 4.3 1,605.5
parse time cpu 59 0.1 29.5
recursive cpu usage 232 0.3 116.0

These figures give us directly the percentages of the Wait Events against the total Response Time so no further calculations are necessary to assess the impact of Wait Events. Service Time is presented as CPU time in this section and corresponds to the total CPU utilisation. We can drill down to the various components of Service Time as follows:
CPU Other = 3,211 - 59 - 232 = 2,920 cs
CPU Other = 2,920 / 3,211 x 5.79% = 5.26%
CPU Parse = 59 / 3,211 x 5.79% = 0.11%
CPU Recursive = 232 / 3,211 x 5.79% = 0.42%
In this example, the main performance problem was an issue related to the Library Cache.
The second most important time consumer was waiting for physical I/O due to multiblock reads (db file scattered read).
In this case a possible approach would be to look at the SQL ordered by Reads section of Statspack.

Operating System resource analysis shows that excessive CPU or Disk I/O usage is caused by one or more Oracle processes:
If Operating System utilities show that most CPU usage is due to a small number of Oracle processes then typically they will be SQL Traced and have TKPROF reports generated from their tracefiles. Analysis of the TKPROF reports will lead to the most time consuming SQL statements which will be the subject of subsequent tuning.

If CPU usage is excessive but spread out fairly evenly among all the Oracle processes on the system then typically a tool such as Statspack will be used to perform Response Time analysis. The components of Service Time will be evaluated and if this shows CPU Other as being significant the next step will be to look at the SQL performing most block accesses in the SQL by Gets section of the Statspack report.

If Disk I/O is highly utilized on the system then a Response Time analysis using Statspack can be done to confirm that the Disk I/O usage is due to Oracle processes and I/O-related Wait Events can be expected to be significant components of overall Response Time. SQL statements performing the most physical reads can then be found in the section SQL ordered by Reads .

Investigation of the performance of a batch job or other session which performs a number of SQL statements and has slow performance:
This will be done with SQL Trace and TKPROF as descrived above and the most important SQL statements in terms of time spent will be identified for further tuning.
Examination of statistics stored for SQL statements in V$ dynamic views:
Part of the information stored with a SQL statement (Shared Cursor) in the Library Cache portion of the Shared Pool are a number of statistics related to its execution. These are available through the V$SQLAREA dynamic view and can be queried to monitor the most expensive SQL statements in each category.
This is the approach used by the graphical tool SQL Analyze in the Oracle Enterprise Manager Tuning Pack.

For more information on the topics discussed in this section please refer to:
Note 190124.1 THE COE PERFORMANCE METHOD
Note 228913.1 Systemwide Tuning using STATSPACK Reports:
Note 223117.1 Tuning I/O-related waits

TOP SQL STATEMENTS IN STATSPACK REPORTS
Statspack reports generated from snapshots at level 5 (default) and above can contain SQL reporting sections for the following types of resource intensive SQL statements:
SQL ordered by Gets
containing the SQL statements with most buffer accesses.
The default threshold value is 10,000 buffer gets.
Columns displayed are:
Buffer Gets, Executions, Gets per Exec, % Total, Hash Value (8.1.7)
Buffer Gets, Executions, Gets per Exec, %Total, CPU Time (s), Elapsed Time (s), Hash Value (9.0.1 & 9.2)

SQL ordered by Reads
containing the SQL statements with most read I/Os from disk.
The default threshold value is 1,000 disk reads.
Columns displayed are:
Physical Reads, Executions, Reads per Exec, % Total, Hash Value (8.1.7)
Physical Reads, Executions, Reads per Exec, %Total, CPU Time (s), Elapsed Time (s), Hash Value (9.0.1 & 9.2)

SQL ordered by Executions
containing the SQL statements executed the most times.
The default threshold value is 100 executions.
Columns displayed are:
Executions, Rows Processed, Rows per Exec, Hash Value (8.1.7)
Executions, Rows Processed, Rows per Exec, CPU per Exec (s), Elapsed per Exec (s), Hash Value (9.0.1 & 9.2)

SQL ordered by Parse Calls (Oracle9i and above)
containing the SQL statements with most soft parse calls.
The default threshold value is 1,000 parse calls.
Columns displayed are:
Parse Calls, Executions, % Total Parses, Hash Value

SQL ordered by Sharable Memory
containing the SQL statements occupying the most Library Cache memory.
The default threshold value is 1Mb (1,048,576 bytes).
Columns displayed are:
Sharable Mem (b), Executions, % Total, Hash Value (8.1.7, 9.0.1 & 9.2)

SQL ordered by Version Count
containing the SQL statements with most versions (children cursors).
The default threshold value is 20 versions.
Columns displayed are:
Version Count, Executions, Hash Value (8.1.7, 9.0.1 & 9.2)

In the next few sections we look at examples of each type of Statspack SQL reporting section.

FINDING SQL WITH HIGH CPU OTHER TIME IN STATSPACK
Here are a few examples of SQL ordered by Gets sections from Statspack.

SQL ordered by Gets for DB: PROD Instance: prod Snaps: 8 -9
-> End Buffer Gets Threshold: 10000
-> Note that resources reported for PL/SQL includes the resources used by
all SQL statements called within the PL/SQL code. As individual SQL
statements are also reported, it is possible and valid for the summed
total % to exceed 100

Buffer Gets Executions Gets per Exec % Total Hash Value
--------------- ------------ -------------- ------- ------------
91,938,671 4,249 21,637.7 24.1 3503723562
SELECT "TEKSTI_IK", "U_VERSION", "ASIAKIR_IK", "KONTAKT_IK", "L
OMAKE_IK", "PVM", "TIEDON_LKA", "TEKSTI_VER", "TEKST_TILA", "VA
LK_AUKKO", "SUOR_PA_IK", "SUOR_PA_ID", "RESURSS_IK", "RESURSS_I

39,196,483 4,257 9,207.5 10.3 576408779
SELECT "KONTAKT_IK", "ASIAKAS_IK", "KAYNTIPVM", "KLO_JNRO", "KT
_PIKASEL", "RESURSS_ID", "SUOR_PA_IK", "SUOR_PA_ID", "TEKSTI_IK
", "KT_TEKSTI", "KONT_LAJI" FROM "TEI1000_VIEW" WHERE (kontakt_i

31,870,113 4,262 7,477.7 8.3 3583640853
SELECT "LAAKE_T_IK", "U_VERSION", "TAPAHTU_IK", "ASIAKAS_IK", "
TOT_DATIM", "LAAKE_IK", "KAUPPANIMI", "VALM_MUOTO", "VAHVUUS",
"PAKK_KOKO", "ANNOS", "INDIKAATIO", "PYSYVAIS", "VOIM_OLEVA", "S

30,567,449 4,259 7,177.1 8.0 1901268379
SELECT "LAB_TUL_IK", "U_VERSION", "TAPAHTU_IK", "ASIAKAS_IK", "
TOT_DATE", "TOT_TIME", "PALVELU_IK", "PALV_LYHEN", "SL_KOODI",
"OSAVAS_NRO", "OSAVAS_HOP", "VAST_TYYPP", "VAST_ARVO", "VAST_SIJ

Here the first SQL statement (with hash value 3503723562) alone accounts for 24.1% of all buffer gets in the instance.
The next 3 statements account for 10.3%, 8.3% and 8.0%.
All 4 statements are executed approximately the same number of times (around 4,250 executions).
The first statement has more total Gets because it fetches more buffers each time it runs (Gets/Exec is 21,637.7 compared to 9,207.5, 7,477.7 and 7,177.1).
So it is a first candidate for tuning as it has greater impact on CPU Other time than the other 3 statements.
A better execution plan for this statement resulting in fewer Gets/Exec will reduce its CPU consumption.
Here is another example:


Buffer Gets Executions Gets per Exec % Total Hash Value
--------------- ------------ -------------- ------- ------------
3,200,593 1 3,200,593.0 52.2 397365298
select c.contract_no||'/'||c.contract_version, c.owner_ag
ency_id, a.agency_name, TERRITORYPACK.getsalescont
act(a.agency_id,'SALES','N'), c.start_date, LEAST(

404,024 88,481 4.6 6.6 985453413
select cv_dist_flag from applicant
where applicant_id = :p1

178,600 3,028 59.0 2.9 3013728279
select privilege#,level from sysauth$ connect by grantee#=prior
privilege# and privilege#>0 start with (grantee#=:1 or grantee#=

The first statement (hash value 397365298) generated 52.2% of the buffer gets in the instance with just 1 execution.
It has a high number of Gets/Exec 3,200,593.0 when compared to the others.
If this statement is not just a one-time query then it is a good candidate for tuning before it starts getting used more often.
The second statement (hash value 985453413) fetches on average less than 5 buffers per execution but appears high in the list because it is executed very frequently.
Initially it is not significant enough to warrant further investigation.
If after tuning the first statement, CPU Other is still a significant component of overall Response Time and a new Statspack report shows the second statement still high on the list, then it could be looked at more closely.

Here is a similar case, this time it is from Oracle9i and we can see the new CPU & Elapsed Time columns:


CPU Elapsd
Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
16,177,286 1 16,177,286.0 12.1 209.00 297.91 342588312
select sf.satz_id, f1.feld, f2.feld feld20, substr(sf.fehler
,instr(sf.fehler,'geschrieben:')+13) feld30 --merkwürdigerweise
wird ab 31 Byte in eine neue Zeile geschrieben from d98_ditr_s

8,177,886 375,622 21.8 6.1 214.09 302.26 3544921891
SELECT /*+ RULE */ * from d98_schemaeintraege_view where pro
f_id = :b1 order by sortierung

The Statspack report does not always show the full text of the SQL statement. The Hash Value can be used to get this using the following query, provided the SQL statement is still in the Library Cache at the time the query is run:


SELECT sql_text
FROM v$sql_text
WHERE hash_value = '&hash_value_of_SQL'
ORDER BY piece;

FINDING SQL STATEMENTS WITH HIGH CPU PARSE TIME IN STATSPACK
If CPU Parse time is a significant component of Response Time, it can be because cursors are repeatedly opened and closed every time they are executed instead of being opened once, kept open for multiple executions and only closed when they are no longer required.
The SQL ordered by Parse Calls can help find such cursors, here is an example:


SQL ordered by Parse Calls for DB: DWI1 Instance: DWI1 Snaps: 1 -4
-> End Parse Calls Threshold: 1000

% Total
Parse Calls Executions Parses Hash Value
------------ ------------ -------- ----------
13,632,745 13,632,745 98.90 3980186470
SELECT distinct TS002.C_JOB_DEP, TS002.C_JOB FROM TS002_JO
B_DEP TS002, TS001_JOB TS001 WHERE TS001.C_JOB = TS002.C_JO
B_DEP AND TS002.C_JOB = :b1 AND TS001.C_TIP_JOB !=

11,701 27,255,840 0.08 3615375148
COMMIT

8,192 8,192 0.06 238087931
select t.schema, t.name, t.flags, q.name from system.aq$_queue_t
ables t, sys.aq$_queue_table_affinities aft, system.aq$_que
ues q where aft.table_objno = t.objno and aft.owner_instance = :
1 and q.table_objno = t.objno and q.usage = 0 and b
itand(t.flags, 4+16+32+64+128+256) = 0 for update of t.name, aft

8,192 8,192 0.06 2780709284
select q_name, state, delay, expiration, rowid, msgid, dequeue
_msgid, chain_no, local_order_no, enq_time, enq_tid, step_no,
priority, exception_qschema, exception_queue, retry_count, corri
d, time_manager_info, sender_name, sender_address, sender_prot
ocol from SYS.AQ_SRVNTFN_TABLE where time_manager_info <= :1

The first SQL statement (hash value 3980186470) has had the most parses issued against it (98.90% of all parses in the instance). It is parsed every time it is executed (Parse Calls = Executions). Due to its frequency it is a prime candidate for reducing parse calls as described above.
Note: in excessive parsing situations, it is likely that there will be symptoms such as latch free waits on the Library Cache latches and possibly the Shared Pool latch, in addition to CPU Parse time.

FINDING SQL STATEMENTS WITH HIGH DISK I/O WAITS IN STATSPACK
Identifying SQL statements responsible for most physical reads from the Statspack section SQL ordered by Reads has similar concepts as for SQL ordered by Gets.
% Total can be used to evaluate the impact of each statement.
Reads per Exec together with Executions can be used as a hint of whether the statement has a suboptimal execution plan causing many physical reads or if it is there simply because it is executed often.
Possible reasons for high Reads per Exec are use of unselective indexes require large numbers of blocks to be fetched where such blocks are not cached well in the buffer cache, index fragmentation, large Clustering Factor in index etc.

Here is an example:


SQL ordered by Reads for DB: PROD Instance: prod Snaps: 14 -16
-> End Disk Reads Threshold: 1000

Physical Reads Executions Reads per Exec % Total Hash Value
--------------- ------------ -------------- ------- ------------
3,633,017 48 75,687.9 28.0 3954888792
SELECT "VAR_RES_IK", "RESURSS_IK", "PVM", "ALKAEN_KLO", "PAATT_
KLO", "AJ_STATUS", "ILMOITT", "HETU", "AS_NIMI", "KASITELTY", "T
OIMIPI_IK", "SUOR_PA_IK", "SUOR_PA_ID", "AIKATYY_IK", "AIKATYY_I

1,511,867 26 58,148.7 11.6 394819206
SELECT "VAR_RES_IK", "RESURSS_IK", "PVM", "ALKAEN_KLO", "PAATT_
KLO", "AJ_STATUS", "ILMOITT", "HETU", "AS_NIMI", "KASITELTY", "T
OIMIPI_IK", "SUOR_PA_IK", "SUOR_PA_ID", "AIKATYY_IK", "AIKATYY_I

762,101 6 127,016.8 5.9 4274178025
SELECT "LAB_TUL_IK", "PALV_LYHEN", "PALV_TILA", "OSAVAS_HOP", "
VAST_ARVO", "VAST_SIJ", "MITTAYKS", "POIKKEAVA", "PALVELU_IK", "
ASIAKAS_IK", "VERIRYHMA", "VV_MAARPVM", "TOT_DATE", "TOT_TIME",

512,142 3 170,714.0 3.9 1591034069
SELECT "LAB_TUL_IK", "PALV_LYHEN", "PALV_TILA", "OSAVAS_HOP", "
VAST_ARVO", "VAST_SIJ", "MITTAYKS", "POIKKEAVA", "PALVELU_IK", "
ASIAKAS_IK", "VERIRYHMA", "VV_MAARPVM", "TOT_DATE", "TOT_TIME",

The first two SQL statements are both executed more often than the others and cause more blocks to be read in from disk each time.
Together they account for almost 40% of read I/O. They both are prime candicates for further SQL tuning.
EVALUATING SQL STATEMENTS WITH MOST EXECUTIONS IN STATSPACK
Identifying those SQL statements that execute most often in a database and tuning them can improve performance even when such statements do not consume many resources in each execution.
This is because of two reasons:

The overall resource consumption of these statements across all their executions may be significant.
Such frequently executed statements are often part of OLTP-style short transactions. Tuning them can improve the performance of the database as experienced by users entering such transactions into the system.
Here is an example of Statspack SQL ordered by Executions:

SQL ordered by Executions for DB: DIN Instance: DIN Snaps: 263 -264
-> End Executions Threshold: 100

CPU per Elap per
Executions Rows Processed Rows per Exec Exec (s) Exec (s) Hash Value
------------ --------------- ---------------- ----------- ---------- ----------
404,871 133,781 0.3 0.00 0.00 3592950473
SELECT nvl(NVL(EIGTWX.WERT,EIGTW.WERT),eig.wert) wert,
1 sortier FROM D8_EIGENTYPWERTE_TEXT EIGTWX ,D98_
EIGENTYPWERTE EIGTW ,D98_EIGENSCHAFTEN EIG WHERE EIG.ANH

324,014 324,014 1.0 0.00 0.00 293077222
SELECT /*+ INDEX (D98_SCHEMAFORMATE SCHFMT_FORM_FKT_UNTER) */
upper(funktionsname), unterformat FROM
D98_SCHEMAFORMATE WHERE formatierung = :b1

183,276 183,276 1.0 0.00 0.00 66213032
INSERT INTO D98_Batch_Variablenwerte (ausf_id, b
atch_id, var_nr, wert) VALUES (:b4,
:b3, :b2, :b1)

114,224 8,936 0.1 0.00 0.00 1604001664
SELECT termin_ist FROM d98_termine WHERE a
nhang_id=:b2 AND terminart = :b1 AND aktiv = 'J'
order by termin_ist desc

It will frequently be the case that the timing columns in this section will show 0.00 for CPU and Elapsed time, as the most frequently executing SQL statements are likely to be quite fast.
FINDING SQL STATEMENTS WITH HIGH SHARED POOL CONSUMPTION IN STATSPACK
This can help with Shared Pool and Library Cache/Shared Pool latch tuning.
Statements with many versions (multiple child cursors with the same parent cursor i.e. identical SQL text but different properties such as owning schema of objects, optimizer session settings, types & lengths of bind variables etc.) are unsharable.

This means they can consume excessive memory resources in the Shared Pool and cause performance problems related to parsing e.g. Library Cache and Shared Pool latch contention or lookup time e.g. Library Cache latch contention.

Statspack has 2 sections to help find such unsharable statements, SQL ordered by Sharable Memory and SQL ordered by Version Count:


SQL ordered by Sharable Memory for DB: DIN Instance: DIN Snaps: 263 -264
-> End Sharable Memory Threshold: 1048576

Sharable Mem (b) Executions % Total Hash Value
---------------- ------------ ------- ------------
3,445,680 1 0.1 2317124142
select /*+rule*/ decode(UPPER(:P_TITEL_SORT), 'NAME', fin_sort_ansp_name,
'FIRMA', fin_sort_ans_firma, 'KURZBEZ. FIRMA', fin_sort_ans_name,

3,386,429 76 0.1 3470710979
SELECT ID,ANHANGSTYP,OBJEKT_ID,PROF_ID,ANHANGSART,SPRACHE,AKTIV,
ANFANG,ENDE,SEITEN,ARCH_BEMERKUNG,DESKRIPTOR,EIGTW_ID,EIG_WERT,T

2,836,746 447 0.1 2274525714
SELECT ID,ANHANGSTYP,OBJEKT_ID,PROF_ID,ANHANGSART,SPRACHE,AKTIV,
ANFANG,ENDE,SEITEN,ARCH_BEMERKUNG,DESKRIPTOR,EIGTW_ID,EIG_WERT,T


SQL ordered by Version Count for DB: P97 Instance: P97 Snaps: 177 -180
-> End Version Count Threshold: 20

Version
Count Executions Hash Value
-------- ------------ ------------
26 36,228 3957083415
SELECT 1 FROM NK245_RECHTE A WHERE (NK245_NK211_ID BETWEEN :b
1 AND :b2 ) AND NK245_GEHEIMSTUFE >= :b3 AND NK245_NK209_ID = :
b4 AND NK245_NKXX_ID = :b5 AND NK245_ANZAHL > 0 AND (:b6 BETW

25 606 2916558383
UPDATE KVS.NK21_DOKUMENTE SET NK21_NK41_PDA_KUERZEL=:b1,NK21_NK4
1_PDA_NAME=:b2,NK21_STR_LEVEL=:b3,NK21_STR_NR=:b4,NK21_STR_TYP=:
b5,NK21_STRL1_NR=:b6,NK21_STRL1_TYP=:b7,NK21_STRL2_NR=:b8,NK21_S

24 1,602 1157590177
INSERT INTO NK297_NACHRICHTEN ( NK297_ID,NK297_TIMESTAMP,NK297_T
IMESTAMP_E,NK297_NK210_ABSENDER,NK297_NK270_USERNAME_ABS,NK297_T
ITEL,NK297_NTEXT,NK297_NK248_ID,NK297_NK244_ID,NK297_NK213_ID,NK

For more information on tuning the Shared Pool please refer to the article:
Note 62143.1 Understanding and Tuning the Shared Pool
TOP SQL STATEMENTS IN TKPROF REPORTS
TKPROF is a tool for producing formatted reports from SQL Trace files (also known as event 10046 tracefiles).
Each SQL (and PL/SQL) statement appearing in the tracefile has its information summarized and collected in one place in the TKPROF report.
This information includes: number of parse, execution & fetch operations, total cpu & elapsed times, buffers read in consistent (query) and current mode, blocks read from disk and row counts, Row Source operations, execution plans, library cache misses, parsing user id & optimizer mode and with TKPROF version 9.0.1 and above, summary of wait events for tracefiles generated with event 10046 at levels 8 or 12.

A powerful feature available in TKPROF is the sort option which allows for ordering the SQL statement in the report according to a number of criteria.
This enables the easy identification of the most resource-intensive SQL statements and helps target efficiently the SQL tuning process.
Here are the options available for sorting, they may be combined:


prscnt number of times parse was called
prscpu cpu time parsing
prsela elapsed time parsing
prsdsk number of disk reads during parse
prsqry number of buffers for consistent read during parse
prscu number of buffers for current read during parse
prsmis number of misses in library cache during parse
execnt number of execute was called
execpu cpu time spent executing
exeela elapsed time executing
exedsk number of disk reads during execute
exeqry number of buffers for consistent read during execute
execu number of buffers for current read during execute
exerow number of rows processed during execute
exemis number of library cache misses during execute
fchcnt number of times fetch was called
fchcpu cpu time spent fetching
fchela elapsed time fetching
fchdsk number of disk reads during fetch
fchqry number of buffers for consistent read during fetch
fchcu number of buffers for current read during fetch
fchrow number of rows fetched

The most commonly used sort options are the ones ordering according to elapsed times consumed for the execute and fetch phases: we are usually interested in tuning statements that take more time to run as time is the most important property in the tuning process.

exeela elapsed time executing
fchela fchela elapsed time fetching

It should be clear however that it is as simple to order the SQL in order to find which ones cause the most disk i/o during fetch

fchdsk number of disk reads during fetch

or according to which ones access the most buffers in consistent mode e.g. for queries this would be in the fetch phase

fchqry number of buffers for consistent read during fetch

or for DML it would be in the execute phase

exeqry number of buffers for consistent read during execute

For more information on working with TKPROF please refer to the article:
Note 32951.1 Tkprof Interpretation
TOP SQL STATEMENTS IN V$SQLAREA & V$SQL
The Oracle Server provides 3 dynamic views for querying execution statistics of all SQL statements currently cached in the Library Cache of the Shared Pool.
They are V$SQL, V$SQLAREA and V$SQLXS.

V$SQL has 1 row for each different version of a SQL statement.
This means that each child cursor has its own execution statistics.


V$SQLAREA has 1 row for each different SQL string i.e. each parent cursor.
This means that the statistics for all child cursors i.e. different versions of this cursor are grouped together. It is not based on V$SQL.
.

V$SQLXS is a simpler version of V$SQLAREA.
It is used mainly by Statspack for generating the SQL reporting sections.
It queries V$SQL with a GROUP BY.
It is defined in ORACLE_HOME/rdbms/admin/catsnmp.sql.

V$SQLAREA or V$SQLXS can be used most often to find the top few SQL statements for a specific category of statistic.
Once these are identified, V$SQL can be used to drill down to see whether different versions of each statement exhibit similar statistics or whether some particular versions stand out.

V$SQL is less resource intensive than V$SQLAREA as it avoids the GROUP BY operation and causes less Library Cache latch contention.

Here is a general form of a query on any of these views:


SELECT * FROM
(SELECT hash_value,address,substr(sql_text,1,40) sql,
[list of columns], [list of derived values]
FROM [V$SQL or V$SQLXS or V$SQLAREA]
WHERE [list of threshold conditions for columns]
ORDER BY [list of ordering columns] DESC)
WHERE rownum <= [number of top SQL statements];

Here is an example:


SELECT * FROM
(SELECT hash_value,address,substr(sql_text,1,40) sql,
buffer_gets, executions, buffer_gets/executions "Gets/Exec"
FROM V$SQLAREA
WHERE buffer_gets > 100000 AND executions > 10
ORDER BY buffer_gets DESC)
WHERE rownum <= 10;

[list of columns] = buffer_gets, executions
[list of derived values] = buffer_gets/executions
[list of threshold conditions for columns] = buffer_gets > 100000, executions > 10
[list of ordering columns] = buffer_gets
[number of top SQL statements] = 10
The following article contains a selection of ready to run Top-10 queries:

Note 235146.1 Example "Top SQL" queries from V$SQLAREA

A list of columns on which to base similar queries are:

buffer_gets
disk_reads
executions
rows_processed
sorts
parse_calls
sharable_mem
version_count
invalidations
All of these are available in all three views V$SQL, V$SQLAREA & V$SQLXS.
There are a number of other columns for queries of this kind , not so frequently used, which can be found by inspecting V$SQL and V$SQLAREA.

Note 43761.1 VIEW: "V$SQLAREA" Reference Note
Note 43762.1 VIEW: "V$SQL" Reference Note

TOP SQL STATEMENTS IN ENTEPRISE MANAGER SQL ANALYZE
SQL Analyze is a GUI tool available with the Oracle Enterprise Manager Tuning Pack that can be used to identify and can help with tuning resource intensive SQL statements.

The queries for the heaviest SQL statements are done from the Top SQL menu and a variety of search criteria are available:

Buffer Cache Hit Ratio
Buffer Gets
Buffer Gets per Execution
Buffer Gets per Row
Disk Reads
Disk Reads per Execution
Executions
Parse Calls
Parse Calls per Execution
Rows Processed
Sharable Memory
Sorts
The search can be tailored to include Top N results or All statements and can also filter out Recursive SQL.

For more information please refer to the Online Help available with the tool or the following manual:
Oracle Enterprise Manager Database Tuning with the Oracle Tuning Pack Release 9.0.1 June 2001 Part No. A86647-01

RELATED DOCUMENTS
Note 190124.1 THE COE PERFORMANCE METHOD
Note 228913.1 Systemwide Tuning using STATSPACK Reports:
Note 223117.1 Tuning I/O-related waits
Note 62143.1 Understanding and Tuning the Shared Pool
Note 43761.1 VIEW: "V$SQLAREA" Reference Note
Note 43762.1 VIEW: "V$SQL" Reference Note
Note 235146.1 Example "Top SQL" queries from V$SQLAREA
Note 32951.1 Tkprof Interpretation .

Monday, February 04, 2008

csv file and automatic ftp

create directory yangbodir as '/oracle/';
CREATE OR REPLACE PROCEDURE printcsvreport(filedir IN VARCHAR2, filename IN VARCHAR2)
AS
filehndl UTL_FILE.FILE_TYPE;
CURSOR JobCursor IS select * from test;
vJobRecord JobCursor%RowType;
BEGIN
OPEN JobCursor;
filehndl := UTL_FILE.FOPEN(filedir,filename,'w');
FETCH JobCursor INTO vJobRecord;
while JobCursor%FOUND loop
--UTL_FILE.PUT_LINE(filehndl,'Just Heading'||' Next heading');
UTL_FILE.PUTF(filehndl,'%s %s %s %s\n', vJobRecord.id||'|'||vJobRecord.name||'|'||vJobRecord.birth||'|'||vJobRecord.description);
FETCH JobCursor INTO vJobRecord;
end loop;
CLOSE JobCursor;
UTL_FILE.FCLOSE(filehndl);
EXCEPTION
WHEN UTL_FILE.INVALID_OPERATION
THEN UTL_FILE.FCLOSE(filehndl);
-- raise a user-defined exception
RAISE_APPLICATION_ERROR(-20051,'Invalid Operation');
END;
/




begin
printcsvreport('YANGBODIR','testyangbo');
end;
/

ftp 10.10.0.180 《《EOF
user username password
cd /dbms/
lcd /oracle
put testyangbo
bye
EOF

Tuesday, January 29, 2008

How To Indentify The Row Which is Locked By an Other User's Session

Subject: How To Indentify The Row Which is Locked By an Other User's Session
Doc ID: Note:198150.1 Type: TROUBLESHOOTING
Last Revision Date: 18-MAY-2004 Status: PUBLISHED



goal: Identify the row which is locked by an other user's session
fact: Oracle Server - Enterprise Edition



fix:

To determine which row is locked in a certain table can only be queried when an
other user is waiting for the row involved.

To find the row, 3 queries must be executed:

1) This query will display some information about the object and user involved.
The OBJECT_ID value returned must be used in the second query. The
OBJECT_NAME is used in the last query. The queries must be executed as a DBA
user.

sql> select a.os_user_name,
2 a.oracle_username,
3 a.object_id,
4 c.object_name,
5 c.object_type
6 from v$locked_object a, dba_objects c
7 where a.object_id=c.object_id
8 /

2) This query will return the ROW_WAIT_FILE#, ROW_WAIT_BLOCK# and ROW_WAIT_ROW#
values for the OBJECT_ID involved. The ROW_WAIT_FILE#, ROW_WAIT_BLOCK# and
ROW_WAIT_ROW# will be needed in the last query. If this query returns no
rows, no user is waiting for this row.

sql> select sid,
2 row_wait_obj# objn,
3 row_wait_file# fn,
4 row_wait_block# bn,
5 row_wait_row# rn
6 from v$session
7 where row_wait_obj#=
8 /

3) The final query will return the row which is locked an the user is waiting
for. The OBJN, FN, BN and RN values from the second query and OBJECT_NAME
from the first query need to be subsituted in this query.

sql> select * from
2 where rowid = dbms_rowid.rowid_create(1, , , , )
3 /

Sunday, January 27, 2008

bind variables

var mybind number;
execute :mybind:=100
print :mybind

Friday, January 25, 2008

bat, batch job

@echo off
set /p seq=sequence#:
echo spool D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.txt>>D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
echo.>>D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
echo.>>D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
echo.>>D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
echo spool off;>>D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
start notepad D:\work\%date:~0,4%%date:~5,2%%date:~8,2%%seq%.sql
@echo on

Wednesday, January 23, 2008

DBMS_CRYPTO encryption 加密 AES

目前主流的加密方法大致有MD5、SHA-1、DES、Triple DES、AES,目前MD5、SHA-1、DES都已经有破解方法,Triple DES、AES还没有被破解的记载,其中AES是最新最安全的加密方法,最多可提供256位的加密。

Oracle 9i提供MD5、DES、Triple DES,而Oracle 10g和10g R2提供了上面提到的所有加密方法供选择。



鉴于以上情况,针对Oracle 10g,我的想法是使用DBMS_CRYPTO包提供的Triple DES或者AES进行加密(Oracle 9i中没有这个包)。

与其他方法相比,这样做的优点是:



1. Triple DES、AES是最安全的加密方法,没有被破解的记载

2. 有可逆和不可逆两种加密选择

3. 支持对BLOB和CLOB加密




1.脚本

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

加密函数

create or replace function encrypt256(v_input varchar2) return raw

is

v_result raw(256);

c_key char(32) := '1q2wa3es4rz5tx6ycD*UF8tif9ogjen2';

begin

v_result := DBMS_CRYPTO.ENCRYPT(

UTL_I18N.STRING_TO_RAW(v_input, 'AL32UTF8'),

DBMS_CRYPTO.ENCRYPT_AES256+DBMS_CRYPTO.CHAIN_CBC+DBMS_CRYPTO.PAD_PKCS5,

UTL_I18N.STRING_TO_RAW(c_key, 'AL32UTF8'));

return v_result;

end;

/



解密函数

create or replace function decrypt256(v_input raw) return varchar2

is

v_result raw(256);

c_key char(32) := '1q2wa3es4rz5tx6ycD*UF8tif9ogjen2';

begin

v_result := DBMS_CRYPTO.DECRYPT(

v_input,

DBMS_CRYPTO.ENCRYPT_AES256+DBMS_CRYPTO.CHAIN_CBC+DBMS_CRYPTO.PAD_PKCS5,

UTL_I18N.STRING_TO_RAW(c_key, 'AL32UTF8'));

return UTL_I18N.RAW_TO_CHAR(v_result, 'AL32UTF8');

end;

/

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



2.功能演示



SQL> insert into test values(1,encrypt256('一次成功')); <--用户插入或者修改数据时这样使用



已创建 1 行。



SQL> commit;



提交完成。



SQL> select * from test;



ID RAWS

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

1 597B660AFD6CC3A90D064B00DF7EB80D <--数据已经被密文保存



SQL> select id,raws from test where raws=encrypt256('一次成功'); <--核对或者查找时这样使用



ID RAWS

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

1 597B660AFD6CC3A90D064B00DF7EB80D



SQL> select id,decrypt256(raws) raws from test; <--解密方法和结果



ID RAWS

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

1 一次成功





3. 加密对性能的影响

在我的测试中,逻辑读的量基本不变,扫描索引的耗时变为不加密时的10.8倍(66us --> 717us)。

INDEX RANGE SCAN YB_IND_TESTT_1 (cr=3 pr=0 pw=0 time=66 us)(object id 81639)

INDEX RANGE SCAN YB_IND_TESTT_2 (cr=3 pr=0 pw=0 time=717 us)(object id 81640)

这种耗时的增加与使用何种加密方式无关。



4. 对于脚本中密钥的保护

虽然密钥仍然是写死在脚本中,但是不用担心开发人员或者数据库管理人员会得到密钥,这里使用的方法是Oracle提供的wrap程序包,使用这个包可以将脚本以不可逆的方式加密。



例如:创建encrypt256()这个函数的脚本经过加密以后,会变成下面这样。

这样的脚本仍然可以创建函数,但没有人知道这个函数内容更没有人知道密钥是什么。

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

create or replace function encrypt256 wrapped

a000000

354

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

abcd

8

18b 15c

cSBfE65CYUS4abCCuiwqeQWAEZEwg/DIDK5qfC9Grfjqzqc2UfIyWpTjI7h2sFSyE4XQwwA7

LyfVV6mp8no/ANyNnp4A9SCHcrSaWUNnVD2mjcrSwg1WkEakxRGQY6SxBkD2b8xiO+tnKg8v

AVoHo6vqBfl2I4SJtjfHvhrte1k0+SPy1giZEp0MKyCcZA8pMwubQg9BmMUFIthkQXjQCklv

XRrIgkQkckLqk2iraDchjDcWFNJyV7qMqxd8ZSvVdWt5S0mISwurpXs4/yuTL5W1R4A/Z9Hw

0FII+JeAzKlRL1sFp5y0/wKhhl5rn5V2yjphQHv+r8dma0dyvPumJQEJ



/

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



5. 几点提示和注意事项

(1) 示例脚本中被加密的字段最大255字节因此需要开发人员在程序中判断长度;

这个长度限制根据需要可以调整到最大1999字节。

(2) BLOB和CLOB类型的数据也可以加密

(3) 由于使用了wrap方式保护密钥且这个方法不可逆,所以密钥必须妥善保存。

Monday, January 21, 2008

os authentication

In order for a database account to accept connections without a password the
database logon must be created with an 'IDENTIFIED EXTERNALLY' clause.

Eg: CREATE USER OSUSER_SCOTT IDENTIFIED EXTERNALLY;
This will allow SCOTT to 'CONNECT /'.
This will NOT allow SCOTT to connect as OSUSER_SCOTT in any other manner

CREATE USER OSUSER_SCOTT IDENTIFIED BY XYZ;
The user must supply the username AND password to connect as the
account has actually been created as requiring database authentication.
Ie: 'CONNECT /' will *NOT* work.
'CONNECT OSUSER_SCOTT/XYZ' will connect.

If the OS_AUTHENT_PREFIX is set to OPS$ a user can connect in either
manner if created with a password. This is more of a security risk
as there are 2 ways to access the database account.

Eg: CREATE USER OPS$SCOTT IDENTIFIED BY XYZ;
Allows the user to 'CONNECT /' or 'CONNECT OPS$SCOTT/XYZ'.

NOTE: on unix platforms, you need use sqlplus "OPS\$SCOTT/XYZ" to connect to oracle server.

Thursday, January 10, 2008

The Priority of NLS Parameters Explained

Subject: The Priority of NLS Parameters Explained
Doc ID: Note:241047.1 Type: BULLETIN
Last Revision Date: 21-AUG-2007 Status: PUBLISHED


This note explains the order in which NLS parameters are taken into account
in the database client/server model using a standard client connection.
(This does NOT cover JDBC connections, please see Note 115001.1
NLS_LANG Client Settings and JDBC Drivers for more info on jdbc and NLS.)

There are 3 levels at which you can set NLS parameters: Database, Instance and
Session. If a parameter is defined at more than one level then the rules on
which one takes precedence are quite straighforward:
1. NLS database settings are overwritten by NLS instance settings
2. NLS database & NLS instance settings are overwritten by NLS session settings

In the remainder of this note we shall explain all the different settings in
detail. The categories A to C shown below indicate the order of precedence with
A being the highest and C the lowest.
For example, if you set NLS_NUMERIC_CHARACTERS in the init.ora (point B) and
in the environment (point A 6), then for a session the value defined in the
environment will take priority because point A 6 comes before point B.


A) The Session Parameters.
--------------------------

select * from NLS_SESSION_PARAMETERS;

These are the settings used for the current sql session.

These reflect (in this order):

1) The values of NLS parameters set by "alter session .... "

alter session set NLS_DATE_FORMAT = 'DD/MM/YYYY';

* this can also been done with an after logon trigger(!).
select OWNER, TRIGGER_NAME, TRIGGER_BODY from DBA_TRIGGERS where
trim(TRIGGERING_EVENT) = 'LOGON';
-> Note 251044.1 How to set a NLS session parameter at database
level for all sessions ?

2) If there are no explicit "alter sessions ..." statements done then it
reflects the setting of the corresponding NLS parameter on the client derived
from the NLS_LANG variable.

NLS_LANG consist of: NLS_LANG=_.
for example:
NLS_LANG=DUTCH_BELGIUM.WE8MSWIN1252

For information on how to find the NLS_LANG your sqlplus session is using
see point "4.2 How can I Check the Client's NLS_LANG Setting?" in Note 158577.1

3) If NLS_LANG is specified with only the part
then AMERICAN is used as default .

So if you set NLS_LANG=_BELGIUM.WE8PC850 then you get this:

PARAMETER VALUE
------------------------------ --------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY BELGIUM
NLS_CURRENCY
NLS_ISO_CURRENCY BELGIUM
....

Note the difference between NLS_LANG=_BELGIUM.WE8PC850 (correct) and
NLS_LANG=BELGIUM.WE8PC850 (incorrect), you need to set the "_" as separator.

4) If NLS_LANG is specified with only the part then the
defaults to a setting based on .

So if you set NLS_LANG=ITALIAN_.WE8PC850 then you get this:

PARAMETER VALUE
------------------------------ --------------
NLS_LANGUAGE ITALIAN
NLS_TERRITORY ITALY
NLS_CURRENCY
NLS_ISO_CURRENCY ITALY
.....

Note the difference between NLS_LANG=ITALIAN_.WE8PC850 (correct) and
NLS_LANG=ITALIAN.WE8PC850 (incorrect), you need to set the "_" as separator.

5) If NLS_LANG is specified without the _ part
then the _ part defaults to AMERICAN_AMERICA.

So if you set NLS_LANG=.WE8PC850 then you get this:

PARAMETER VALUE
------------------------------ ----------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
....

Note the difference between NLS_LANG=.WE8PC850 (correct) and
NLS_LANG=WE8PC850 (incorrect), you need to set the "." as separator.

6) If the NLS_LANG is set (either like in point 3,4 or 5) then parameters like
NLS_SORT, NLS_DATE_FORMAT,... can be set as a "standalone" setting and will
overrule the defaults derived from NLS_LANG _ part.

So if you set NLS_LANG=AMERICAN_AMERICA.WE8PC850 and NLS_ISO_CURRENCY=FRANCE
then you get this:

PARAMETER VALUE
------------------------------ -----------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY FRANCE
...

* Make sure that you set "NLS_ISO_CURRENCY=FRANCE", NLS_ISO_CURRENCY= FRANCE
(note the space) will not give an error but the parameter is just ignored
and the default based on NLS_TERRITORY will be used.


Defaults:
---------
* If NLS_DATE_LANGUAGE or NLS_SORT are not set then they are derived from
NLS_LANGUAGE.

* If NLS_CURRENCY, NLS_DUAL_CURRENCY, NLS_ISO_CURRENCY, NLS_DATE_FORMAT,
NLS_TIMESTAMP_FORMAT, NLS_TIMESTAMP_TZ_FORMAT, NLS_NUMERIC_CHARACTERS are
not set then they are derived from NLS_TERRITORY


7) If the NLS_LANG is not set at all, then it defaults to
_.US7ASCII and the values for the
_ part used are the ones found in
NLS_INSTANCE_PARAMETERS. Parameters like NLS_SORT defined as "standalone" on
the client side are ignored.

* Oracle does NOT recommend to have the NLS_LANG UNSET, please always define
at least the proper part for the NLS_LANG like shown
in point 5)
See Note 158577.1 NLS_LANG Explained (How does Client-Server Character Conversion Work?)
and Note 179133.1 The correct NLS_LANG in a Windows Environment

Note that:

* If set, client parameters (NLS_SESSION_PARAMETERS) take always precedence
above NLS_INSTANCE_PARAMETERS and NLS_DATABASE_PARAMETERS.

* This behavior can not be disabled on/from the server, so a parameter set
on the client always has precedence above an instance or database parameter.

* NLS_LANG cannot be changed by alter session, NLS_LANGUAGE and NLS_TERRITORY
can. However NLS_LANGUAGE and /or NLS_TERRITORY cannot be set as a "standalone" parameters
in the enviroment or registry on the client.

* NLS_SESSION_PARAMETERS is NOT visible for other sessions. If you need to trace
this then you have to use a logon trigger to create your own logging table
(based on session_parameters)

* The part of NLS_LANG is *NOT* shown in any system table
or view. (see section 4.2 How can I Check the Client's NLS_LANG Setting? in
Note 158577.1)

* On Windows you have two possible options, normally the NLS_LANG is set in
the registry, but it can also be set in the environment, however this is not
often done and genrally not recommended to do so.
The value in the environment takes precedence over the value in
the registry and is used for ALL Oracle_Homes on the server(!) if defined as
a system environment variable.
See Note 179133.1 The correct NLS_LANG in a Windows Environment

* NLS_COMP *cannot* be set as enviroment variable (unlike documented in the
manual). All Oracle8i and Oracle9 versions use NLS_COMP from INIT.ORA or
from explicit ALTER SESSION.
Bug 2155062 NLS_COMP cannot be set in the client ENVIRONMENT

* NLS_LENGTH_SEMANTICS *cannot* be set as enviroment variable in 9i,
from 10g onwards it can be, please note that it needs to be set as UPPERCASE.
It is however possible to do a ALTER SESSION.
If not set explicit in a session it will use the NLS_INSTANCE_PARAMETER setting.

* NLS_NCHAR_CONV_EXCP *cannot* be set as enviroment variable.
It is however possible to do a ALTER SESSION.

* NLS_LANGUAGE in the session parameters also declares the language for the
client error messages, see also Note 132090.1.

* you cannot "set" a NLS parameter in an SQL script, you need to use alter
session.

B) The Instance Parameters.
---------------------------

select * from NLS_INSTANCE_PARAMETERS;

These are the settings in the init.ora of the database at the moment that
the database was started or set trough ALTER SYSTEM.

If the parameter is not explicitly set in the init.ora / defined by
ALTER SYSTEM then it's value is NOT derived from a "higher" parameter

(=we are talking about parameters like ex. NLS_SORT who
derive a default from NLS_LANGUAGE in NLS_SESSION_PARAMETERS,
this is NOT the case for NLS_INSTANCE_PARAMETERS )

Note that:

* NLS_LANG is not a init.ora parameter, NLS_LANGUAGE and NLS_TERRITORY are.
so you need to set NLS_LANGUAGE and NLS_TERRITORY separated.

* you cannot define the or NLS_LANG in the init.ora
the clients characterset is defined by the NLS_LANG on client side (see above).

* you cannot define the database characterset in the init.ora.
The database characterset is defined by the "Create Database" command (see point c)).

* These settings take precedence above the NLS_DATABASE_PARAMETERS.

* These values are used for the NLS_SESSION_PARAMETERS if on the client the
NLS_LANG is NOT set (we strongly advice to set the NLS_LANG).

* Oracle *strongly* recommends that you set the NLS_LANG on the client at least to
NLS_LANG=.

* ALTER SYSTEM SET NLS_LENGTH_SEMANTICS does not change the SESSION parameters
(who take precedence) due to bug number 1488174 until the database is restarted.
however it can be set in the init.ora or Spfile -> see Note 144808.1

* ALTER SYSTEM SET NLS_NCHAR_CONV_EXCP does not change the SESSION parameters
(who take precedence).. workaround: use a init.ora parameter.

C) The Database Parameters.
---------------------------

select * from NLS_DATABASE_PARAMETERS;

These are always defaulting to american america if there were no parameters
explicitly set in the init.ora during database creation time (!).
If there were parameters set in the init.ora during database creation you see
them here. There is no way to change these after the database creation.
Do NOT update systemtables!
These settings are used to give the database a default if the INSTANCE and
SESSION parameters are not set.

Note that:

* NLS_LANG is not a init.ora parameter, NLS_LANGUAGE and NLS_TERRITORY are.
So you need to set NLS_LANGUAGE and NLS_TERRITORY separatly.

* These parameters are overruled by NLS_INSTANCE_PARAMETERS and
NLS_SESSION_PARAMETERS.

* you cannot define the or NLS_LANG in the init.ora
the clients characterset is defined by the NLS_LANG on client side (see above).

* you cannot define the database characterset in the init.ora.
The database (national) characterset (NLS_(NCHAR)_CHARACTERSET)
is defined by the "Create Database ..." command.

* The NLS_CHARACTERSET and NLS_NCHAR_CHARACTERSET parameters cannot be
overruled by instance or session parameters.

They are defined by the value specified in "create database ..." and are not
intended to be changed afterwards dynamically.
Do NOT update systemtables to change the characterset.
This will corrupt your database and potentialy it will by impossible to open
the database again.
See Note 225912.1 Changing the Database Character Set - an Overview
If you want to change the database characaterset. Don't mess with this if you
don't know what you are doing. Log a tar if any doubt.

* Setting the NLS_LANG during the creation of the database dous not influence
the NLS_DATABASE_PARAMETERS.

* The NLS_LANG set during the database creation has NO impact on the database
(national) Characterset.

* These settings are used in evaluation of CHECK constraints if TO_CHAR/TO_DATE
without a date format is used in the CHECK condition. Writing CHECK
constraints without explicit date formats is a bad habit, you should use
explicit formats and this setting becomes irrelevant.

Additional selects:
-------------------

A) select name,value$ from sys.props$ where name like '%NLS%';

This gives the same info as NLS_DATABASE_PARAMETERS.
You should use NLS_DATABASE_PARAMETERS instead of props$.
Note the UPPERCASE '%NLS%'

B) select * from v$nls_parameters;

A view that shows the current session parameters and
the *DATABASE* characterset as seen in the NLS_DATABASE_PARAMETERS view.

C) select name,value from v$parameter where name like '%nls%';

This gives the same info as NLS_INSTANCE_PARAMETERS.
Note the LOWERCASE '%nls%'

D) select userenv ('language') from dual;
and
select sys_context('userenv','language') from dual;

Both these select statements give the session's _
and the *DATABASE* character set. The database character set is not the
same as the character set of the NLS_LANG that you started this connection
with! So don't be fooled, although the output of this query looks like the
value of a NLS_LANG variable - it is NOT.

For more info on SYS_CONTEXT please see Note 120797.1

E) select userenv ('lang') from dual;

This select gives the short code that Oracle uses for the Language defined
by NLS_LANGUAGE setting for this session.
If NLS_LANGUAGE is set to French then this will return "F",
if NLS_LANGUAGE is set to English then this will return "GB"
If NLS_LANGUAGE is set to American then this will return "US", and so on...

F) show parameter NLS%

This will give the same as the NLS_INSTANCE_PARAMETERS

Remark:
-------

The part of NLS_LANG is *NOT* shown in any systemtable
or view (it is not known in the database). If you require to know the current
setting of a clients NLS_LANG then please see section 4.2 (How can I Check the
Client's NLS_LANG Setting?) of Note 158577.1



Related Documents:
------------------

Note 179133.1 The correct NLS_LANG in a Windows Environment
Note 158577.1 NLS_LANG Explained (How does Client-Server Character Conversion Work?)
Note 227331.1 Setting NLS Parameters - Frequently Asked Questions

Note 13978.1 NLS Sort Characteristics
Note 13882.1 Linguistic Sorting of Data in Oracle7 and Oracle8
Note 30557.1 NLS_DATE_FORMAT and a Default Century

Note 225912.1 Changing the Database Character Set - an Overview

Note 132090.1 How to get messages in your own language on MS Windows platform?
Note 120797.1 How to Determine Client IP-address,Language & Territory and Username for Current Session

Note 251044.1 How to set a NLS session parameter at database level for all sessions ?
Note 144808.1 Examples and limits of BYTE and CHAR semantics usage

Bug 2155062 NLS_COMP cannot be set in the client ENVIRONMENT

For further NLS / Globalization information you may start here:
Note 267942.1 Globalization Technology (NLS) Knowledge Browser
Note 60134.1 NLS Frequently Asked Questions

Wednesday, January 09, 2008

AIX / redhat linux: Percentage of memory currently used by the file cache

Percentage of memory currently used by the file cache
AIX
vmstat -vs |grep "numperm percentage"

redhat
vmstat

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 29772 37820 45952 3729772 0 0 9 127 3 51 1 0 95 5

cache: the amount of memory used as cache.

linux环境sqlplus中使用backspace键出现乱码的解决方法

linux环境sqlplus中使用backspace键出现乱码的解决方法

1. 要使用回删键(backspace)时,同时按住ctrl键

2. 设定环境变量

在bash下:$ stty erase ^H
或者把 stty erase ^H 添加到.bash_profile中。

Wednesday, December 26, 2007

HOW TO FIND THE SESSION HOLDING A LIBRARY CACHE LOCK

Subject: HOW TO FIND THE SESSION HOLDING A LIBRARY CACHE LOCK
Doc ID: Note:122793.1 Type: TROUBLESHOOTING
Last Revision Date: 25-JUL-2005 Status: PUBLISHED


PURPOSE
-------

In some situations it may happen your session is 'hanging' and is awaiting for
a 'Library cache lock'. This document describes how to find the session that
in fact has the lock you are waiting for.


SCOPE & APPLICATION
-------------------

Support analysts, dba's, ..


HOW TO FIND THE SESSION HOLDING A A LIBRARY CACHE LOCK
------------------------------------------------------

Common situations:

* a DML operation that is hanging because the table which is accessed is currently
undergoing changes (ALTER TABLE). This may take quite a long time depending on
the size of the table and the type of the modification
(e.g. ALTER TABLE x MODIFY (col1 CHAR(200) on thousands of records).

* The compilation of package will hang on Library Cache Lock and Library Cache Pin
if some users are executing any Procedure/Function defined in the same package.

In the first situation the V$LOCK view will show that the session doing the
'ALTER TABLE' has an exclusive DML enqueue lock on the table object (LMODE=6,
TYPE=TM and ID1 is the OBJECT_ID of the table). The waiting session however does
not show up in V$LOCK yet so in an environment with a lot of concurrent sessions
the V$LOCK information is insufficient to track down the culprit blocking your
operation.

METHOD 1: SYSTEMSTATE ANALYSIS
------------------------------

One way of finding the session blocking you is to analyze the system state dump.
Using the systemstate event one can create a tracefile containing detailed
information on every Oracle process. This information includes all the resources
held & requested by a specific process.

Whilst an operation is hanging, open a new session and launch the following
statement:

ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME SYSTEMSTATE LEVEL 10';

Oracle will now create a systemstate tracefile in your USER_DUMP_DEST directory.
Get the PID (ProcessID) of the 'hanging' session from the V$PROCESS by matching
PADDR from V$SESSION with ADDR from V$PROCESS:

SELECT PID FROM V$PROCESS WHERE ADDR=
(SELECT PADDR FROM V$SESSION WHERE SID=sid_of_hanging_session);

The systemstate dump contains a separate section with information for each
process. Open the tracefile and do a search for 'PROCESS pid_from_select_stmt'.
In the process section look up the wait event by doing a search on 'waiting for'.

Example output:

PROCESS 8:
----------------------------------------
SO: 50050b08, type: 1, owner: 0, flag: INIT/-/-/0x00
(process) Oracle pid=8, calls cur/top: 5007bf6c/5007bf6c, flag: (0) -
int error: 0, call error: 0, sess error: 0, txn error 0
(post info) last post received: 82 0 4
last post received-location: kslpsr
last process to post me: 5004ff08 1 2
last post sent: 0 0 13
last post sent-location: ksasnd
last process posted by me: 5004ff08 1 2
(latch info) wait_event=0 bits=0
Process Group: DEFAULT, pseudo proc: 50058ac4
O/S info: user: daemon, term: pts/1, ospid: 15161
OSD pid info: 15161
----------------------------------------
SO: 5005f294, type: 3, owner: 50050b08, flag: INIT/-/-/0x00
(session) trans: 0, creator: 50050b08, flag: (41) USR/- BSY/-/-/-/-/-
DID: 0001-0008-00000002, short-term DID: 0000-0000-00000000
txn branch: 0
oct: 6, prv: 0, user: 41/LC
O/S info: user: daemon, term: pts/1, ospid: 15160, machine: goblin.forgotten.realms
program: sqlplus@goblin.forgotten.realms (TNS V1-V3)
application name: SQL*Plus, hash value=3669949024
waiting for 'library cache lock' blocking sess=0x0 seq=253 wait_time=0
!>> handle address=5023ef9c, lock address=5019cad4, 10*mode+namespace=15

Using the 'handle address' you can look up the process that is keeping a lock
on your resource by doing a search on the address within the same tracefile.

Example output:

PROCESS 9:
----------------------------------------
SO: 50050e08, type: 1, owner: 0, flag: INIT/-/-/0x00
(process) Oracle pid=9, calls cur/top: 5007bbac/5007bbfc, flag: (0) -
int error: 0, call error: 0, sess error: 0, txn error 0

....

----------------------------------------
SO: 5019d5e4, type: 34, owner: 5015f65c, flag: INIT/-/-/0x00
!>> LIBRARY OBJECT PIN: pin=5019d5e4 handle=5023ef9c mode=X lock=0
user=5005fad4 session=5005fad4 count=1 mask=0511 savepoint=118218 flags=[00]

From the output we can see that the Oracle process with PID 9 has an exclusive
lock on the object we are trying to access. Using V$PROCESS and V$SESSION we can
retrieve the sid,user,terminal,program,... for this process. The actual statement
that was launched by this session is also listed in the tracefile (statements and
other library cache objects are preceded by 'name=').


METHOD 2: EXAMINE THE X$KGLLK TABLE
-----------------------------------

The X$KGLLK table (accessible only as SYS/INTERNAL) contains all the
library object locks (both held & requested) for all sessions and
is more complete than the V$LOCK view although the column names don't
always reveal their meaning.

You can examine the locks requested (and held) by the waiting session
by looking up the session address (SADDR) in V$SESSION and doing the
following select:

select * from x$kgllk where KGLLKSES = 'saddr_from_v$session'

This will show you all the library locks held by this session where
KGLNAOBJ contains the first 80 characters of the name of the object.
The value in KGLLKHDL corresponds with the 'handle address' of the
object in METHOD 1.

You will see that at least one lock for the session has KGLLKREQ > 0
which means this is a REQUEST for a lock (thus, the session is waiting).
If we now match the KGLLKHDL with the handles of other sessions in
X$KGLLK that should give us the address of the blocking session since
KGLLKREQ=0 for this session, meaning it HAS the lock.

SELECT * FROM X$KGLLK LOCK_A
WHERE KGLLKREQ = 0
AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
WHERE KGLLKSES = 'saddr_from_v$session' /* BLOCKED SESSION */
AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
AND KGLLKREQ > 0);

If we look a bit further we can then again match KGLLKSES with SADDR
in v$session to find further information on the blocking session:

SELECT SID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION
WHERE SADDR in
(SELECT KGLLKSES FROM X$KGLLK LOCK_A
WHERE KGLLKREQ = 0
AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
WHERE KGLLKSES = 'saddr_from_v$session' /* BLOCKED SESSION */
AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
AND KGLLKREQ > 0)
);

In the same way we can also find all the blocked sessions:

SELECT SID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION
WHERE SADDR in
(SELECT KGLLKSES FROM X$KGLLK LOCK_A
WHERE KGLLKREQ > 0
AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
WHERE KGLLKSES = 'saddr_from_v$session' /* BLOCKING SESSION */
AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
AND KGLLKREQ = 0)
);


RELATED DOCUMENTS
-----------------

Note 1020008.6 SCRIPT FULLY DECODED LOCKING SCRIPT
Note 1054939.6 COMPILATION OF PACKAGE IS HANGING ON LIBRARY CACHE LOCK

Monday, December 24, 2007

a fga + vpd example

DROP PACKAGE MAINKEY;
begin
DBMS_RLS.DROP_POLICY (
'TEST','UTIPOSMAINKEY','PROTECTMAINKEY');
end;
/
begin
DBMS_FGA.DROP_POLICY(
object_schema=>'TEST',
object_name=>'UTIPOSMAINKEY',
policy_name=>'AUDITMAINKEY');
end;
/

=========================

CREATE OR REPLACE PACKAGE mainkey AS
FUNCTION usercontrol (D1 VARCHAR2, D2 VARCHAR2)
RETURN VARCHAR2;
END;
/

CREATE OR REPLACE PACKAGE BODY mainkey AS
FUNCTION usercontrol (D1 VARCHAR2, D2 VARCHAR2) RETURN VARCHAR2
IS
D_predicate VARCHAR2 (2000);
BEGIN
D_predicate := 'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') = ''TEST''';
RETURN D_predicate;
END usercontrol;
END mainkey;
/


BEGIN
DBMS_RLS.ADD_POLICY (
object_schema=>'TEST',
object_name=>'UTIPOSMAINKEY',
policy_name=>'PROTECTMAINKEY',
function_schema=>'TEST',
policy_function=>'MAINKEY.USERCONTROL',
statement_types=>'SELECT, UPDATE, DELETE, INSERT, INDEX',
update_check=>TRUE,
policy_type=>DBMS_RLS.STATIC);
END;
/

begin
DBMS_FGA.ADD_POLICY(
object_schema=>'TEST',
object_name=>'UTIPOSMAINKEY',
policy_name=>'AUDITMAINKEY',
audit_condition=>'SYS_CONTEXT(''USERENV'', ''SESSION_USER'') <> ''TEST''',
statement_types=>'INSERT, UPDATE, DELETE, SELECT',
audit_trail=>DBMS_FGA.DB + DBMS_FGA.EXTENDED);
end;
/

Thursday, November 08, 2007

范式, NF, normal form

4.4 关系模式的范式


4.4.1 第一范式
考核要求:达到“领会”层次
知识点:1NF的定义


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

1NF:第一范式—— 即关系模式中的属性的值域中每一个值都是不可再分解的值。
如果某个数据库模式都是第一范式的,则称该数据库模式是属于第一范式的数据库模式。

比如有一个关系 study={学号,课程},若有这样几行记录: 学号
课程

99001
C语言

99002
数据结构

99003
C语言,数据结构

 

这时的第三条记录就表示本关系模式不是1NF的,因为课程中的值域还是可以分解的,它包括了两门课程。

如果改为:

学号
课程

99001
C语言

99002
数据结构

99003
C语言

99003
数据结构

 
则成为1NF的关系。


4.4.2 第二范式
考核要求:达到“领会”层次
知识点:2NF的定义


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

如果关系模式R为第一范式,并且R中每一个非主属性完全函数依赖于R的某个候选键, 则称为第二范式模式。

首先温习、理解“非主属性”、“完全函数依赖”、“候选键”这三个名词的含义。
(1)候选键:可以唯一决定关系模式R中某元组值且不含有多余属性的属性集。
(2)非主属性:即非键属性,指关系模式R中不包含在任何建中的属性。
(3)完全函数依赖:设有函数依赖W→A,若存在XW,有X→A成立,那么称W→A是局部依赖,否则就称W→A是完全函数依赖。

在分析是否为第2范式时,应首先确定候选键,然后把关系模式中的非主属性与键的依赖关系进行考察, 是否都为完全函数依赖,如是,则此关系模式为2NF。
如果数据库模式中每个关系模式都是2NF的,则此数据库模式属于2NF的数据库模式。

比如有一个关系 study={学号,学生姓名,课程,成绩} 学号
姓名
课程
成绩

99001
Lily
C语言
91

99002
Rose
数据结构
82

99003
Keven
C语言
77

99003
keven
数据结构
86



其中,(学号,课程)为候选键;“成绩”对键的函数依赖为完全函数依赖,而“姓名”只依赖于“学号”, 对键的依赖为部分函数依赖。所以,该关系模式不符合2NF。如果将该 模式分解为以下两个关系:
     student={学号,姓名}
     study={学号,课程,成绩}
则分解后的两个关系模式均为2NF


4.4.3 第三范式
考核要求:达到“领会”层次
知识点:3NF的含义


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


如果关系模式R是第二范式,且每个非主属性都不传递依赖于R的候选键,则称R为第三范式模式。
传递依赖的含义: 在关系模式中,如果Y→X,X→A,且XY(X不决定Y)和AX(A不属于X),那么Y→A是传递依赖。 Notice:要求非主属性都不传递依赖于候选键。

上一小节例子中student={学号,姓名},study={学号,课程,成绩}都是3NF




4.4.4 BCNF
考核要求:达到“领会”层次
知识点:BCNF的含义


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

这个范式和第三范式有联系,它是3NF的改进形式。
若关系模式R是第一范式,且每个属性都不传递依赖于R的候选键。这种关系模式就是BCNF模式。
四种范式,可以发现它们之间存在如下关系:
BCNF3NF2NF1NF



1NF
↓ 消去非主属性对键的部分函数依赖
2NF
↓ 消去非主属性对键的传递函数依赖
3NF
↓ 消去主属性对键的传递函数依赖
BCNF





4.4.5 分解成BCNF模式集的算法
考核要求:达到“识记”层次
知识点:分解成BCNF模式集的算法


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

对于任一关系模式,
(1)可找到一个分解达到3NF,且具有无损联接和保持函数依赖性。
(2)对于BCNF分解,则可以保证无损联接但不一定能保证保持函数依赖集。
(定理4.9)
(算法4.3)
无损联接分解成BCNF模式集的算法:
(1)置初值ρ={R};
(2)如果ρ中所有关系模式都是BCNF,则转(4);
(3)如果ρ中有一个关系模式S不是BCNF,则S中必能找到一个函数依赖集X→A有X不是S的键,且A不属于X,设S1=XA,S2=S-A,用分解S1,S2代替S,转(2);
(4)分解结束。输出ρ。
Notice:重点在于(3)步,判断哪个关系不是BCNF,并找到X和A。
(以上内容可结合习题内容加以理解)

4.4.6 分解成3NF模式集
考核要求:达到“识记”层次
知识点:算法4.4


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

(算法4.4)
(1)如果R中的某些属性在F的所有依赖的左边和右边都不出现,那么这些属性可以从R中分出去,单独构成一个关系模式。
(2)如果F中有一个依赖X→A有XA=R,则ρ={R},转(4)
(3)对于F中每一个X→A,构成一个关系模式XA,如果F有有X→A1,X→A2...X→An,则可以用模式XA1A2...An代替n个模式XA1,XA2...XAn;
(4)w分解结束,输入ρ。
(以上内容可结合习题内容加以理解)

4.4.7 模式设计方法的原则
考核要求:达到“识记”层次
知识点:四项特性和三条原则


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

关系模式R相对于函数依赖集F分解成数据库模式ρ={R1,R2...Rk},一般具有下面四项特性:
(1)ρ中每个关系模式Ri上应具有某种范式性质(3NF或BCNF)
(2)无损联接性。
(3)保持函数依赖集。
(4)最小性,即ρ中模式个数应最少且模式中属性总数应最少。

一个好的模式设计方法应符合下列三条原则:
(1)表达性
(2)分离性
(3)最小冗余性


4.4.8 多值依赖
考核要求:达到“识记”层次
知识点:多值依赖的概念及其和函数依赖的区别


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

函数依赖有效地表达了属性值之间多对一的联系,是最重要的一种数据依赖;而多值依赖是为了刻划属性值之间一对多的联系.


4.4.9 第四范式
考核要求:达到“识记”层次
知识点:第四范式的概念


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

设R是一个关系模式,D是R上的多值依赖集合。如果D中成立非平凡多值依赖X→→Y时,X必是R的超键, 那么称R是第四范式(4NF)。
(定理4.13) 一个关系模式若属于4NF,则必然属于BCNF。
(算法4.5) :了解一下。

Tuesday, October 30, 2007

Which indexes are used and how many times they are used?

Which indexes are used and how many times they are used?

col c1 heading object|Owner format a15
col c2 heading object|Name format a25
col c3 heading operation format a10
col c4 heading option format a15
col c5 heading index|Usage|Count format 999,999

select
p.object_owner c1,
p.object_name c2,
p.operation c3,
p.options c4,
count(1) c5
from
dba_hist_sql_plan p,
dba_hist_sqlstat s
where
p.object_owner <> 'SYS'
and
p.operation like 'INDEX%' and
p.sql_id = s.sql_id
group by
p.object_owner,
p.object_name,
p.operation,
p.options
order by
1,2,3,4;

Friday, September 28, 2007

Ora-02437 When Creating PK Using Novalidate When Table Has duplicate data iPK Columns

Subject: Ora-02437 When Creating PK Using Novalidate When Table Has duplicate data iPK Columns
Doc ID: Note:264003.1 Type: PROBLEM
Last Revision Date: 02-JUL-2007 Status: MODERATED


The information in this article applies to:
Oracle Server - Enterprise Edition - Version: 8.1.7.4 to 10.2.0.0
This problem can occur on any platform.

Errors
ORA 2437 cannot enable - primary key violated


Symptoms
Have a table with duplicate data in the PK columns.
Trying to create the PK with the novalidate option fails with an ora-02437.

Test Case to exhibit the problem:

CREATE TABLE chris (col1 INTEGER)
/
INSERT INTO chris VALUES (1)
/
INSERT INTO chris VALUES (2)
/
INSERT INTO chris VALUES (3)
/
INSERT INTO chris VALUES (4)
/
INSERT INTO chris VALUES (4)
/
ALTER TABLE chris ADD PRIMARY KEY (col1) NOVALIDATE
/
-- fails with error ORA-02437
ALTER TABLE chris ADD PRIMARY KEY (col1) DISABLE
/
-- ok
ALTER TABLE chris ENABLE NOVALIDATE PRIMARY KEY
/
-- again fails with error ORA-02437

Cause
This error occurs because it tries to create a unique index for the unique or primary
key index. The uniqueness is checked during the creation of the unique index.
Fix
- First, create a NON-UNIQUE index on the same fields that you want to
include in the constraint.
- Then add the unique or primary key constraint.

Thats is:

create index idx_chris_col1 on chris(col1);

After this give:

ALTER TABLE chris ADD PRIMARY KEY (col1) NOVALIDATE
/

OR

ALTER TABLE chris ENABLE NOVALIDATE PRIMARY KEY
/

References
Bug 544502 - Enabling Novalidate Not Deferrable Unique Constraint Creates Unique Index