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 / 257970
Accepted
Danielle Paquette-Harvey
Danielle Paquette-Harvey
Asked: 2020-01-23 07:50:58 +0800 CST2020-01-23 07:50:58 +0800 CST 2020-01-23 07:50:58 +0800 CST

Rastreamento de alterações causando contenção de trava

  • 772

Estou usando o Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64) 15 de junho de 2019 23:15:58 Copyright (c) Microsoft Corporation Standard Edition (64 bits) no Windows Server 2012 R2 Standard 6.3 (Construção 9600:)

O banco de dados tem cerca de 870 GB de tamanho. É SQL Standard e tenho 128 GB de RAM no servidor. O banco de dados está em unidades SSD. O arquivo de dados está em uma unidade diferente do arquivo de log e o Tempdb também possui sua própria unidade SSD. O servidor recebe cerca de 1200 consultas/segundo em média, podendo chegar a 2000 consultas/segundo. A recompilação permanece baixa, apenas 1 a 8 por segundo. A expectativa de vida da página é boa, com média de 61 minutos.

O servidor possui 6 núcleos físicos + hyper threads.

Estamos usando muito o rastreamento de alterações do SQL Server em um sistema em que milhares de dispositivos se conectam e tentam sincronizar as alterações com a chave de rastreamento.

Geralmente roda bem, mas depois, de vez em quando, um dia ou outro, os travamentos do servidor disparam, passando de 0ms para uma média de 60677ms.

Trava SQL

Quando verifico quais consultas estão em execução, só vejo as consultas de sincronização, todas bloqueadas, com "PAGELATCH_UP", todas tentando acessar as tabelas de controle de alterações, mais de 300 consultas bloqueadas.

Eu tenho algumas perguntas:

  • O SQL Server bloqueia a tabela inteira enquanto procura alterações no controle de alterações?
  • Teria melhores resultados com o SQL Entreprise ou não muda nada?
  • Alguma ideia de por que o rastreamento de alterações funciona bem na maioria das vezes, mas trava sem motivo aparente de semana para semana?

Esses são o tamanho da minha tabela de rastreamento de alterações. As tabelas que minha consulta bloqueia são as três primeiras, apenas alguns mb de dados.

insira a descrição da imagem aqui

Eles estão todos esperando no mesmo waitresource.

esperarrecurso

Waitresource 2:4:88968 está no tempdb. Mas o tempdb é responsável apenas por cerca de 9% das gravações do servidor e 6% das leituras.

relatório io

Mas minha consulta não usa o tempdb, então acho que é assim por causa da maneira interna como o rastreamento de alterações funciona? Aqui está minha consulta

DECLARE @Id INT; SET @Id = (SELECT Id FROM Users WHERE No=@No); 

SELECT DISTINCT lh.Key1 
FROM ( 
    SELECT Key1 FROM CHANGETABLE(CHANGES dbo.Table1, @TrackingKey) AS CT 
    UNION ALL 
    SELECT Key1 
    FROM dbo.Table2 lhd 
    INNER JOIN (SELECT Key2 FROM CHANGETABLE(CHANGES dbo.Table2, @TrackingKey) AS CT) AS CTLHD ON(CTLHD.Key2=lhd.Key2) 
    UNION ALL 
    SELECT Key1 
    FROM CHANGETABLE(CHANGES dbo.Table3, @TrackingKey) AS CT 
) AS L 
JOIN dbo.Table1 lh ON lh.Key1 = L.Key1 
WHERE lh.Id = @Id AND lh.Date BETWEEN @StartUtc AND @EndUtc 

Meu tempdb tem 10 arquivos e eles são do mesmo tamanho.

tempdb

O que geralmente acabo fazendo para que o cliente volte ao normal é colocá-lo em tempo de inatividade, depois colocá-lo de volta aos poucos para que todos os dispositivos móveis consigam sincronizar pouco a pouco. Mas nosso sistema é de missão crítica e esta não é uma solução de longo prazo.

Outra solução que tenho pensado é mudar a forma como o sistema funciona com as consultas de controle de alterações. Faça com que o dispositivo móvel sincronize com uma tabela "feita em casa" e preencha essa tabela com uma única alteração de leitura de serviço do rastreamento de alterações. Dessa forma, limitarei as consultas simultâneas às tabelas de controle de alterações, mas temo que apenas mova o problema para a tabela feita em casa.

Algum pensamento sobre isso? Qualquer ajuda será apreciada.


EDITADO: Bloqueador de cabeça

Tentei determinar quem é o bloqueador de cabeça e o que está esperando, mas é uma tarefa difícil. Parece que tenho muitos "bloqueadores de cabeça".

Todas as consultas estão executando o mesmo SELECT, quase todas divididas em 4 threads, para algumas consultas elas não estão bloqueadas, mas aguardando "MISCELLANEOUS", mas para algumas consultas, pelo menos parte das threads são bloqueadas por outras consultas.

Por exemplo, agora, 294 tópicos estão sendo exibidos.

A consulta 202 é dividida em 4 threads e uma de suas threads está bloqueada por 123, mas as outras threads não estão bloqueadas. Os três encadeamentos estão aguardando em "MISCELLANEOUS" e o encadeamento bloqueado está aguardando em "PAGELATCH_UP"

Quanto à consulta 123, ela não está bloqueada, são 4 threads aguardando "DIVERSOS"

Ou, por exemplo, a consulta 219 é bloqueada pela consulta 140 em um encadeamento e bloqueada por 69 nos outros três encadeamentos.

69 está bloqueado por 193 e 193 está em execução, aguardando "MISCELLANEOUS" novamente. 140 não está mais na lista, por isso expirou ou foi concluído.

Meu limite de custo para paralelismo é 70.
Bloqueios 0
Grau máximo de paralelismo 3
Espera de consulta -1

O nível de isolamento do instantâneo não está habilitado no banco de dados. As consultas não estão usando o nível de isolamento de instantâneo.

opções de banco de dados

Também verifiquei as estatísticas nas tabelas e até nas tabelas sys.change_tracking. Os índices nas tabelas não são fragmentados (menos de 10%) para as tabelas consultadas.

Executei uma ou duas consultas e geralmente o resultado da consulta é de 4 linhas, que se tornam apenas uma linha por causa da cláusula DISTINCT. Portanto, não é como se estivesse retornando milhares de linhas.

Quando executo a consulta no SSMS, ela é rápida e não bloqueia, mesmo que atualmente veja centenas de consultas bloqueadas no servidor na mesma consulta. Então eu acho que pode estar relacionado ao sniffing de parâmetros, talvez?

Aqui estão as estatísticas de E/S quando executo no SSMS.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 92 ms, elapsed time = 92 ms.
Table 'Users'. Scan count 0, logical reads 2, 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 = 0 ms,  elapsed time = 0 ms.

(1 row affected)
Table 'Worktable'. 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 '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 'syscommittab'. Scan count 3, logical reads 555, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'change_tracking_62623266'. Scan count 1, logical reads 3364, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Table1'. Scan count 3, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Table2'. Scan count 0, logical reads 34281, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'change_tracking_46623209'. Scan count 1, logical reads 1152, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'change_tracking_78623323'. Scan count 1, logical reads 1077, 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 = 296 ms,  elapsed time = 435 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

Completion time: 2020-01-22T14:18:25.9480651-05:00

Aqui está meu plano de consulta https://www.brentozar.com/pastetheplan/?id=By7k-7UWI

Mas, novamente, essa é a versão que não bloqueia. Eu tenho o repositório de consultas habilitado para que eu pudesse tentar obter a versão que bloqueia, só não estou 100% como fazê-lo.


EDITADO: QUERY STORE INFO

Minha consulta é a primeira nas "consultas regredidas" do Query Store.

Consultar informações da loja

planos

De acordo com a loja Query, aqui está o "plano ruim" https://www.brentozar.com/pastetheplan/?id=ryqKGQUbL

E aqui está o "bom plano" https://www.brentozar.com/pastetheplan/?id=rknnGQ8WL

Devo apenas "forçar" o bom plano?


EDITADO Minha solução

Ok, então eu usei o sp_blitzcache de Brent Ozar ( https://www.brentozar.com/blitz/ ) com "expert_mode" em 1 para poder recuperar o identificador do "plano ruim" e poder limpá-lo de cache (sem limpar mais nada).

DBCC FREEPROCCACHE (0x06000800155A5106F08F632F1C00000001000000000000000000000000000000000000000000000000000000);

Meu servidor voltou ao estado normal novamente e todas as centenas de consultas bloqueadas desapareceram. Eu acho que é sniffing de parâmetros então? Esperando que não aconteça novamente. Gostaria de encontrar uma maneira para que isso não aconteça novamente.

sql-server-2016 change-tracking
  • 1 1 respostas
  • 487 Views

1 respostas

  • Voted
  1. Best Answer
    Josh Darnell
    2020-01-25T08:41:42+08:002020-01-25T08:41:42+08:00

    Não tenho certeza de como lidar com o problema do plano ruim, talvez alguém venha com melhores habilidades de ajuste de consulta para ajudar com isso.

    No entanto, para falar sobre o problema de contenção do tempdb, a página pela qual todas essas sessões estão lutando é uma página PFS. Estes são definidos na documentação como:

    As páginas PFS (Page Free Space) registram o status de alocação de cada página, se uma página individual foi alocada e a quantidade de espaço livre em cada página.

    Observe que eles rastreiam apenas o espaço livre para determinados tipos de páginas:

    A quantidade de espaço livre em uma página é mantida apenas para páginas heap e de texto/imagem.

    O comentário "Texto/Imagem" inclui tipos de dados LOB mais modernos ( nvarchar(max)e similares).

    A propósito, você pode dizer que é uma página PFS porque é divisível uniformemente por 8088:

    Assim, há uma nova página PFS 8.088 páginas após a primeira página PFS e páginas PFS adicionais em intervalos de 8.088 páginas subsequentes.


    Tudo isso para dizer que o "plano ruim" provavelmente está se espalhando para o tempdb (há dois tipos e uma junção de hash), o que está causando contenção sobre essa página PFS específica. Há também alguns spools de índice ansiosos que estão gravando no tempdb.

    Você pode atenuar esse problema instalando o SP2 CU1 , que inclui esta correção :

    Essa correção melhora a alocação de página PFS executando alocações round-robin em várias páginas PFS no mesmo arquivo de dados, além da alocação round-robin em todos os arquivos de dados tempdb. Portanto, quanto mais páginas de dados PFS estiverem contidas em um arquivo de dados e quanto mais arquivos de dados houver, melhor será a distribuição de alocação.

    Assim, mesmo com o "plano ruim", espera-se que você tenha menos contenção de trava, tornando as coisas mais lentas.

    • 4

relate perguntas

  • Cláusula Where para filtrar linhas para o Azure Stretch Database?

  • As tabelas temporais serão incluídas na Standard Edition do SQL Server 2016?

  • Não é possível obter o serviço SQL Server 2016 CTP3 para iniciar no Windows 10

  • Uso inválido de um operador de efeito colateral 'change_tracking_min_valid_version' dentro de uma função

  • Segurança em nível de linha no SQL Server 2016 com um esquema normalizado

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