AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 237671
Accepted
John Eisbrener
John Eisbrener
Asked: 2019-05-09 09:12:12 +0800 CST2019-05-09 09:12:12 +0800 CST 2019-05-09 09:12:12 +0800 CST

Consulta de longa execução na réplica somente leitura que demora alguns instantes no primário

  • 772

Eu tenho uma configuração de AG de 4 nós da seguinte forma:

Configuração de hardware de VM de todos os nós:

  • Microsoft SQL Server 2017 Enterprise Edition (RTM-CU14) (KB4484710)
  • 16 vCPUs
  • 356 GB de RAM (longa história para este...)
  • grau máximo de paralelismo: 1 (conforme exigido pelo fornecedor do aplicativo)
  • limite de custo para paralelismo: 50
  • memória máxima do servidor (MB): 338944 (331 GB)

Configuração AG:

  • Nó 1: Secundário não legível de confirmação primária ou síncrona, configurado para failover automático
  • Nó 2: Secundário não legível de confirmação primária ou síncrona, configurado para failover automático
  • Nó 3: Conjunto secundário legível com confirmação assíncrona, configurado para failover manual
  • Nó 4: Conjunto secundário legível com confirmação assíncrona, configurado para failover manual

A consulta em questão:

Não há nada de muito louco nessa consulta, ela fornece um resumo dos itens de trabalho pendentes em várias filas dentro do aplicativo. Você pode ver o código em um dos links do plano de execução abaixo.

Comportamento de execução no nó primário:

Quando executado no nó Primário, o tempo de execução é geralmente em torno da marca de 1 segundo. Aqui está o plano de execução e abaixo estão as estatísticas capturadas de STATISTICS IO e STATISTICS TIME do nó primário:

(347 rows affected)
Table 'Worktable'. Scan count 647, logical reads 2491, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'workitemlc'. Scan count 300, logical reads 7125, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulertask'. Scan count 1, logical reads 29, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'wfschedulertask'. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerservice'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerworkerpool'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'itemlc'. Scan count 1, logical reads 26372, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 500 ms,  elapsed time = 656 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Comportamento de execução no nó secundário somente leitura:

Ao executar em um nó secundário somente leitura (ou seja, nó 3 ou nó 4), esta consulta usa o mesmo plano de execução (este é um link de plano diferente) e aproximadamente as mesmas estatísticas de execução são mostradas (por exemplo, pode haver mais algumas páginas verificações, pois esses resultados estão sempre mudando), mas com exceção do tempo de CPU, eles são muito semelhantes. Aqui estão as estatísticas capturadas de STATISTICS IO e STATISTICS TIME do nó secundário somente leitura:

(347 rows affected)
Table 'Worktable'. Scan count 647, logical reads 2491, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'workitemlc'. Scan count 300, logical reads 7125, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulertask'. Scan count 1, logical reads 29, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'wfschedulertask'. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerservice'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'schedulerworkerpool'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'itemlc'. Scan count 1, logical reads 26372, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 55719 ms,  elapsed time = 56335 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Outros detalhes:

Também executei o script sp_WhoIsActivede Paul RandalWaitingTasks.sql no secundário enquanto essa consulta está sendo executada, mas não vejo nenhuma espera ocorrendo, o que é francamente frustrante:

insira a descrição da imagem aqui

Isso também não parece ser um caso de latência de AG, pois o status de sincronização é realmente muito bom:

--https://sqlperformance.com/2015/08/monitoring/availability-group-replica-sync

SELECT 
       ar.replica_server_name, 
       adc.database_name, 
       ag.name AS ag_name, 
       drs.is_local, 
       drs.synchronization_state_desc, 
       drs.synchronization_health_desc, 
       --drs.last_hardened_lsn, 
       --drs.last_hardened_time, 
       drs.last_redone_time, 
       drs.redo_queue_size, 
       drs.redo_rate, 
       (drs.redo_queue_size / drs.redo_rate) / 60.0 AS est_redo_completion_time_min,
       drs.last_commit_lsn, 
       drs.last_commit_time
FROM sys.dm_hadr_database_replica_states AS drs
INNER JOIN sys.availability_databases_cluster AS adc 
       ON drs.group_id = adc.group_id AND 
       drs.group_database_id = adc.group_database_id
INNER JOIN sys.availability_groups AS ag
       ON ag.group_id = drs.group_id
INNER JOIN sys.availability_replicas AS ar 
       ON drs.group_id = ar.group_id AND 
       drs.replica_id = ar.replica_id
ORDER BY 
       ag.name, 
       ar.replica_server_name, 
       adc.database_name;

insira a descrição da imagem aqui

Esta consulta parece ser o pior ofensor. Outras consultas que também levam menos de um segundo no nó primário podem levar de 1 a 5 segundos no nó secundário e, embora o comportamento não seja tão grave, parece estar causando problemas.

Por fim, também examinei os servidores e verifiquei processos externos, como varreduras de A/V, trabalhos externos gerando E/S inesperadas, etc. e cheguei de mãos vazias. Não acho que isso esteja sendo causado por algo fora do processo do SQL Server.

A questão:

É apenas meio-dia onde estou e já foi um longo dia, então suspeito que estou perdendo algo óbvio aqui. Ou isso ou temos algo mal configurado, o que é possível, pois tivemos várias chamadas para o fornecedor e MS relacionadas a esse ambiente.

Para toda a minha investigação, eu simplesmente não consigo encontrar o que está causando essa diferença no desempenho. Eu esperaria ver algum tipo de espera ocorrendo nos nós secundários, mas nada. Como posso solucionar ainda mais isso para identificar a causa raiz? Alguém já viu esse comportamento antes e encontrou uma maneira de resolvê-lo?

ATUALIZAÇÃO #1 Depois de trocar os estados do terceiro nó (uma das réplicas somente leitura) para não legível e depois de volta para legível como um teste, essa réplica ainda está sendo mantida por uma transação aberta, com todas as consultas do cliente exibindo o HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONINGesperar.

A execução de um DBCC OPENTRANcomando produz os seguintes resultados:

Oldest active transaction:
    SPID (server process ID): 420s
    UID (user ID) : -1
    Name          : QDS nested transaction
    LSN           : (941189:33148:8)
    Start time    : May  7 2019 12:54:06:753PM
    SID           : 0x0
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Ao pesquisar este SPID em sp_who2, ele o mostra como um BACKGROUNDprocesso QUERY STORE BACKlistado como o comando.

Embora possamos fazer backups do TLog, suspeito que estamos enfrentando uma funcionalidade semelhante a esse bug resolvido , então pretendo abrir um tíquete com a MS sobre esse problema específico hoje.

Dependendo do resultado desse ticket, tentarei capturar um rastreamento de pilha de chamadas de acordo com a sugestão de Joe e ver para onde vamos.

Atualização final (problema resolvido automaticamente)

Depois de eclipsar a marca de 52 horas da transação do Query Store sendo aberta (conforme identificado acima), o AG decidiu fazer o failover automaticamente. Antes que isso acontecesse, eu puxei algumas métricas adicionais. Por este link , fornecido por Sean, o banco de dados em questão tinha um armazenamento de versão muito grande dedicado a este banco de dados, especificamente em um ponto eu havia registrado 1651360 páginas no reserved_page_countcampo e 13210880 para o reserved_space_kbvalor.

De acordo com os ERRORLOGs, o failover ocorreu após um dilúvio de 5 minutos de falhas de proteção de transações relacionadas a QDS base transactione QDS nested transactiontransações.

O failover causou uma interrupção de cerca de 10 minutos no meu caso. O banco de dados tem ~6 TB de tamanho e é muito ativo, então isso foi realmente muito bom na minha opinião. Enquanto o novo nó primário estava online durante esse período, nenhuma consulta de cliente pôde ser concluída, pois todos estavam aguardando o QDS_LOADDBtipo de espera.

Após o failover, os números de armazenamento de versão foram reduzidos para 176 reserved_page_counte 1408 para reserved_space_kb. As consultas nas réplicas somente leitura secundárias também começaram a ser executadas tão rapidamente quanto se fossem executadas a partir do primário, portanto, parece que o comportamento desapareceu completamente, como resultado do failover.

sql-server performance
  • 3 3 respostas
  • 1932 Views

3 respostas

  • Voted
  1. Joe Obbish
    2019-05-09T13:32:24+08:002019-05-09T13:32:24+08:00

    Isenção de responsabilidade: não sei nada sobre grupos de disponibilidade, mas sei um pouco sobre como solucionar problemas de consultas que parecem usar mais CPU do que deveriam.

    Você tem um problema de CPU em que você está usando muito dele. Uma coisa importante a dizer sobre esperas é que quase todas elas não estão ocupadas com a CPU. Quando um trabalhador entra em um estado de espera, ele cedeu e não está mais em execução no agendador no SQLOS. Portanto, se você tiver uma consulta MAXDOP 1 com as seguintes estatísticas de execução:

    Tempo de CPU = 55719 ms, tempo decorrido = 56335 ms.

    Você atingiu quase 99% de utilização da CPU para a consulta. Por que deve haver estatísticas de espera significativas para essa consulta? Você pode ver alguns se tiver algumas esperas ocupadas da CPU, como esperas externas ou preventivas, mas isso também não é garantido. A conclusão é que as estatísticas de espera podem não ser tão úteis aqui.

    Há algumas coisas para verificar em ordem aproximada (a ordem depende do que você sabe sobre o meio ambiente):

    • O servidor secundário tem algum monitoramento caro em andamento, como eventos estendidos, rastreamentos ou criação de perfil?
    • O hardware do servidor secundário corresponde aproximadamente ao primário?
    • Há algum problema de configuração ou software com o servidor secundário?
    • Alguma espera ou travamento significativo? Pode não ser aplicável à sua consulta, mas ainda pode fornecer pistas.
    • Algum spinlock significativo?
    • Existem outros DMVs ou coisas que você pode verificar no SQL Server que podem dar pistas? Você mencionou que os Grupos de Disponibilidade provavelmente são uma parte importante do problema.
    • O que o rastreamento ETW diz a você?
    • Que tipo de acordos de suporte você tem?

    A maioria dos itens acima é bem abordada em várias postagens de blog e documentação, mas vou expandir o rastreamento de ETW. Se você quiser saber por que o SQL Server está usando tanta CPU para uma consulta específica e tiver acesso ao host, sempre poderá fazer o rastreamento ETW para visualizar as pilhas de chamadas e ver quanta CPU várias pilhas de chamadas estão fazendo. Em outras palavras, o sistema operacional host fica feliz em dizer para que CPU está sendo usado, se você souber como perguntar. Os métodos comuns de rastreamento de ETW incluem o Windows Performance Recorder e o PerfView .

    Dar sentido a esses resultados requer profundo conhecimento interno e é fácil chegar a uma conclusão errada. Em muitos casos, é melhor coletar os dados brutos e pedir a especialistas para examiná-los. Ao executar um rastreamento, você deseja que o mínimo de atividade possível ocorra no SQL Server. Abaixo estão algumas respostas postadas aqui que usam o rastreamento ETW para tirar conclusões sobre o SQL Server:

    • Como diagnosticar o try_parse sendo muito lento?
    • Por que pode levar até 30 segundos para criar um rowgroup CCI simples?
    • As leituras lógicas na RAM aparecem nas estatísticas de espera ou onde?
    • Por que o NOLOCK faz uma varredura com atribuição de variável mais lenta?
    • Qual é o algoritmo por trás do operador EXCEPT?
    • Comando ALTER TABLE sem valor padrão demorando para sempre?
    • Dados ordenados implicitamente como se fossem um índice clusterizado; Posso aproveitar isso?

    Suspeito que, no seu caso, se você conseguir coletar pilhas de chamadas enquanto a consulta de 45 segundos for executada, obterá algumas pistas muito úteis sobre a natureza do problema.

    • 10
  2. Best Answer
    Sean Gallardy
    2019-05-10T02:41:59+08:002019-05-10T02:41:59+08:00

    Esta resposta é uma adição à resposta de Joe, pois não posso ter 100% de certeza de que é o armazenamento de versões, no entanto, há evidências suficientes até agora para implicar que isso seja parte do problema.

    Quando uma réplica secundária é marcada como legível, um bom estado estável para as informações de versão precisa ser obtido primeiro para que haja um ponto de partida conhecido e bom para todas as operações de leitura no secundário. Quando estiver aguardando a transição e ainda houver transações abertas no primário, isso se manifestará como HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONINGe também é um bom indicador de que o primário passa por uma grande quantidade de rotatividade de dados (ou pelo menos alguém tem uma transação aberta muito longa que também não é bom). Quanto mais tempo as transações estiverem abertas e quanto mais alterações de dados houver, mais controle de versão ocorrerá.

    As réplicas secundárias atingem o status legível usando o isolamento de instantâneo nos bastidores da sessão, mesmo que, se você verificar as informações da sessão, elas apareçam na leitura padrão confirmada. Como o isolamento de instantâneos é otimista e usa o armazenamento de versão, todas as alterações precisarão ser versionadas. Isso é agravado quando há muitas consultas em execução (e possivelmente de longa duração) no secundário enquanto a rotatividade de dados é alta no primário. Geralmente, isso se manifesta apenas em algumas tabelas para um sistema OLTP, mas é completamente dependente do aplicativo e da carga de trabalho.

    O próprio armazenamento de versão é medido em gerações e quando uma consulta é executada que requer o uso do armazenamento de versão, o ponteiro de registro de versão é usado para apontar para a cadeia TempDB dessa linha. Eu digo chain, porque é uma lista de versões para aquela linha e toda a chain deve ser percorrida sequencialmente para encontrar a versão apropriada com base no timestamp inicial da transação para que os resultados estejam alinhados com os dados naquele momento.

    Se o armazenamento de versão tiver muitas gerações para essas linhas devido a transações de longa execução nas réplicas primárias e secundárias, isso causará tempos mais longos do que a média para a execução das consultas e geralmente na forma de CPU mais alta, enquanto todos os outros itens aparentemente permanecem exatamente os mesmos - como plano de execução, estatísticas, linhas retornadas, etc. A caminhada da cadeia é quase uma operação puramente de CPU, portanto, quando as cadeias se tornam muito longas e a quantidade de linhas retornadas é muito alta, você obtém um (não linear, mas pode ser próximo) aumenta o tempo para a consulta.

    A única coisa que pode ser feita é limitar o comprimento das transações no primário e no secundário para garantir que o armazenamento de versão não esteja se tornando muito grande no TempDB enquanto tem muitas gerações. As tentativas de limpar o armazenamento de versões acontecem aproximadamente uma vez por minuto, no entanto, a limpeza exige que todas as versões da mesma geração não sejam mais necessárias antes de serem removidas e todas as versões futuras não podem ser limpas até que a versão mais antiga não seja mais necessária. Assim, uma consulta de longa duração pode causar a incapacidade de limpar efetivamente muitas gerações não utilizadas.

    Alternar a réplica para dentro e para fora do modo legível também limpará o armazenamento de versão, pois não é mais legível.

    Existem outros itens que também podem estar em jogo, mas este parece ser o mais plausível, dados os dados atuais e a forma como a réplica estava reagindo.

    DMVs de versionamento TempDB (não confundir com versionamento ADR).

    • 10
  3. John Eisbrener
    2019-05-11T06:30:17+08:002019-05-11T06:30:17+08:00

    Como o problema se resolveu, resta-me especular sua causa (rima não intencional). Com base na postagem de Sean e no fato de que uma transação aberta do Query Store parece ter sido a causa raiz do aumento do tamanho do meu armazenamento de versão (por exemplo, a causa das HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONINGesperas), só posso supor que o Query Store teve uma parte no comportamento que foi apresentado. Esse banco de dados é maior (~6 TB), bastante ativo e a maioria das consultas que o atingem são geradas no cliente e não parametrizadas (ou seja, consultas ad-hoc), então não acredito que o Query Store se preste a fornecer muito uso neste cenário. Por isso, desabilitaremos o Query Store neste ambiente durante uma futura janela de manutenção, após a qual suspeito que não veremos esse comportamento novamente.

    Abrimos um ticket com a Microsoft, mas o tempo não estava a nosso favor, pois o problema foi resolvido antes que pudéssemos fazer qualquer análise detalhada por meio de um rastreamento PSSDIAG ou algo semelhante. Espero que eles possam fazer alguns testes localizados e replicar esse problema, caso seja um bug que encontramos. Se forem identificadas outras atualizações em uma resolução mais permanente, também atualizarei esta resposta.

    • 5

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve