A Microsoft não tem o hábito de depreciar as coisas hoje em dia, mas quando o fazem, é por um motivo – e certamente não é porque eles querem tornar sua vida mais difícil. Pelo contrário, é quase sempre porque eles desenvolveram formas melhores e mais modernas de resolver esses mesmos problemas.
Mas os hábitos são difíceis de quebrar; pergunte-me como eu sei. Com demasiada frequência, vejo pessoas apegadas a uma maneira mais antiga de realizar alguma tarefa, mesmo que exista uma maneira melhor.
Gostaria de compartilhar alguns exemplos recentes que ajudam a ilustrar como o uso de recursos obsoletos do SQL Server continua a nos incomodar. Nesta primeira parte, quero falar sobre…
sysprocesses
A tabela do sistema
sys.sysprocesses
foi substituído no SQL Server 2005 por um conjunto de exibições de gerenciamento dinâmico (DMVs), principalmente sys.dm_exec_requests
, sys.dm_exec_sessions
e sys.dm_exec_connections
. A documentação oficial para sys.sysprocesses
avisa:Esta tabela de sistema do SQL Server 2000 está incluída como uma exibição para compatibilidade com versões anteriores. Recomendamos que você use as exibições de sistema atuais do SQL Server. Para encontrar a exibição ou exibições do sistema equivalentes, consulte Mapeamento de tabelas do sistema para exibições do sistema (Transact-SQL). Esse recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em novos trabalhos de desenvolvimento e planeje modificar os aplicativos que atualmente usam esse recurso.
Um exemplo recente
Recentemente, uma de nossas equipes estava investigando um problema de latência do leitor de log. Damos muita atenção à latência aqui, juntamente com quaisquer transações de longa duração, devido ao impacto downstream em tecnologias que usam o leitor de log – como grupos de disponibilidade e replicação transacional. Nossos primeiros avisos geralmente são vistos em um painel que traça a latência do leitor de log em relação à duração da transação (explicarei os pontos no tempo que rotulei
t0
e t1
Em breve):Eles determinaram, digamos, no tempo
t0
, que uma determinada sessão teve uma transação aberta bloqueando o processo do leitor de log. Eles primeiro verificaram a saída de DBCC INPUTBUFFER
, para tentar determinar o que essa sessão durou, mas os resultados simplesmente indicaram que eles também emitiram outros lotes durante a transação:event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Observe que
DBCC INPUTBUFFER
também tem um substituto mais capaz em versões modernas:sys.dm_exec_input_buffer
. E embora não tenha um aviso de descontinuação explícito, a documentação oficial do DBCC
comando tem este empurrão gentil:A partir do SQL Server 2014 (12.x) SP2, use sys.dm_exec_input_buffer para retornar informações sobre instruções enviadas a uma instância do SQL Server.
Depois de não obter nada do buffer de entrada, eles consultaram
sys.sysprocesses
:SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Os resultados foram igualmente inúteis, pelo menos em termos de determinar o que a sessão estava fazendo para manter sua transação aberta e interromper o leitor de log:
Estou destacando o
physical_io
coluna porque esse valor provocou uma discussão sobre se eles queriam ou não arriscar matar a sessão de sono. O pensamento era que, no caso de todas as E/S físicas serem escritas, matar a transação poderia resultar em uma reversão demorada e disruptiva – potencialmente piorando ainda mais o problema. Não vou colocar os tempos reais nisso, mas digamos que isso se transformou em uma conversa prolongada e deixou o sistema nesse estado a partir do momento t0
ao tempo t1
no gráfico acima. Por que isso é um problema
A questão neste caso específico é que eles gastaram esse tempo contemplando uma decisão baseada em informações incompletas. Essas E/S são leituras ou gravações? Se o usuário tiver uma transação aberta e apenas ler muitos dados, haverá muito menos impacto em reverter essa transação do que se ele alterado muitos dados. Então, em vez de
sys.sysprocesses
, vamos ver o que o DMV mais moderno, sys.dm_exec_sessions
, pode nos mostrar sobre esta sessão:SELECT session_id, [status], open_transaction_count, cpu_time, [reads], writes, logical_reads, last_request_start_time, last_request_end_time FROM sys.dm_exec_sessions WHERE session_id = 107;
Resultados:
Aqui vemos que
sys.dm_exec_sessions
divide a E/S física separadamente em leituras e gravações. Isso nos permite tomar uma decisão muito mais informada, muito mais rapidamente do que t1 - t0
, sobre o impacto de uma possível reversão. Se a E/S é toda escrita, e dependendo de quão alto é o número, podemos hesitar um pouco mais e talvez gastar o tempo tentando localizar o usuário (para que possamos bater em seus dedos ou perguntar por que eles têm uma transação aberta ). Se soubermos que é principalmente leituras, podemos nos inclinar para matar a sessão e forçar a transação a ser revertida. Claro,
sys.sysprocesses
tem dbid
e waittime
. Mas dbid
é pouco confiável e marginalmente útil de qualquer maneira, particularmente para consultas entre bancos de dados; há informações muito melhores em sys.dm_tran_locks
. Informações de espera (tempo e último tipo de espera) podem ser encontradas em sys.dm_exec_requests
, mas informações muito mais detalhadas são oferecidas em sys.dm_exec_session_wait_stats
(adicionado no SQL Server 2016). Uma desculpa que eu costumava ouvir muito era que sys.dm_exec_sessions
estava faltando open_tran
, mas open_transaction_count
foi adicionado novamente no SQL Server 2012. Portanto, há muito pouca razão para pensar em usar sys.sysprocesses
hoje. Se você quiser descobrir com que frequência
sys.sysprocesses
foi referenciado desde que o SQL Server foi reiniciado pela última vez, você pode executar esta consulta no DMV dos contadores de desempenho:SELECT instance_name, cntr_value FROM sys.dm_os_performance_counters WHERE [object_name] LIKE N'%:Deprecated Features%' AND instance_name = N'sysprocesses' ORDER BY cntr_value DESC;
Se você realmente deseja evitar dormir esta noite, ou apenas gosta de adicionar constantemente à lista de coisas com as quais se preocupa, remova o predicado de
instance_name
. Isso lhe dará uma ideia assustadora e de alto nível de quantas coisas suas instâncias estão executando e que você precisará alterar. Enquanto isso, faça o download de
sp_WhoIsActive
, o procedimento armazenado ultra útil de Adam Machanic para monitorar e solucionar problemas de processos do SQL Server em tempo real. Implementamos esse procedimento armazenado em todas as instâncias em nosso ambiente, e você também deve fazer isso, independentemente de quais outras ferramentas de monitoramento de ponta você também possa estar usando. Próxima vez
Na Parte 2, falarei um pouco sobre o SQL Server Profiler, um aplicativo que as pessoas usam mais por familiaridade do que qualquer outra coisa – sem perceber o quão perigoso pode ser.