[SQL]SQL Server におけるデッドロックの分析と回避

文書翻訳 文書翻訳
文書番号: 169960 - 対象製品
この記事は、以前は次の ID で公開されていました: JP169960
すべて展開する | すべて折りたたむ

目次

概要

Microsoft SQL Server はロックを使ってトランザクションの完全性とデータベースの一貫性を維持します。SQL Server version 6.5 はオプションで挿入操作には行レベルのロッキングを使用し、その他の操作にはページ レベルのロッキングを使います。リレーショナル データベース システムではロッキングためにユーザー間でデッドロックが起こってしまうことがあります。たとえば、ユーザー 1 (あるいは接続 1) ではデータ項目 "A" にロックがあり、データ項目 "B" にロックがほしいとします。ユーザー 2 ではデータ項目 "B" にロックがあり、データ項目 "A" にロックがほしいとします。この場合 SQL Server ではユーザー 1 かユーザー 2 のどちらかがデッドロックの犠牲となり、他方のユーザーは求めるロックが与えられます。

SQL Server のアプリケーション開発者は SET DEADLOCK_PRIORITY を使って、どの接続がデッドロックの犠牲となる候補か決めることができます。開発者がデッドロックの為の優先順位を指定しない場合、SQL Server はロックのチェーンより、デッドロックの犠牲となり完了するプロセスを選択します。

データベースのアプリケーション システムは、あるリレーショナル データベースから別のリレーショナル データベースに移植されると動作が違ってきます。そのひとつがロッキングです。この資料では SQL Server におけるデッドロックの調査方法と回避方法を説明します。

詳細

この資料ではデッドロックを調べるのにトレース フラグ T1204 の出力を使います。トレース フラグ T1204 を設定すると SQL Server はデッドロックが起こったときその情報を出力するようになります。このトレース フラグを使うにはコマンド プロンプトで次のコマンドを使い SQL Server を起動します。
sqlservr -c -T1204

トレース結果はトレース フラグ T3605 を設定しなければコンソールのウィンドウに送られます。T3605 を設定するとトレース結果はエラー ログに出力されます。

デッドロックが起きるのはふたつの接続がテーブルを反対の順序で更新してしまったときです。たとえば、トランザクションの中で、ある接続は、最初にテーブル "example1" に挿入して次に "example2" に挿入する、その間に、別の接続は、最初にテーブル "example2" に挿入して次に "example1" に挿入するとします。このような例を考えると、どのようにデッドロックを回避したらよいかがよく説明できます。

次に示すのはこの例に使われているテーブルをつくる SQL ステートメントです。
   create table example1 (column1 int, column2 char(20), column3 char(50))
   go
   create table example2 (column1 int, column2 char(20), column3 char(50))
   go

   declare @lvar int
   select @lvar = 0
   while @lvar < 500
   begin
   insert into example1 values (@lvar, 'AAA', 'CCC')
   insert into example2 values (@lvar, 'AAA', 'CCC')
   select @lvar = @lvar + 1
   end
   go

   create unique clustered index ex1ind1 on example1 (column1, column2)
   with fill factor = 90, PAD_INDEX
   go

   create unique clustered index ex2ind1 on example2 (column1, column2)
   with fill factor = 90, PAD_INDEX
   go

例 1: 順序が逆になったテーブル挿入

この例では、ふたつのテーブルは逆順で挿入された為にデッドロックが起こっています。ふたつ以上の接続が逆順でテーブルに更新や削除を行なってもデッドロックが起こります。
   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')
   接続 2 > INSERT INTO example2 VALUES (200, 'AAAB', 'CCC')
   接続 2 > INSERT INTO example1 VALUES (200, 'AAAB', 'CCC')

ここで接続 2 が挿入している行は、接続 1 が既に行を挿入しロックを保持しているのと同じページにあるので接続 1 は接続 2 をブロックします。
接続 1 > INSERT INTO example2 VALUES (100, 'AAAA', 'CCC')

ここで接続 2 は接続 1 をブロックします。接続 1 が挿入している列が、接続 2 が既に列を挿入しロックを保持しているのと同じページにあるからです。これがデッドロックを起します。

デッドロックが起ったときのトレース フラグ 1204 の出力を次に示します。
  97/04/20 11:51:57.88 spid13   *** DEADLOCK DETECTED with spid 14 ***
   spid 13 requesting EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 14, dbid 6, page 0x188, table example2, indid 0x1
     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example2 VALUES (100,
   'AAAA', 'CCC')
   spid 14 waiting for EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 13, dbid 6, page 0x180, table example1, indid 0x1
     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (200,
   'AAAB', 'CCC')
   VICTIM: spid 13, pstat 0x0000 , cputime 30

トレースを一行一行追跡すれば、ユーザーはデッドロックについてたくさんの情報を知ることができます。接続 1 は spid 13 で接続 2 は spid 14 です (接続に関連する spid を決定するには sp_who システム ストアド プロシージャを使います)。
   >> 97/04/20 11:51:57.88 spid13   *** DEADLOCK DETECTED with spid 14 ***
   The deadlock was detected between spid 13 and spid 14.
   >> spid 13 requesting EX_PAGE (waittype 0x8005), blocked by:
   >>   EX_PAGE: spid 14, dbid 6, page 0x188, table example2, indid 0x1
   >>   pcurcmd INSERT(0xc3), input buffer: INSERT INTO example2 VALUES
   (100, 'AAAA', 'CCC')

Spid 13 は EX_PAGE ロックを要求しましたが spid 14 によってブロックされています。この spid 14 は既に dbid 6 のテーブル example2 にあるページ 0x188 に EX_PAGE ロックを保持しています。そのロックはクラスタ化されたインデックスに属するページに保持されています。
  Indid 値        説明
  -----------------------------------------------------------------
  
  0               クラスタ化インデックスがなければデータ ページで、
                  クラスタ化インデックスがあればクラスタ化
                  インデックスのリーフ ページ
  1               クラスタ化インデックス ページの非リーフ ページ
  255             テキスト/イメージ ページ 
  その他の値      クラスタ化されていない二次インデックス


spid 13 で実行中のコマンドは INSERT でトレースは input buffer にそれを示します。
   >> spid 14 waiting for EX_PAGE (waittype 0x8005), blocked by:
   >>   EX_PAGE: spid 13, dbid 6, page 0x180, table example1, indid 0x1
   >>   pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES
   (200, 'AAAB', 'CCC')

Spid 14 は EX_PAGE ロックを待っていますが、spid 13 によってブロックされています。この spid 13 は同じページに EX_PAGE ロックを保持しています。
   >> VICTIM: spid 13, pstat 0x0000 , cputime 30
   SQL Server has chosen spid 13 as the deadlock victim.

トレースにある、さまざまなロックの意味を次に示します。

SH_INT and EX_INT
インテント ロックは、低いレベルのロック (たとえば、ページ) の前に、高いレベルの項目 (たとえば、テーブル) で取得することができます。なぜならば、ロック マネージャは異なるタイプの項目 (この場合、ページとテーブル) にどのような違いがあるかを関知しないからです。ページで EX_PAG ロックを取得するまえにテーブルで EX_INT ロックがとられなければ、別のユーザーが同じテーブルで EX_TAB ロックを取得するので、ロック マネージャは競合の存在に気づきません。今のところ SQL Server はテーブルにだけインテント ロックがあります。インテント ロックには 2 種類あり、それは共有ロック (SH_INT) と排他ロック (EX_INT) です。

EX_PAGE
これは排他ページ ロックで、insert 行レベル ロッキング (IRL) が無効のときに DELETE、UPDATE、あるいは INSERT ステートメントでページが更新されるときに取得されるものです。
UP_PAGE
これは更新ページ ロックで、ページが調べられ、オプティマイザがそのページの更新が行われること (あるいは UPDLOCK ヒントが使われること) がわかっているときに、共有ページ ロックのかわりに取得されるものです。

PR_EXT、NX_EXT、UPD_EXT、および EX_EXT
これらのロックは、ディスク スペースの割り当てあるいは割り当て解除を行なうときに取得されるものです。UPD_EXT は既存のエクステントからページを割り当てたり割り当て解除をするときに取得されるものです。その他はエクステント全体を割当てたり割り当て解除をするときに使われるものです。

IX_PAGE および LN_PAGE
これらは IRL ロックです。IX_PAGE はページで行ロッキングを行なうインテント ロックです。LN_PAGE は IRL が行なわれているページが分割される必要があるときに取得されるものです。

RLOCK および XRLOCK
これらは短期ロックでインデックス b-ツリーを走査するときに取得されるものです。このロックには 2 種類あり、それは共有ロック (RLOCK) と排他ロック (XRLOCK) です。共有ロックはスキャンのときに取得され、排他ロックは更新の間、インデックス ページで取得されます。

EX_TAB
これは排他テーブル ロックで、SQL Server のオプティマイザが更新クエリを解決する最も効果的な方法としてテーブル スキャンを採用したときに (たとえば、テーブルにインデックスがひとつもないとき) 起こるものです。EX_TAB ロックも TABLOCKX ヒントでテーブルをロックしたときや SQL Server がテーブルにあるページ ロックをテーブル ロックにエスカレートしたときに現われます。

SH_TAB
これは共有テーブル ロックで、テーブルの大部分がスキャンされる (あるいはページ ロッキングがエスカレートする) あるいは TABLOCK ヒントが使われていると、オプティマイザがみなしたときに使われるものです。

前掲のデッドロック例は、ふたつの接続が以下の順序でテーブルを更新すれば回避できます。
   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')
   接続 2 > INSERT INTO example1 VALUES (200, 'AAAB', 'CCC')
   接続 2 > INSERT INTO example2 VALUES (200, 'AAAB', 'CCC')
   接続 1 > INSERT INTO example2 VALUES (100, 'AAAA', 'CCC')

例 2: 同じテーブルの異なる部分への挿入

このデッドロックは、行がページを共有しているとき、逆の順序で同じテーブルの異なる部分にふたつの接続が挿入を行なうと起こります。たとえば次のようなことがあります。
   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')
   接続 2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC')
   接続 1 > INSERT INTO example1 VALUES (400, 'AAAA', 'CCC')

この例のテーブルでは、example1 テーブルの最初のカラムにクラスタ化インデックスがあります。最初のカラムの同じ値のある行は同じページに入れられることに注意します。例では、多分、接続 1 によって挿入された 2 番目の行は、接続 2 によって挿入された最初の行と同じページに入れられます。それは両方ともクラスタ化インデックス値 400 を持っているからです。これにより、接続 2 が接続 1 をブロックすることになります。
   接続 2 > INSERT INTO example1 VALUES (100, 'AAAB', 'CCC')

接続 2 もまた接続 1 にブロックされ、デッドロックになります。デッドロック トレースは次のようになります。
   97/04/20 12:56:01.40 spid16   *** DEADLOCK DETECTED with spid 15 ***
   spid 16 requesting EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 15, dbid 6, page 0x2c5, table example1, indid 0
     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (100,
   'AAAB', 'CCC')
   spid 15 waiting for EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 16, dbid 6, page 0x8bd, table example1, indid 0
     pcurcmd INSERT(0xc3), input buffer: INSERT INTO example1 VALUES (400,
   'AAAA', 'CCC')
   VICTIM: spid 16, pstat 0x0000 , cputime 130

ページ 0x2c5 の EX_PAGE ロックに対する spid 16 リクエストは spid 15 にブロックされています。spid 15 は最初の挿入を行なったあとすぐに 0x2c5 の EX_PAGE ロックを保持しています。また spid 15 も spid 16 にブロックされ、ページ 0x8db の EX_PAGE ロックを待機しており、デッドロックになります。

このデッドロックは次のコマンドを使ってテーブル example1 の IRL を有効にすれば回避することができます。
   sp_tableoption 'example1', 'insert row lock', true

例 3: IRL を使った挿入

IRL は二人以上のユーザーがインサートだけを行う際、ユーザーがページを共有できるようにします。これにより、しばしばスループットが向上します。しかし IRL を有効にすればデッドロックが少なくなるかといえば必ずしもそうではありません。IRL がデッドロックをもたらす場合もあります。
   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')
   接続 2 > INSERT INTO example1 VALUES (105, 'AAAB', 'CCC')

IRL が有効になっていると、両方の接続が 2 つの新しい列を含むページで IX_PAGE ロックを持つことになります。IRL が無効になると、接続 1 は EX_PAGE ロックを獲得し、接続 2 はすぐにブロックされます。
   接続 2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 105
   and column2 = 'AAAB'

ここで接続 2 は UPDATE ステートメントを行うために排他ページ ロックを必要とします。このステートメントは接続 1 の IX_PAGE ロックと互換性がないので、接続 2 は待機状態になります。
   接続 1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 100
   and column2 = 'AAAA'

こうなると接続 1 は接続 2 にブロックされることになり、デッドロックとなります。デットロック トレースは次のようになります。
   97/04/20 15:13:50.07 spid17   *** DEADLOCK DETECTED with spid 18 ***
   spid 17 requesting UP_PAGE (waittype 0x8007), blocked by:
     IX_PAGE: spid 18, dbid 6, page 0x2c5, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCA' where column1 = 100 and column2 = 'AAAA'
   spid 18 waiting for UP_PAGE (waittype 0x8007), blocked by:
     IX_PAGE: spid 17, dbid 6, page 0x2c5, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCB' where column1 = 105 and column2 = 'AAAB'
   VICTIM: spid 17, pstat 0x0000 , cputime 20

Spid 17 (接続 1) は UP_PAGE ロックを待っています。これは排他ページ ロックを取得する最初の段階です。それは spid 18 にブロックされていて、ページ 0x2c5 で IX_PAGE ロックを保持しています。Spid 18 は同じページで UP_PAGE ロックを待っていて、spid17 が持っている IX_PAGE ロックにブロックされています。これでデッドロックが起こります。IX_PAGE ロックは共有することができますが、UP_LOCK はできません。最初の挿入の間、両方の spid が同じページで IX_PAGE ロックを取得していて、後でそのロックを UP_PAGE ロックに更新しようとしています。これは UP_PAGE ロックが排他的なので不可能です。

デッドロックを回避するひとつの方法は、同じトランザクションの中で、行を挿入した後に更新を行うのではなく、テーブルに更新された値を直接挿入することです。これが可能でないときは、次のコマンドを使って IRL を無効にしデッドロックを回避します。
   sp_tableoption 'example1', 'insert row lock', false

例 4: 同じページの行への挿入

ふたつの spid で働く異なる行が同じページに属しているときにも、デッドロックが起こります。
   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC')
   接続 2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC')
   接続 1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 405
   and column2 = 'AAAA'

ここで、接続 1 は接続 2 にブロックされます。接続 2 が既に行を挿入してしまったページで、接続 1 が行を更新しようとしている為に、このような状態になります。
   接続 2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 105
   and column2 = 'AAAB'
ここで、接続 2 は接続 1 にブロックされ、デッドロックにいたります。接続 1 が行を挿入したページに接続 2 が行を更新しようとしているからです。デッドロック トレースは次のようになります。
   97/04/20 15:48:21.18 spid20   *** DEADLOCK DETECTED with spid 19 ***
   spid 20 requesting UP_PAGE (waittype 0x8007), blocked by:
     EX_PAGE: spid 19, dbid 6, page 0x2c4, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCB' where column1 = 105 and column2 = 'AAAB'
   spid 19 waiting for UP_PAGE (waittype 0x8007), blocked by:
     EX_PAGE: spid 20, dbid 6, page 0xc48, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCA' where column1 = 405 and column2 = 'AAAA'
   VICTIM: spid 20, pstat 0x0000 , cputime 60

このデッドロックは、行を別のページに分割することによって回避できます。これを行うひとつの方法は、大きな FILLFACTOR でこのテーブルにクラスタ化インデックスを再作成することです。50 % の FILLFACTOR でクラスタ化インデックスを作るステートメントは次のようになります。
   create unique clustered index ex1ind1 on example1 (column1, column2)
   with fill factor = 50, PAD_INDEX

このステートメントはページの半分を空にしたまま、クラスタ化インデックスを作成します。(PAD_INDEX オプションがあるので) これには非リーフ レベルのクラスタ化インデックスが含まれます。テーブルは実際のサイズの二倍を占め、ページあたりの行数は半分になります。

テーブルで FILLFACTOR は維持されません。テーブルはインデックスが作られている間だけ指定された FILLFACTOR で再構成されます。それ以降のページごとの行数は、インデックス作成の間に指定された FILLFACTOR から変わります。これが起きたら、求める FILLFACTOR でクラスタ化されたインデックスを再作成するのは良い考えです。

先に述べたデッドロックを回避するもうひとつの方法は、テーブルにダミーのカラム (たとえば dummy1 char(255)) をパッドする (詰め込む) ことです。これにより行のサイズを大きくし、ページあたりの行を少なくします (ページあたり 1 行)。このようなパディングは、時間がたっても維持されるので、パディングを維持する為に、クラスタ化インデックスを再作成する必要がありません。(他の理由で、クラスタ化インデックスを再作成したい場合もあるかもしれませんが)。この方法の不利な点は、記憶領域がダミーフィールドに消費されてしまうことです。

例 5: 行のパディング

行にパディングを行うと、ページあたりの行が少なくなり (つまりデッドロックも少なくなり) ますが、完全にデッドロックがなくなることはありません。

この例のテーブル、example1 は、ページあたり 1 行になるようにパディングしています。次のステートメントはこの例でテーブルをつくるのに使われるものです。
   create table example1 (column1 int, column2 char(20), column3 char(50),
   dummy_column4 char (255), dummy_column5 char (255), dummy_column6 char
   (255))
   go

   create unique index ex1ind5 on example1 (column3, column2, column1,
   dummy_column4, dummy_column5, dummy_column6) with fill factor = 85
   go

   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCC', ' ', ' ',
   ' ', ' ')
   接続 2 > INSERT INTO example1 VALUES (400, 'AAAB', 'CCC', ' ', ' ',
   ' ', ' ')
   接続 1 > UPDATE example1 SET column3 = 'CCCA' where column1 = 401
   and column2 = 'AAAA'

ここで、接続 1 は行の更新の際、接続 2 にブロックされます。SQL Server はページ チェイン ポインタを維持しなければならないので、前のページ、次のページおよび更新されているページをロックします。接続 2 は前のページにロックを保持しているので、接続 1 は接続 2 がトランザクションをコミットするまで待機することになります。
   接続 2 > UPDATE example1 SET column3 = 'CCCB' where column1 = 101
   and column2 = 'AAAB'

ここで、接続 2 は接続 1 にブロックされます。接続 1 にロックされている前のページをロックしなければならないからです。その結果デッドロックとなります。デッドロックトレースは次のようになります。
   spid 20 requesting UP_PAGE (waittype 0x8007), blocked by:
     EX_PAGE: spid 19, dbid 6, page 0x12b5, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCB' where column1 = 101 and column2 = 'AAAB'
   spid 19 waiting for UP_PAGE (waittype 0x8007), blocked by:
     EX_PAGE: spid 20, dbid 6, page 0x1531, table example1, indid 0
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCA' where column1 = 401 and column2 = 'AAAA'
   VICTIM: spid 20, pstat 0x0000 , cputime 300

このデッドロックは、挿入中、更新中あるいは削除中の、行の間にダミーの行を挿入して回避することができます。たとえば、接続 1 が行 pk = 1 で (挿入、更新、あるいは削除) 作業をしていて、接続 2 が行 pk = 5 で作業をしている場合、このふたつの行の間に (pk = 3 を含むような) 行を挿入すればデッドロックは回避できます。この方法はテーブルのサイズも大きくしますが、このようにアプリケーションにとって決定的な意味を持つキューテーブルには最もよい解決策でしょう。

例 6: クラスタ化されていないインデックス

クラスタ化されていない二次インデックスがデッドロックを引き起こすことがあります。ここでは二次インデックスの維持がデッドロックを引き起こしています。

この例で使われる二次インデックスをつくるステートメントは次のようになります。
create index ex1ind2 on example1 (column3) with fill factor = 90,
   PAD_INDEX

   接続 1 > BEGIN TRANSACTION
   接続 2 > BEGIN TRANSACTION
   接続 1 > INSERT INTO example1 VALUES (100, 'AAAA', 'CCBA', ' ', '
   ', ' ', ' ')
   接続 2 > INSERT INTO example1 VALUES (300, 'AAAB', 'CCCZ', ' ', '
   ', ' ', ' ')
   接続 2 > UPDATE example1 SET column3 = 'CCBA' where column1 = 105

ここで、接続 2 は接続 1 にブロックされます。接続 1 は接続 2 が更新する必要があるクラスタ化されていない二次インデックス ページにロックを保持しているからです。
   接続 1 > UPDATE example1 SET column3 = 'CCCZ' where column1 = 305

ここで、接続 1 は接続 2 にブロックされデッドロックとなります。接続 2 がそのページで既に挿入しロックを保持しているクラスタ化されていない二次インデックスを更新するために、接続 1 がロックを待っているときこのようになります。このデッドロック例のデッドロック トレースは次のようになっています。
   97/04/20 19:05:38.75 spid11   *** DEADLOCK DETECTED with spid 12 ***
   spid 11 requesting EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 12, dbid 6, page 0x112f, table example1, indid 0x2
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCCZ' where column1 = 305
   spid 12 waiting for EX_PAGE (waittype 0x8005), blocked by:
     EX_PAGE: spid 11, dbid 6, page 0x1108, table example1, indid 0x2
     pcurcmd UPDATE(0xc5), input buffer: UPDATE example1 SET column3 =
   'CCBA' where column1 = 105
   VICTIM: spid 11, pstat 0x0000 , cputime 50

このデッドロックは、二次インデックスを廃棄すれば回避することができます。インデックスをパディングし 1 ページあたり 1 行にすることはできないので、これを回避するにはクラスタ化されていない二次インデックスをなくすか、アプリケーションに手を加えるかしかありません。

デッドロックは 2 つ以上の接続がある場合に起こります。その場合には、デッドロック トレースがデッドロックにかかわる spid および競合するロックをリストします。デッドロックは、インデックス走査をしているとき取得された RLOCK および XRLOCK ロックがあるときに起こります。またデッドロックはエクステント ロックがあるときも起こります。(PR_EXT, NX_EXT, UPD_EXT & EX_EXT)。

次のトレース フラグを有効にすれば、デッドロックについてより詳しく知ることができます。

T1200
ロックがいつ起ったか、デッドロックがあったか否かなどロックのリクエスト/リリース情報をすべてプリントします。これは、パフォーマンスの観点から負荷がかかりますが、デッドロックの分析に役に立ちます。

T1206
デッドロックに参加している spid に保持されているロックすべてをプリントします。

T1208
クライアントからのホスト名、プログラム名をプリントします。クライアントがそれぞれの接続についてユニークな値を指定しているとみなせば、これでデッドロックに関わっているクライアントを特定することができます。

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 169960 (最終更新日 1998-03-09) をもとに作成したものです。

プロパティ

文書番号: 169960 - 最終更新日: 2003年11月10日 - リビジョン: 3.0
この資料は以下の製品について記述したものです。
  • Microsoft SQL Server 6.5 Standard Edition
キーワード:?
dead irl kbhowto kbusage lock デッド ロック KB169960
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"
サポート期間が終了した「サポート技術情報」資料に関する免責事項
この資料は、マイクロソフトでサポートされていない製品について記述したものです。そのため、この資料は現状ベースで提供されており、今後更新されることはありません。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com