異なるプロセスの同じ一時テーブルのロックからのデッドロック


17

私は不可能だと思った何かを示すように見えるデッドロックを発見しました。デッドロックには2つのプロセスが関係します。

1. process8cf948 SPID 63

  • 一時テーブル#PB_Cost_Excp_Process_Invoices_WorkでALTER TABLEを実行します。

  • オブジェクトID 455743580でテーブル#PB_Cost_Excp_Process_Invoices_WorkのIXロックを所有

2. process4cb3708 SPID 72

  • 一時テーブル#PB_Cost_Excp_Process_Invoices_WorkでUPDATEを実行します。これは、テーブルの独自のコピーであると想定されています。

  • 同じオブジェクトID 455743580で#PB_Cost_Excp_Process_Invoices_WorkのSch-Mロックを所有しています

これは不可能だと思われます。何か不足していますか?#Temporaryテーブルは、これら2つのSPID間で本当に再利用されましたか?

これは、累積的な更新1(バージョン10.50.4260)が適用されたSQL Server 2008 R2 Service Pack 2にあります。

変更されていない完全なデッドロックトレースは以下のとおりです。2つのプロセスが、同じテーブル名#PB_Cost_Excp_Process_Invoices_Work_SNIP_0000000D8519を使用して同じオブジェクトIDで動作していることに注意してください。

12/14/2012 13:46:03,spid23s,Unknown,waiter id=process8cf948 mode=X requestType=wait
12/14/2012 13:46:03,spid23s,Unknown,waiter-list
12/14/2012 13:46:03,spid23s,Unknown,owner id=process4cb3708 mode=Sch-M
12/14/2012 13:46:03,spid23s,Unknown,owner-list
12/14/2012 13:46:03,spid23s,Unknown,objectlock lockPartition=0 objid=455743580 subresource=FULL dbid=2 objectname=tempdb.dbo.#PB_Cost_Excp_Process_Invoices_Work_________________________________________________________________________________0000000D8519 id=lock371705d00 mode=Sch-M associatedObjectId=455743580
12/14/2012 13:46:03,spid23s,Unknown,waiter id=process4cb3708 mode=Sch-M requestType=wait
12/14/2012 13:46:03,spid23s,Unknown,waiter-list
12/14/2012 13:46:03,spid23s,Unknown,owner id=process8cf948 mode=IX
12/14/2012 13:46:03,spid23s,Unknown,owner-list
12/14/2012 13:46:03,spid23s,Unknown,objectlock lockPartition=3 objid=455743580 subresource=FULL dbid=2 objectname=tempdb.dbo.#PB_Cost_Excp_Process_Invoices_Work_________________________________________________________________________________0000000D8519 id=lock3139b4780 mode=IX associatedObjectId=455743580
12/14/2012 13:46:03,spid23s,Unknown,resource-list
12/14/2012 13:46:03,spid23s,Unknown,Proc [Database Id = 8 Object Id = 1857974987]
12/14/2012 13:46:03,spid23s,Unknown,inputbuf
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Submit_SP @SiteKey, @PWDate
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.DR_SubmitPaperwork_SP line=174 stmtstart=12912 stmtend=13018 sqlhandle=0x03000800cb72be6e500434018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Create_SP

    -- Clean up work table
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Submit_SP line=138 stmtstart=11890 stmtend=12012 sqlhandle=0x03000800428c1f1950f833018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,UPDATE #PB_Cost_Excp_Process_Invoices_Work
    SET PBCEPrcInv_RtlPkg_Item_Quantity = RtlPkg_Item_Quantity
    FROM #PB_Cost_Excp_Process_Invoices_Work
        INNER JOIN Item_Packages (NOLOCK)
            ON PBCEPrcInv_ItemPkg_Key = ItemPkg_Key
        INNER JOIN Retail_Packages (NOLOCK)
            ON ItemPkg_RtlPkg_Key = RtlPkg_Key

    -- Lookup pricebook cost
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Create_SP line=25 stmtstart=2394 stmtend=3050 sqlhandle=0x030008003a082846321f46018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,executionStack
12/14/2012 13:46:03,spid23s,Unknown,process id=process8cf948 taskpriority=0 logused=0 waitresource=OBJECT: 2:455743580:0  waittime=3739 ownerId=707053534 transactionname=UPDATE lasttranstarted=2012-12-14T13:45:59.327 XDES=0x3c4502930 lockMode=X schedulerid=4 kpid=7276 status=suspended spid=72 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2012-12-14T13:45:58.337 lastbatchcompleted=2012-12-14T13:45:58.337 clientapp=PDI WCF Services - pdidb01-PDIMaster.cfg hostname=PDIWEB01 hostpid=2084 loginname=pdiuser isolationlevel=read committed (2) xactid=707053534 currentdb=8 lockTimeout=4294967295 clientoption1=673316896 clientoption2=128568
12/14/2012 13:46:03,spid23s,Unknown,Proc [Database Id = 8 Object Id = 1857974987]
12/14/2012 13:46:03,spid23s,Unknown,inputbuf
12/14/2012 13:46:03,spid23s,Unknown,EXEC PB_ProcessExc_Costs_Submit_SP @SiteKey, @PWDate
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.DR_SubmitPaperwork_SP line=174 stmtstart=12912 stmtend=13018 sqlhandle=0x03000800cb72be6e500434018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,EXEC dbo.PB_ProcessExc_Costs_CreateInvoiceWorkTable_SP
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_Submit_SP line=58 stmtstart=5782 stmtend=5894 sqlhandle=0x03000800428c1f1950f833018da000000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,ALTER TABLE #PB_Cost_Excp_Process_Invoices_Work DROP COLUMN PBCEPrcInv_Filler
12/14/2012 13:46:03,spid23s,Unknown,frame procname=PDICompany_218_01.dbo.PB_ProcessExc_Costs_CreateInvoiceWorkTable_SP line=50 stmtstart=5382 stmtend=5538 sqlhandle=0x0300080025d75a14ffff4701969f00000100000000000000
12/14/2012 13:46:03,spid23s,Unknown,executionStack
12/14/2012 13:46:03,spid23s,Unknown,process id=process4cb3708 taskpriority=0 logused=0 waitresource=OBJECT: 2:455743580:3  waittime=3739 ownerId=707052778 transactionname=ALTER TABLE lasttranstarted=2012-12-14T13:45:58.517 XDES=0x5f48bce80 lockMode=Sch-M schedulerid=6 kpid=7212 status=suspended spid=63 sbid=0 ecid=0 priority=0 trancount=1 lastbatchstarted=2012-12-14T13:45:58.513 lastbatchcompleted=2012-12-14T13:45:58.513 clientapp=PDI WCF Services - pdidb01-PDIMaster.cfg hostname=PDIWEB01 hostpid=2084 loginname=pdiuser isolationlevel=read committed (2) xactid=707052778 currentdb=2 lockTimeout=4294967295 clientoption1=673316896 clientoption2=128568
12/14/2012 13:46:03,spid23s,Unknown,process-list
12/14/2012 13:46:03,spid23s,Unknown,deadlock victim=process4cb3708
12/14/2012 13:46:03,spid23s,Unknown,deadlock-list

更新

問題のマシンには、タスクマネージャーとデバイスマネージャーに16個のプロセッサーが表示されているため、ロックパーティションが有効になっており、2つのロックは異なるロックパーティションにあります。ここでロックのパーティション分割が原因であるかどうかはわかりません。

CSS SQL Server Engineersブログにもこの興味深い記事があります

更新2

一時テーブルは、すべてのストアドプロシージャの最後に削除されます。それらは、パターン#create、スキーマの変更、挿入、更新、選択、およびドロップを使用して作成されます。このtemp #tableを使用する共通のプロシージャには複数のエントリポイントがあるため、共通のプロシージャを呼び出すために必要な列を設定する中央プロシージャがあります。そうでなければ、すべてのエントリポイントプロシージャで同じ#table定義を複製する必要があります。

プロセスは、複数のクライアントアプリケーションから頻繁に呼び出されます。一部のクライアントアプリケーションは、このプロセスを複数のスレッドから呼び出します。他の人は一度に1つずつ実行します。ホームオフィスが数千の店舗のデータを並行して処理し、同時に店舗も同じプロセスを実行する在庫/会計ソフトウェアを考えてください。したがって、ロックパーティショニングが有効になっているときにこれがまれな問題である場合、大規模な顧客データベースではそれほどまれではありません。

更新3-2012-12-19

別のお客様は、SQL Server 2012ビルド11.0.2100で同じ問題を抱えています。累積的な更新プログラムの説明には、この問題の修正に関する言及はありませんでした。調査中。

更新4-2013-02-13

Microsoftは、次のアップデートでこのバグの修正をリリースしました。


@AaronBertrand:いいえ、#tempテーブルキャッシングは必要ありません。それは同じ接続では十分に悪いことであり、プロセス間での再利用ははるかに少ないでしょう。.xdlファイルはなく、トレースフラグ1222情報のみがあります。
ポールウィリアムズ

これらの#tempテーブルを使い終わったら、明示的に削除します。
ポールウィリアムズ

2
.xdlファイルをどこかにキャプチャして投稿することをお勧めします。そうすれば、他の人がより詳しく見ることができます。
アーロンバートランド

2
ここでロックのパーティション分割が関係していることを確認できます。これらの投稿には、ロックパーティションに関連するデッドロックの分析に関する詳細が含まれています。 bit.ly/Ruzmym bit.ly/W7yuRK しかし、両方のセッションが同じObjectIDを投稿した理由はわかりません。
ロージPトーマス

@SQLKiwi問題をご覧いただきありがとうございます!ロックリソースのハッシュについては考えませんでした。オブジェクトID上にあることを考えると、そうではないと思いますが、私は推測しているだけです。お客様は数日間、デッドロックを報告してきました。私はたった1日分のデッドロックトレースを持っていますが、これは彼らが経験しているデッドロックだと思います。マイクロソフトでサポートチケットを開いて、解決に役立てています。詳細については、この質問を更新します。
ポールウィリアムズ

回答:



4

この問題に関してマイクロソフトとのケースを開きました。マイクロソフトは、このバグがSQL Server 2012にも影響することを確認しました。SQLServer 2012 Service Pack 2(この回答を書いている時点ではリリースされていません)で修正プログラムをリリースする予定です。

Microsoftがこのサービスパックをリリースするまで、SQL Server 2012ユーザーはトレースフラグ1229を介してロックパーティションを無効にすることで問題を回避できます。

この問題は、16以上のプロセッサを搭載したマシンにのみ適用されることに注意してください。

ロックパーティショニングの詳細

マイクロソフトのサポートに感謝します!彼らは非常に迅速で親切でした。

更新

このバグは、SQL Server 2012 SP 1のSQL Server 2012累積更新2で修正されています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.