Bom dia Galera, esse vai ser meu primeiro Post técnico do blog espero que gostem do assunto.
Bom essa semana estive automatizando alguns processos que eram feitos manualmente, para isso uma das etapas era descompactar um arquivo .RAR(Winrar) que continha dentro dele um Backup do SQL Server (.bak), para posteriormente fazer o seu Restore, o comando que eu estava executando era o seguinte:
exec xp_cmdshell ‘C:\”Program Files”\WinRAR\WinRAR.exe x G:\Arquivos\Arquivos.pat001.rar G:\Arquivos\’
Obs: XP_CMDSHELL me permite executar tarefas a nível de sistema operacional, tome cuidado com quem tem acesso a ele, pois ele executa no contexto de segurança da conta que esta vinculada a sua instancia do SQL Server.
O comando XP_CMDSHELL é executado de forma síncrona, ou seja a sessão no SQL Server só ira finalizar quando ela receber a resposta do SO(Sistema operacional), devido a isso a minha sessão no SQL Server fica no modo ‘Running’ aguardando um retorno, abaixo segue um DUMP da minha sessão.
USE MASTER GO DBCC STACKDUMP
Utilizando o DBCC STACKDUMP, ele gera três arquivos de Dump na pasta de LOG do SQL Server, abrindo o arquivo .TXT e procurando pela minha sessão (224), tenho algumas informações sobre ela.
Obs: O comando DBCC STACKDUMP é um comando não documentado pela Microsoft.
Bom chegado até aqui, minha sessão esta em execução, tudo OK certo ? Mas ela estava demorando muito então resolvi dar um KILL nela para aborta-la.
KILL 224
Ok, porém olhando para minha sessão através da DMV SYS.DM_EXEC_SESSIONS a minha sessão continua em modo ‘Running’ e processo continua rodando por um longo tempo, investigando na DMV SYS.DM_OS_WAITING_TASKS conseguimos ver que ela esta esperando a um bom tempo pelo Wait Type ‘PREEMPTIVE_OS_PIPEOPS’, vamos olhar novamente o Dump dessa sessão:
Bom o Dump tem informações diferentes agora, podemos ver que o campo ‘m_fkill’ esta sinalizado com o valor 1 agora, mas por que ela continua rodando ? por que o meu KILL não finalizou a sessão?
De forma bem resumida, o comando KILL na verdade não finaliza sua sessão ele apenas modifica esse Flag indicando que aquela sessão foi abortada e deixa que a própria sessão aborte a sua execução. Legal, mas a minha sessão esta flegada para ser abortada porque ela não finalizou ? Lembra que no inicio comentei que o comando XP_CMDSHELL me permite executar tarefas a nível de SO ?! Pois é, quando executamos o XP_CMDSHELL o SQLOS (Sistema operacional do SQL Server) passa a bola para o SO(Windows) e deixa que ele gerencie essa tarefa, sendo assim mesmo eu sinalizando para o SQL Server que aquela sessão foi abortada o SO não pode enxergar isso, devido a isso iremos esperar infinitamente a execução dessa sessão.
O Wait Type ‘PREEMPTIVE_OS_PIPEOPS’ seria a troca do modo de non-preemptive(Modo utilizado pelo SQLOS) para o modo preemptive(utilizado pelo SO), isso pode até virar um assunto para Posts futuros por isso não irei muito a fundo aqui.
Bom e agora ? Para finalizarmos nossa sessão precisamos identificar qual é a tarefa que esta aberta no SO referente a ela, para isso podemos utilizar a ferramenta “Process explorer” como abaixo:
Podemos ver abaixo do sqlserver.exe suas as tarefas que estão abertas no SO, no caso podemos finalizar a tarefa Winrar pelo próprio Process Explorer ou até mesmo pelo gerenciador de tarefas, iremos ver nossa sessão finalizando com a seguinte mensagem:
(1 row(s) affected) Msg 596, Level 21, State 1, Line 0 Cannot continue the execution because the session is in the kill state. Msg 0, Level 20, State 0, Line 0 A severe error occurred on the current command. The results, if any, should be discarded.
Bom galera é isso, no meu caso era meu comando para descompactar os arquivos que estava incorreto apenas corrigindo o caminho do arquivo o comando é executado com sucesso pelo SO e retornado para o SQL Server, não é um caso muito comum de ocorrer mas vale a dica para quem já passou por isso e quer entender melhor como funciona ou quem ainda vai passar por situações assim rs, espero que tenham gostado da explicação, qualquer duvida e criticas são bem vindas. Obrigado galera e até o próximo post.
Referencias:
Misterioso Comando KILL
PREEMPTIVE_OS_PIPEOPS
DBCC STACKDUMP
XP_CMDSHELL
PROCESS EXPLORER
Reginaldo Silva