2017-01-04 1 views
13

Если я расшифровал следующий тупиковый граф правильно, это выглядит как два процесса (SPID,: 216 и 209) принадлежит исключительное (X) замок на той же странице:SQL Server - Как одна и та же страница может быть исключительно (X) заблокирована двумя процессами?

The XDL <resource-list> показывает

<pagelock 
    fileid="1" 
    pageid="17410848" 
    dbid="21" 
    subresource="FULL" 
    objectname="33bd93e0-f5b2-43f6-93ca-56bbe6493e0c.dbo.sync_publishers2" 
    id="lock630b1d5380" 
    mode="X" 
    associatedObjectId="72057608416264192"> 
    <owner-list> 
     <owner 
      id="process90763f08c8" 
      mode="X" 
      requestType="wait" /> 
    </owner-list> 
    <waiter-list> 
     <waiter 
      id="process861129bc28" 
      mode="X" 
      requestType="wait" /> 
    </waiter-list> 
</pagelock> 

И немного дальше вниз

<pagelock 
    fileid="1" 
    pageid="17410848" 
    dbid="21" 
    subresource="FULL" 
    objectname="33bd93e0-f5b2-43f6-93ca-56bbe6493e0c.dbo.sync_publishers2" 
    id="lock630b1d5380" 
    mode="X" 
    associatedObjectId="72057608416264192"> 
    <owner-list> 
     <owner 
      id="process90763f04e8" 
      mode="X" /> 
    </owner-list> 
    <waiter-list> 
     <waiter 
      id="process90763f08c8" 
      mode="X" 
      requestType="wait" /> 
    </waiter-list> 
</pagelock> 

deadlock graph

Как это даже р ossible и что это значит?

Полное определение взаимоблокировки доступно здесь: http://pastebin.com/A4Te3Chx.

UPD: Я зарегистрировал товар в Microsoft Connect, чтобы попытаться собрать авторитетный ответ: https://connect.microsoft.com/SQLServer/Feedback/Details/3119334.

ответ

0

Эта проблема возникает из-за переменной таблицы @tmp, которую вы используете.

Когда вы используете переменную таблицы в своем запросе, план оптимизирован для одной строки, так что точка вашего запроса блокирует одну строку (тактично она потребовала блокировку страницы), но блокировка была увеличена и приобрела блокировку страницы, поэтому это тупик произошел.

+0

спасибо за ответ, но цель вопроса состоит в том, чтобы выяснить, как одна и та же страница может быть заблокирована только двумя различными процессами, как показывает график взаимоблокировки? Я здесь тоже не ищу тупика. –

+2

[блокировки строк никогда не переходят на блокировки страниц] (https://www.microsoftpressore.com/articles/article.aspx?p=2233327&seqNum=6) –

9

Это означает, что на этом замке была очередь.

Вы можете воспроизвести его следующим образом (запустите настройку и затем перейдите к 1. Затем у вас есть 15 секунд, чтобы запустить tran 2 и tran 3 последовательно в разных соединениях).

Установка

USE tempdb 

CREATE TABLE T 
    (
    X INT PRIMARY KEY WITH(ALLOW_ROW_LOCKS = OFF), 
    Filler AS CAST('A' AS CHAR(8000)) PERSISTED 
); 

INSERT INTO T VALUES (1), (2), (3); 

Tran 1

SET XACT_ABORT ON 
USE tempdb -- t1 

BEGIN TRAN 

UPDATE T SET X = X WHERE X = 1 

WAITFOR DELAY '00:00:15' 


--See what locks are granted just before the deadlock 
SELECT resource_description, 
     request_status, 
     request_session_id, 
     X 
FROM sys.dm_tran_locks tl 
     LEFT JOIN T WITH(NOLOCK) 
      ON sys.fn_PhysLocFormatter(T.%% physloc%%) = '(' + RTRIM(resource_description) + ':0)' 
WHERE resource_associated_entity_id = (SELECT partition_id 
             FROM sys.partitions 
             WHERE object_id = object_id('T')); 

RAISERROR ('',0,1) WITH NOWAIT; 

UPDATE T SET X = X WHERE X = 3 

WAITFOR DELAY '00:00:20' 
ROLLBACK 

Tran 2

SET XACT_ABORT ON 
USE tempdb -- t2 

BEGIN TRAN 

UPDATE T SET X = X WHERE X = 2 

UPDATE T SET X = X WHERE X = 1 

WAITFOR DELAY '00:00:20' 
ROLLBACK 

Tran 3

SET XACT_ABORT ON 

USE tempdb -- t3 
BEGIN TRAN 

UPDATE T SET X = X WHERE X = 3  

UPDATE T SET X = X WHERE X = 1 

ROLLBACK 

Результат запроса к tran_locks непосредственно перед запросом блокировки, что приведет к тупиковой ситуации показывает

+----------------------+----------------+--------------------+---+ 
| resource_description | request_status | request_session_id | X | 
+----------------------+----------------+--------------------+---+ 
| 4:416    | GRANT   |     61 | 1 | 
| 4:416    | WAIT   |     64 | 1 | 
| 4:416    | WAIT   |     65 | 1 | 
| 4:418    | GRANT   |     64 | 2 | 
| 4:419    | GRANT   |     65 | 3 | 
+----------------------+----------------+--------------------+---+ 

Тупик граф я получил следующим образом.

Хотя он говорит, что жертва тупика ожидала блокировки, принадлежащей tran 2, на самом деле это не так. Во время тупика замок принадлежал tran 1, а tran 2 был первым в очереди для него до tran 3.

enter image description here

Тупик график XML показывает, что это, как это имеет два узла для того же ресурса (стр 416), а также в одном «владельцем» имеет requestType="wait"

<resource-list> 
    <pagelock 
     fileid="4" 
     pageid="416" 
     dbid="2" 
     subresource="FULL" 
     objectname="tempdb.dbo.T" 
     id="lock2486d8c4380" 
     mode="X" 
     associatedObjectId="936748728230805504"> 
     <owner-list> 
      <owner 
       id="process2486ba0cca8" 
       mode="X" 
       requestType="wait" /> 
     </owner-list> 
     <waiter-list> 
      <waiter 
       id="process2485370c8c8" 
       mode="X" 
       requestType="wait" /> 
     </waiter-list> 
    </pagelock> 
    <pagelock 
     fileid="4" 
     pageid="416" 
     dbid="2" 
     subresource="FULL" 
     objectname="tempdb.dbo.T" 
     id="lock2486d8c4380" 
     mode="X" 
     associatedObjectId="936748728230805504"> 
     <owner-list> 
      <owner 
       id="process2485370c4e8" 
       mode="X" /> 
     </owner-list> 
     <waiter-list> 
      <waiter 
       id="process2486ba0cca8" 
       mode="X" 
       requestType="wait" /> 
     </waiter-list> 
    </pagelock> 
    <pagelock 
     fileid="4" 
     pageid="419" 
     dbid="2" 
     subresource="FULL" 
     objectname="tempdb.dbo.T" 
     id="lock248636ace80" 
     mode="X" 
     associatedObjectId="936748728230805504"> 
     <owner-list> 
      <owner 
       id="process2485370c8c8" 
       mode="X" /> 
     </owner-list> 
     <waiter-list> 
      <waiter 
       id="process2485370c4e8" 
       mode="X" 
       requestType="wait" /> 
     </waiter-list> 
    </pagelock> 
</resource-list> 
+0

, если мы рассматриваем транзакцию № 2 (SPID 64), она не должна быть собственностью и подождать две _различные_ страницы (соответствующие X = 1 и X = 2)? Почему выглядит так, как SPID 64 владеет и ждет X-блокировку на той же странице 416 ?! –

+0

@ EugeneD.Gubenkov во время тупиковой ситуации у него есть блокировка на стр. 418 для x = 2. Вы можете видеть это из вывода tran_locks. Этот ресурс не имеет отношения к тупиковой ситуации, поскольку ни одна из других транзакций не запрашивает его, поэтому не отображается в тупиковой диаграмме. Почему он выглядит так, как будто он владеет и ждет блокировку X на той же странице, потому что это очередь. T1 владеет ресурсом, T2 ждет его, и T3 также ждет его, но ему нужно ждать, пока T2 получит свой запрос и сначала отпустите блокировку. –

+0

Я правильно понял, что «владелец» не всегда означает владельца, иногда это означает официант? –

Смежные вопросы