DBAtlas · Atlas de operações de banco de dados

Lag de replicação / replicação parada

O standby/réplica está ficando para trás do primário, ou a replicação parou completamente. Esta árvore restringe passo a passo o tipo de lag (crescente, constante ou parado) para chegar à causa raiz, como um erro de apply, um gargalo de thread única, um recovery conflict ou corrupção.

Como o lag está se comportando?

Meça a situação primeiro. Olhe o fluxo da réplica e a métrica de lag: o lag está crescendo com o tempo, preso em um nível constante, ou o apply parou completamente? Isso divide a investigação em três ramos principais.

SELECT client_addr, state, write_lag, flush_lag, replay_lag,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS bytes_behind
FROM pg_stat_replication;
  • O apply parou completamente / há um erro
  • O lag continua crescendo (não consegue alcançar)
  • O lag é constante, mas há suspeita de uma consulta longa
  • Muito atrasado / parece inconsistente

O que diz o erro de apply?

Se a replicação parou, geralmente há um erro em um evento sendo aplicado. Olhe a mensagem de erro: é uma linha/tabela ausente no destino, um conflito de primary key ou uma queda de conexão/rede?

SHOW REPLICA STATUS\G  -- Last_Error, Last_SQL_Error, Replica_IO_Running, Replica_SQL_Running
  • Erro de linha ou tabela em conflito/ausente
  • Rede/conexão caiu, IO thread parada

Por que não consegue alcançar?

Se o lag continua crescendo, a réplica não acompanha a taxa de escrita do primário. O gargalo é o apply em thread única ou o disco/IO da réplica está lento? Olhe o estado do worker de apply e as esperas de IO.

SHOW REPLICA STATUS\G  -- Seconds_Behind_Source and apply thread state
SELECT * FROM performance_schema.replication_applier_status_by_worker;
  • Apply em thread única + carga de escrita pesada
  • O disco/IO da réplica está lento

Há uma consulta longa no standby?

Uma consulta longa rodando em um standby somente leitura pode bloquear o apply (recovery). No PostgreSQL, é assim que surge um recovery conflict. Olhe as consultas ativas e os contadores de conflito no standby.

SELECT now()-query_start AS dur, pid, state, query
FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
SELECT confl_snapshot, confl_lock, confl_bufferpin FROM pg_stat_database_conflicts WHERE datname=current_database();
  • Sim, uma consulta longa está bloqueando o apply
  • Não, não há consulta, mas continua atrasado

Causa raiz: erro de apply (conflito de dados)

A réplica está presa em um evento que não consegue aplicar: uma linha ausente no destino, um conflito de primary key ou uma tabela ausente. Corrija a causa da inconsistência em vez de pular às cegas.

Causa raiz: queda de conexão / rede

A thread receptora (IO/receiver) não consegue se conectar ao primário. A rede, a autenticação ou segmentos de log acumulados/expurgados podem ser o problema.

Causa raiz: gargalo de apply em thread única

Enquanto o primário grava em paralelo, a réplica aplica as mudanças em uma única sequência e não acompanha. Paralelize o apply.

Causa raiz: gargalo de IO na réplica

A thread de apply está esperando o disco, não a CPU. O storage da réplica não acompanha a taxa de escrita do primário.

Causa raiz: recovery conflict no standby

Uma consulta longa somente leitura no standby está bloqueando a aplicação das mudanças vindas do primário (conflito de vacuum/lock). O PostgreSQL resolve isso atrasando o apply ou cancelando a consulta.

Causa raiz: réplica atrasada demais / corrompida - reconstrua-a

A réplica está atrasada demais para se recuperar, os logs necessários foram removidos ou os dados estão inconsistentes. O caminho mais seguro é reconstruí-la a partir de um backup novo.

Abrir no DBAtlas →