I usually think about locks (and the meaning of the lmode and request columns in v$lock) in terms of numbers, and never seem to remember which number goes with which name – apart from mode 6 = exclusive. So I’ve finally put up a little list somewhere I’ll always be able to find it if I need it.
Value Name(s) Table method (TM lock)
0 No lock n/a
1 Null lock (NL) Used during some parallel DML operations (e.g. update) by
the pX slaves while the QC is holding an exclusive lock.
2 Sub-share (SS) Until 9.2.0.5/6 "select for update"
Row-share (RS) Since 9.2.0.1/2 used at opposite end of RI during DML
Lock table in row share mode
Lock table in share update mode
3 Sub-exclusive(SX) Update (also "select for update" from 9.2.0.5/6)
Row-exclusive(RX) Lock table in row exclusive mode
Since 11.1 used at opposite end of RI during DML
4 Share (S) Lock table in share mode
Can appear during parallel DML with id2 = 1, in the PX slave sessions
Common symptom of "foreign key locking" (missing index) problem
5 share sub exclusive (SSX) Lock table in share row exclusive mode
share row exclusive (SRX) Less common symptom of "foreign key locking" but likely to be more
frequent if the FK constraint is defined with "on delete cascade."
6 Exclusive (X) Lock table in exclusive mode
create index -- duration and timing depend on options used
insert /*+ append */
(See Lock Horrorfor notes on the mode 3 lock during RI in 11g).
It’s a minor irritant, of course, that some of the lock modes have two names and two abbreviations – and some documents use one name and the other abbrevation (e.g. talking about row-exclusive locks, then using the SX abbreviation). The various lock trace files seem to favour SS, SX, and SSX over RS, RX and SRX.n
The change to mode 3 for “select for update” is described in Metalink (MOS) in note 3646162.8 – which references a bug of the same number describing a false deadlock issue in RAC; and it may still be possible to reverse the change in Oracle 11 (according to bug note 4969880) by setting the “_fix_control” hidden parameter to ’4969880:ON’.
The requirement for the ‘mode 2 at opposite end of RI’ may relate to problems of checking referential integrity while executing parallel DML (unpublished bug 2435787 may apply, but I have a note to myself about parallel DML resulting in deadlocks although I can’t find anything about this on Metalink).
I also have a note about a session in 9.2 getting two TM locks on the same object during parallel dml, one in mode 1 with id1 = 0 and one in mode 4 with id1 = 1. I haven’t looked at this for a long time, though.
Update 18th Aug:
Following a thread on OTN relating to deadlocks and wait-for-graphs (WFG) from the lock manager daemon (LMD), I found the following link that showed GES (global enqueue resources) enqueues having different values for the lock mode, viz:
#define KJUSERNL 0 /* no permissions */ (Null) #define KJUSERCR 1 /* concurrent read */ (Row-S (SS)) #define KJUSERCW 2 /* concurrent write */ (Row-X (SX)) #define KJUSERPR 3 /* protected read */ (Share) #define KJUSERPW 4 /* protected write */ (S/Row-X (SSX)) #define KJUSEREX 5 /* exclusive access */ (Exclusive)
(You can see the “define” names appearing in gv$ges_enqueue if you want to set up a few tests in a RAC system – or you could just check the racdiag.sql script from Metalink (MOS) to see them used in a monitoring query.)
So when LMD dumps a deadlock trace with something like the following:
Global Wait-For-Graph(WFG) at ddTS[0.4] : BLOCKED 4098bcd08 5 [0x130025][0x1475c9],[TX] [65595,583] 0 BLOCKER 412275b78 5 [0x130025][0x1475c9],[TX] [131100,2] 1 BLOCKED 41228b128 5 [0x70001][0x178a52],[TX] [131100,2] 1 BLOCKER 4098bade8 5 [0x70001][0x178a52],[TX] [65595,583] 0
you should be able to look at the column of 5′s – in this example – and assume that you have “crossed” “TX mode 6″ locks in the instances, which means you have a standard data collision except that it’s across nodes.

Very helpful reference.
I cannot recall at the moment, but have you written an article that explores the interaction of a holder’s LMODE and a requester’s REQUEST mode – and the possible causes that lead to the combinations? Such an exploration might help answer the question of “What happened in the program that lead to session 1 blocking session 2?” or “Why did session 1 and session 2 deadlock?”. The exploration would be very helpful when a DBA performs a self-join on V$LOCK.
For example:
* TYPE=TX, LMODE=6, REQUEST=4 = session 2 is attempting to insert a row with the same primary key value or unique index value as a row just inserted by session 1
* TYPE=TX, LMODE=6, REQUEST=4 = ITL Problem or bitmap index fragment problem
* TYPE=TX, LMODE=6, REQUEST=6 = session 2 is attempting to update a row that is locked by session 1′s transaction (likely session 1 already updated the row)
* TYPE=TM, LMODE=3, REQUEST=5 = possible missing index on a foreign key column
Comment by Charles Hooper — June 22, 2010 @ 11:41 am UTC Jun 22,2010 |
Hi,
Here is the way I remember them (the ‘Sub’ is explained in dbmslock.sql comments):
S and X are Shared and eXclusive locks concerning the whole table (if talking about TM locks)
SS/RS and SX/RX are Shared and eXclusive locks concerning only a Subset of the table (just some Rows)
SSX/SRX is a Shared lock for whole table + eXclusive lock concerning only a Subset of the table (just some Rows)
Then I can remember the compatibility matrix knowing that eXclusive prevents Shared or eXclusive except when this incompatibility is only at Subset level (as they can be a different subset – concerning different rows).
Regards,
Franck.
Comment by Franck Pachot — June 22, 2010 @ 3:42 pm UTC Jun 22,2010 |
For French readers: here’s a link to a detailed article on locking by Franck Pachot. See reply to this comment for the latest location of an English translation.
Comment by Jonathan Lewis — July 12, 2010 @ 8:16 pm UTC Jul 12,2010 |
Hi, the English version is now published at SOUG Newsletter (The previous link was on Knol … outdated)
Comment by Franck Pachot — January 9, 2013 @ 9:59 am UTC Jan 9,2013 |
Franck,
Thanks for the update. I’ve modified the original comment.
Comment by Jonathan Lewis — January 12, 2013 @ 12:35 pm UTC Jan 12,2013 |
[...] chain (i.e. join the queue) when they attempt to create or convert a lock on an object. There are six (or seven) lock modes, and the rules are about which chain a session joins are dictated by the precedence of [...]
Pingback by Glossary « Oracle Scratchpad — August 14, 2011 @ 8:21 am UTC Aug 14,2011 |
[...] Jonathan Lewis: Lock Modes [...]
Pingback by WFG – mode 5 TM deadlock « OraStory — November 23, 2011 @ 12:06 pm UTC Nov 23,2011 |
I’ve just come across an interesting case. Here’s my wait graph:
Just 3s across the board. But up above, in the enqueue dumps, it is clear that all three of these enqueues are being held in KJUSEREX mode (5) and all three deadlocked transactions (holding locks in EX mode) are requesting the locks in PR mode (3). I’m not sure why the graph is displaying only 3s – maybe a bug in 11.2.0.3.0 or maybe it is only showing the modes of the requestors and not the holders?
sorry for the data dump… but I’m wondering if anyone else has seen inconsistency like this?
also, wondering if anyone has ideas about figuring out what this enqueue is protecting? can you make any sense out of valblk perhaps?
Comment by Jeremy Schneider — December 4, 2012 @ 12:34 am UTC Dec 4,2012 |
>it is clear that all three of these enqueues are being held in KJUSEREX mode (5)
Can you walk through how that is clear?
I read this deadlock scenario like this:
Because ASH is captured every 1 second and deadlock detection is typically 3 seconds, V$ACTIVE_SESSION_HISTORY can often provide useful additional information.
Quoting Jonathan from this OTN thread (which was about similar lock modes but across rac nodes)
https://forums.oracle.com/forums/thread.jspa?messageID=10659671
“Generally tx/4 is something to do with indexes, although there are a couple of exotic causes that relate to internal activity”
Comment by Dom Brooks — December 4, 2012 @ 10:09 am UTC Dec 4,2012 |
Thanks Jonathan for properly formatting my code dumps. :)
Dom – I didn’t post all three enqueue dumps to this comment, but the other two looked exactly like the one I that I did post. They also showed enqueues held in KJUSEREX. I was hoping you’d just take my word for it since copying the other enqueue dumps seemed a bit redundant!
Even in the scenario you worked out, you showed the transaction which I posted with an X lock — which is inconsistent with the Wait-For-Graph. Any ideas about the inconsistency?
Comment by Jeremy Schneider — December 4, 2012 @ 3:35 pm UTC Dec 4,2012 |