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.