Enqueue Waits : Locks
Thanks to Doug Burns for much of the
Row Lock example
Kyle Hailey
Kylehailey.com
kyle@delphix.com
Oaktable World UK
•

Mon Dec 2, Tues Dec 3
Who is Kyle Hailey
 1990 Oracle
–
–
–
–
–

90 support
92 Ported v6
93 France
95 Benchmarking
98 ST Real World Performance...
Who is Kyle Hailey
 1990 Oracle
–
–
–
–
–






90 support
92 Ported v6
93 France
95 Benchmarking
98 ST Real World Pe...
Who is Kyle Hailey
•

1990 Oracle






•
•
•
•
•

90 support
92 Ported v6
93 France
95 Benchmarking
98 ST Real World...
Production
Instance

Database

File system
File system

QA

UAT

Instance

Instance

Instance

Database

Database

Databas...
Production
Instance

Database

File system

Development

QA

UAT

Instance

Instance

Instance

Database

Database

Databa...
AWR Method
Who/When

Summary

Top 5 Timed Events
~~~~~~~~~~~~~~~~~~
% for
Load profile goodTotal
Event
Waits having a (s) ...
Row Locks 10g+
Top 5 Timed Events
Avg %Total
~~~~~~~~~~~~~~~~~~
wait
Call
Event
Waits
Time (s)
(ms)
Time
-----------------...
Power of ASH !
v$active_session_history
•

Waiter
– SESSION_ID
– SESSION_SERIAL#
– USER_ID

•

Object
– CURRENT_OBJ#
– CUR...
Content
Part I : Row Locks
– enq: TX - row lock contention
•
•
•
•
•

Data in ASH
OEM
V$lock & v$session
ASH
Find blocking...
Lock Types
•

9i
– One Wait : “enqueue”

•

10g

TX
TM
Transaction Table Modification

– 208 enqueue waits
– Specific to e...
Lock Modes
# Type
--- ------1 Null
2 SS
3 SX
4 S
5 SSX
6 X

Name
--------------------------Null
Sub share
Sub exclusive
Sh...
Lock Type and Mode
Select parameter1 from v$event_name where name like ‘enq%’;
Parameter1
---------Name|mode
Select p1, p1...
Type and Mode
SELECT
SELECT
chr(bitand(p1,-16777216)/16777215)||
chr(bitand(p1,-16777216)/16777215)||
chr(bitand(p1, 16711...
enq: TX - row lock contention, mode 6
To Solve we need, and ASH gives :

1. Waiter
2. Blocker
3. Blocking Object
4. Lock T...
OEM 10g

if P1 = 1415053318
then mode = 6
Then it is a data block
row lock
enq: TX - row lock contention
Mode 6, row in data block
User 1
SQL> delete from toto
where id = 1;

User 2

SQL> delete f...
Querying ASH
select
substr(event,0,20)
ash.session_id
mod(ash.p1,16)
ash.p2
ash.p3
o.object_name
o.object_type
CURRENT_FIL...
Other Data Sources
In “real time” can also use
–
–
–
–
–
–

v$lock
v$session (v$session_wait)
dba_blockers
dba_waiters
?/r...
Step one: get a lock
Session 1
Session_1> select pk_id from test_tab1
where rownum=1 ;
PK_ID
--------------

4051
select p...
Step 2: create a blocker
Session 2 Session_2> select pk_id from test_tab1
where pk_id = 4051
for update;

Hangs …
Step 3: release the lock and blocking
Session 1
Session_1> commit;
Commit complete.

Session 2 now continues
PK_ID
-------...
Locks in OEM:

Application
Wait
click

One SQL

One Session
Click on “Application”

Click on
SQL ID
Click on SQL

SQL waits for lock
get’s lock and does I/O to complete
Click on “Session ID”

Click on
Session ID
No info is lock is gone

Limited Use : lock is already released
Session Before Lock released
Click

Blocker
Holds lock

Waiter
ASH data in EM, but missing blocking info

BLOCKING_SESSION_STATUS
BLOCKING_SESSION
BLOCKING_SESSION_SERIAL#
v$lock & v$session – during lock wait
SQL> select s.sid, s.state, s.event, s.sql_id, l.type, l.lmode
2

from v$session s, ...
v$lock : after commit by Session 1
SQL> select s.sid, s.state, s.event, s.sql_id, l.type, l.lmode
2

from v$session s, v$l...
v$active_session_history – during and after
SQL> select
a.sample_time,
a.session_id,
a.event,
a.session_state,
a.blocking_...
V$active_session_history
SQL> select
a.sample_time,
a.session_id,
a.event,
a.session_state,
a.blocking_session
BSID,
a.blo...
How do we find the SQL that took the
lock?
Session B
update toto set
update toto set
name = ‘ADAMS’
name = ‘ADAMS’
where id = 1;
where id = 1;

TX Lock
Wait for Tx
T...
Logminer : setup
SQL> select group#, thread#, status from v$log;
GROUP#
THREAD# STATUS
---------- ---------- -------------...
Logminer : setup locking
SQL> create table test_tab1
as select object_id pk_id, object_name from all_objects;
SQL> select ...
Find Transaction
•

From v$transaction
– Xid of current active transaction

•

From v$active_session _history
– Calculate ...
Logminer with XID
SQL> select

@tx.sql

xid, xidusn, xidslot, xidsqn
from v$transaction order by start_time;

XID
XIDUSN
X...
Finding XID from ASH
Normal use P2, P3 from wait:
WAIT TYPE = 'enq: TX - Row Lock Contention’
Then
P2=usn<<16||slot
P3=Seq...
Logminer by USN and SLOT
SQL> select

xid, xidusn, xidslot, xidsqn
from v$transaction order by start_time;
XID
XIDUSN
XIDS...
Dumping Redo Directly
SQL> select rowid, object_name from test_tab1 where pk_id=5041;
ROWID
OBJECT_NAME
------------------...
Data block row update

FILE_ID

BLOCK_NUMBER

----------

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

10

106571

SYS@TEST1020> alter system dump logfil...
Verify DBA and Table
REDO RECORD - Thread:1 RBA: 0x0000b3.00000009.0010 LEN: 0x0210 VLD: 0x0d SCN:
0x0000.008a42e6 SUBSCN:...
Update Value
“session 1”
Array Update of 1 rows:
…
col 1: [ 9] 53 45 53 53 49 4f 4e 20 30
CHANGE #3 TYP:2 CLS:1 AFN:1 DBA:...
Last Try: flashback
SELECT

VERSIONS_XID
,
VERSIONS_STARTTIME
,
VERSIONS_ENDTIME
,
VERSIONS_STARTSCN
,
VERSIONS_ENDSCN
,
V...
From ASH
BLOCK_XID
---------------0A00010072640000

P2HEX
P3HEX
USN
SLOT
SQN WAIT_XID
--------- --------- ---------- -----...
enq: TX - row lock contention – Mode 4
P1 = name | mode
select distinct parameter1 from v$event_name
where name like 'enq:%'

PARAMETER1
name|mode
select
event,
...
enq: TX - row lock contention
• Mode 6 (exclusive)

– modification of a row lock

• Mode 4 (share)
– ??
enq: TX - row lock contention

if P1 = 1415053318
then mode = 6
Then it is a data block
row lock
TX – Mode 4

if P1 = 1415053316
then mode = 4
Not same data but conflicts
enq: TX - row lock contention
Mode 4, happens for 3 reasons
1. Unique key contention
2. Foreign Key contention
3. Bitmap i...
1. enq: TX - row lock contention
Mode 4 , unique index

User 2

User 1
create table p(n number);
create unique index p_i ...
2. enq: TX - row lock contention
Mode 4, foreign key
User 1
create table parent (
id number primary key);
create table ch...
3. enq: TX - row lock contention
Mode 4, bitmap
• Bitmaps are compressed
• Changes to the same bitmap cause locks

Value ...
3. enq: TX - row lock contention
Mode 4, foreign key
Session 1
create table t1 ((
Different rows but
create table t1
valu...
3. enq: TX - row lock contention
Mode 4, foreign key
•
•

Bitmaps are compressed
Changes to the same bitmap chunk cause l...
3. enq: TX - row lock contention
Mode 4, foreign key
Value Start End
Bitmap
Rowid Rowid
1
01010000111000011100001100
200....
Summary: TX 4 from ASH
Mode 4, unique key
SID LM
P2
P3 OBJ

uniq index
ST
EVENT
----- ---------------------10:39 enq: TX ...
Specific ‘enq: TX’ wait events
•

enq: TX - allocate ITL entry
– ITL space waits

•

enq: TX - index contention ?
– Index ...
enq: TX - allocate ITL entry

Data Block
Data Block
Header
Header
ITL

Data

Transaction 1 Info
Transaction 2 Info
enq: TX - allocate ITL entry

Data Block
Data Block
Header
Header
Transaction 1
Transaction 2
Row 3
Row 2
Data
Row 1

Tran...
enq: TX - allocate ITL entry
create table itl (
create table itl (
id number,
id number,
data varchar2(20)
data varchar2(2...
enq: TX - contention
1. Altering tablespace read only with open transaction
Example
– Session 1 – start transaction, don’t...
enq: TM - contention
•
•

TX locks have a corresponding TM lock
TM locks the structure from change

 Parameter1

= object...
enq: TM - contention
Exclusive Row Level Lock
User 1
create table parent (
id number primary key);
create table child (
i...
enq: TM - contention
PK

Parent

Child

ID
1
X
2

ID
1
X
2

ID Name
1

Session 1
Session 2

Value

Insert into Child ID=1
...
enq: TM – contention Solution
PK

Parent

ID
1
2

ID

Value

Index
ID
1

Child
ID Name

Foreign Key
Session 1: Insert into...
TM Further Investigation
select
event,
sql_id,
mod(p1,16) as "mode",
p2|| ' ' || o.name obj
from v$active_session_history ...
Other Resources

@?/rdbms/admin/utllockt
WAITING_SESSION LOCK_TYPE

MODE_REQUESTED MODE_HELD LOCK_ID1

LOCK_ID2

---------...
Blocking Sessions
Content
Part I : Row Locks
– enq: TX - row lock contention
•
•
•
•
•

Data in ASH
OEM
V$lock & v$session
ASH
Find blocking...
Without TM Locks
Child
Name
ID
1
2
3
4
…
10000

Delete
Parent

Child
Delete
Child

Could scan Child table for value “2” an...
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction Locks
UKOUG, Oracle Transaction Locks
Upcoming SlideShare
Loading in …5
×

UKOUG, Oracle Transaction Locks

1,290 views

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,290
On SlideShare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
70
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • In Oracle Support I learned more faster than I think I could have anywhere.
    Porting gave me my first appreciation for the shareable nature of Oracle code and also a bit of disbelief that it worked as well as it did.
    Oracle France gave me an opportunity to concentrate on the Oracle kernel.
    At Oracle France I had 3 amazing experiences. First was being sent to the Europecar site where I first met a couple of the people who would later become the founding members of the Oaktable, James Morle and Anjo Kolk. The Europecar site introduced me to a fellow name Roger Sanders who first showed me the wait interface before anyone knew what it was. Roger not only used it but read it directly from shared memory without using SQL.
    Soon after Europecar I began to be sent often to benchmarks at Digital Europe. These benchmarks were some of my favorite work at Oracle. The benchmarks usually consisted of installing some unknown Oracle customer application and then having a few days to make it run as fast as possible. I first started using TCL/TK and direct shared memory access (DMA) at Digital Europe and got solid hands on tuning experience testing things like striping redo and proving it was faster long before people gave up arguing that this was bad from a theoretical point of view.
    Finally in France, my boss, Jean Yves Caleca was by far the best boss I ever had, but on top of that he was wonderful at exploring the depths of Oracle and explaining it to others, teaching me much about the internals of block structure, UNDO, REDO and Freelsits.
    I came back from France wanting to do performance work and especially graphical monitoring. The kernel performance group had limited scope in that domain, so I left for a dot com where I had my first run as the sole DBA for everything, backup, recovery, performance, installation and administration. I was called away by Quest who had my favorite performance tool Spotlight. It turns out thought that scope for expanding Spotlight was limited so I jumped at the chance in 2002 to restructure Oracle OEM. The work at OEM I’m proud of but still want to do much more to make performance tuning faster, easier and more graphical.
  • In Oracle Support I learned more faster than I think I could have anywhere.
    Porting gave me my first appreciation for the shareable nature of Oracle code and also a bit of disbelief that it worked as well as it did.
    Oracle France gave me an opportunity to concentrate on the Oracle kernel.
    At Oracle France I had 3 amazing experiences. First was being sent to the Europecar site where I first met a couple of the people who would later become the founding members of the Oaktable, James Morle and Anjo Kolk. The Europecar site introduced me to a fellow name Roger Sanders who first showed me the wait interface before anyone knew what it was. Roger not only used it but read it directly from shared memory without using SQL.
    Soon after Europecar I began to be sent often to benchmarks at Digital Europe. These benchmarks were some of my favorite work at Oracle. The benchmarks usually consisted of installing some unknown Oracle customer application and then having a few days to make it run as fast as possible. I first started using TCL/TK and direct shared memory access (DMA) at Digital Europe and got solid hands on tuning experience testing things like striping redo and proving it was faster long before people gave up arguing that this was bad from a theoretical point of view.
    Finally in France, my boss, Jean Yves Caleca was by far the best boss I ever had, but on top of that he was wonderful at exploring the depths of Oracle and explaining it to others, teaching me much about the internals of block structure, UNDO, REDO and Freelsits.
    I came back from France wanting to do performance work and especially graphical monitoring. The kernel performance group had limited scope in that domain, so I left for a dot com where I had my first run as the sole DBA for everything, backup, recovery, performance, installation and administration. I was called away by Quest who had my favorite performance tool Spotlight. It turns out thought that scope for expanding Spotlight was limited so I jumped at the chance in 2002 to restructure Oracle OEM. The work at OEM I’m proud of but still want to do much more to make performance tuning faster, easier and more graphical.
  • In Oracle Support I learned more faster than I think I could have anywhere.
    Porting gave me my first appreciation for the shareable nature of Oracle code and also a bit of disbelief that it worked as well as it did.
    Oracle France gave me an opportunity to concentrate on the Oracle kernel.
    At Oracle France I had 3 amazing experiences. First was being sent to the Europecar site where I first met a couple of the people who would later become the founding members of the Oaktable, James Morle and Anjo Kolk. The Europecar site introduced me to a fellow name Roger Sanders who first showed me the wait interface before anyone knew what it was. Roger not only used it but read it directly from shared memory without using SQL.
    Soon after Europecar I began to be sent often to benchmarks at Digital Europe. These benchmarks were some of my favorite work at Oracle. The benchmarks usually consisted of installing some unknown Oracle customer application and then having a few days to make it run as fast as possible. I first started using TCL/TK and direct shared memory access (DMA) at Digital Europe and got solid hands on tuning experience testing things like striping redo and proving it was faster long before people gave up arguing that this was bad from a theoretical point of view.
    Finally in France, my boss, Jean Yves Caleca was by far the best boss I ever had, but on top of that he was wonderful at exploring the depths of Oracle and explaining it to others, teaching me much about the internals of block structure, UNDO, REDO and Freelsits.
    I came back from France wanting to do performance work and especially graphical monitoring. The kernel performance group had limited scope in that domain, so I left for a dot com where I had my first run as the sole DBA for everything, backup, recovery, performance, installation and administration. I was called away by Quest who had my favorite performance tool Spotlight. It turns out thought that scope for expanding Spotlight was limited so I jumped at the chance in 2002 to restructure Oracle OEM. The work at OEM I’m proud of but still want to do much more to make performance tuning faster, easier and more graphical.
  • bitand(p1, 65536) &quot;Mode&quot;
  • Lock seems easy
    Compared to latches, buffer busy waits etc
  • col event for a22
    col block_type for a18
    col objn for a18
    col otype for a10
    col fn for 99
    col sid for 9999
    col bsid for 9999
    col lm for 99
    col p3 for 99999
    col blockn for 99999
    select
    to_char(sample_time,&apos;HH:MI&apos;) st,
    substr(event,0,20) event,
    ash.session_id sid,
    mod(ash.p1,16) lm,
    ash.p2,
    ash.p3,
    nvl(o.object_name,ash.current_obj#) objn,
    substr(o.object_type,0,10) otype,
    CURRENT_FILE# fn,
    CURRENT_BLOCK# blockn,
    ash.SQL_ID,
    BLOCKING_SESSION bsid
    --,ash.xid
    from v$active_session_history ash,
    all_objects o
    where event like &apos;enq: TX %&apos;
    and o.object_id (+)= ash.CURRENT_OBJ#
    and sample_time &gt; sysdate - &amp;1/(60*24)
    Order by sample_time
    /
  • TX
    if P1 = 1415053316
    then mode = 4
    if P1 = 1415053318
    then mode = 6
  • create table p(n number);
    create unique index p_i on p(n);
    insert into p values(3);
  • Subject:
    Bitmap Indexes and Deadlocks: Deadlocks on Insert Statements
    Doc ID:
    Note:171795.1
    Type:
    TROUBLESHOOTING
    Last Revision Date:
    18-MAY-2004
    Status:
    PUBLISHED
    PURPOSE
    -------
    The purpose of this article is to explain the occurrence of deadlocks
    when the only DML activity is insert statements against a table with
    a bitmap index
    SCOPE &amp; APPLICATION
    -------------------
    Database administrators and Application developers involved in
    application design.
    BITMAP INDEXES: THE HIDDEN DEADLOCK THREAT
    ------------------------------------------
    The &quot;Oracle8i Designing and Tuning for Performance&quot; guide explains
    the limitations of bitmap indexes as this:
    Extract of documentation:
    &quot;DML and DDL statements, such as UPDATE, DELETE, DROP TABLE, affect bitmap
    indexes the same way they do traditional indexes: the consistency model is
    the same. A compressed bitmap for a key value is made up of one or more bitmap
    segments, each of which is at most half a block in size (but may be smaller).
    The locking granularity is one such bitmap segment. This may affect performance
    in environments where many transactions make simultaneous updates. If numerous
    DML operations have caused increased index size and decreasing performance for
    queries, then you can use the ALTER INDEX ... REBUILD statement to compact the
    index and restore efficient performance.
    A B*-tree index entry contains a single rowid. Therefore, when the index entry
    is locked, a single row is locked. With bitmap indexes, an entry can potentially
    contain a range of rowids. When a bitmap index entry is locked, the entire range
    of rowids is locked. The number of rowids in this range affects concurrency.
    As the number of rowids increases in a bitmap segment, concurrency decreases.
    Locking issues affect DML operations, and may affect heavy OLTP environments.
    Locking issues do not, however, affect query performance. As with other types
    of indexes, updating bitmap indexes is a costly operation. Nonetheless, for
    bulk inserts and updates where many rows are inserted or many updates are made
    in a single statement, performance with bitmap indexes can be better than with
    regular B*-tree indexes.&quot;
    **************
    What is not mentioned is the fact that the same architectural feature that
    locks a range of rowid&apos;s also means that its possible to get a deadlock within
    the bitmap when updating rows in the underlying table. This deadlock is not in
    the table itself, as one might suspect, but rather in the bitmap index blocks.
    This kind of deadlock is easily diagnosable by the deadlock trace file, which
    has an entry that looks like the example below:
    The following deadlock is not an ORACLE error. It is a
    deadlock due to user error in the design of an application
    or from issuing incorrect ad-hoc SQL. The following
    information may aid in determining the deadlock:
    Deadlock graph:
    ---------Blocker(s)-------- ---------Waiter(s)---------
    Resource Name process session holds waits process session holds waits
    TX-00080027-0000d2a1 12 37 X 15 35 S
    TX-000a0016-0000d6d2 15 35 X 12 37 S
    session 37: DID 0001-000C-00000002 session 35: DID 0001-000F-00000002
    session 35: DID 0001-000F-00000002 session 37: DID 0001-000C-00000002
    Rows waited on:
    Session 35: no row
    Session 37: no row
    The piece of information that leads us to a bitmap deadlock is the &quot;no row&quot;
    value in the session information. If we had encountered a deadlock in the
    underlying table, the Session line would give us row information so that we
    could track down the exact point of failure. Without a row, it would seem that
    we are at a dead end. Even more mysterious is when we get this deadlock on
    inserts, where we are inserting only new rows and therefore it would seem
    impossible to get a deadlock. No one should be requesting a row that someone
    else holds locked.
    There are no solutions to this kind of problems, except not using bitmap indexes
    when having an application where you can&apos;t control when the DML are issued against
    the tables with bitmap indexes. Bitmaps are normally intended for datawarehouse
    applications that are loading data via batches and that users are only querying.
    The following testcase can be used to see the results of this type of problem.
    We will create a table called CAR_TYPE, which holds information about cars,
    including the car&apos;s color. We will build a bitmap index on the COLOR column.
    After doing so, we will populate the table with data. After the initial insert,
    we will open two sessions of the same user, and run simultaneous inserts into
    the CAR_TYPE table.
    TESTCASE:
    =====================================
    =====================================
    create table car_type (
    make varchar2(20),
    model varchar2(20),
    color varchar2(20),
    VIN number(15) primary key,
    year number(4));
    create bitmap index car_type_bm_idx on car_type(color);
    create sequence car_type_seq
    start with 35001
    increment by 1
    nocache
    nocycle;
    declare
    v_CarMake varchar2(20) := &apos;Audi&apos;;
    v_CarModel varchar(20) := &apos;Quattro&apos;;
    v_CarColor varchar(20) := &apos;Gold&apos;;
    v_CarVin binary_integer :=1;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 5000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Toyota&apos;;
    v_CarModel varchar(20) := &apos;Camry&apos;;
    v_CarColor varchar(20) := &apos;Red&apos;;
    v_CarVin binary_integer :=5001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 10000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Audi&apos;;
    v_CarModel varchar(20) := &apos;Quattro&apos;;
    v_CarColor varchar(20) := &apos;Blue&apos;;
    v_CarVin binary_integer :=10001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 15000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Toyota&apos;;
    v_CarModel varchar(20) := &apos;Camry&apos;;
    v_CarColor varchar(20) := &apos;Silver&apos;;
    v_CarVin binary_integer :=15001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 20000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Audi&apos;;
    v_CarModel varchar(20) := &apos;Quattro&apos;;
    v_CarColor varchar(20) := &apos;Green&apos;;
    v_CarVin binary_integer :=20001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 25000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Audi&apos;;
    v_CarModel varchar(20) := &apos;Quattro&apos;;
    v_CarColor varchar(20) := &apos;Black&apos;;
    v_CarVin binary_integer :=25001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 30000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := &apos;Toyota&apos;;
    v_CarModel varchar(20) := &apos;Camry&apos;;
    v_CarColor varchar(20) := &apos;White&apos;;
    v_CarVin binary_integer :=30001;
    begin
    loop
    insert into car_type (make,model,color,VIN,year)
    values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;);
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin &gt; 35000;
    end loop;
    end;
    /
    commit;
    ===============================
    ===============================
    After this initial creation, cut the following script into a .sql file, and
    then execute it simultaneously from two sessions:
    ===============================
    ===============================
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;);
    insert into car_type values (
    &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;);
    commit;
    ========================================
    ========================================
    The result will be occasional deadlock errors:
    insert into car_type values (
    *
    ERROR at line 1:
    ORA-00060: deadlock detected while waiting for resource
    The trace file will show the tell-tale &apos;No Row&apos; message:
    Rows waited on:
    Session 11: no row
    Session 10: no row
    RELATED DOCUMENTS
    -----------------
    Oracle8i Designing and Tuning for Performance
    Release 2 (8.1.6)
    Part Number A76992-01
    .
  • UKOUG, Oracle Transaction Locks

    1. 1. Enqueue Waits : Locks Thanks to Doug Burns for much of the Row Lock example Kyle Hailey Kylehailey.com kyle@delphix.com
    2. 2. Oaktable World UK • Mon Dec 2, Tues Dec 3
    3. 3. Who is Kyle Hailey  1990 Oracle – – – – – 90 support 92 Ported v6 93 France 95 Benchmarking 98 ST Real World Performance  2000 Dot.Com  2001 Quest  2002 Oracle OEM 10g Success! First successful OEM design
    4. 4. Who is Kyle Hailey  1990 Oracle – – – – –     90 support 92 Ported v6 93 France 95 Benchmarking 98 ST Real World Performance 2000 Dot.Com 2001 Quest 2002 Oracle OEM 10g 2005 Embarcadero – DB Optimizer
    5. 5. Who is Kyle Hailey • 1990 Oracle      • • • • • 90 support 92 Ported v6 93 France 95 Benchmarking 98 ST Real World Performance 2000 Dot.Com 2001 Quest 2002 Oracle OEM 10g 2005 Embarcadero  DB Optimizer Delphix When not being a Geek - Have a little 4 year old boy who takes up all my time
    6. 6. Production Instance Database File system File system QA UAT Instance Instance Instance Database Database Database File system File system File system File system File system File system File system Development
    7. 7. Production Instance Database File system Development QA UAT Instance Instance Instance Database Database Database
    8. 8. AWR Method Who/When Summary Top 5 Timed Events ~~~~~~~~~~~~~~~~~~ % for Load profile goodTotal Event Waits having a (s) Call Time Time feel for the ---------------------- ------------ application and ----------- --------buffer busy waits 2,748 250 78.72 comparing two 10.16 CPU time 32 periods for changes free buffer waits 1,588 15 4.63 Efficiency 8 ratios 2.51 write complete waits 10 log buffer space 306 misleading carry 1.51 5 ---------------------------------------- 6 over from version days Waits Big Picture
    9. 9. Row Locks 10g+ Top 5 Timed Events Avg %Total ~~~~~~~~~~~~~~~~~~ wait Call Event Waits Time (s) (ms) Time ----------------------------------------- ------------ ----------- ------ -----enq: TX - row lock contention 59 160 2714 41.8 PL/SQL lock timer 4 117 29291 30.6 CPU time 28 7.2 buffer busy waits 1,217 18 15 4.7 log file parallel write 422 11 27 3.0 Who is waiting? Who is blocking? What is the SQL? What is the row? Not in AWR report
    10. 10. Power of ASH ! v$active_session_history • Waiter – SESSION_ID – SESSION_SERIAL# – USER_ID • Object – CURRENT_OBJ# – CURRENT_FILE# – CURRENT_BLOCK# • SQL Waiting - SQL_ID • Blocker - BLOCKING_SESSION - BLOCKING_SESSION_STATUS - BLOCKING_SESSION_SERIAL# • Lock Type and Mode - Event = Type (name) - P1 = Type | Mode
    11. 11. Content Part I : Row Locks – enq: TX - row lock contention • • • • • Data in ASH OEM V$lock & v$session ASH Find blocking SQL Part II : Row Locks ?? – enq: TX - row lock contention, mode 4 Part III : Other TX locks – – – enq: TX - allocate ITL entry enq: TX - index contention enq: TX – contention Part IV : TM locks
    12. 12. Lock Types • 9i – One Wait : “enqueue” • 10g TX TM Transaction Table Modification – 208 enqueue waits – Specific to each type of enqueue – select name,wait_class from v$event_name where name like 'enq%' enq: enq: enq: enq: enq: enq: enq: enq: enq: enq: HW SQ SS ST TM TW TX TX TX TX – contention contention contention contention contention contention allocate ITL entry index contention row lock contention contention Configuration Configuration Configuration Configuration Application Administrative Configuration Concurrency Application Application
    13. 13. Lock Modes # Type --- ------1 Null 2 SS 3 SX 4 S 5 SSX 6 X Name --------------------------Null Sub share Sub exclusive Share Share/sub exclusive Exclusive
    14. 14. Lock Type and Mode Select parameter1 from v$event_name where name like ‘enq%’; Parameter1 ---------Name|mode Select p1, p1raw from v$session where event like 'enq%'; P1 P1RAW ---------- -------1415053318 54580006 Name: 5458 Hex Decimal 54 = 84 58 = 88 ASCII = “T” = “X” Mode: 0006 Lock = TX 6
    15. 15. Type and Mode SELECT SELECT chr(bitand(p1,-16777216)/16777215)|| chr(bitand(p1,-16777216)/16777215)|| chr(bitand(p1, 16711680)/65535) chr(bitand(p1, 16711680)/65535) TYPE, TYPE, mod(p1,16) LMODE mod(p1,16) LMODE from v$session from v$session where event like ‘enq%’; where event like ‘enq%’; TY LMODE TY LMODE -- ----------- ---------TX 6 TX 6
    16. 16. enq: TX - row lock contention, mode 6 To Solve we need, and ASH gives : 1. Waiter 2. Blocker 3. Blocking Object 4. Lock Type – type – Mode 1. Blocking SQL : Missing 1.Log miner? 2.Undo ?
    17. 17. OEM 10g if P1 = 1415053318 then mode = 6 Then it is a data block row lock
    18. 18. enq: TX - row lock contention Mode 6, row in data block User 1 SQL> delete from toto where id = 1; User 2 SQL> delete from toto where id =1; Table ID Value foo 1
    19. 19. Querying ASH select substr(event,0,20) ash.session_id mod(ash.p1,16) ash.p2 ash.p3 o.object_name o.object_type CURRENT_FILE# CURRENT_BLOCK# ash.SQL_ID BLOCKING_SESSION lock_name, waiter, lmode, p2, Meaning varies p3, object, otype, filen, blockn, waiting_sql, blocker from v$active_session_history ash, all_objects o where event like 'enq: %' and o.object_id (+)= ash.CURRENT_OBJ# / http://ashmasters.com Any enqueue
    20. 20. Other Data Sources In “real time” can also use – – – – – – v$lock v$session (v$session_wait) dba_blockers dba_waiters ?/rdbms/admin/utllockt.sql http://www.evdbt.com/enqwaits.sql
    21. 21. Step one: get a lock Session 1 Session_1> select pk_id from test_tab1 where rownum=1 ; PK_ID -------------- 4051 select pk_id from test_tab1 where pk_id = 4051 for update;
    22. 22. Step 2: create a blocker Session 2 Session_2> select pk_id from test_tab1 where pk_id = 4051 for update; Hangs …
    23. 23. Step 3: release the lock and blocking Session 1 Session_1> commit; Commit complete. Session 2 now continues PK_ID ---------4051
    24. 24. Locks in OEM: Application Wait click One SQL One Session
    25. 25. Click on “Application” Click on SQL ID
    26. 26. Click on SQL SQL waits for lock get’s lock and does I/O to complete
    27. 27. Click on “Session ID” Click on Session ID
    28. 28. No info is lock is gone Limited Use : lock is already released
    29. 29. Session Before Lock released Click Blocker Holds lock Waiter
    30. 30. ASH data in EM, but missing blocking info BLOCKING_SESSION_STATUS BLOCKING_SESSION BLOCKING_SESSION_SERIAL#
    31. 31. v$lock & v$session – during lock wait SQL> select s.sid, s.state, s.event, s.sql_id, l.type, l.lmode 2 from v$session s, v$lock l 3 where s.sid = l.sid 4 and s.username='TESTUSER' 5 order by s.sid; SID STATE (+) EVENT SQL_ID TY LMODE ---------- ----------- -------------------------------- ------------- -- ----150 WAITING enq: TX - row lock contention 0ut22yp7mh229 TM 3 150 WAITING enq: TX - row lock contention 0ut22yp7mh229 TX 0 157 WAITING SQL*Net message from client TX 6 157 WAITING SQL*Net message from client TM 3 Blocker Idle, holds locks Waiter, wants locks
    32. 32. v$lock : after commit by Session 1 SQL> select s.sid, s.state, s.event, s.sql_id, l.type, l.lmode 2 from v$session s, v$lock l 3 where s.sid = l.sid 4 and s.username='TESTUSER' 5 order by s.sid; SID STATE (+) EVENT SQL_ID TY LMODE ---------- ----------- -------------------------------- ------------- -- ----150 WAITING SQL*Net message from client TM 3 150 WAITING SQL*Net message from client TX 6 157 WAITING SQL*Net message from client Non-blocking, idle Holds Locks
    33. 33. v$active_session_history – during and after SQL> select a.sample_time, a.session_id, a.event, a.session_state, a.blocking_session BSID, a.blocking_session_status BSTATUS from v$active_session_history a, dba_users u where u.user_id = a.user_id and u.username = 'TESTUSER'; TIME -------14.59.37 14.59.36 14.59.35 14.59.34 14.59.33 14.59.32 14.59.31 14.59.30 14.59.29 SID --150 150 150 150 150 150 150 150 150 STATE ------ON_CPU ON_CPU WAITING WAITING WAITING WAITING WAITING WAITING WAITING a.sql_id, EVENT SQL_ID BSID BSTATUS ----------------------------- ------------- ---- -----------0ut22yp7mh229 NOT IN WAIT 0ut22yp7mh229 NOT IN WAIT db file scattered read 0ut22yp7mh229 NO HOLDER db file scattered read 0ut22yp7mh229 NO HOLDER enq: TX - row lock contention 0ut22yp7mh229 157 VALID enq: TX - row lock contention 0ut22yp7mh229 157 VALID enq: TX - row lock contention 0ut22yp7mh229 157 VALID enq: TX - row lock contention 0ut22yp7mh229 157 VALID enq: TX - row lock contention 0ut22yp7mh229 157 VALID Where is the BLOCKER, 157, info in ASH ? Now Past
    34. 34. V$active_session_history SQL> select a.sample_time, a.session_id, a.event, a.session_state, a.blocking_session BSID, a.blocking_session_status BSTATUS from v$active_session_history a, dba_users u where u.user_id = a.user_id and u.username = 'TESTUSER'; TIME 22.23.59 22.23.58 22.23.57 22.23.56 22.23.55 22.23.33 22.23.32 22.23.31 22.23.30 SID 147 147 147 147 147 148 148 148 148 STATE ON CPU WAITING WAITING WAITING WAITING WAITING WAITING WAITING WAITING SESSION_ID + SESSION_SERIAL# a.sql_id, EVENT enq: TX enq: TX enq: TX enq: TX db file db file db file db file - row lock contention - row lock contention - row lock contention - row lock contention scattered read scattered read scattered read scattered read SQL> select sql_text from v$sql where sql_id='cda14zb83bb5u’; sql_id='cda14zb83bb5u’; SQL_TEXT -------------------------------------------------------------------------------select count(*) from test_tab1 NOTE: Is unique SQL_ID BSID BSTATUS 0ut22yp7mh229 NOT IN WAIT 0ut22yp7mh229 148 VALID 0ut22yp7mh229 148 VALID 0ut22yp7mh229 148 VALID 0ut22yp7mh229 148 VALID cda14zb83bb5u NO HOLDER cda14zb83bb5u NO HOLDER cda14zb83bb5u NO HOLDER cda14zb83bb5u NO HOLDER
    35. 35. How do we find the SQL that took the lock?
    36. 36. Session B update toto set update toto set name = ‘ADAMS’ name = ‘ADAMS’ where id = 1; where id = 1; TX Lock Wait for Tx To commit Undo Segment Header Redo Table Toto Data Block Data Block Header Header Transaction 1 Session a Row 1 Undo Segment update toto set update toto set name = ‘SMITH’ name = ‘SMITH’ where id = 1; where id = toto where id Delete from 1; Delete from toto where id = 2; = 2; Delete from toto where id Delete from toto where id
    37. 37. Logminer : setup SQL> select group#, thread#, status from v$log; GROUP# THREAD# STATUS ---------- ---------- ---------------1 1 CURRENT 2 1 ACTIVE 3 1 ACTIVE SQL> select group#, member from v$logfile; GROUP# ---------1 2 3 MEMBER -----------------------------------------------------------C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO01.LOG C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO02.LOG C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO03.LOG SQL> exec dbms_logmnr.add_logfile('&my_member'); Enter value for my_member: C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO01.LOG PL/SQL procedure successfully completed. SQL> exec dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog); PL/SQL procedure successfully completed. @lgmr.sql
    38. 38. Logminer : setup locking SQL> create table test_tab1 as select object_id pk_id, object_name from all_objects; SQL> select rowid, object_name from test_tab1 where pk_id=5042; ROWID OBJECT_NAME ------------------ -----------------------------AAAN2NAAKAAAaBLAEX SYSTEM_PRIVILEGE_MAP SESSION_1> update test_tab1 set object_name='UKOUG 1' where pk_id=5042; SESSION_2> update test_tab1 set object_name='UKOUG 2' where pk_id=5042; Future Reference: ROWID Create Lock Wait
    39. 39. Find Transaction • From v$transaction – Xid of current active transaction • From v$active_session _history – Calculate XID from p2, p3 – For currently waiting ‘enq: TX row lock contention’ • Use XID to dump redo log for that TX
    40. 40. Logminer with XID SQL> select @tx.sql xid, xidusn, xidslot, xidsqn from v$transaction order by start_time; XID XIDUSN XIDSLOT XIDSQN -------------------- ---------- ---------- ---------0A00240064180000 10 36 6244 Only one transaction active on system, ours SQL> select username, session# sid, serial# , sql_redo from v$logmnr_contents where XID = '&tx'; USERNAME SID SERIAL# SQL_REDO ----------------- ---------- ---------- ----------------UNKNOWN 0 0 set transaction read write; UNKNOWN 0 0 update "SYS"."TEST_TAB1" set "OBJECT_NAME" = UNKNOWN 0 0 'SESSION 1' where "OBJECT_NAME" = 'CLUSTER_NODES' and ROWID = 'AAAT5XAABAAAW7hAEr’; commit; @lgmrtx.sql
    41. 41. Finding XID from ASH Normal use P2, P3 from wait: WAIT TYPE = 'enq: TX - Row Lock Contention’ Then P2=usn<<16||slot P3=Sequence => XID select distinct lpad(ltrim(to_char(p2,'XXXXXX')),6,'0')||'00'|| ltrim(to_char(mod(p3,256),'XX'))|| ltrim(to_char(trunc(p3/256),'XX'))||'0000' block_xid, to_char(p2,'XXXXXXXX') p2hex, to_char(p3,'XXXXXXXX') p3hex, trunc(p2/65536) usn, mod(p2,65536) slot, p3 sqn, xid wait_xid from v$active_session_history where event like 'enq: T%' and sample_time > sysdate - &v_minutes/(60*24) ; select username, session# sid, serial# , sql_redo from v$logmnr_contents where XID = '&tx'; '&tx'; @ashtx.sql @lgmrtx.sql
    42. 42. Logminer by USN and SLOT SQL> select xid, xidusn, xidslot, xidsqn from v$transaction order by start_time; XID XIDUSN XIDSLOT XIDSQN -------------------- ---------- ---------- ---------0A00240064180000 10 36 6244 SYS@TEST1020> select distinct username, session# sid, serial# , sql_redo from v$logmnr_contents where timestamp > sysdate- &minutes/(60*24) and xidusn=10 and xidslt=36; Enter value for minutes: 10 USERNAME SID SERIAL# SQL_REDO ----------------- ---------- ---------- ----------------UNKNOWN 0 0 set transaction read write; UNKNOWN 0 0 update "SYS"."TEST_TAB1" set "OBJECT_NAME" = UNKNOWN 0 'SESSION 1' where "OBJECT_NAME" = 'CLUSTER_NODES' and ROWID = 'AAAT5XAABAAAW7hAEr’; 0 commit;
    43. 43. Dumping Redo Directly SQL> select rowid, object_name from test_tab1 where pk_id=5041; ROWID OBJECT_NAME ------------------ -----------------------------AAAN2NAAKAAAaBLAEX SYSTEM_PRIVILEGE_MAP SYS@TEST1020> select dbms_rowid.rowid_block_number('&my_rowid') block_number, dbms_rowid.rowid_to_absolute_fno('&my_rowid','SYS','TEST_TAB1') file_id from dual; Enter value for my_rowid: AAAN2NAAKAAAaBLAEX FILE_ID ---------10 BLOCK_NUMBER -----------106571
    44. 44. Data block row update FILE_ID BLOCK_NUMBER ---------- ------------ 10 106571 SYS@TEST1020> alter system dump logfile '&&my_member' dba min 10 106571 dba max 10 106571; C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO01.LOG System altered DUMP OF REDO FROM FILE 'C:ORACLEPRODUCT10.2.0ORADATATEST1020REDO01.LOG' Opcodes *.* DBAs: (file # 10, block # 106571) thru (file # 10, block # 106571) RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff … REDO RECORD - Thread:1 RBA: 0x0000b3.00000009.0010 LEN: 0x0210 VLD: 0x0d SCN: 0x0000.008a42e6 SUBSCN: 1 04/20/2009 20:46:57 CHANGE #1 TYP:2 CLS: 1 AFN:10 DBA:0x0281a04b OBJ:56717 SCN:0x0000.008a4239 SEQ: 2 OP:11.19 KTB Redo op: 0x11 ver: 0x01 op: F xid: 0x000a.024.00001864 uba: 0x0080009d.031a.27 0A00240064180000 CLS: 1 - Data Class Block OP:11.19 - Operation Update Multiple Rows.
    45. 45. Verify DBA and Table REDO RECORD - Thread:1 RBA: 0x0000b3.00000009.0010 LEN: 0x0210 VLD: 0x0d SCN: 0x0000.008a42e6 SUBSCN: 1 04/20/2009 20:46:57 CHANGE #1 TYP:2 CLS: 1 AFN:10 DBA:0x0281a04b OBJ:56717 SCN:0x0000.008a4239 SEQ: 2 OP:11.19 KTB Redo op: 0x11 ver: 0x01 op: F xid: 0x000a.024.00001864 uba: 0x0080009d.031a.27 TESTUSER@TEST1020> select object_name, object_type from user_objects where object_id=56717; OBJECT_NAME OBJECT_TYPE ------------------- ------------------TEST_TAB1 TABLE SYS@TEST1020> select to_char(dbms_utility.make_data_block_address(10,106571), 'XXXXXXXX') DBA from dual; DBA --------281A04B
    46. 46. Update Value “session 1” Array Update of 1 rows: … col 1: [ 9] 53 45 53 53 49 4f 4e 20 30 CHANGE #3 TYP:2 CLS:1 AFN:1 DBA:0x00416ee1 OBJ:81495 SCN:0x0000.01052c55 SEQ:1 OP:11.19 ENC:0 RBL:0 … col 1: [ 9] 53 45 53 53 49 4f 4e 20 32 “session 2”
    47. 47. Last Try: flashback SELECT VERSIONS_XID , VERSIONS_STARTTIME , VERSIONS_ENDTIME , VERSIONS_STARTSCN , VERSIONS_ENDSCN , VERSIONS_OPERATION , object_name FROM SYS.TEST_TAB1 VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE where VERSIONS_XID is not null ORDER BY VERSIONS_STARTTIME /
    48. 48. From ASH BLOCK_XID ---------------0A00010072640000 P2HEX P3HEX USN SLOT SQN WAIT_XID --------- --------- ---------- ---------- ---------- ---------------A0001 6472 10 1 25714 From Flashback VERSIONS_XID VERSIONS_STARTTIME ENDTIME STARTSCN ENDSCN V OBJECT_NAME ---------------- --------------------- ------- -------- ------- - -------------0A00010072640000 15-OCT-13 06.46.30 PM 17042888 U SESSION 1
    49. 49. enq: TX - row lock contention – Mode 4
    50. 50. P1 = name | mode select distinct parameter1 from v$event_name where name like 'enq:%' PARAMETER1 name|mode select event, mod(p1,16) as "mode" from v$active_session_history where event like 'enq:%‘; EVENT enq: TX - row lock contention enq: TX - row lock contention mode 6 4
    51. 51. enq: TX - row lock contention • Mode 6 (exclusive) – modification of a row lock • Mode 4 (share) – ??
    52. 52. enq: TX - row lock contention if P1 = 1415053318 then mode = 6 Then it is a data block row lock
    53. 53. TX – Mode 4 if P1 = 1415053316 then mode = 4 Not same data but conflicts
    54. 54. enq: TX - row lock contention Mode 4, happens for 3 reasons 1. Unique key contention 2. Foreign Key contention 3. Bitmap index contention (others?)
    55. 55. 1. enq: TX - row lock contention Mode 4 , unique index User 2 User 1 create table p(n number); create unique index p_i on p(n); insert into p values(2); insert into p values(2); PK Table ID 2? ID Value 2?
    56. 56. 2. enq: TX - row lock contention Mode 4, foreign key User 1 create table parent ( id number primary key); create table child ( id number references parent, name varchar2(20)); insert into parent values (2); PK ID 2? Parent ID Value 2? User 2 insert into child values (2,88); Child ID Name 2
    57. 57. 3. enq: TX - row lock contention Mode 4, bitmap • Bitmaps are compressed • Changes to the same bitmap cause locks Value Start Rowid 1 000.000.0000 End Bitmap Rowid 01010000111000011100001100 000.000.000 2 01010000111000011100001100 000.000.0000 000.000.000
    58. 58. 3. enq: TX - row lock contention Mode 4, foreign key Session 1 create table t1 (( Different rows but create table t1 value number(4), value number(4), same key value row number(4)); row number(4)); insert into t1 insert into t1 select 1, rownum select 1, rownum from all_objects from all_objects where rownum <= 400; where rownum <= 400; commit; commit; create bitmap index i1 on t1(value); create bitmap index i1 on t1(value); update t1 set value = 2 update t1 set value = 2 Session 2 where row= 12; where row= 12; update t1 set value = 2 update t1 set value = 2 where row= 13; where row= 13;
    59. 59. 3. enq: TX - row lock contention Mode 4, foreign key • • Bitmaps are compressed Changes to the same bitmap chunk cause locks Value Start End Bitmap Rowid Rowid 1 01010000111000011100001100 200.0 1 2 205.0 200.0 block 204.7 210.3 205.6 row 01010000111000011100001100 01010000111000011100001100
    60. 60. 3. enq: TX - row lock contention Mode 4, foreign key Value Start End Bitmap Rowid Rowid 1 01010000111000011100001100 200.0 2 3 205.0 200.0 204.7 210.3 205.6 01010000111000011100001100 01010000111000011100001100 Session 1 Update row=12 set value 2 Session 2 Update row=13 set value 2
    61. 61. Summary: TX 4 from ASH Mode 4, unique key SID LM P2 P3 OBJ uniq index ST EVENT ----- ---------------------10:39 enq: TX - row lock c 10:39 enq: TX - row lock c 10:39 enq: TX - row lock c 10:39 enq: TX - row lock c --- --- ------ ---141 4 655406 6672 141 4 655406 6672 141 4 655406 6672 141 4 655406 6672 OTYPE FN BLOCKN SQL_ID ----- ----- --- ------ --1 0 0 bjvx94vnxtxgv -1 0 0 bjvx94vnxtxgv -1 0 0 bjvx94vnxtxgv -1 0 0 bjvx94vnxtxgv BSID 158 158 158 158 Mode 4, foreign key FK (10.2.0.3) ST EVENT ----- ---------------------10:41 enq: TX - row lock c 10:41 enq: TX - row lock c 10:41 enq: TX - row lock c SID LM P2 P3 OBJ --- --- ------ ---- ----144 4 179681 7074 CHILD 144 4 179681 7074 CHILD 144 4 179681 7074 CHILD OTYPE FN BLOCKN SQL_ID ----- --- ------ -TABLE 1 60954 ahm7c9rupbz9r TABLE 1 60954 ahm7c9rupbz9r TABLE 1 60954 ahm7c9rupbz9r BSID OTYPE FN BLOCKN SQL_ID ----- --- ------ -INDEX 0 0 azav296xxqcjx INDEX 0 0 azav296xxqcjx INDEX 0 0 azav296xxqcjx INDEX 0 0 azav296xxqcjx BSID 1 1 1 Mode 4, bitmap bitmap ST EVENT ----- ---------------------10:41 enq: TX - row lock c 10:41 enq: TX - row lock c 10:41 enq: TX - row lock c 10:41 enq: TX - row lock c SID LM P2 P3 OBJ --- --- ------ ---- ----143 4 966081 4598 I1 143 4 966081 4598 I1 143 4 966081 4598 I1 143 4 966081 4598 I1 Copyright 2006 Kyle Hailey 144 144 144 144
    62. 62. Specific ‘enq: TX’ wait events • enq: TX - allocate ITL entry – ITL space waits • enq: TX - index contention ? – Index block split • enq: TX – contention Unusual – Alter tablespace … read only; – Free Lists slot waits – Possible with two phase commit
    63. 63. enq: TX - allocate ITL entry Data Block Data Block Header Header ITL Data Transaction 1 Info Transaction 2 Info
    64. 64. enq: TX - allocate ITL entry Data Block Data Block Header Header Transaction 1 Transaction 2 Row 3 Row 2 Data Row 1 Transaction 3
    65. 65. enq: TX - allocate ITL entry create table itl ( create table itl ( id number, id number, data varchar2(20) data varchar2(20) ) ) pctfree 0 pctfree 0 initrans 1 initrans 1 ; ; insert into itl select rownum,'a' from all_objects insert into itl select rownum,'a' from all_objects where rownum < 2000; where rownum < 2000; commit; commit; session 1: update itl set data=data where id=1; session 1: update itl set data=data where id=1; session 2: update itl set data=data where id=2; session 2: update itl set data=data where id=2; session 3: update itl set data=data where id=3; session 3: update itl set data=data where id=3; session 4: update itl set data=data where id=4; session 4: update itl set data=data where id=4; session 5: update itl set data=data where id=5; session 5: update itl set data=data where id=5;
    66. 66. enq: TX - contention 1. Altering tablespace read only with open transaction Example – Session 1 – start transaction, don’t commit – Session 2 – alter tablespace read only 1. Data File Extension – waiter waiting for another session to extend file
    67. 67. enq: TM - contention • • TX locks have a corresponding TM lock TM locks the structure from change  Parameter1 = object id LOCK Parmeter1 LOCK Parmeter1 ------- --------------- --------enq: TM name|mode enq: TM name|mode Parmeter2(ID1) Parameter3(ID2) Parmeter2(ID1) Parameter3(ID2) ----------------------------------------------------object # table/partition object # table/partition
    68. 68. enq: TM - contention Exclusive Row Level Lock User 1 create table parent ( id number primary key); create table child ( id number references parent, name varchar2(20)); insert into parent values (1); insert into parent values (2); commit; delete from parent where id=2; User 2 insert into child values (1,’a’); No commit
    69. 69. enq: TM - contention PK Parent Child ID 1 X 2 ID 1 X 2 ID Name 1 Session 1 Session 2 Value Insert into Child ID=1 Delete from Parent where ID=2 : Enqueue TM 4 Session 2 doesn’t know the value Session 1 inserted Session 2 only knows there is an outstanding change
    70. 70. enq: TM – contention Solution PK Parent ID 1 2 ID Value Index ID 1 Child ID Name Foreign Key Session 1: Insert into Child ID=1 Session 2: Delete from Parent ID=2 OK – can verify quickly in the child index
    71. 71. TM Further Investigation select event, sql_id, mod(p1,16) as "mode", p2|| ' ' || o.name obj from v$active_session_history ash, obj$ o where event like 'enq: TM%' and o.obj# (+)= ash.p2 order by sample_time; EVENT enq: enq: enq: enq: enq: enq: TM TM TM TM TM TM SQL_ID - contention contention contention contention contention contention 8zw36yw3fq4yy 8zw36yw3fq4yy 8zw36yw3fq4yy 8zw36yw3fq4yy 8zw36yw3fq4yy 8zw36yw3fq4yy mode OBJ 4 4 4 4 4 4 53372 53372 53372 53372 53372 53372 CHILD CHILD CHILD CHILD CHILD CHILD
    72. 72. Other Resources @?/rdbms/admin/utllockt WAITING_SESSION LOCK_TYPE MODE_REQUESTED MODE_HELD LOCK_ID1 LOCK_ID2 --------------- ----------- -------------- --------- --------- -------144 139 None Transaction Share Exclusive 131113 7507
    73. 73. Blocking Sessions
    74. 74. Content Part I : Row Locks – enq: TX - row lock contention • • • • • Data in ASH OEM V$lock & v$session ASH Find blocking SQL Part II : Row Locks ?? – enq: TX - row lock contention, mode 4 Part III : Other TX locks – – – enq: TX - allocate ITL entry enq: TX - index contention enq: TX – contention Part IV : TM locks
    75. 75. Without TM Locks Child Name ID 1 2 3 4 … 10000 Delete Parent Child Delete Child Could scan Child table for value “2” and someone could come in behind and delete value 2 in an area that is already scanned but before the scan has finished. The TM lock prevents this Name ID 1 2 3 4 … 10000 Delete Parent

    ×