Liberação de Cache do SQL Server e E / S de Disco

11

Estamos ocupados testando um sistema OLTP que desenvolvemos no .NET 4.0 e executando o SQL Server 2008 R2 nas costas. O sistema usa filas do SQL Server Service Broker, que são de alto desempenho, mas estamos experimentando uma tendência peculiar durante o processamento.

O SQL Server processa solicitações a uma taxa empolgante por 1 minuto, seguido por ~ 20 segundos de maior atividade de gravação em disco. O gráfico a seguir ilustra o problema.

Sistema OLTP SQL - Contadores de desempenho

Yellow = Transactions per second
Blue   = Total CPU usage
Red    = Sqlsrv Disk Write Bytes/s
Green  = Sqlsrv Disk Read Bytes/s

Durante a solução de problemas, tentamos o seguinte sem nenhuma alteração significativa no padrão:

  • Agente do SQL Server parado.
  • Matou quase todos os outros processos em execução (sem A / V, SSMS, VS, Windows Explorer, etc.)
  • Removidos todos os outros bancos de dados.
  • Desativou todos os cronômetros de conversação (não usamos gatilhos).
  • Afastado de uma abordagem orientada a fila de mensagens para um design de monitoramento de tabela simples / bruto.
  • Usou cargas diferentes, de leves a pesadas.
  • Corrigidos todos os impasses.

Parece que o SQL Server pode estar construindo seu cache e gravando-o em disco em intervalos específicos baseados em tempo, mas não consigo encontrar nada online para apoiar essa teoria.

Em seguida, pretendo mudar a solução para o nosso ambiente de teste dedicado para ver se consigo replicar o problema. Qualquer ajuda nesse ínterim seria muito apreciada.

Atualização 1 Conforme solicitado, a seguir, um gráfico que inclui as páginas de ponto de verificação / segundo , a expectativa de vida da página e alguns contadores de latência do disco.

Sistema OLTP SQL - Contadores de desempenho - Ponto de verificação

Parece que o ponto de verificação (linha azul clara) é a causa do desempenho reduzido (linha amarela) que estamos observando. ^

A latência do disco permanece relativamente consistente durante o processamento e a expectativa de vida da página não parece ter nenhum efeito perceptível. Também ajustamos a quantidade de memória RAM disponível para o SQL Server, o que também não teve um grande efeito. Alterar o modelo de recuperação de SIMPLEpara FULLtambém fez pouca diferença.

Atualização 2 Alterando o "Intervalo de recuperação" da seguinte maneira, conseguimos reduzir o intervalo no qual os pontos de verificação ocorrem:

EXEC sp_configure 'show advanced options',1
GO 

RECONFIGURE
GO

EXEC sp_configure 'recovery interval', '30'
GO

RECONFIGURE 
GO

EXEC sp_configure 'show advanced options',0
GO
RECONFIGURE

Não tenho certeza se isso é uma prática ruim?

André Hauptfleisch
fonte
1
Adicione o contador de páginas / s do ponto de verificação. E teste novamente e mostre o gráfico. E enquanto suas transações diminuem e as gravações aumentam - você está vendo problemas de desempenho? Eu também adicionaria alguns contadores de latência de disco - avg sec / read e avg sec / write
Mike Walsh
E quando você publicar os próximos gráficos, poderá incluir os números. Esse gráfico não mostra nenhuma escala.
Mike Walsh
5
E uma última coisa (desculpe!) - Qual é a memória deste servidor? Você também pode adicionar o contador de expectativa de vida da página? Você pode descrever a configuração física (memória, configuração IO, não é dividir o seu log e arquivos de dados, etc)
Mike Walsh
2
Em qual modelo de recuperação está o banco de dados? Parece um ponto de verificação automático à medida que o log de transações é preenchido. Observe que, mesmo que o banco de dados esteja dentro FULLou BULK_LOGGED, ele ainda se comporta como se estivesse SIMPLEaté que você faça um backup completo.
precisa
2
Jon - o ponto de verificação ainda ocorrerá independentemente do modelo de recuperação. Simplificado: a única diferença é o que acontece com os dados no log após um ponto de verificação nos modelos de recuperação. Em Full, ele permanece no log e precisa ser copiado. De maneira simples, pode ser truncado (ou marcado para truncamento .. reutilização), mas o ponto de verificação ainda precisa acontecer.
Mike Walsh

Respostas:

11

Outros já apontaram o culpado: o SQL Server acumula atualizações na memória (no pool de buffers) e as libera periodicamente (nos pontos de verificação). As duas opções sugeridas (-k e intervalo do ponto de verificação) são complementares:

Mas eu não respondi apenas para regurgitar os bons comentários que você recebeu até agora :)

Infelizmente, o que você está vendo é um comportamento muito típico do processamento em fila . Independentemente de você usar filas do Service Broker ou optar por usar tabelas como abordagens de filas , o sistema é muito propenso a esse tipo de comportamento. Isso ocorre porque o processamento baseado em filas é pesado, ainda mais pesado que o processamento OLTP. As primitivas de enfileiramento e desenfileiramento são operações de gravação e quase não há operações de leitura. Simplificando, o processamento da fila gerará mais gravações (= mais páginas sujas e mais log) em comparação com qualquer outra carga de trabalho, mesmo OLTP (ou seja, TPC-C como carga de trabalho).

Muito importante, as gravações de uma carga de trabalho de fila seguem o padrão de inserção / exclusão: todas as linhas inseridas são excluídas muito rapidamente. É importante distinguir de um padrão somente anexado de uma carga de trabalho de inserção pesada (ETL). Você está basicamente alimentando a tarefa de limpeza de fantasmas com uma refeição completa e pode facilmente superá-la. Pense no que isso significa:

  • enfileirar é uma inserção, ele criará uma página suja
  • desenfileirar é uma exclusão, ela suja a mesma página novamente (pode ter sorte e capturá-la antes do ponto de verificação, para evitar a descarga dupla, mas somente se tiver sorte)
  • A limpeza de fantasmas limpará a página, tornando-a suja novamente

Sim, isso realmente significa que você pode escrever uma página três vezes em disco, em três solicitações de E / S diferentes, para cada mensagem processada (pior caso). E também significa que a IO aleatória dos pontos de verificação será realmente aleatória, pois o ponto de gravação da página será visitado por aqueles que movem as cabeças novamente entre dois pontos de verificação (compare com muitas cargas de trabalho OLTP tendem a agrupar as gravações em alguns 'pontos de acesso', não filas ...).

Então você tem esses três pontos de gravação, correndo para marcar a mesma página de novo e de novo. E isso é antes de considerarmos as divisões de páginas, que o processamento da fila também pode ser propenso devido à ordem das chaves de inserção. Em comparação, as cargas de trabalho OLTP 'típicas' têm uma taxa de leitura / gravação muito mais equilibrada e as gravações OLTP são distribuídas entre inserções / atualizações / exclusões, geralmente com atualizações (alterações de 'status') e inserções que representam a maior parte. As gravações de processamento de fila são inseridas / excluídas exclusivamente com, por definição, divisão 50/50.

Algumas consequências a seguir:

  • O ponto de verificação se torna um problema muito quente (não é mais uma surpresa para você)
  • Você verá uma fragmentação pesada (a fragmentação em si não importará muito, pois você não fará varreduras de intervalo, mas sua eficiência de E / S sofre e a limpeza de fantasmas tem mais a funcionar, diminuindo ainda mais a velocidade)
  • O rendimento aleatório de IO do armazenamento de MDF será seu gargalo

Minha recomendação vem em três letras: S, S e D. Mova seu MDF para um armazenamento que possa lidar com E / S aleatórias e rápidas. SSD. Fusion-IO se você tiver o dinheiro. Infelizmente, este é um daqueles sintomas que não podem ser resolvidos com uma RAM mais barata ...

Editar:

Como Mark aponta, você tem dois discos lógicos apoiados por um disco físico. Talvez você tenha tentado seguir as práticas recomendadas e dividir o logon D: e os dados em C: mas infelizmente não adianta, C e D são o mesmo disco. Entre os pontos de verificação, você obtém uma taxa de transferência seqüencial, mas, assim que a verificação é iniciada, as cabeças do disco começam a se mover e a taxa de transferência do log é reduzida, reduzindo a taxa de transferência inteira do aplicativo. Certifique-se de separar o log do banco de dados para que não seja afetado pelos dados IO (disco separado).

Remus Rusanu
fonte
2
Por outro lado, seria interessante saber por que as E / S controladas por pontos de verificação causam um impacto tão dramático nos contadores de aplicativos. Idealmente, o aplicativo deve avançar enquanto o ponto de verificação faz seu trabalho. Obviamente, presumo que você não compartilhe o caminho de acesso ao armazenamento LDF e MDF (se sim, então merece ...). Talvez você tenha alguns pontos de contenção desnecessários no aplicativo.
Remus Rusanu
Resposta muito bem feita, Remus.
Mark Storey-Smith
3
Olhando para os contadores da perfmon listados, suspeito que você possa estar certo nos dados e logs na mesma unidade ou matriz.
Mark-Storey-Smith #
@ MarkStorey-Smith: Acho que você está certo, o OP possui discos lógicos C:e D:apoiados pelo mesmo disco físico. Duvido que o disco físico seja uma bateria de 100 eixos com riscas curtas, então essa é provavelmente a causa principal.
Remus Rusanu
Sim, esse teste foi realizado na minha máquina local de desenvolvimento, que possui apenas uma única unidade. Obrigado pela ajuda a todos.
André Hauptfleisch