15

複数のユーザーがアプリケーションを使用している場合、アプリケーションで「ora-00060 リソースの待機中にデッドロックが検出されました」というエラーが頻繁に発生します。Oracle 管理者からトレース ファイルを入手しましたが、それを読むには助けが必要です。以下は、トレース ファイルからのデータの一部です。これが原因の特定に役立つことを願っています。

*** 2013-06-25 09:37:35.324
DEADLOCK DETECTED ( ORA-00060 )

[Transaction Deadlock]

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
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

session 72: DID 0001-00D2-000000C6  session 24: DID 0001-00D0-00000043 
session 24: DID 0001-00D0-00000043  session 72: DID 0001-00D2-000000C6 

Rows waited on:
 Session 72: no row
 Session 24: no row

----- Information for the OTHER waiting sessions -----
Session 24:
 sid: 24 ser: 45245 audsid: 31660323 user: 90/USER
  flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
  flags2: (0x40009) -/-/INC
 pid: 208 O/S info: user: zgrid, term: UNKNOWN, ospid: 2439
   image: oracle@xyz.local
 client details:
   O/S info: user: , term: , ospid: 1234
   machine: xyz.local program: 
 current SQL:
  delete from EMPLOYEE where EMP_ID=:1

 ----- End of information for the OTHER waiting sessions -----

Information for THIS session:

 ----- Current SQL Statement for this session (sql_id=dyfg1wd8xa9qt) -----
 delete from EMPLOYEE where EMP_ID=:1
===================================================

「デッドロックグラフ::」が何を言っているのか教えていただければ幸いです。また、セクションで待機している行には、行がないと表示されます。

また、いくつかのブログで、トレース ファイルの「sqltxt」セクションが原因を示唆している可能性があることを読みました。以下は、そのセクションに表示されるクエリです。

 select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1

employee_salary テーブルには、EMPSAL_EMP_ID 列に外部キー制約があります。

SQL ヒントには「all_rows」と表示されていますが、このテーブルは従業員テーブルからレコードを削除するときにテーブル レベルのロックを取得するということですか? 現在、外部キー列にインデックスがありません。この列にインデックスを追加すると役に立ちますか?

さらに情報が必要な場合に備えて、投稿してください。

ありがとう

4

1 に答える 1

35

まず第一に、selectステートメントはOracleで何もロックせず、最後に利用可能な一貫したバージョンのデータを使用するだけです。select ... for updateOracle 9i 以降のようにデータをロックするケースではありませんが、質問からのクエリには句updateがありません。for update

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX

セッション #72 は、「Row Exclusive」タイプ (SX) のテーブル レベル ロック (TM) を保持しており、同じテーブルで「Share Row Exclusive」(SSX) ロックを取得しようとしています。このセッションは、同じタイプ (SX) のテーブル レベル ロックを既に保持し、SSX ロックが使用可能になるまで待機するセッション #24 によってブロックされます。

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

これ (2 行目) はまったく同じ状況を示していますが、反対方向です。セッション #24 は SSX ロックが使用可能になるのを待ちますが、同じテーブルで SX ロックを既に保持しているセッション #72 によってブロックされます。

したがって、セッション #24 とセッション #72 は互いにブロックし合い、デッドロックが発生します。

両方のロック タイプ (SX と SSX) は、テーブル レベルのロックです。
この状況を理解するには、Franck Pachot によるこの記事を読むことをお勧めします。

以下は、あなたの状況に直接関連するこの記事からの引用です (SSX と SRX の略語は同等であることに注意してください)。

参照整合性も TM ロックを取得します。たとえば、索引付けされていない外部キーに関する一般的な問題により、親テーブルでキーの削除または更新を発行すると、子テーブルで S ロックが発生します。これは、インデックスがないと、参照整合性に違反する可能性のある同時挿入を防ぐために、Oracle がロックする下位レベルのリソースが 1 つもないためです。
外部キー列が通常のインデックスの先頭の列である場合、親の値を持つ最初のインデックス エントリを単一のリソースとして使用し、行レベルの TX ロックでロックできます。
また、参照整合性に on delete カスケードがある場合はどうなるでしょうか? S モードに加えて、行 X (RX) モードと同様に、子テーブルの行を更新する意図があります。ここで、共有行排他 (SRX) が発生します: S+RX=SRX。

したがって、最も可能性の高いバリアントは、セッション #72 とセッション #24 がEMPLOYEEテーブル内のいくつかの行を同時に削除することであり、列が最初にリストされたテーブルにインデックスがないことと組み合わせてon delete cascade制約があります。EMPSAL_EMP_IDEMPLOYEE_SALARYEMPSAL_EMP_ID

于 2013-06-28T11:59:16.187 に答える