Oracle 0 ~ 6 レベルのロックを理解するための 1 つの記事 (詳細なケース説明付き)

11gの概念から抽出されたロック情報

テーブルロック(TM)

テーブル ロック (TM ロックとも呼ばれます) は、INSERT、UPDATE、DELETE、MERGE、FOR UPDATE 句を指定した SELECT、または LOCK TABLE ステートメントによってテーブルが変更されると、トランザクションによって取得されます。DML 操作では、トランザクションに代わってテーブルへの DML アクセスを予約し、トランザクションと競合する DDL 操作を防ぐために、テーブル ロックが必要です。

トランザクションが INSERT、UPDATE、DELETE、MERGE、および FOR UPDATE によってテーブルを変更すると、TM ロック句またはテーブル ロック ステートメントとも呼ばれるテーブル ロックが取得されます。DML 操作では、トランザクションのテーブルへの DML アクセスを保持し、トランザクションと競合する DDL 操作を防ぐために、テーブル ロックが必要です。
テーブル ロックは、次のいずれかのモードで保持できます。

ロウシェア(RS)

サブシェア テーブル ロック (SS) とも呼ばれるこのロックは、テーブルのロックを保持しているトランザクションがテーブル内の行をロックし、それらを更新しようとしていることを示します。行共有ロックは、テーブル ロックの最も制限の少ないモードであり、テーブルに対して最高度の同時実行性を提供します。

サブ共有テーブル ロック (SS) とも呼ばれるこのロックは、テーブル ロックを保持しているトランザクションがテーブル内の行をロックし、それらをロックして更新しようとしていることを示します。行共有ロックは、テーブル ロックの最も制限の少ないモードであり、テーブルに最高度の同時実行性を提供します。

行専用テーブルロック(RX)

このロックは、サブエクスクルーシブ テーブル ロック (SX) とも呼ばれ、通常、ロックを保持しているトランザクションがテーブルの行を更新したか、SELECT … FOR UPDATE を発行したことを示します。SX ロックを使用すると、他のトランザクションが同じテーブル内の行を同時にクエリ、挿入、更新、削除、またはロックできます。したがって、SX ロックを使用すると、複数のトランザクションが同じテーブルに対して同時に SX およびサブシェア テーブル ロックを取得できます。

サブエクスクルーシブ テーブル ロック (SX) とも呼ばれるこのロックは、通常、ロックを保持しているトランザクションがテーブルの行を更新したか、SELECT...FOR UPDATE を発行したことを示します。SX ロックを使用すると、他のトランザクションが同じテーブル内の行を同時にクエリ、挿入、更新、削除、またはロックできます。したがって、SX ロックを使用すると、複数のトランザクションが同期された SX および同じテーブルのサブ共有テーブル ロックを取得できます。

シェアテーブルロック(小)

トランザクションが保持する共有テーブル ロックにより、他のトランザクションは (SELECT … FOR UPDATE を使用せずに) テーブルをクエリできますが、更新は単一のトランザクションが共有テーブル ロックを保持している場合にのみ許可されます。複数のトランザクションが共有テーブル ロックを同時に保持する可能性があるため、このロックを保持するだけでは、トランザクションがテーブルを変更できることを保証するには不十分です。

トランザクションが保持する共有テーブル ロックにより、他のトランザクションはテーブルをクエリできますが ( SELECT...FOR UPDATE を除く)、更新は 1 つのトランザクションが共有テーブル ロックを保持している場合にのみ可能です。複数のトランザクションが共有テーブル ロックを同時に保持する可能性があるため、このロックを保持するだけでは、トランザクションがテーブルを変更できることを保証するには不十分です。

シェアロウエクスクルーシブテーブルロック(SRX)

このロックは、share-subexclusive テーブル ロック (SSX) とも呼ばれ、share テーブル ロックよりも制限が厳しくなります。特定のテーブルで SSX ロックを取得できるのは、一度に 1 つのトランザクションだけです。トランザクションが保持する SSX ロックにより、他のトランザクションはテーブルをクエリできますが (SELECT … FOR UPDATE を除く)、テーブルを更新することはできません。

このロックは共有部分排他テーブル ロック (SSX) とも呼ばれ、共有テーブル ロックよりも制限が厳しくなります。特定のテーブルで一度に取得できるトランザクション SSX ロックは 1 つだけです。トランザクションが保持する SSX ロックにより、他のトランザクションはテーブルをクエリできますが ( SELECT... FOR UPDATE を除く)、テーブルを更新することはできません。

専用テーブルロック(X)

このロックは最も制限が厳しく、他のトランザクションがあらゆる種類の DML ステートメントを実行したり、テーブルにあらゆる種類のロックを設定したりすることを禁止します。

このロックは最も制限的であり、他のトランザクションが任意のタイプの DML ステートメントを実行したり、テーブルに任意のタイプのロックを設定したりすることを禁止します。
Oracle はさまざまな同時実行機能を処理する必要があるため、非常に多くの同時実行を処理できない場合は、キューに入れる必要があります.キューイングの公平性を確保するために、さまざまな優先順位が表示されるため、さまざまな同時実行要件をサポートするために多くのロック モードが派生します。ビジネス層。

在同一个session里面,你执行一个UPDATE语句,在表上有DML锁,那自己能去做DDL语句吗,比如DROP?

同じセッションであるため、同時実行性はありません. また、サブミットせずに更新を実行して、テーブルを削除することもできます.

ロックレベル

行ロック: 0 および 6 種類のロック

テーブルロック:0、1、2、3、4、5、6の7種類のロック

0(なし)
1(ヌル)
2(RS)
3(RX)
4(S)
5(SRX)
6(X)

R は ROW、S は SHARE、X は eXclusive、exclusive、exclusive lock を表します。

0: null 空の
一般的な SELECT、テーブルと行の両方で 0 レベルのロック

1: null 空の
レベル 1 ロック: Select が v$locked_object に表示されることがあります。

2: 行-S 行共有 (RS): 共有テーブル ロック、サブ共有
レベル 2 ロックには以下が含まれます: 行共有のロック、オンラインでのインデックスの作成

テーブル ロックの場合:
locked_mode 2 は、次の locked_mode 2、3、4、および 5 のセッションには影響しません。後者のセッションの locked_mode が 6 の場合、後者のセッションの操作は ora-00054 エラーを引き起こします。 .
ORA-00054: リソースがビジーで、NOWAIT を指定して取得するか、タイムアウトになりました

行ロックの場合:
locked_mode 2 は行ロック レベル 0 のロックに対応し、他のセッションには影響しません。

3: 行 X 行の排他的 (RX): 行の変更に使用され、サブ排他的
3 レベルのロックには次が含まれます: 挿入、更新、削除、更新の選択、行の排他的ロック

テーブル ロックの場合:
locked_mode 3 は後者の locked_mode 3 のセッションには影響しませんが、後者のセッション locked_mode が 4、5、6 の場合、後者のセッション操作は ora-00054 エラーを引き起こします。
ORA-00054: リソースがビジーで、NOWAIT を指定して取得するか、タイムアウトになりました

行ロックの場合:
locked_mode 3 のテーブル ロックは、行ロック レベル 6 のロックに対応し、2 つのセッションが同じ行に影響します。

4: 共有共有ロック (S): 他の DML 操作を防止します。共有
レベル 4 のロックには、インデックスの作成、共有のロックが含まれます。

5: S/Row-X 共有行排他 (SRX): 他のトランザクション操作を防止し、共有/サブ排他的
5 レベルのロックには以下が含まれます: ロック 共有行排他的
具体的には、主キーと外部キーの制約がある場合に更新/削除します。発生、5ロック。

6: 排他的 (X): 独立したアクセスに使用されます。排他的な
6 レベル ロックには、テーブルの削除、インデックスの削除、テーブルの変更、テーブルの切り詰め、排他的なロックが含まれます。

宝石店のアナロジー

宝石店は誰でも無料で見学でき、予約もできるし、試着して気に入ったら買うもよし、店ごと買うもよし。

タイプ 0 の人々、無料で宝石店を訪れる人々。

第1種、高齢者、虚弱者、病人、身体障害者、妊娠中のお客様は宝石店を無料でご利用いただけます。

試用期間を予約した2番目のタイプの人は、最初に数日間購入し、試用後に気分が良ければ購入します。

3 番目のタイプの人は、直接店に行く目的はすぐに購入することです。

4番目のタイプの人、店全体のジュエリーは、他の人が訪問して予約できるようにパッケージ化されていますが、売買することはできません(これはORACLEでは読み取り専用ロックと呼ばれ、他の人には読み取りのみを許可します。つまり、 0、1、および 2 のタイプの人だけが来ることができます. 宝石店は、他の人が読み取り専用で訪問することを許可し、取引は許可されていません. 、しかし、みんなの目的は共有することであり、排他的ではないため、互換性があります);

第五類型と第四類型の違いは一つだけで、第五類型が宝石店全体を乗っ取った後は、もう一人の第五類型はそれ以上購入することができない(これはORACLE では書き込みロックと呼ばれます)、つまり、第 5 型の人はチャネルが 1 つしかないため、宝石店では第 5 型の人を 1 人しか見つけることができず、2 番目の第 5 型の人を見つけることは不可能です。カテゴリ 0、1、および 2 では、訪問は引き続き許可されますが、売買は許可されません。

第六のタイプの人々、それは宝石店全体を置き去りにします、誰も意図的に訪問することを許可されていません、自由な訪問のみが許可されています、それは排他的です、0,1タイプの人々だけが訪問を許可されています;

・上記カテゴリー2は予約制のため、第3カテゴリーは第6カテゴリーと互換性がありません・
上記第3カテゴリーはジュエリー買取のため、第3カテゴリーは4、5、6カテゴリーと互換性がありません。

宝石店を時計に見立て、宝石店のジュエリーキャビネットを宝石店に例えると、
時計の0、1、2、7種類のロックに対応する7つのモードに対応する7種類の人がいます。 3、4、5、6
キャビネット、オープンまたはクローズ 2 つのモードに対応する 2 つの状態、列 0、6 の 2 つのロックに対応

宝石店

(同時に入店できますか、はい)
時計レベルのロックは、警備員によって守られている宝石店のドアロックに相当し、0、1、2、3、4、5、と7種類の人に対応する6つのテーブルロックで、7種類の人が登場可能 0、1、2、3種類の人が同時に入店するなど、複数の種類の人が同時に入店するシチュエーション時、または3種類の人が同時に入ってくる人が多い。

レベル 0 ロック: ロックなし、純粋な select ステートメントのみ
タイプ 0: 無料アクセス、他の顧客との競合なし

レベル 1 ロック: 実際には、ロックの役割を果たすことはできません. 通知機能があるだけで、DDL をまったく防止することはできません. これは、実行計画内のオブジェクトをセッションに通知するのと同じです.タイプ 1: (高齢者、弱者、病人、障害者) 訪問無料、
なし 他の顧客との競合はありませんが、この顧客には、取り壊されるかどうかなど、店舗の今後の展開を知る権利があります。 .
たとえば、セッション A が select * from T を実行し、実行計画をメモリに保存すると、実行計画が正しいことを保護するために、セッション A は老人、弱者、病人、妊娠中、若年者の治療を享受する必要があります。 T テーブルが他のユーザーによって削除された後、セッション A 生成された実行計画はまだ有用ですか? 通知しない場合、A はこのテーブル オブジェクト、つまりロックが 1 番のオブジェクトの有効期限が切れていることをどのように知るのでしょうか。オブジェクトが削除されると、オブジェクトを所有するセッションに通知されます。このオブジェクトは削除されます。 SQL を再分析すると、No. 1 のロックがシステムによって自動的に生成されます

レベル 2 テーブル ロック: X とのみ競合します。他は共有ロックであるためです。RX と SRX にも X がありますが、それらは行 X であり、テーブルはまだ共有されています。レベル 2 ロックは、レベル 0 ~ 5 と競合しません。テーブル レベル
2 種類の人々: ジュエリーを購入するつもりが、今は商品が価値があるかどうかを確認するために来ているので、カウンターを開くには、単なる SELECT アクションです。無料で訪問し、ビジネス上の意図がある顧客と直接競合することはありません。
レベル 2 テーブル ロックの生成方法
テーブル レベル ロックを明示的に生成する (LOCK TABLE table IN ROW SHARE MODE、明示的に RS テーブル レベル ロックを生成する)
テーブル レベル ロックの明示的生成はテーブル レベル ロックのみを生成し、生成しないことに注意してください。行レベルのロックをカスケードするため、他のセッションとの行ロックはありません

レベル 3 ロック: 原因 (更新、削除、更新の選択、表示ロック テーブル LOCK TABLE テーブル IN ROW EXCLUSIVE MODE)
タイプ 3 の人々: ジュエリーを直接購入するため、カウンターを開く必要がある人々

6 番目の X は、テーブル レベル全体での排他ロックであり、ロック テーブル LOCK TABLE table IN Exclusive MODE を示します。

ジュエリーキャビネット


(同じキャビネットを同時に開けられるか?いいえ、そんな概念はありません)カウンタの 2 つの状態に対応するロック 0 と 6。

Open:
通常、顧客が宝石店に入ると、カウンターに走る目的は何ですか?

訪問:
キャビネットの状態は閉じています: モード 0.
訪問目的のみの顧客 (タイプ 0, タイプ 1) はリソース競合の問題を抱えていません. 営業担当者はまだロックを取り出して開く必要がありますか?カウンタ?いいえ、リソースの競合がなければロックは必要ないためです。
モード 0 の行レベル ロックは、0 と 1 のテーブル レベル ロックによって引き起こされます。単純な選択ステートメントは、0 レベル テーブル レベル ロックと 0 レベル行レベル ロックの両方です。つまり、ロックはありません。 .

購入:
キャビネットのオープン状態:モードNo.6
タイプ2人、試用期間中(試用期間中は他人が使用不可)
タイプ3人、即購入(弊社更新相当、削除、更新選択、LOCK) TABLE table IN ROW EXCLUSIVE MODE ステートメント)
要約: update、delete、select for update すべてが行に対して排他ロックを生成します。

共有ロックは、他の共有ロックの存在を許可します。つまり、共有は共有と競合しません。
たとえば、ユーザー A がテーブル T で UPDATE 行 1 を実行すると、テーブル t にテーブル レベルの共有ロックが存在し、次にユーザー B がテーブル T で UPDATE 行 2 を実行すると、テーブル t にもテーブルが存在します。 レベルの共有ロックただし、行はすべて排他ロックですが、同じ行ではないため、行でもテーブルでも競合はありません。
たとえば、ユーザー A が LOCK TABLE T IN ROW EXCLUSIVE MODE を実行すると、ユーザー B は LOCK TABLE T IN ROW EXCLUSIVE MODE または LOCK TABLE T IN ROW SHARE MODE を同時に実行できます。

有行级锁,必有表级锁(3级表锁引起6级行锁)
有表级锁,可以没有行级锁(显式锁,2,3,6号显示锁对应的表级锁
6号模式的行级锁是因为2、3号的表级锁造成的

ORACLE ロックは DATABASE BUFFER および LIBRARY CACHE ブロックに配置され、他のメモリを占有しません。他の db2 および informix では、ロックがメモリを占有するため、db2 の行ロックはテーブル ロックにアップグレードされます。

ロックの種類は、ロックの目的によって次の 3 つのカテゴリに分けられます。
· DML ロック
· DDL ロック
· 内部ロックまたは LATCH

DML と DDL には、可視の SCHEMA オブジェクトが含まれます。
DML は、テーブル、ビューなどを操作する DELETE、UPDATE、INSERT ステートメントであり、目に見える SCHEMA オブジェクトです。

DDL ステートメントは ALTER TABLE、CREATE TABLE およびその他のステートメントであり、同じオブジェクトはテーブル、ビュー、ストアド プロシージャなどであり、これらも可視の SCHEMA オブジェクトです。

内部ロックまたは LATCH はユーザーには見えず、カプセル化されたオブジェクトはユーザーには見えません. これらのオブジェクトは共有されており、共有オブジェクトはリソースの競合を伴うため、これらは内部ロック (LIBRARY CACHE, DATABASE BUFFER) です. したがって、ロックを使用してリソースへのアクセスを制限します. メモリを保護する低レベルのロックをラッチと呼びます. そのメカニズムは信号機に似ています. 道路は公道なので信号機を設定する必要があります. プライベートの場合は、信号機を設定する必要がないため、PGA にはラッチがありません。

DML は、複数のユーザーが並行してアクセスするデータを制御して一貫性を確保するために使用されるデータ メンテナンス ロックです。SELECT にはロックがなく、更新用の選択のみにロックがあります。
select... for update は結果行をロックし、他のセッションを更新できなくします。

DML ロックは、特定のトランザクション中に変更されたデータが他のトランザクションによって変更されないようにすることです。
DML ロックは、変更中のテーブルのトランザクションが終了していない間、他のトランザクションがテーブルで DDL を実行できないようにします。
(もちろん、ユーザーの現在のセッションは、テーブルの更新を送信しません。ユーザーの現在のセッションは、テーブルに対して直接 ddl を実行できます。ユーザーは、セッションを再度開いた後にテーブルに対して ddl を実行できません。ユーザーはテーブルに対して ddl を実行できません。)


DMLロックは、
さまざまなオブジェクト レベルに従って分類されます。

ORACLE は、行レベルのロックをテーブル レベルのロックにアップグレードしません。
これは中庭のようなもので、4つのドアが中庭を形成し、中庭のゲートがテーブルロックで、各部屋が列ロックです。
sqlserver データベースで、ロックするドアが 3 つある場合、ドアを直接ロックします。sqlserver データベースではロック キーが非常に高価であるため、キーを保存するために、行からロックのアップグレードがあります。レベル ロックをページ レベル ロックに変更してから、ページ レベル ロックからテーブル レベル ロックにアップグレードします。

現在のセッション sid を表示します。

SQL> select distinct sid from v$mystat;

2 つのセッションのロック情報を照会します。

SQL> select sid,id1,id2,type,lmode,request from v$lock where sid in (sid1,sid2) order by sid;

クエリ ロック タイプの具体的な意味:


SQL> select * from V$LOCK_TYPE where type in ('TX','AE','TM','TO','OD');
TYPE  NAME           ID1_TAG           ID2_TAG           IS_USE DESCRIPTION
----- -------------- ----------------- ----------------- ------ ----------------------------------------------------------------------
TM    DML            object #          table/partition   YES    Synchronizes accesses to an object
TX    Transaction    usn<<16 | slot    sequence          YES    Lock held by a transaction to allow other transactions to wait for it
AE    Edition Lock   edition obj#      0                 NO     Prevent Dropping an edition in use
OD    Online DDLs    object #          0                 NO     Lock to prevent concurrent online DDLs
TO    Temp Object    object #          1                 NO     Synchronizes DDL and DML operations on a temp object

ケース

ケース1

セッション 1 の sid は 161、セッション 2 の sid は 189

sid1 はコミットしません


SQL> update test set id=11;1 row updated

sid2 の作成に失敗しました

SQL> alter table test add hid3 number;

sid3 クエリの結果、sid1 と sid2 のテーブル レベルのロックが両方とも 3 であることがわかりました

SQL>  select sid,id1,id2,type,lmode,request from v$lock where sid in (161,189) order by sid;       
SID        ID1        ID2 TY      LMODE    REQUEST
---------- ---------- ---------- -- ---------- ----------       
161      65547       1930 TX          6          0       
161      88539          0 TM          3          0 --sid1的表级锁为3      
161        100          0 AE          4          0       
161      79833          1 TO          3          0       
189     196612       2185 TX          6          0       
189      88539          0 TM          3          0  --sid2的表级锁为3       
189        100          0 AE          4          0       
189      88539          0 OD          6          0       
189      65547       1930 TX          0          4       
189      79833          1 TO          3          0

SQL> select sid,FINAL_BLOCKING_SESSION,event from v$session where state='WAITING' and FINAL_BLOCKING_SESSION_STATUS='VALID';       
SID                FINAL_BLOCKING_SESSION   EVENT      
-----------------   ----------------------   -----------       
189                161                      enq: TX - row lock contention

ケース 2

セッション 1 の sid は 161、セッション 2 の sid は 189


sid1不commit
SQL> update test set id=11;
1 row updated
sid2,直接报错
SQL> drop table test;
drop table test
           *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

sid3 が ddl を変更した後、sid2 が再度実行され、sid クエリの結果が得られます。

SQL> alter system set ddl_lock_timeout=60
SQL> select sid,id1,id2,type,lmode,request from v$lock where sid in (161,189) order by sid;
       SID        ID1        ID2 TY      LMODE    REQUEST
---------- ---------- ---------- -- ---------- ----------
       161      88539          0 TM          3          0 --sid1的表级锁为3
       161        100          0 AE          4          0
       161      79833          1 TO          3          0
       161     458768       1934 TX          6          0
       189      88539          0 TM          0          6 --sid2当前表级锁为0,但是请求表级锁6
       189        100          0 AE          4          0
       189          0          1 AE          4          0
       189      79833          1 TO          3          0

SQL> select sid,FINAL_BLOCKING_SESSION,event from v$session where state='WAITING' and FINAL_BLOCKING_SESSION_STATUS='VALID';
       SID      FINAL_BLOCKING_SESSION     EVENT
       ---      ----------------------    -------------
       189                    161          enq: TM - contention

CREATE INDEX ONLINE は最初に update を実行せず、次に送信せず、次に create index online をエラーなしで実行しますが、create index online は常にブロックされます。最初に create index online を実行し、次に update を実行して通常どおり更新しますが、update が送信されない場合、create index online は常にブロックされます。
create index online会堵塞update吗?


理解: オンラインでインデックスを作成すると、行ごとにインデックスが作成されます。これは、この行のインデックスが作成されたことを意味するわけではありません。この行を更新するときは、オンラインでインデックスを作成する前に、すべての行が完了するまで待つ必要があります。更新がオンラインでのインデックス作成の前後に関係なく、オンラインでのインデックス作成は更新に影響しませんが、更新が提出されていない場合は、オンラインでのインデックス作成に影響します。

次の 2 つの実験セッション 1 の sid は 161、セッション 2 の sid は 189 です。

実験3

最初に create index online を実行します。作成の半分が終了したら、行 ID が最小の行を更新します。これは、create index online がこの行を通過する必要があり、更新セッションをブロックする必要があるのは当然のことです。実際、ブロックされていません。更新は同じくらい高速で、更新がオンラインでのインデックスの作成をブロックしていることがわかった最後のクエリです。

sid1 の実行

SQL> select object_id from test1 where rowid in (select min(rowid) from test1); 
OBJECT_ID
----------
4559

sid2 が実行され、作成に通常 6 秒かかります

SQL> create index ind_obd on test1 (OBJECT_ID) online;
Index created.Elapsed: 00:00:06.06SQL> drop index ind_obd;Index dropped.Elapsed: 00:00:00.14SQL> create index ind_obd on test1 (OBJECT_ID) online;

sid2 実行の 6 秒間の間に、すぐに sid1 で実行され、sid1 はすばやく実行され、ブロックされないことがわかりました


SQL> update test1 set object_id=1 where OBJECT_ID=4559;
32 rows updated.

sid3 は次のように実行され、sid1 161 が sid2 189 をブロックしていることがわかります。

SQL> select sid,FINAL_BLOCKING_SESSION,event from v$session where state='WAITING' and FINAL_BLOCKING_SESSION_STATUS='VALID';
       SID    FINAL_BLOCKING_SESSION    EVENT
       ----   ----------------------   -------------------------
       189                    161      enq: TX - row lock contention

SQL>  select sid,id1,id2,type,lmode,request from v$lock where sid in (161,189) order by sid;
       SID        ID1        ID2 TY      LMODE    REQUEST
---------- ---------- ---------- -- ---------- ----------
       161      79833          1 TO          3          0
       161     262151       1938 TX          6          0
       161      88544          0 TM          3          0
       161        100          0 AE          4          0
       189        100          0 AE          4          0
       189      79833          1 TO          3          0
       189     131075       2139 TX          6          0
       189      88544          0 DL          3          0
       189     262151       1938 TX          0          4
       189      88552          0 TM          4          0
       189      88544          0 DL          3          0
       189      88544          0 OD          4          0
       189      88544          0 TM          2          0
13 rows selected.

実験4

最初に create index online を実行し、作成の半分が終了したら、rowid が最大の行を更新します. create index online がこの行に到達しないのは当然であり、更新セッションをブロックしません. 実験では、これも発見されました.実際、更新は非常に高速で、最後のクエリが作成されます。欠点は、更新によってインデックスのオンライン作成がブロックされることです。

sid1 の実行


SQL>  select object_id from test1 where rowid in (select max(rowid) from test1);
 OBJECT_ID
----------
      85998

sid2 が実行され、作成に通常 6 秒かかります

SQL> create index ind_obd on test1 (OBJECT_ID) online;
Index created.
Elapsed: 00:00:06.06
SQL> drop index ind_obd;
Index dropped.
Elapsed: 00:00:00.14
SQL> create index ind_obd on test1 (OBJECT_ID) online;

sid2 実行の 6 秒間の間に、すぐに sid1 で実行され、sid1 はすばやく実行され、ブロックされないことがわかりました


SQL> update test1 set object_id=1 where OBJECT_ID=85998;
32 rows updated.

sid3 は次のように実行され、sid1 161 が sid2 189 をブロックしていることがわかります。

SQL> select sid,FINAL_BLOCKING_SESSION,event from v$session where state='WAITING' and FINAL_BLOCKING_SESSION_STATUS='VALID';
       SID    FINAL_BLOCKING_SESSION    EVENT
       ----   ----------------------   -------------------------
       189                    161      enq: TX - row lock contention
SQL> select sid,id1,id2,type,lmode,request from v$lock where sid in (161,189) order by sid;
       SID        ID1        ID2 TY      LMODE    REQUEST
---------- ---------- ---------- -- ---------- ----------
       161      79833          1 TO          3          0
       161      88544          0 TM          3          0
       161     393242       2315 TX          6          0
       161        100          0 AE          4          0
       189      79833          1 TO          3          0
       189      88544          0 TM          2          0
       189      88546          0 TM          4          0
       189     458777       1936 TX          6          0
       189        100          0 AE          4          0
       189      88544          0 DL          3          0
       189      88544          0 DL          3          0
       189     393242       2315 TX          0          4
       189      88544          0 OD          4          0
13 rows selected.

どのテーブルがロック オブジェクトで、どの行が SQL であるかをクエリして
、最初にブロックされたセッションの SID を見つけてから、次のように、どのテーブルがブロックされ、どの行がその行であるかをクエリします。

select a.sid, a.row_wait_obj#, a.row_wait_file#, a.row_wait_block#, a.row_wait_row#,b.owner,b.object_name from v$session a,dba_objects b where a.row_wait_obj#=b.object_id and sid in (XX);

select sid, row_wait_obj#, row_wait_file#, row_wait_block#, row_wait_row# from v$session where sid in (XX);--此次查询到row_wait_obj#=-1表示是持有锁的会话

row_wait_obj#:被等待的这行在哪个对象上
row_wait_file#:被等待的这行在哪个文件上
row_wait_block#:被等待的这行在哪个块上
row_wait_row#:被等待的这行在哪行上

統計収集によって検出されたロック


DBMS_STATS: GATHER_STATS_JOB encountered errors
ORA-04021: timeout occurred while waiting to lock object

統計情報を収集するときは、テーブルまたはインデックスの定義をロックする必要があります.実際には、ここでのロックはライブラリ キャッシュ ロック/ピンです~オブジェクトをロックするのではなく、オブジェクトの統計情報を収集するときに発見され
ます必要なオブジェクトがロックされていることを確認します。他のセッションがロックされており、一定時間待機した後も、他の​​セッションがオブジェクトに対して保持されているロックを解放していないため、統計セッションがロックを取得できません。オブジェクト上。

統計情報を収集すると、X モード (ライブラリ キャッシュ内のテーブルの表現) のライブラリ キャッシュ ロックが保持されるため、ロックが発生しますが、通常理解しているエンキュー ロックではありません。
他のユーザーは、このテーブルを使用する SQL を解析するときに、S モードでテーブル ライブラリ キャッシュ オブジェクトのライブラリ キャッシュ ロックを申請する必要があり、この時点で競合/ブロックが発生します。

おすすめ

転載: blog.csdn.net/Ruishine/article/details/129205963