Estamos vendo muitos desses deadlocks de threads paralelos intra-consulta em nosso ambiente de produção (SQL Server 2012 SP2 - sim... eu sei...), no entanto, ao analisar o XML de deadlock que foi capturado por meio de eventos estendidos, a lista de vítimas está vazia.
<victim-list />
O deadlock parece estar entre 4 threads, dois com o WaitType="e_waitPipeNewRow"
e dois com o WaitType="e_waitPipeGetRow"
.
<resource-list>
<exchangeEvent id="Pipe13904cb620" WaitType="e_waitPipeNewRow" nodeId="19">
<owner-list>
<owner id="process4649868" />
</owner-list>
<waiter-list>
<waiter id="process40eb498" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe30670d480" WaitType="e_waitPipeNewRow" nodeId="21">
<owner-list>
<owner id="process368ecf8" />
</owner-list>
<waiter-list>
<waiter id="process46a0cf8" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe13904cb4e0" WaitType="e_waitPipeGetRow" nodeId="19">
<owner-list>
<owner id="process40eb498" />
</owner-list>
<waiter-list>
<waiter id="process368ecf8" />
</waiter-list>
</exchangeEvent>
<exchangeEvent id="Pipe4a106e060" WaitType="e_waitPipeGetRow" nodeId="21">
<owner-list>
<owner id="process46a0cf8" />
</owner-list>
<waiter-list>
<waiter id="process4649868" />
</waiter-list>
</exchangeEvent>
</resource-list>
Então:
- A Lista de Vítimas está vazia
- O aplicativo que executa a consulta não apresenta erro e conclui a consulta
- Até onde podemos ver, não há nenhum problema óbvio, exceto que o gráfico é capturado
Portanto, isso é algo para se preocupar além do ruído?
Editar: Graças à resposta de Paul, posso ver onde o problema provavelmente ocorre e parece se resolver com o vazamento de tempdb.
Eu não ficaria surpreso se esta é a aparência do gráfico de deadlock quando um deadlock paralelo intra-consulta é resolvido por um derramamento de troca (portanto, não há vítima, exceto desempenho).
Você pode confirmar essa teoria capturando vazamentos de câmbio e combinando-os (ou não) com o impasse.
Gravar buffers de troca no tempdb para resolver um impasse não é o ideal. Procure eliminar sequências de operações de preservação de ordem no plano de execução (por exemplo, trocas de preservação de ordem alimentando uma junção de mesclagem paralela). A menos que não esteja causando um problema de desempenho perceptível e você tenha outras coisas com que se preocupar.
Fragmentação, não. Estatísticas desatualizadas: não em nenhum sentido específico que eu possa pensar, não. Claro que estatísticas não representativas raramente são uma coisa boa em geral.
A questão fundamental aqui é que o paralelismo funciona melhor quando há o menor número possível de dependências entre as threads; a ordenação preservada introduz dependências bastante desagradáveis. As coisas podem facilmente ficar complicadas, e a única maneira de limpar o impasse é derramar um monte de linhas mantidas em exchanges para tempdb .
Observação
Os deadlocks paralelos intraconsulta não geram mais gráficos xml quando o deadlock pode ser resolvido com um derramamento de troca, seguindo uma correção lançada para a atualização cumulativa 10 para SQL Server 2017 e atualização cumulativa 2 para SQL Server 2016 SP2.
Para distinguir esses impasses não críticos de "resolução automática por derramamento" de impasses mais importantes, algumas semânticas de pesquisa podem ser aplicadas à estrutura Xdl.
O SP a seguir não funcionará imediatamente, pois depende de ufn_ExtractSubstringsByPattern(), no entanto, esse método pode ser substituído por algo que retorne a contagem distinta diretamente.