Desafio: Comando KILL demorado (infinito)


A ideia desse post surgiu há 3 semanas durante um treinamento interno com a equipe de suporte. Desde então tivemos comemorações de Natal e Ano Novo. Espero que todos tenham aproveitado essa época. Aproveito para desejar a todos um ótimo ano de 2014!!!

O tópico de hoje é entender um conceito relacionado a threads e tarefas do SQL Server. Estava fazendo diagnósticos em um servidor e decidi usar o comando xp_cmdshell para procurar arquivos no sistema. Comecei assim:

image

Ótimo! Consegui o resultado esperado. O segundo passo foi executar um comando para procurar uma DLL específica, mas sem querer (por costume?) escrevi “notepad” na linha de comando. Eis que a query ficou executando e aquele círculo verde, rodando.

image

Minha reação foi executar o comando de KILL. Infelizmente nem isso foi capaz de cancelar a bobagem anterior. O comando xp_cmdshell ficou rodando e o comando KILL apresentou a mensagem de que estava tudo ok e logo seria completado (“… in progress. Estimated rollback completion: 0%. Estimated time ramaining 0 seconds”).

image

Esse é o desafio: seria possível executar comandos que rodam infinitamente no servidor e não podem ser cancelados pelo DBA?

O que fazer nesse caso?

Alguma explicação?

- Fabricio Catae

Comments (12)

  1. Laerte disse:

    Bom, acredito eu que quando fazemos um KILL o SQL Server tem que "avisar" ao cliente que ele esta sendo "morto" ou o processo sendo "killed".  Neste caso vejo que sim, como temos essa comunicação (acredito eu, na minha hipotese) entre o SQL e o cliente, podemos sim ter esse "hang"

    Para matar esse processo (notepad) no SQL, pare o no SO

    Abra o powershell  e

    get-process *notepad* | stop-process -force

    Isso vai matar todos os processos notepad e provavelmente vai liberar o SQL também.

  2. Leonardo Pedroso Costa disse:

    Nesse caso, eu pegaria o host_process_id na DMV abaixo e com o process explorer faria a localização do processo e mataria-o direto no S.O.:

    select host_process_id, * From sys.dm_exec_sessions where session_id = xxx

  3. Processos que dependem de uma interatividade do usuário tem este comportamento, como a calculadora, word, excel e assim por diante(Console). Serviços nativos (ou não) podem ser encerrados de outro modo além do kill.

    Para "matar" estes processos eu faria assim, via t-sql:

    exec xp_cmdshell 'tasklist' — mostra a lista dos processos que estao sendo executados, console ou serviço

    Uma das colunas apresentadas é o PID ( Identificacao). De posse desta identifição, utilizaria:

    xp_cmdshell 'tskill xxx' — onde xxx é o identificador do processo.

    Será que é isso???

  4. Já responderam??? Isso foi na mosca… powershell, task manager ou taskkill estão todas corretas.

    Agora vai uma segunda pergunta: por que o SQL Server não fez isso por você? Uma dica: dm_os_waiting_tasks.

  5. Laerte disse:

    Bom, andei  fazendo uns testes e com o select na dm_os_waiting_task o wait_type foi PREEMPTIVE_OS_PIPEOPS. Dando uma pesquisada no assunto seria porque neste caso da xp_cmdshell o processo é executado pelo SO e o SQL Server não tem controle sobre isso ? Algo como é aberto uma thread no SQL edo SQL abre no SO e o Kill nao tem como saber se o processo é externo ao SQL ?

  6. Luiz Mercante disse:

    Só não entendi o motivo do xp_cmdshell 'notepad' não ter sido concluído já que o SQL abriria um shell, executaria o comando notepad e receberia um retorno 0, ou seja, sucesso. Mas acredito que o processo notepad seria um processo filho do processo CMD que já é um processo filho do SQL, o que manteria a cadeia de processos aberta. Estou sem lab, se falei uma bobagem muito grande descartem… rs

  7. Laerte disse:

    Então..pensando no caso do Luiz, eu acredito que não obteve resposta do SO, porque chamando Notepad ele esta abrindo a GUI e não em modo de execução de comando e isso, partindo da ideia do Advaldo, precis a de interação  do usuario pra fechar. Por exemplo.

    Se eu abrir um processo powershell desta maneira :

    xp_cmdshell 'Powershell'

    Vai dar o mesmo problema, mas se eu abrir :

    xp_cmdshell 'Powershell.exe -command "get-process"'

    Não trava e traz o retorno, pois eu fiz em modo de execução de comando e tive um retorno do comando pelo SO e consequentemente mandando para o SQL

    Bom..estou apenas supondo..seila se to viajando na maionese tb hehehe

  8. Laerte disse:

    E o mais legal usando o Process explorer, podemos ver o sqlservr.exe e abaixo dele na cadeia o cmd e o notepad. Parto do mesma suposição, que por ser um processo externo ao SQL , ele não tem controle sobre ele. FAzendo uma analogia bem tusca, seria como uma modelagem com FK´s. Nao consigo dropar uma dado em uma tabela pai senao tirar a filha primeiro..no caso tenho que parar o processo no SO primeiro que seria o final da cadeia.

  9. Leivio disse:

    PREEMPTIVE_OS_PIPEOPS:

    PREEMPTIVE – chamada externa ao dominio do pool de tarefas do SQL Server. Ou seja muda a execução para o pre-emptive scheduling mode do host chamado.

    OS – chamada ao SO.

    PIPEOPS – comunicação inter processos utilizando PIPE(sqlservr.exe e cmd.exe). Em poucas palavras "Seria o redirecionamento da saída padrão de um programa para a entrada padrão de outro".

    Para a resposta: a chamada ao XP_CMDSHELL e sicrona o qual sempre tem uma halt a esperar.!

    Está correto?

  10. Se temos a cadeia no Process Explorer e não tivermos acesso ao taskill ou ao powershell, somente reiniciando o serviço para o notepad ser finalizado? Pelo jeito sim, correto?

  11. Laerte disse:

    Entao Advaldo, se nao tiver como parar o processo no SO, no meu ver sim.

  12. Os comentários do Laerte e do Leivio sobre o PREEMPTIVE_OS_PIPEOPS foram precisos. Luiz e Advaldo, vocês estão no caminho certo. Estou escrevendo um post para mostrar algo bem interessante com o Process Explorer.

Skip to main content