Eu tenho ensinado e escrito sobre erros comuns do SQL Server por muitos anos. Eu escrevi um blog sobre isso anos atrás também, no entanto, com o passar do tempo, a orientação mudou um pouco. Este artigo expandirá meu artigo anterior e apontará como eles se aplicam ao SQL Server, ao Banco de Dados SQL do Azure e à Instância Gerenciada do SQL do Azure.
Por muitos anos, encontrei usuários cometendo os mesmos erros. Eu os chamo de erros, no entanto, na maioria dos casos, são apenas coisas que não estão sendo feitas corretamente porque as pessoas que gerenciam o meio ambiente não sabem melhor. Aqui estão alguns dos itens mais críticos que qualquer pessoa que esteja instalando e dando suporte ao SQL Server deve conhecer:
- Cópias de segurança
- DBCC CHECKDB
- Configurações de memória
- Estatísticas
- Manutenção do índice
- MAXDOP e limite de custo para paralelismo
- Alertas do SQL Server Agent
Backups
Eu sempre verifico os backups primeiro quando olho para um novo sistema. Ter backups adequados para atender aos objetivos de recuperação é fundamental. A perda de dados pode ser prejudicial para uma organização. Ao analisar os backups, verifico o modelo de recuperação e o histórico atual de backups para cada banco de dados. Eu costumo encontrar uma combinação do seguinte:
- Nenhum backup – nenhum registro de qualquer backup para o banco de dados
- Backups ausentes – nenhum backup de log para um banco de dados usando o modelo de recuperação completa
- Nenhum backup recente – o último backup tinha semanas/meses/anos
Backups mal configurados são prejudiciais para uma organização quando surge uma situação de recuperação. Trabalhar e ter que dizer aos clientes que eles perderam dados nunca é divertido ou fácil. Ter backups adequados para atender aos SLAs deve ser a principal prioridade de qualquer organização, além de garantir que haja cópias desses backups armazenadas em um local secundário externo.
Essa situação se aplica ao SQL Server e IaaS locais. O Banco de Dados SQL do Azure e a Instância Gerenciada do Azure têm backups gerenciados.
DBCC CHECKDB
A corrupção do banco de dados acontece infelizmente. Sem verificar regularmente a corrupção, os clientes podem se encontrar em uma situação ruim por não ter backups para recuperar quando essa corrupção afetar os dados físicos. Para verificar se há corrupção, o DBCC CHECKDB deve ser executado em cada banco de dados regularmente. O que eu acho é muito semelhante aos backups:
- Nenhum DBCC CHECKDB foi executado
- DBCC CHECKDBs sendo executados apenas em bancos de dados selecionados
- DBCC CHECKDBs realizados pela última vez meses ou anos atrás
O pior caso é um relatório de trabalho agendado com falha de DBCC CHECKDBs
Nunca é agradável encontrar corrupção ou ter um cliente entrando em contato com um problema de corrupção quando a corrupção é um heap ou índice clusterizado e não há backups antes da ocorrência da corrupção. Nesses casos, a corrupção são os dados reais e iniciar a restauração antes da corrupção é, na maioria dos casos, a única opção. Nos casos em que a corrupção é um índice não clusterizado, a reconstrução do índice é a correção.
Em algumas situações, tive que trabalhar com clientes que têm corrupção desagradável sem backups adequados, onde consegui criar scripts no banco de dados e copiar manualmente todos os dados utilizáveis em um banco de dados recém-criado. Essas situações dispendiosas podem ser facilmente evitadas executando o DBCC CHECKDB e mantendo a retenção de backup adequada.
Aconselho os clientes a executarem DBCC CHECKDB localmente, IaaS, Banco de Dados SQL do Azure e Instância Gerenciada de SQL do Azure. O Azure faz um ótimo trabalho verificando a corrupção física; no entanto, sinto que os consumidores precisam verificar se há corrupção lógica.
Configurações de memória
Uma instalação padrão do Microsoft SQL Server tem o valor mínimo de memória definido como 0 e o valor máximo de memória do servidor definido como 2147483647 MB, que é 2 Petabytes. Antes do SQL Server 2012, o valor máximo de memória do servidor aplicava-se apenas ao bufferpool, portanto, os clientes precisavam limitar a quantidade de memória que o bufferpool poderia usar para economizar memória para o sistema operacional e outros processos. O SQL Server 2012 introduziu uma regravação do gerenciador de memória para que o valor máximo de memória do servidor se aplique a todas as alocações de memória do SQL Server.
É altamente recomendável definir um valor máximo para sua instância do SQL Server. Jonathan Kehayias escreveu uma postagem no blog Quanta memória meu SQL Server realmente precisa, com uma fórmula que ajuda a estabelecer a linha de base para o valor máximo de memória. Em casos de SQL Server compartilhado, recomendo que meus clientes definam o valor mínimo para 30% da memória do servidor.
Em situações com várias instâncias ou onde o servidor é usado para SQL Server, SSIS, SSAS ou SSRS, você precisa avaliar quanta memória esses outros sistemas precisam e reduzir o valor máximo de memória do servidor para permitir memória adequada para o SO e os outros Serviços.
Esse problema é válido para local, IaaS e parcialmente para instância gerenciada de SQL do Azure. A instância gerenciada define um valor máximo de memória do servidor com base na camada implantada, no entanto, quando testei o redimensionamento do ambiente, o valor máximo de memória não foi alterado dinamicamente. Nessa situação, você precisaria atualizar manualmente o valor. Esse problema não se aplica ao Banco de Dados SQL do Azure.
Estatísticas
O otimizador de consulta usa estatísticas para construir planos de execução. Isso significa que o SQL Server precisa que as estatísticas estejam atualizadas para que o otimizador de consultas tenha mais chances de construir um bom plano de execução. Por padrão, as estatísticas são atualizadas após 20% +500 linhas de dados terem sido modificadas. Isso pode levar muito tempo em mesas maiores. A partir do nível de compatibilidade 130, o limite para atualizações de estatísticas para tabelas grandes foi reduzido. Para SQL Server 2008R – 2014, você pode diminuir esse limite usando o sinalizador de rastreamento 2371.
Descobri regularmente que os clientes não estão atualizando manualmente as estatísticas e, mesmo com o limite mais baixo, descobri que a atualização manual torna o ambiente mais estável.
Eu recomendo que os clientes usem um script de terceiros para atualizar as estatísticas. Ola Hallengren publicou uma solução de manutenção amplamente utilizada para SQL Server. Parte desse processo é o procedimento Index Optimize, que pode levar parâmetros adicionais para atualizar as estatísticas.
@UpdateStatistics ALL = update index and column statistics INDEX = update index statistics COLUMNS = update column statistics NULL = Do not perform statistics maintenance (this is the default) @OnlyModifiedStatistics Y = Update statistics only if rows have been modified since most recent stats update N = Update statistics regardless of whether any rows have been modified
Descobri que os clientes que estão usando produtos ou scripts de terceiros para realizar a manutenção do índice com base no nível de fragmentação do índice não estão considerando que as reorganizações não atualizam estatísticas como as reconstruções. Muitos desses aplicativos de terceiros têm opções para atualizar estatísticas, assim como o procedimento Index Optimize da Ola, você só precisa ativá-lo.
A atualização de estatísticas se aplica ao local, IaaS, Banco de Dados SQL do Azure e Instância Gerenciada de SQL do Azure.
Manutenção do Índice
Realizar a manutenção do índice removendo a fragmentação de seus índices ainda é importante. Algumas documentações retiradas da Microsoft afirmavam que a fragmentação de índice pode ter um impacto negativo de 13 a 460%, dependendo do tamanho do ambiente e do nível de fragmentação. Embora hardwares como SANs inteligentes, Solid State Disk e outros avanços tenham ajudado a acelerar as coisas, o espaço desperdiçado no índice pode se traduzir em espaço desperdiçado no pool de buffers, além de desperdiçar mais E/S.
A fragmentação ocorre por meio de operações regulares, como inserções, atualizações e exclusões. Para corrigir isso, é necessária a manutenção adequada do índice de reconstrução ou reorganização de seus índices. Volto novamente a Ola Hallengren, por seu script Index Optimize. O script do Ola fornece a capacidade de especificar para reconstruir ou reorganizar com base no nível de fragmentação e páginas mínimas. Muitas ferramentas de terceiros oferecem a mesma lógica. Os planos de manutenção de banco de dados do SQL Server anteriores ao SQL Server 2016 só têm permissão para reconstruir ou reorganizar todos os índices. A partir do SQL Server 2016, agora você pode especificar lógica semelhante com base nos níveis de fragmentação. Não se esqueça dessas estatísticas se você estiver usando lógica inteligente com base em níveis de fragmentação.
Eu gosto do script do Ola e das ferramentas de terceiros que registram em uma tabela. Posso, então, consultar a tabela para ver se tenho algum ponto de acesso de índice em que a fragmentação está ocorrendo constantemente em altos níveis e solucionar problemas por que a fragmentação é tão prevalente e pode ser feito qualquer coisa.
Existem exceções para todas as regras ou práticas recomendadas. Alguns padrões de acesso a dados levam à fragmentação constante. O custo de reconstruir/reorganizar constantemente essas tabelas pode não valer a pena e pode ser excluído da manutenção. Essas situações devem ser avaliadas caso a caso.
Isso se aplica ao local, IaaS, Banco de Dados SQL do Azure e Instância Gerenciada de SQL do Azure.
MAXDOP
Acho que o grau máximo de paralelismo e o limite de custo para paralelismo são normalmente deixados nos valores padrão nos servidores clientes. Para MAXDOP, o valor padrão é zero, o que significa que um número “ilimitado” de CPUs pode ser usado para executar uma região paralela de uma consulta. Tecnicamente até 64 processadores, a menos que você ative um sinalizador de rastreamento para usar mais.
Há uma década, quando os processadores tinham contagens de núcleos mais baixas, esse valor era aceitável. Hoje, com alta densidade de núcleos e servidores multi-socket, um número ilimitado de CPUs para paralelismo não é tão bom. A Microsoft deu orientações sobre quais valores usar para MAXDOP.
Se você estiver no SQL Server 2008 – SQL Server 2014, para um único nó NUMA com menos de 8 processadores lógicos, mantenha MAXDOP igual ou inferior ao número de processadores lógicos. Se você tiver mais de 8 processadores lógicos, mantenha MAXDOP em 8. Se você tiver vários nós NUMA com menos de 8 processadores lógicos por nó NUMA, mantenha MAXDOP em ou abaixo do número de processadores lógicos por nó NUMA. Maior que 8, mantenha MAXDOP em 8.
O SQL Server 2016 introduziu nós soft-NUMA. Durante a inicialização do serviço, se o Mecanismo de Banco de Dados detectar mais de 8 núcleos físicos por nó ou soquete NUMA, os nós soft-NUMA serão criados automaticamente. O mecanismo se encarrega de colocar processadores lógicos do mesmo núcleo físico em diferentes nós soft-NUMA. Por esse motivo, temos orientações ligeiramente diferentes para MAXDOP para SQL Server 2016 em diante.
Se você estiver no SQL Server 2016 e superior, para um único nó NUMA com menos de 16 processadores lógicos, mantenha MAXDOP igual ou inferior ao número de processadores lógicos. Se você tiver mais de 16 processadores lógicos, mantenha MAXDOP em 16. Se você tiver vários nós NUMA com menos de 16 processadores lógicos por nó NUMA, mantenha MAXDOP em ou abaixo do número de processadores lógicos por nó NUMA. Maior que 16, mantenha MAXDOP na metade do número de processadores lógicos por nó NUMA com um valor MAX de 16.
Se você estiver virtualizado principalmente em máquinas com 8 ou menos processadores lógicos com um MAXDOP padrão, provavelmente está OK. Se você tiver um grande hardware físico com padrões, deve procurar otimizar o MAXDOP.
Todos os números acima são diretrizes, não verdades duras. Suas cargas de trabalho variam e deve-se levar em consideração ao determinar qual valor é mais ideal para sua carga de trabalho.
A configuração do MAXDOP se aplica ao local, IaaS e Instância Gerenciada de SQL do Azure. No entanto, há uma configuração com escopo de banco de dados que pode ser aplicada por banco de dados a partir do SQL Server 2016, e isso se aplica ao Banco de Dados SQL do Azure.
Limite de custo para paralelismo
O limite de custo para paralelismo tem um valor padrão de 5. O histórico desse número remonta aos primeiros dias do SQL Server e à estação de trabalho em que o teste de carga de trabalho foi executado. Com hardware moderno, a estimativa de custo de 5 está desatualizada. Os testes mostraram que aumentar o número de 5 para um valor mais alto impedirá que as consultas de execução mais curta tenham um plano paralelo. Eu costumo recomendar aumentar esse valor para um número maior depois de examinar o Cache do Plano. Em muitos casos, acabo começando com um valor de 25 e depois monitoro mais e ajusto a partir daí, se necessário. Para obter mais informações sobre como ajustar o limite de custo para o paralelismo, Jonathan Kehayias escreveu:Ajustando o 'limite de custo para o paralelismo' do Plan Cache.
Isso se aplica ao local, IaaS e Instância Gerenciada de SQL do Azure.
Alertas do SQL Server Agent
Todos devem aproveitar os alertas do SQL Agent, a menos que tenham um aplicativo de terceiros monitorando as mesmas condições de erro. A configuração de alertas é fácil e gratuita, e configurá-los fornecerá informações críticas quando seus servidores estiverem com problemas.
Escrevi um artigo intitulado Alertas do SQL Server Agent, fornecendo instruções passo a passo sobre como criar alertas para erros de gravidade 19-25 e erro 825. Ativar esses alertas é fácil:habilite o correio de banco de dados, crie um operador de correio e, em seguida, crie o alertas. Isso pode ser feito usando a GUI ou com T-SQL. Eu encorajo todos a criarem scripts desse processo usando T-SQL e torná-lo parte de sua compilação de servidor padrão.
Isso se aplica ao local, IaaS e Instância Gerenciada de SQL do Azure.
Resumo
Como você pode ver, há muitas configurações que devem ser modificadas dos padrões após a instalação do SQL Server. Essa não é uma lista compreensiva; no entanto, ele cobre muitos dos problemas mais críticos e com impacto no desempenho que encontrei, e que agrupei na categoria "Percalços do SQL Server".