Recebemos um ticket do cliente que está relatando que às vezes obtém dados parciais da consulta. Na consulta de palavras simples, há uma consulta em exibição:
SELECT column1, column2, column3, column4, column5, column6 ... column50
from [dbo].[view]
Ver retorno de cerca de 3 milhões de registros. No servidor temos algumas regras que matam a consulta após 30 minutos de execução. Em situação normal esta consulta demora cerca de 5 minutos mas em casos de grande carga de trabalho esta consulta demora mais de 30 minutos. Nesta situação, o cliente pode obter dois tipos de erros:
• Uma consulta eliminada que retorna
“Msg 596, Level 21 Não é possível continuar a execução porque a sessão está no estado kill”
o que faz com que o nó de importação do aplicativo falhe e, portanto, é a situação “ideal”, porque eles não dependem de um fluxo de trabalho com conjunto de dados de entrada parcial.
• Um cenário relacionado ao processo de morte com um
“Msg 0, Level 20 Ocorreu um erro grave no comando atual”
que de uma perspectiva ODBC parece o mesmo que uma execução bem-sucedida e, portanto, terminamos com um conjunto de dados parcial - essa é a situação mais perigosa.
Você sabe talvez como evitar esse tipo de problema?
Você deixou de fora a parte mais importante desse segundo erro ( grifo meu):
Qualquer que seja o "nó de importação do aplicativo", ele precisa lidar com esse erro descartando o conjunto de resultados - e potencialmente desfazendo qualquer trabalho que tenha feito nos resultados que foram transmitidos até agora.
Qualquer outra solução seria uma solução alternativa e provavelmente insegura.
É importante observar que, enquanto
KILL
o spid pode causar esse erro, a leitura de páginas corrompidas do disco também pode. Se você vir esse erro inesperadamente, deverá executarDBCC CHECKDB
para garantir que seus dados estejam seguros.Eu escrevi um pequeno programa em C# que cria uma conexão ODBC (usando a
System.Data.OdbcConnection
classe) e inicia o streaming de resultados de uma consulta de longa duração:Cada vez que eu executava o programa, esperava alguns segundos e, em seguida, emitia um
KILL
comando no spid que estava executando minha consulta.Eu tentei isso com quatro drivers ODBC diferentes no meu computador e encontrei erros em cada um:
Os erros que obtive foram os seguintes:
Driver ODBC 17 para SQL Server
servidor SQL
SQL Server Native Client 11.0
SQL Server Native Client RDA 11.0
Igual ao anterior
Tudo isso para dizer, o aplicativo deve receber um erro na conexão que foi interrompida. E deve ter lógica para lidar com o fato de que os resultados podem não ter sido completos quando a consulta foi encerrada.
Tivemos um problema semelhante, exceto que nossa consulta inicial foi interrompida por uma interrupção na rede. Isso, por sua vez, corrompeu um de nossos índices que estava ocupado reconstruindo. O resultado? Finalmente descobrimos que, se você consultar uma determinada tabela, o SQL entrará no estado de interrupção. Eu reconstruí manualmente cada índice e testei a tabela após cada reconstrução. Finalmente encontrei o índice causando um problema, deletei-o, recriei-o e tudo correu bem a partir daí.
Os logs do SQL, entradas do visualizador de eventos, logs do SSRS, eram quase inúteis neste...