UKOUG, Oracle Transaction Locks
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

UKOUG, Oracle Transaction Locks

on

  • 323 views

 

Statistics

Views

Total Views
323
Views on SlideShare
320
Embed Views
3

Actions

Likes
0
Downloads
13
Comments
0

2 Embeds 3

http://www.linkedin.com 2
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • In Oracle Support I learned more faster than I think I could have anywhere. <br /> 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. <br /> Oracle France gave me an opportunity to concentrate on the Oracle kernel. <br /> 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. <br /> 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. <br /> 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. <br /> 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. <br />
  • In Oracle Support I learned more faster than I think I could have anywhere. <br /> 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. <br /> Oracle France gave me an opportunity to concentrate on the Oracle kernel. <br /> 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. <br /> 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. <br /> 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. <br /> 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. <br />
  • In Oracle Support I learned more faster than I think I could have anywhere. <br /> 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. <br /> Oracle France gave me an opportunity to concentrate on the Oracle kernel. <br /> 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. <br /> 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. <br /> 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. <br /> 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. <br />
  • bitand(p1, 65536) "Mode" <br />
  • Lock seems easy <br /> Compared to latches, buffer busy waits etc <br />
  • col event for a22 <br /> col block_type for a18 <br /> col objn for a18 <br /> col otype for a10 <br /> col fn for 99 <br /> col sid for 9999 <br /> col bsid for 9999 <br /> col lm for 99 <br /> col p3 for 99999 <br /> col blockn for 99999 <br /> select <br /> to_char(sample_time,&apos;HH:MI&apos;) st, <br /> substr(event,0,20) event, <br /> ash.session_id sid, <br /> mod(ash.p1,16) lm, <br /> ash.p2, <br /> ash.p3, <br /> nvl(o.object_name,ash.current_obj#) objn, <br /> substr(o.object_type,0,10) otype, <br /> CURRENT_FILE# fn, <br /> CURRENT_BLOCK# blockn, <br /> ash.SQL_ID, <br /> BLOCKING_SESSION bsid <br /> --,ash.xid <br /> from v$active_session_history ash, <br /> all_objects o <br /> where event like &apos;enq: TX %&apos; <br /> and o.object_id (+)= ash.CURRENT_OBJ# <br /> and sample_time > sysdate - &1/(60*24) <br /> Order by sample_time <br /> / <br />
  • TX <br /> if P1 = 1415053316 <br /> then mode = 4 <br /> if P1 = 1415053318 <br /> then mode = 6 <br />
  • create table p(n number); <br /> create unique index p_i on p(n); <br /> insert into p values(3); <br />
  • Subject: <br /> Bitmap Indexes and Deadlocks: Deadlocks on Insert Statements <br /> Doc ID: <br /> Note:171795.1 <br /> Type: <br /> TROUBLESHOOTING <br /> Last Revision Date: <br /> 18-MAY-2004 <br /> Status: <br /> PUBLISHED <br /> PURPOSE <br /> ------- <br /> The purpose of this article is to explain the occurrence of deadlocks <br /> when the only DML activity is insert statements against a table with <br /> a bitmap index <br /> SCOPE & APPLICATION <br /> ------------------- <br /> Database administrators and Application developers involved in <br /> application design. <br /> BITMAP INDEXES: THE HIDDEN DEADLOCK THREAT <br /> ------------------------------------------ <br /> The "Oracle8i Designing and Tuning for Performance" guide explains <br /> the limitations of bitmap indexes as this: <br /> Extract of documentation: <br /> "DML and DDL statements, such as UPDATE, DELETE, DROP TABLE, affect bitmap <br /> indexes the same way they do traditional indexes: the consistency model is <br /> the same. A compressed bitmap for a key value is made up of one or more bitmap <br /> segments, each of which is at most half a block in size (but may be smaller). <br /> The locking granularity is one such bitmap segment. This may affect performance <br /> in environments where many transactions make simultaneous updates. If numerous <br /> DML operations have caused increased index size and decreasing performance for <br /> queries, then you can use the ALTER INDEX ... REBUILD statement to compact the <br /> index and restore efficient performance. <br /> A B*-tree index entry contains a single rowid. Therefore, when the index entry <br /> is locked, a single row is locked. With bitmap indexes, an entry can potentially <br /> contain a range of rowids. When a bitmap index entry is locked, the entire range <br /> of rowids is locked. The number of rowids in this range affects concurrency. <br /> As the number of rowids increases in a bitmap segment, concurrency decreases. <br /> Locking issues affect DML operations, and may affect heavy OLTP environments. <br /> Locking issues do not, however, affect query performance. As with other types <br /> of indexes, updating bitmap indexes is a costly operation. Nonetheless, for <br /> bulk inserts and updates where many rows are inserted or many updates are made <br /> in a single statement, performance with bitmap indexes can be better than with <br /> regular B*-tree indexes." <br /> ************** <br /> What is not mentioned is the fact that the same architectural feature that <br /> locks a range of rowid&apos;s also means that its possible to get a deadlock within <br /> the bitmap when updating rows in the underlying table. This deadlock is not in <br /> the table itself, as one might suspect, but rather in the bitmap index blocks. <br /> This kind of deadlock is easily diagnosable by the deadlock trace file, which <br /> has an entry that looks like the example below: <br /> The following deadlock is not an ORACLE error. It is a <br /> deadlock due to user error in the design of an application <br /> or from issuing incorrect ad-hoc SQL. The following <br /> information may aid in determining the deadlock: <br /> Deadlock graph: <br /> ---------Blocker(s)-------- ---------Waiter(s)--------- <br /> Resource Name process session holds waits process session holds waits <br /> TX-00080027-0000d2a1 12 37 X 15 35 S <br /> TX-000a0016-0000d6d2 15 35 X 12 37 S <br /> session 37: DID 0001-000C-00000002 session 35: DID 0001-000F-00000002 <br /> session 35: DID 0001-000F-00000002 session 37: DID 0001-000C-00000002 <br /> Rows waited on: <br /> Session 35: no row <br /> Session 37: no row <br /> The piece of information that leads us to a bitmap deadlock is the "no row" <br /> value in the session information. If we had encountered a deadlock in the <br /> underlying table, the Session line would give us row information so that we <br /> could track down the exact point of failure. Without a row, it would seem that <br /> we are at a dead end. Even more mysterious is when we get this deadlock on <br /> inserts, where we are inserting only new rows and therefore it would seem <br /> impossible to get a deadlock. No one should be requesting a row that someone <br /> else holds locked. <br /> There are no solutions to this kind of problems, except not using bitmap indexes <br /> when having an application where you can&apos;t control when the DML are issued against <br /> the tables with bitmap indexes. Bitmaps are normally intended for datawarehouse <br /> applications that are loading data via batches and that users are only querying. <br /> The following testcase can be used to see the results of this type of problem. <br /> We will create a table called CAR_TYPE, which holds information about cars, <br /> including the car&apos;s color. We will build a bitmap index on the COLOR column. <br /> After doing so, we will populate the table with data. After the initial insert, <br /> we will open two sessions of the same user, and run simultaneous inserts into <br /> the CAR_TYPE table. <br /> TESTCASE: <br /> ===================================== <br /> ===================================== <br /> create table car_type ( <br /> make varchar2(20), <br /> model varchar2(20), <br /> color varchar2(20), <br /> VIN number(15) primary key, <br /> year number(4)); <br /> create bitmap index car_type_bm_idx on car_type(color); <br /> create sequence car_type_seq <br /> start with 35001 <br /> increment by 1 <br /> nocache <br /> nocycle; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Audi&apos;; <br /> v_CarModel varchar(20) := &apos;Quattro&apos;; <br /> v_CarColor varchar(20) := &apos;Gold&apos;; <br /> v_CarVin binary_integer :=1; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 5000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Toyota&apos;; <br /> v_CarModel varchar(20) := &apos;Camry&apos;; <br /> v_CarColor varchar(20) := &apos;Red&apos;; <br /> v_CarVin binary_integer :=5001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 10000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Audi&apos;; <br /> v_CarModel varchar(20) := &apos;Quattro&apos;; <br /> v_CarColor varchar(20) := &apos;Blue&apos;; <br /> v_CarVin binary_integer :=10001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 15000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Toyota&apos;; <br /> v_CarModel varchar(20) := &apos;Camry&apos;; <br /> v_CarColor varchar(20) := &apos;Silver&apos;; <br /> v_CarVin binary_integer :=15001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 20000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Audi&apos;; <br /> v_CarModel varchar(20) := &apos;Quattro&apos;; <br /> v_CarColor varchar(20) := &apos;Green&apos;; <br /> v_CarVin binary_integer :=20001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 25000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Audi&apos;; <br /> v_CarModel varchar(20) := &apos;Quattro&apos;; <br /> v_CarColor varchar(20) := &apos;Black&apos;; <br /> v_CarVin binary_integer :=25001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 30000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> declare <br /> v_CarMake varchar2(20) := &apos;Toyota&apos;; <br /> v_CarModel varchar(20) := &apos;Camry&apos;; <br /> v_CarColor varchar(20) := &apos;White&apos;; <br /> v_CarVin binary_integer :=30001; <br /> begin <br /> loop <br /> insert into car_type (make,model,color,VIN,year) <br /> values (v_CarMake, v_CarModel, v_CarColor, v_CarVin, &apos;2002&apos;); <br /> v_CarVin := v_CarVin + 1; <br /> exit when v_CarVin > 35000; <br /> end loop; <br /> end; <br /> / <br /> commit; <br /> =============================== <br /> =============================== <br /> After this initial creation, cut the following script into a .sql file, and <br /> then execute it simultaneously from two sessions: <br /> =============================== <br /> =============================== <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;White&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Red&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Toyota&apos;,&apos;Camry&apos;,&apos;Silver&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Black&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Gold&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Blue&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> insert into car_type values ( <br /> &apos;Audi&apos;,&apos;Quatro&apos;,&apos;Green&apos;,car_type_seq.nextval,&apos;2002&apos;); <br /> commit; <br /> ======================================== <br /> ======================================== <br /> The result will be occasional deadlock errors: <br /> insert into car_type values ( <br /> * <br /> ERROR at line 1: <br /> ORA-00060: deadlock detected while waiting for resource <br /> The trace file will show the tell-tale &apos;No Row&apos; message: <br /> Rows waited on: <br /> Session 11: no row <br /> Session 10: no row <br /> RELATED DOCUMENTS <br /> ----------------- <br /> Oracle8i Designing and Tuning for Performance <br /> Release 2 (8.1.6) <br /> Part Number A76992-01 <br /> . <br />

UKOUG, Oracle Transaction Locks Presentation Transcript

  • 1. Enqueue Waits : Locks Thanks to Doug Burns for much of the Row Lock example Kyle Hailey Kylehailey.com kyle@delphix.com
  • 2. Oaktable World UK • Mon Dec 2, Tues Dec 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. 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. 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. 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. Production Instance Database File system Development QA UAT Instance Instance Instance Database Database Database
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. OEM 10g if P1 = 1415053318 then mode = 6 Then it is a data block row lock
  • 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. 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. 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. 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. Step 2: create a blocker Session 2 Session_2> select pk_id from test_tab1 where pk_id = 4051 for update; Hangs …
  • 23. Step 3: release the lock and blocking Session 1 Session_1> commit; Commit complete. Session 2 now continues PK_ID ---------4051
  • 24. Locks in OEM: Application Wait click One SQL One Session
  • 25. Click on “Application” Click on SQL ID
  • 26. Click on SQL SQL waits for lock get’s lock and does I/O to complete
  • 27. Click on “Session ID” Click on Session ID
  • 28. No info is lock is gone Limited Use : lock is already released
  • 29. Session Before Lock released Click Blocker Holds lock Waiter
  • 30. ASH data in EM, but missing blocking info BLOCKING_SESSION_STATUS BLOCKING_SESSION BLOCKING_SESSION_SERIAL#
  • 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. 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. 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. 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. How do we find the SQL that took the lock?
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. enq: TX - row lock contention – Mode 4
  • 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. enq: TX - row lock contention • Mode 6 (exclusive) – modification of a row lock • Mode 4 (share) – ??
  • 52. enq: TX - row lock contention if P1 = 1415053318 then mode = 6 Then it is a data block row lock
  • 53. TX – Mode 4 if P1 = 1415053316 then mode = 4 Not same data but conflicts
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. enq: TX - allocate ITL entry Data Block Data Block Header Header ITL Data Transaction 1 Info Transaction 2 Info
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. Blocking Sessions
  • 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. 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