Author

47 posts

Desempenho do Processador x Desempenho do SQL Server – Parte 3

Post 3/3. Este post é parte da série: Desempenho do Processador x Desempenho do SQL Server

São 7 horas da manhã, e recebo uma ligação da Equipe de BI, dizendo que todas as cargas estão 50% mais lentas. O caos se instaura na equipe, pois os relatórios do dia não estariam prontos…

Isso aconteceu depois de uma migração. A máquina antiga era virtual. A máquina nova? Física. Com configurações idênticas! Como pode? O mínimo, era ter desempenho igual, não inferior. O que aconteceu?

Vou contar melhor essa história…


Bem vindo de volta!

No último post desta série, você viu como uma redução de 50% no clock da CPU impactou diretamente no tempo das consultas de um SQL Server.

Se você ficou surpreso com isso, saiba que não tem nada de novo. Isso se dá por uma simples teoria matemática: velocidade e tempo são grandezas inversamente proporcionais. Se eu dobrar a velocidade, eu faço na metade do tempo. Do mesmo jeito que, se eu usar metade da velocidade, eu gasto o dobro do tempo.

E, foi exatamente isso que aconteceu no exemplo o post anterior: a velocidade da CPU diminui, e o tempo das instruções, e, consequentemente, da nossa query, aumentou.

Mas por que você se preocuparia com isso? Afinal, quem seria louco o suficiente para baixar a velocidade da CPU pelo gerenciamento de energia? E é aí que voltamos a nossa historinha…

Um caso real e inesquecível

Que absurdo é esse, onde, uma máquina física, idêntica a virtual (pra ser mais preciso, idêntica ao host da máquina virtual), é tão mais lenta?

Nós gastamos um bom tempo checando tudo, configurações da instância, bloqueios, disco, etc. Até que, tive a ideia de fazer um simples teste de CPU: Vou comparar quanto tempo levo pra executar uma quantidade de instruções na instância antiga e na nova. Como fazer isso no SQL Server? Um simples loop:

Este código SQL é  muito simples:

  1. A variável @i, começa em 10 milhões. O meu objetivo é decrementar ela até que chegue em zero. O processador vai ser utilizado basicamente para operações aritméticas… Que são simples e rápidas…
  2. Eu utilizo a variável @start para gravar a data e hora atuais, antes de começar o loop WHILE…
  3. Ao final do meu loop while, eu calculo quanto tempo se passou, subtraindo a data de agora, pelo valor gravado em @Start

Este é um código que vai gastar apenas CPU. Não tem disco, rede, memória, ou outra coisa significativa envolvida.  Mais de 99% do tempo desse script vai ser gasto executando instruções na CPU. Quando eu executei este script na máquina antiga, ele me retornou um tempo de 5 segundos. Quando executei na nova, variava de 7 a 8 segundos.

Comparando tempos de CPU usando T-SQL. O script demora aproximadamente 4 segundos para subtrair 10 milhões em uma CPU de 3.1 Ghz! Já em uma CPU de 1.39 Ghz, ele leva 10.5 segundo! 😯 😯 😯 😯

 

Pronto, tinha achado um norte. O próximo passo nesse caso, foi verificar se o problema estava dentro do SQL Server, ou era algo generalizado, no Sistema Operacional. Então, fiz a mesma versão desse script, em powershell:

E novamente, comparei o resultado com a máquina nova e antiga! Mesma situação. Agora excluí o SQL Server do problema. O script na máquina antiga (virtual) retornava um valor muito inferior ao da máquina nova(física). A partir daí, usei o CPU-Z (era um Windows Server 2008) e constatei que o clock do processador do servidor novo estava operando a 2.2 GHz, enquanto que o CPU-Z da máquina virtual, reportava 2.5 GHz. Uma diferença de apenas 300 MHz, foi suficiente para dar dor da cabeça no ambiente de BI!

Você pode estar se perguntando o porquê de apenas 300 MHz, causar 50% de lentidão no processo de carga e a razão é muito simples:

  • O processo de carga não envolve apenas uma única consulta. São várias consultas. Consultas de 2, 3, 15 minutos, subindo para 4, 6, 18 minutos, respectivamente. As consultas pequenas também.
  • A instância onde ocorria tudo isso, além de concorrer com um Analysis Service e Integration Services, que também estavam sendo impactados pelo problema, tinham outras queries em execução, de outros relatórios, e não somente do processo de carga.
  • Todo o sistema operacional lento, logo, gravações em disco mais lento, comunicação de rede mais lento. Toda a concorrência do processador estava maior, uma vez, que a CPU está mais lenta, tudo demora mais na CPU, e aí aumenta a espera por CPU

A rua é o processador, e os veículos são nossas queries e processos… Experimenta colocar todo mundo um pouco mais lento pra ver o caos que vira…

 

O problema foi resolvido depois que, comprovado para a equipe de infraestrutura que o problema era da máquina, eles abriram chamado no fabricante, que detectou uma atualização de BIOS. E aí resolveu tudo (depois de várias tentativas por parte deles, como mudar configuração da BIOS, colocar a máquina com 100% de energia, já que ela aceitava 4 cabos de força, e apenas dois estavam plugados, etc.). Isso levou meses, e tivemos que desfazer a migração até lá. Quando nos foi reportado que a máquina estava pronta, apenas repetir todos os testes, e dessa vez, os tempos estavam iguais. Prosseguimos com a migração, e tudo certo. O processo de carga estava até um pouco mais rápido!

Image result for gif claps velinhas

Epidemia

Alguns meses depois deste problema, um colega me procurou e me relatou sobre um problema de lentidão após um ambiente extremamente crítico migrar de SQL 2008 R2 para SQL 2014. Chegaram a cogitar problema com o novo CE… De novo, o problema era um clock mais lento nas novas máquinas.

Ainda, muito antes de fazer parte do #TeamFabricioLima, o Fabrício me contou sobre o mesmo sintoma: novo servidor e tudo mais lento, e novamente, achamos problema com velocidade do clock.

Depois disso, encontrei muitos problemas como este, até em ambiente com outros bancos de dados… Com outras tecnologias… Me dei a liberdade de batizar isso de epidemia de ClockLentopsia.

Image result for gif vergonha alheia

A questão aqui é: Quantas vezes você parou pra validar o desempenho do seu processador? Você coloca isso no seu checklist de migração? Um conceito extremamente simples, que pode estar afetando seu ambiente.

Você percebeu no post anterior que uma query de 266 ms foi para mais de 500ms… Na casa dos milissegundos, ninguém percebe isso. Você já pode ter migrado um ambiente sem nem sequer notar que a CPU ficou mais lenta… Mas as queries podem ter saído de 50ms, para 100ms…

Mas aqui vai um conselho: Sempre verifica! Sempre valide! Até agora nesta série, você já aprendeu a usar duas ferramentas e tem dois scripts para validar. Coloque isso nos seus processos e durma feliz após as migrações críticas! Não tô dizendo que este sempre vai ser o problema, mas se for, você vai pegá-lo, antes que o inverso aconteça.

 

E se ainda você precisar de uma força para avaliar casos estranhos como estes, pode chamar a gente do #TeamFabricioLima que vamos até  os bit e bytes da sua CPU para achar o problema!

E você acha que acabou por aqui? Nada disso! Ainda tem muito o que falar sobre CPU!

No próximo post quero explicar a você uma diferença muito importante sobre o tempo de CPU e o percentual de CPU. Você vai passar a analisar as queries de outra forma! Até lá!

 

 

Desempenho do Processador x Desempenho do SQL Server – Parte 2

Post 2/3. Este post é parte da série: Desempenho do Processador x Desempenho do SQL Server

Olá caro leitor,

Esta é mais uma série de posts, e o assunto da vez é o desempenho do processador. No post anterior, vimos alguns conceitos básicos sobre velocidade da CPU. Agora vamos aplicar um pouco desses conceitos no SQL Server e observar alguns efeitos na prática.

Revisão:

  • Clock = dispositivo da CPU que liga e desliga em uma certa frequência (clock tick)
    • 1 Hertz = 1 vez por segundo
    • 1 KHz = Mil vezes por segundo
    • 1 MHz = Um  milhão de vezes por segundo
    • 1 GHz = 1 bilhão de vezes por segundo
  • Cada instrução leva X clocks ticks. Quanto mais rápido um processodor, mais rápida as instruções executam.

 

No caso de código SQL, uma infinidade de instruções são executadas, não somente para acessar os dados e fazer alguma operação em cima deles, mas também para:

  • verificar locks/latches
  • checar permissões
  • acionar disco, rede

São centenas de milhares de instruções sendo executadas por uma simples consulta SQL. Isto significa que qualquer alteração na velocidade da CPU, a query poderá ser impactada (para melhor, ou para pior).

Vamos fazer um simples exercício, baseado numa query simples como esta:

  • Imagine que a query acima gaste  10 instruções. E pra simplificar mais ainda, imagine que cada instrução desta gaste apenas 1 tick do nosso clock.
  • Imagine que essa query execute num incrível processador de 100 Hertz (isso mesmo, cem ticks por segundo)
  • Primeiro, calcule o tempo de um tick:
    • 1 tick = 1000ms/100
    • 10ms = Cada tick nesse nosso incrível processador gasta apenas 10 ms!
  • Ora, se nossa query gasta 10 ticks, e cada tick tem 10ms, então ela vai gastar 100 ms de CPU (10ms * 10 ticks = 100 ms).
  • NOTA MUITO IMPORTANTE:  Aqui é só uma simulação de um gasto SOMENTE de CPU. Não estou colocando outras variáveis, como disco, memória, rede, etc.

Um exemplo de uma query que gasta um número X de instruções. O tempo total de CPU, vai sempre depender da velocidade do processador

Quando otimizamos essa query, criando um índice, ou adicionando mais filtros, estamos reduzindo o número de instruções (ou escolhendo instruções que gastam menos tempo).  E por isso o tempo de CPU diminui. Por exemplo, imagine que após criar um índice, causando a leitura de menos dados, a query execute com  apenas 4 instruções, então o tempo, no processador de mesma velocidade, será de 40ms ( 10ms * 4 ticks).

Simulando a otimização da query. Por exemplo, saindo de um clustered index scan, para um index scan, poderia causar a execução de menos instruções, devido a um menor número de páginas, menos colunas, etc. Tudo isso impacta na quantidade de instruções no final.

Simples, não?

Velocidade do Processador na prática

Vamos fazer o seguinte: Vamos brincar com nosso processador e observar como a velocidade do mesmo impacta em nossas consultas.

Os processadores mais modernos permitem alterar sua velocidade dinamicamente para poupar energia. Um clock que opera a 2.5 GHz gasta mais energia do que o mesmo clock operando a somente 100 MHz. Geralmente, os sistemas operacionais nos fornecem várias opções de controlar o gerenciamento de energia do processador.

Vamos criar um simples banco de dados com uma tabela grande e alguma quantidade considerável de registros:

  • Este código simplesmente cria um banco novo, uma tabela neste banco e insere alguns registros aleatórios.
  • Eu faço CROSS JOINs entre várias instâncias da view “sys.objects” apenas para gerar um grande número de registros.
  • O abs(CHECKSUM(newid())) gera um número aleatório para cada linha.

Antes de executar alguma query, vamos garantir que nosso computador irá operar no seu potencial máximo:

  1. Procure as opções de energia do seu computador. Você pode digitar powercfg.cpl no menu iniciar.
  2. Irá abrir tela tela semelhante a esta:

  3. Clique em “Alterar configurações do plano”, no respectivo plano que está marcando com a bolinha preta (No meu caso, o plano se chama “Dell”).
  4. Na próxima tela, cliquem em “Alterar configurações de energia avançadas”:

  5. Na janela que abrir, procure por “gerenciamento de energia do processador”:
  6. Altere o valor de mínimo para 100. Certifique-se que o máximo esteja em 100%, caso contrário, ajuste também. Se você está usando notebook, mas ele está usando a bateria como fonte de energia, então faça as alterações na opção “Na Bateria”. Se quiser garantir, pode alterar a configuração tanto para bateria, quanto para tomada. Memorize os valores que estavam antes para voltar a configuração original depois, ok?
  7. Pronto, clique em Aplicar, depois ok.
  8. Agora observe no Gerenciador de Tarefas (caso utilize um gerenciador de tarefas de uma versão anterior ao 2012 do Windows, você pode baixar a ferramenta CPU-Z):

  9. A velocidade deverá ficar sempre maior ou igual ao “velocidade base”.

O quê esta opção fez? Nós apenas solicitamos que o nosso processador sempre trabalhe no máximo de velocidade possível. Com isso,  mais energia será gasta, porém, nosso processador nunca irá baixar a velocidade. No meu caso, meu processador consegue trabalhar em 3.1 GHz (3 bilhões de ticks por segundo).

Esse percentual de CPU que você configurou NÃO é o mesmo percentual de CPU reportado pela maioria das ferramentas de monitoramento, como o próprio gerenciador de tarefas, process explorer, perfmon, etc. Seu processador ainda poderá bater 100% de uso! Explicaremos melhor depois.

Pronto, acabamos de deixar o processador em seu desempenho máximo, vamos rodar uma consulta e observar o tempo de CPU. Utilize o seguinte comando para obter o tempo de CPU:

Agora, execute a seguinte query:

Na aba “Messages” observe o tempo da execução. Se você acabou de reiniciar a instância, execute novamente, para garantir que iremos fazer leitura somente de dados em memória. Você está interessado no valor da informação “Cpu Time”:

O primeiro grupo de informação é referente ao tempo de compilação/recompilação da query. Ele rodou abaixo de 1ms, e por isso exibe zero.

Já o segundo grupo, este sim nos interessa. Ele nos diz quanto de CPU a query gastou, através da informação “Cpu time”. Note que o valor é de 266ms.

Agora vamos reduzir o máximo do nosso processador pela metade, e observar o que acontece com nossa query. Acesse novamente o powercfg.cpl, e repita o procedimento:

  • Escolha alterar configuração do plano atual
  • Depois vá em alterar configurações de energia avançadas
  • Vá em gerenciamento de energia do processador
  • Coloque o mínimo e o máximo em 50% (lembre-se, se não estiver conectado na tomada, altere o da bateria).

Confirme no Gerenciador de tarefas, ou no CPU-Z, que a velocidade do clock diminuiu.

Diminuindo o clock do processador para 50% da sua velocidade. Não espere nunca uma redução de exatos 50%. Poderão sofrer algumas pequenas variações, porque isso depende do processador, do sistema operacional, etc.

 

Note que a velocidade do clock de meu processador caiu para 1.29 Ghz

Perceba que agora minha CPU estará rodando com cerca de metade da força. Como será que isso vai impactar no tempo da minha query?

Minha query saiu de 266ms para 594ms. Um aumento de 123% no consumo de CPU, e tempo da query.

Muito interessante como a velocidade da CPU pode afetar o tempo de execução das consultas. No próximo post vou explicar melhor o que aconteceu e falaremos de outras coisas mais!

Até lá!

Desempenho do Processador x Desempenho do SQL Server – Parte 1

Post 1/3. Este post é parte da série: Desempenho do Processador x Desempenho do SQL Server

A CPU é um dos recursos mais fundamentais, senão o mais fundamental, de um computador. É ali que todos os recursos de um computador são coordenados.  Este é o primeiro post de mais uma série onde vamos aprender conceitos básicos sobre velocidade de CPU e como podemos usar isso para análises simples em consultas de um SQL Server.

Hoje vamos obter um conhecimento fundamental sobre CPU antes de partir para o SQL Server!

Clocks e Hertz

Você já deve estar cansado de ver os termos “2.5 GHz”, “3.0 GHz”, etc. Mas você sabe, de fato, o que eles significam? Embora eu necessite de uma série exclusiva somente para este assunto, é necessário um simples entendimento:

  • Quanto maior este valor, mais rápido as instruções são executadas

Basicamente,  toda CPU tem um “clock“, que é um dispositivo que “liga” e “desliga”  X vezes por segundo.  Cada vez que esse dispositivo “liga”, nós dizemos que houve um “clock tick”, ou, apenas “tick”.  Esse é o valor que você vê nas especificações:

  • Um processador de 1 Hertz (1 Hz) significa que seu clock liga e delisga 1 vez por segundo (1 tick por segundo)
  • 1000 Hertz, são 1000 ticks por segundo. Aqui se pode aplicar as unidades do SI (Sistema Internacional de Medidas) : 1000 Hertz = 1 KHz (Kilo Hertz)
  • 1 milhão de Hertz, ou 1 MHz, significa 1 milhão de ticks por segundo.
  • 2.5 GHz (Giga Hertz) , significa 2.5 x  1 bilhão (Giga), que equivale a 2 bilhões e 500 milhões de vezes por segundo

Uma vez que a velocidade do processador dita quantos ticks temos em um segundo, então, podemos calcular quanto tempo dura um tick. Pode parecer confuso o que eu vou dizer agora, mas é apenas uma questão de lógica, pare e reflita.

Cada tick do clock, leva um tempo fixo. Nenhum tick leva mais ou menos tempo que o outro tick. Então, quanto mais lento o processador,  maior será o tempo de 1 tick.  Pense em números pequenos, que vai ajudar:

  • Em um processador de 2 Hertz (dois ticks por segundo), cada tick leva 500 ms (0.5 segundos)
  • Em um processador de 4 Hertz (quatro ticks por segundo), cada tick leva 250 ms ( 0.250 segundos)
  • Percebeu a fórmula mágica pra calcular o tempo de 1 tick?
    • Tempo de um Tick, em Milssegundos = 1000ms/<Número Hertz>
    • 2.5 MHz = 1000/2500000 = 0,0004 ms (1 tick = 400 nanossegundos)
    • 1.0 MHz = 1000/1000000 = 0,001 (1 tick = 1000 nanossegundos)
    • 2.5 GHz  resulta num tick muuuuuuuuuuuuuuuuuuito pequeno! faça as contas você mesmo!

 

As instruções que um processador pode executar, gastam N ticks (isso porque, grosseiramente falando, cada vez que o clock liga, ele aciona certos circuitos e sincroniza o processador com a placa mãe, etc.) . Isso vai depender de cada processador, e de cada instrução.  A velocidade da CPU dita o tempo de cada instrução:

Em uma cpu fictícia de 2 Hz, uma instrução que gastasse 1 tick, demoraria 500 ms para executar. Uma instrução que custasse dois ticks, levaria 1 segundo. E assim por diante…

Por que saber de tudo isso é importante?

Quando você traz esses conceitos para o sistema operacional, e para os seus programas, como o SQL server, fica fácil entender certas coisas. No caso de uma simples consulta SQL, você tem centenas de milhares de instruções executando.  Por exemplo, uma query como esta:

 

Pode causar a execução de milhares de instruções. Vai depender da quantidade de registros, tamanho, concorrência, etc. A questão é que, no final das contas, tudo se resume ao que a CPU irá fazer, e entender a velocidade do seu processador vai te ajudar a compreender certos “fenômenos” e até planejar melhor seu ambiente. Imagine como esta query seria afetada se o tempo de cada instrução dobrasse…

No próximo  post vou mostrar todos estes conceito na prática, quando você executa uma query no SQL Server!

Até lá!

UPDATE: Obrigado ao Luiz Vitor pelas indicações de correção no texto!
UPDATE 2: Muito obrigado José Diz pelas dicas, principalmente sobre o sistema internacional de medidas!

Conhecendo o Processo do SQL Server no Windows e Linux – Parte 3

Post 3/3. Este post é parte da série: Conhecendo o Processo do SQL Server

Olá! Este é mais um post da série de post sobre o processo do SQL Server no Windows e Linux.

Nas duas primeiras partes, mostramos alguns conceitos importantes, como por exemplo, o que é um processo e o que é um thread. Você também aprendeu algumas ferramentas muito úteis para monitorar e obter mais informações de processos no Windows. Ainda, mostramos como podemos aplicar todos esses conceitos para obter informações úteis sobre uma instância SQL Server, como o usuário que está executando, privilégios, etc.

Hoje vamos focar tudo o que vimos e aprendemos, no Linux. O SQL Server no Linux é mais que uma realidade, então, nada mais justo do que aprender todos estes conceitos e ferramentas, também neste ambiente. O post assume que o leitor já possui uma experiência básica com Linux, conseguindo abrir um terminal ou uma sessão ssh, e digitar comandos. Se você não possui esta experiência, mas possui alguma experiência com powershell, você não terá dificuldades em compreender os exemplos.

O “Gerenciador de Tarefas”

A esta altura, você já percebeu o  Gerenciador de Tarefas do Windows é, na verdade, um “Gerenciador de Processos”. Ele te dá uma lista contendo cada processo que existe no Windows com diversas informações sobre cada um deles. Há o “process explorer” e o “Get-Process”, do powershell, também. No Linux, assim como no Windows, possuímos diversas ferramentas que nos fornecem as mesmas informações, umas com mais detalhes, outras com menos.

Por exemplo, você pode usar o comando “ps” para encontrar a linha de comando usada para iniciar o SQL Server:

Note que há dois processos. São duas instâncias? Não. No Linux, o sql server inicia um processo conhecido como “watchdog”,e este por sua vez é quem inicia um segundo processo que irá atuar como uma instância SQL como a conhecemos. Como pode notar, ambos usam o mesmo executável.  O primeiro processo fica monitorando o segundo, e em caso de falhas, irá gerar os dumps para análise. No Windows, é um recurso nativo do sistema operacional quem faz esse trabalho. Este artigo do Bob Dorr, detalha.

Você pode usar o seguinte comando para exibir o PID do processo, o usuário e a linha de comando usada:

Um exemplo:

No exemplo acima, o processo 25526 foi iniciado pelo processo 1 (PPID  = parent pid, ou, pid pai). O processo 1 (init) é semelhante ao processo System e wininit.exe do Windows, que são os responsáveis por iniciar os serviços. Então, podemos dizer que o processo 25526  é o “watchdog”, pois ele foi o primeiro processo com o executável do SQL Sever a ser iniciado. A linha seguinte, demonstra que o respectivo processo, de PID 25531, é filho de 25526 (o  watchdog), então, este é a instância SQL (é este processo, por exemplo, quem escuta na porta 1433, e processa os comandos SQL que chegam).

O comando “htop” pode ser uma alternativa interessante ao comando “ps”. Usando a tecla F5, você consegue trocar a exibição entre uma árvore de processos e uma lista ordenada:

Aqui, a coluna “PID” é auto explicativa. Ela contém o PID do processo, conceito que você já aprendeu no post anterior. É a mesma coisa. A coluna “User” informa qual o usuário sob o qual o processo está executando. A mesma informação está disponível tanto no Gerenciador de Tarefas e no Process Explorer. No powershell é necessário um script mais elaborado para obtê-la.

No Windows, você consegue ver essa relação de processo pai e processo filho melhor com o Process Explorer. Aqui está um exemplo no Windows:

Note que no Windows, não temos um outro processo pai chamado sqlservr.exe. O sqlservr.exe é filho de “services.exe”, pois eu o iniciei através de um serviço do Windows. Entretanto, ao executar um xp_cmdshell ‘ping www.microsoft.com’, podemos ver claramente processos filhos do SQL Server sendo criados. O Process Explorer demonstra que cmd.exe é filho de sqlservr.exe. E PING.EXE é filho de cmd.exe

 

Onde estão os argumentos? No caso do SQL Server no Linux, todos os parâmetros default vem do registro (na verdade, uma implementação parecida, para o Linux):

Assim, como no Windows, ainda é possível usar os parâmetros em linha de comando:

A primeira linha é o comando sudo. Da maneira em que foi executado na imagem, ele faz com que mudemos o usuário atual. O nome do usuário é “mssql”, criado por padrão na instalação do SQL. Na próxima linha, eu apenas inicio o executável do SQL Server, com o parâmetro “-e”, alterando o local do Error Log, semelhante como fizemos no Windows. A razão pelo qual eu mudei de usuário é apenas para evitar problemas de permissão quando eu iniciar o serviço normalmente usando o gerenciador de serviço (systemctl). Eu recomendo que não faça isso, principalmente em ambiente de produção, pois pode vir a ter seu serviço inoperável. Mas, se o fizer, e tiver problemas, tente restabelecer as permissões, desta maneira:

Aqui está o processo, usando o comando “ps”, como mostrado anteriormente:

Note que o processo é filho do processo 23892. Utilizando o comando ps, podemos observar quem é:

bash é um programa que atua como um shell no Linux, semalhante ao que o cmd, ou mesmo o powershell, é no Windows. Ele é responsável por captar e exibir a saída de comandos fornecidos no terminal. Quando eu iniciei o SQL Server na linha de comando do Linux, foi o bash da minha sessão quem o fez. Por isso, ele é o pai.

 

No Windows você também consegue iniciar o serviço do SQL Server na linha de comando. Basta mandar executar o arquivo sqlservr.exe e passar os devidos parâmetros:

Neste exemplo, eu parei o serviço do SQL, usando o Configuration Manager, e executei esta linha de comando:

Quando eu iniciei o sqlservr.exe, o usuário com o qual eu abrir o prompt é o usuário quem vai rodar esse processo. Sendo assim, todas os recursos do Sistema Operacional que minha instância precisar, estarão sujeitos a esse usuário. Note que não é o mesmo usuário que eu configurei lá “Configuration Manager”. Aquele é o usuário que será usado quando o sql for iniciado por lá (ou pelo gerenciador de serviços).

Note que, como no Linux, o processo agora é filho do “cmd.exe” (semelhante ao bash’).

No Linux, é o mesmo caso, porém, eu apenas optei por utilizar o mesmo usuário configurado nas definições do serviço. No caso do Windows, os efeitos de ser fazer isso não são tão graves como no Linux, mas ainda sim, não recomendo que faça isso em um ambiente operacional, pois poderá ter os mesmos problemas.

Como o sqlservr.exe é uma “ConsoleApplication”, ele começou a gerar a saída na tela, além do errorlog. Isso acontece nas versões para ambos os sistemas operacionais.


Bom, há muito o que falar sobre processos. Esta foi uma introdução cujo o objetivo é mostrar como ambos os sistemas operacionais fornecem a mesma visão. Porém, apesar das informações simples, elas são poderosas armas em situações de análises. As vezes, os simples fato de olhar o usuário com o qual o processo está rodando, pode te ajudar a perceber um problema devido a permissões de acesso.

Há ainda uma série de ferramentas poderosíssimas, como o Process Monitor, ou o strace, que ajudam a compreender tudo o que um processo está fazendo. Conhecer o que são os processos e seus conceitos mais simples, ajudam a melhor utilizar essas ferramentas. E em algum momento iremos dedicar atenção a elas aqui no blog!

Aqui estão algumas fontes e referências do assunto de hoje:

Conhecendo o Processo do SQL Server no Windows e Linux – Parte 2

Post 2/3. Este post é parte da série: Conhecendo o Processo do SQL Server

No último post da série vimos alguns conceitos básicos sobre processos e threads, e também usamos algumas ferramentas no Windows para obter mais informações sobre o executável de um processo do SQL Server. Hoje vamos abordar mais alguns conceitos importantes e ver como podem ser úteis na prática!

O Executável do SQL Server

O executável do SQL Server é o sqlservr.exe. No Windows você o encontra em:

<ProgramFiles>\Microsoft SQL Server\<Versao>.<NomeInstancia>\MSSQL\Binn

No Linux, ele fica em:

/opt/mssql/bin/sqlservr (sem extensão).

Talvez você nunca tenha precisado interagir diretamente com o executável do SQL Server porque você sempre iniciou ele através de um serviço. Em palavras simples, um serviço está fazendo a mesma coisa que você: pedindo ao sistema operacional que inicie a execução de um arquivo. Mas, no final das contas, ele é apenas um processo. Você pode confirmar isso usando ferramentas do seu sistema operacional que permitem monitorar e gerenciar os processos, como:

Por exemplo, a seguinte imagem demonstra dois processos, cada um referente a uma instância que iniciei através do Configuration Manager:

No Gerenciador de Tarefas do Windows a partir da versão 2012/8, você encontra essas informações na aba “Detalhes” (ou “details”), Há uma linha para cada processo existente no seu sistema operacional. Se há mais de uma instância SQL Server em execução, cada instância irá ser executada em seu próprio processo. O SQL Server Agent também é outro processo, e que usa um executável diferente do SQL:

Assim como o SQL Browser, Analysis Services, etc. Cada um tem seu próprio executável, e aceitam diferentes parâmetros.

O PID

Uma das informações mais importante sobre um processo é seu identificador, ou “Process ID” (PID). O PID é um número exclusivo que um processo ganha ao ser criado no sistema operacional. Nunca existirão dois processos com o mesmo ID em uma mesma sessão do sistema operacional (isto é, depois do  boot). Porém, o ID pode ser reusado quando seu respectivo processo encerrar. Raramente você verá o serviço do SQL Server usar o mesmo ID de processo entre seus restarts. Se ocorrer, é uma bela sorte!

A linha de comando

Repare na última coluna dessa imagem:

A coluna “Linha de comando” (você consegue habilitar mais colunas usando o botão direito do mouse no cabeçalho da tabela e selecionado a opção “Selecionar colunas”) mostra o caminho do executável que foi usado para iniciar o processo. Se você olhar na definição do serviço desta instância, poderá ver a mesma informação:

  1. Abra o gerenciador de serviços do Windows (digite “services.msc” no executar ou em um shell)
  2. Procure o serviço do SQL Server ( o nome é SQL Server (<NOME INSTANCIA>))
  3. Clique com o botão direito, e vá em propridades. Você verá uma imagem semelhante a esta:

Se você selecionar o texto sob “Caminho do Executável”, poderá ver o resto das informações.

Quando o Windows é solicitado para rodar esta linha de comando, seja diretamente pelo usuário, ou através de um serviço, ele cria um novo processo e aponta a primeira thread para o executável. Além disso, após o nome do executável há os parâmetros que devem ser passados ao processo. O Windows se encarrega de disponibilizar esses valores para a primeira thread do processo, e a partir daí ela faz o que quiser com eles.

No caso do sqlservr.exe, o parâmetro “-s” indica que o valor a seguir é um nome de instância. No caso do SQL Agent, é o parâmetro “-i” quem dita essa informação. (No post anterior há uma tabelinha contendo essas informações).

O usuário

Uma outra informação bastante útil vem da coluna “Nome de usuário”. Essa coluna indica com qual conta de usuário o processo está rodando. Todo processo, e, consequentemente, suas Threads, necessitam rodar sob alguma conta de usuário (geralmente, usamos o nome “conta de serviço”, pois estamos falando de uma conta de usuário que irá rodar um serviço. Mas é tudo a mesma coisa). Essa conta é usada pelo sistema operacional para validar o acesso a recursos do sistema operacional, como os arquivos. É comum observar erros de Access Denied a um arquivo ou diretório porque esta conta não tem as devidas permissões.

Uma outra situação comum, é ter que dar direitos específicos para que o SQL Server consiga realizar determinadas operações. Por exemplo, no Windows, o famoso Instant File Initialization é permitido somente se a conta com a qual o serviço está rodando possui um privilégio chamado SeManageVolumePrivilege. Há diversas formas de verificar se o processo tem esse privilégio habilitado e uma delas é usando o Process Explorer:

  1. Abra o process explorer como Administrador e procure o processo do SQL da instância desejada
  2. Clique com o botão direito no nome do processo e vá em “Properties”
  3. Vá na aba “Security”. No final da janela aberta, você verá a lista de privilégios com as quais o processo executa (que foi herdado do usuário associado com esse processo)

  A lista vem ordenada pelo nome do privilégio. Apesar da conta possuir alguns privilégios atribuídos, o de nosso interesse não está na lista. Após adicionar o privilégio, e reiniciar o serviço do SQL Server, conseguimos vê-lo:

Além disso, há uma série de outras informações a respeito do usuário, que podemos discutir melhor em um outro post.


Hoje conhecemos mais alguns conceitos interessantes pertinentes a um processo! No próximo post, vamos aplicar tudo o que vimos no Linux, já que até agora usamos somente Windows. E não deixe de praticar o que foi aprendido hoje:

  • Utilize as várias ferramentas disponíveis e compare os usuários com os quais o processo executa
  • Experimente retirar ou adicionar permissões da conta de serviço utilizada pelo SQL Server,e observe os efeitos na execução do serviço.
  • Reinicie o serviço do SQL Server e compare os PIDs
  • Powershell:  Explore cmdlet Get-Service ou a classe WMI win32_service para obter mais informações sobre um serviço do Windows
  • Pergunta de prova: Duas instâncias, em diferentes computadores, podem compartilhar o mesmo PID?