Your SlideShare is downloading. ×
OOUG: Oracle transaction locking
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

OOUG: Oracle transaction locking

886
views

Published on

Published in: Technology

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
886
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
47
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • bitand(p1, 65536) "Mode"
  • 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,'HH:MI') 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 'enq: TX %'
    and o.object_id (+)= ash.CURRENT_OBJ#
    and sample_time > sysdate - &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 & APPLICATION
    -------------------
    Database administrators and Application developers involved in
    application design.
    BITMAP INDEXES: THE HIDDEN DEADLOCK THREAT
    ------------------------------------------
    The "Oracle8i Designing and Tuning for Performance" guide explains
    the limitations of bitmap indexes as this:
    Extract of documentation:
    "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."
    **************
    What is not mentioned is the fact that the same architectural feature that
    locks a range of rowid'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 "no row"
    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'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'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) := 'Audi';
    v_CarModel varchar(20) := 'Quattro';
    v_CarColor varchar(20) := 'Gold';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 5000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Toyota';
    v_CarModel varchar(20) := 'Camry';
    v_CarColor varchar(20) := 'Red';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 10000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Audi';
    v_CarModel varchar(20) := 'Quattro';
    v_CarColor varchar(20) := 'Blue';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 15000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Toyota';
    v_CarModel varchar(20) := 'Camry';
    v_CarColor varchar(20) := 'Silver';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 20000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Audi';
    v_CarModel varchar(20) := 'Quattro';
    v_CarColor varchar(20) := 'Green';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 25000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Audi';
    v_CarModel varchar(20) := 'Quattro';
    v_CarColor varchar(20) := 'Black';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 30000;
    end loop;
    end;
    /
    commit;
    declare
    v_CarMake varchar2(20) := 'Toyota';
    v_CarModel varchar(20) := 'Camry';
    v_CarColor varchar(20) := 'White';
    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, '2002');
    v_CarVin := v_CarVin + 1;
    exit when v_CarVin > 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 (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    commit;
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    commit;
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    commit;
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    commit;
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    commit;
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','White',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Red',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Toyota','Camry','Silver',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Black',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Gold',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Blue',car_type_seq.nextval,'2002');
    insert into car_type values (
    'Audi','Quatro','Green',car_type_seq.nextval,'2002');
    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 'No Row' 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
    .
  • Transcript

    • 1. Enqueue Waits : Locks Thanks to Doug Burns for much of the Row Lock example Kyle Hailey Kylehailey.com kyle@delphix.com
    • 2. 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
    • 3. 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
    • 4. 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
    • 5. 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
    • 6. 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
    • 7. enq: TX - row lock contention, mode 6 To Solve we need: 1. Waiter 2. Blocker 3. Blocking Object 4. Lock Type – type – mode Missing : blocking SQL – Possibly with log miner
    • 8. OEM 10g if P1 = 1415053318 then mode = 6 Then it is a data block row lock
    • 9. 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
    • 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 Missing: Blocking SQL !
    • 11. 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, 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
    • 12. 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
    • 13. Step one: get a lock Session 1 Session_1> select pk_id from test_tab1 where rownum=1 for update; PK_ID ---------4051
    • 14. Step 2: create a blocker Session 2 Session_2> select pk_id from test_tab1 where pk_id = 4051 for update; Hangs …
    • 15. Step 3: release the lock and blocking Session 1 Session_1> commit; Commit complete. Session 2 now continues PK_ID ---------4051
    • 16. Locks in OEM: Application Wait click One SQL One Session
    • 17. Click on “Application” Click on SQL ID
    • 18. Click on SQL SQL waits for lock get’s lock and does I/O to complete
    • 19. Click on “Session ID” Click on Session ID
    • 20. No info is lock is gone Limited Use : lock is already released
    • 21. Session Before Lock released Click Blocker Holds lock Waiter
    • 22. ASH data in EM, but missing blocking info BLOCKING_SESSION_STATUS BLOCKING_SESSION BLOCKING_SESSION_SERIAL#
    • 23. 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 s, 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
    • 24. 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
    • 25. 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 ? Time flow direction
    • 26. 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 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: SESSION_ID + SESSION_SERIAL# 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
    • 27. How do we find the SQL that took the lock?
    • 28. 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 Undo Segment Table Toto Data Block Data Block Header Header Transaction 1 Session a Row 1 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
    • 29. 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.
    • 30. 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=313; ROWID OBJECT_NAME ------------------ -----------------------------AAAN2NAAKAAAaBLAEX SYSTEM_PRIVILEGE_MAP SESSION_1> update test_tab1 set object_name='SESSION 1' where pk_id=313; SESSION_2> update test_tab1 set object_name='SESSION 2' where pk_id=313; Future Reference: ROWID Create Lock Wait
    • 31. Logminer with XID SQL> select 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 Normal use P2, P3 from wait: SQL> select username, session# sid, serial# , sql_redo from v$logmnr_contents where XID = '0A00240064180000'; 'enq: TX - Row Lock Contention' P2=usn<<16||slot P3=Sequence => XID 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;
    • 32. 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 Normal use P2, P3 from wait: 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%' ; 'enq: TX - Row Lock Contention' P2=usn<<16||slot P3=Sequence => XID
    • 33. 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;
    • 34. Dumping Redo Directly SQL> select rowid, object_name from test_tab1 where pk_id=313; 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
    • 35. 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.
    • 36. 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
    • 37. 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”
    • 38. 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 /
    • 39. 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
    • 40. 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
    • 41. enq: TX - row lock contention • Mode 6 (exclusive) – modification of a row lock • Mode 4 (share) – ??
    • 42. enq: TX - row lock contention if P1 = 1415053318 then mode = 6 Then it is a data block row lock Copyright 2006
    • 43. TX – Mode 4 if P1 = 1415053316 then mode = 4 Not same data but conflicts Copyright 2006
    • 44. enq: TX - row lock contention Mode 4, happens for 3 reasons 1. Unique key contention 2. Foreign Key contention 3. Bitmap index contention (others?)
    • 45. 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?
    • 46. 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
    • 47. 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
    • 48. 3. enq: TX - row lock contention Mode 4, foreign key Session 1 create table t1 (( Different rows but create table t1 n1 number(4), n1 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(n1); create bitmap index i1 on t1(n1); update t1 set n1 = 2 update t1 set n1 = 2 Session 2 where row= 12; where row= 12; update t1 set n1 = 2 update t1 set n1 = 2 where row= 13; where row= 13;
    • 49. 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
    • 50. 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 id=12 set value 2 Session 2 Update id=13 set value 2
    • 51. 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
    • 52. Specific ‘enq: TX’ wait events • enq: TX - allocate ITL entry – ITL space waits • enq: TX - index contention – Index block split • Unusual enq: TX – contention – Alter tablespace … read only; – Free Lists slot waits – Possible with two phase commit
    • 53. enq: TX - allocate ITL entry Data Block Data Block Header Header ITL Data Copyright 2006 Transaction 1 Info Transaction 2 Info
    • 54. enq: TX - allocate ITL entry Data Block Data Block Header Header Transaction 1 Transaction 2 Row 3 Row 2 Data Row 1 Copyright 2006 Transaction 3
    • 55. 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;
    • 56. 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
    • 57. 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
    • 58. 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,2); No commit
    • 59. 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
    • 60. 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
    • 61. 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
    • 62. 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
    • 63. 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
    • 64. Blocking Sessions
    • 65. 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

    ×