Mesmo lendo o blog de Bart Duncan sobre a leitura de impasses, ainda luto com isso. Incluí o XML de um impasse específico.
<?xml version="1.0" encoding="utf-8" ?>
- <deadlock>
- <victim-list>
<victimProcess id="process2fea928" />
</victim-list>
- <process-list>
- <process XDES="0x64e18e3a8" clientapp=".Net SqlClient Data Provider+TransactionalSqlSession" clientoption1="673316896" clientoption2="128056" currentdb="12" ecid="0" hostname="APPSVM7" hostpid="3208" id="process2fea928" isolationlevel="read uncommitted (1)" kpid="11776" lastattention="1900-01-01T00:00:00.240" lastbatchcompleted="2014-07-25T00:00:41.240" lastbatchstarted="2014-07-25T00:00:41.240" lasttranstarted="2014-07-25T00:00:41.230" lockMode="X" lockTimeout="4294967295" loginname="NTSERVERS\AX2012WEBPROD" logused="0" ownerId="9934810052" priority="0" sbid="0" schedulerid="16" spid="148" status="suspended" taskpriority="0" trancount="2" transactionname="MgdSqlSessionTran" waitresource="OBJECT: 12:277576027:10" waittime="4440" xactid="9934810052">
- <executionStack>
<frame line="25" procname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.proc_MSS_GetNextCrawlBatch" sqlhandle="0x03000c004f6ab01d5de1f8008ca2000001000000000000000000000000000000000000000000000000000000" stmtend="3504" stmtstart="3362">INSERT INTO MSSBatchHistory WITH(TABLOCKX)(CrawlID) VALUES (@CrawlID)</frame>
</executionStack>
<inputbuf>Proc [Database Id = 12 Object Id = 498100815]</inputbuf>
</process>
- <process XDES="0x4212ea3a8" clientapp="SharePoint[OWSTIMER][1][Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a]" clientoption1="673185824" clientoption2="128056" currentdb="12" ecid="0" hostname="APPSVM7" hostpid="9480" id="process403a188" isolationlevel="read committed (2)" kpid="14060" lastattention="1900-01-01T00:00:00.360" lastbatchcompleted="2014-07-25T00:00:40.360" lastbatchstarted="2014-07-25T00:00:40.360" lasttranstarted="2014-07-25T00:00:40.387" lockMode="Sch-M" lockTimeout="4294967295" loginname="NTSERVERS\AX2012WEBPROD" logused="168" ownerId="9934809243" priority="0" sbid="0" schedulerid="11" spid="170" status="suspended" taskpriority="-10" trancount="1" transactionname="ALTER INDEX" waitresource="OBJECT: 12:277576027:0" waittime="584" xactid="9934809243">
- <executionStack>
<frame line="1" procname="adhoc" sqlhandle="0x01000c00d14d6c19c006e5650400000000000000000000000000000000000000000000000000000000000000" stmtend="294" stmtstart="24">ALTER INDEX IX_MSSBatchHistory ON dbo.MSSBatchHistory REBUILD WITH (MAXDOP = 0, FILLFACTOR = 95, DATA_COMPRESSION = PAGE, ONLINE = ON)</frame>
<frame line="133" procname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.proc_MSS_DefragGathererIndexes" sqlhandle="0x03000c0018d2e62d8e07d6008ca2000001000000000000000000000000000000000000000000000000000000" stmtend="8816" stmtstart="8768">EXEC (@command)</frame>
</executionStack>
<inputbuf>Proc [Database Id = 12 Object Id = 770101784]</inputbuf>
</process>
</process-list>
- <resource-list>
- <objectlock associatedObjectId="277576027" dbid="12" id="lock4f20fdc00" lockPartition="10" mode="IS" objectname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.MSSBatchHistory" objid="277576027" subresource="FULL">
- <owner-list>
<owner id="process403a188" mode="IS" />
</owner-list>
- <waiter-list>
<waiter id="process2fea928" mode="X" requestType="wait" />
</waiter-list>
</objectlock>
- <objectlock associatedObjectId="277576027" dbid="12" id="lock4d7444c00" lockPartition="0" mode="X" objectname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.MSSBatchHistory" objid="277576027" subresource="FULL">
- <owner-list>
<owner id="process2fea928" mode="X" />
</owner-list>
- <waiter-list>
<waiter id="process403a188" mode="Sch-M" requestType="wait" />
</waiter-list>
</objectlock>
</resource-list>
</deadlock>
Parece que está ocorrendo o seguinte:
SPID 148 running the query (line 25 of proc Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.proc_MSS_GetNextCrawlBatch)
INSERT INTO MSSBatchHistory WITH(TABLOCKX)(CrawlID) VALUES (@CrawlID)
SPID170 running the query (line 1 of adhoc query)
INDEX IX_MSSBatchHistory ON dbo.MSSBatchHistory REBUILD WITH (MAXDOP = 0, FILLFACTOR = 95, DATA_COMPRESSION = PAGE, ONLINE = ON)
No entanto, no segundo operationStack há um segundo quadro, ou seja, este:
<frame line="133" procname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.proc_MSS_DefragGathererIndexes" sqlhandle="0x03000c0018d2e62d8e07d6008ca2000001000000000000000000000000000000000000000000000000000000" stmtend="8816" stmtstart="8768">EXEC (@command)</frame>
Como isso afeta o impasse? Este é outro processo que estava em execução no momento?
Obrigado
As seguintes informações foram encontradas para o processo da vítima no gráfico de impasse
Isolationlevel="read uncommitted (1)"
para o processo que foi encerrado como parte do impasse.lasttranstarted="2014-07-25T00:00:41.230"
lockMode="X"
procname="Search_Service_Application_CrawlStoreDB_3a7fefdbc44a48ef902a65ffb71c7d3a.dbo.proc_MSS_GetNextCrawlBatch"
A declaração problemática foi:
TRANCOUNT=2
, a transação aberta está láO outro processo que estava em impasse era:
Declaração:
isolationlevel="read committed (2)"
lockMode= "Sch-M"
Pontos:
O que é necessário usar a dica TABLOCK e também com o nível de isolamento de leitura não confirmada. Espero que você esteja ciente sobre o nível de isolamento de leitura não confirmado, não é aconselhável usar esse nível de isolamento em prod devido ao fato de que você pode ler dados não confirmados. Além disso, a dica TABLOCK bloqueará toda a tabela e, portanto, prejudicaria muito a simultaneidade.
Para piorar, você alterou a reconstrução do índice na tabela de histórico do MSSBatch , que levou o bloqueio de modificação do esquema (Sch-M), o que não permitiria que nenhuma operação ocorresse, pois a tabela inteira está bloqueada. Como em ambas as consultas a tabela era dbo.MSSBatchHistory, era altamente possível que ocorresse um impasse. Isso me parece a razão mais possível para o impasse
sugestão
Remova a dica do tablock e, se possível, leia o nível de isolamento não confirmado.
Por favor, não reconstrua o índice durante a hora de produção, a reconstrução do índice é classificada como operação de manutenção e deve ser feita durante a janela de manutenção ou quando a carga for relativamente menor. Mesmo que você tenha usado a reconstrução do índice ONLINE, são necessários bloqueios curtos na primeira fase da reconstrução do índice.
como esta é a manutenção padrão do SharePoint, é improvável que o OP seja responsável pelo código ou seja capaz de interferir nele. O que eles podem influenciar é o horário em que é executado.
dbo.proc_MSS_DefragGathererIndexes só deve ser executado manualmente e após o primeiro rastreamento, mas geralmente não. Você pode confirmar que este processo não foi automatizado como parte de uma tarefa de manutenção?
Recomendações:
se você puder influenciar o SQL que está sendo executado, considere diminuir a prioridade de deadlock no encadeamento de reconstrução do índice, se possível, por exemplo
DEFINIR DEADLOCK_PRIORITY BAIXO
se esse procedimento precisar ser executado, considere desativar o rastreamento primeiro como parte de uma pequena janela de manutenção.
O SQL 2014 tem um recurso muito bom chamado Managed Lock Priority (MLP), que infelizmente não será útil para você, mas pode ser para usuários futuros.