web-dev-qa-db-ja.com

Oracleトレースファイルからデッドロックエラーの原因を見つける

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

*** 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: [email protected]
 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」と言っているので、従業員テーブルからレコードを削除するときに、このテーブルがテーブルレベルのロックを取得するということですか。現在、外部キー列にインデックスはありません。この列にインデックスを追加すると役立ちますか?

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

ありがとう

15
shashikanthb

まず、selectステートメントはOracleで何もロックせず、データの最後に使用可能な一貫したバージョンを使用するだけです。 Oracle 9i以降、updateのようなデータをロックするselect ... for 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は、「行排他」タイプ(SX)のテーブルレベルのロック(TM)を保持しており、同じテーブルで「行共有排他(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)は、テーブルレベルのロックです。
状況を理解するために、フランクパチョットによる この記事 を読むことをお勧めします。

以下は、この記事からの引用であり、状況に直接関連しています(SSXとSRXの略語は同等です)。

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

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

30
ThinkJet