Estamos executando um banco de dados AWS Aurora PostgreSQL versão 13. Outro dia, eu estava tentando configurar uma tarefa de backup para ser executada a partir da réplica de leitura e acabei encontrando o erro "O usuário manteve um bloqueio de relacionamento por muito tempo". Eu trabalhei em torno disso usando a resposta nesta pergunta .
Minha pergunta é teórica e me perdoe se parece estúpida, mas estou faltando alguma coisa aqui. Se o Postgres tiver MVCC em vez de bloquear, por que o pg_dump se preocuparia com o fato de um usuário "bloquear" outra relação? Não deveria estar apenas lendo a última versão da linha?
Trata-se de bloqueios de tabela e conflitos de replicação de streaming.
pg_dump
tem que ler as tabelas, e a leitura de uma tabela requer umACCESS SHARE
bloqueio na tabela. Esse bloqueio entra em conflito apenas com atividades como , ,DROP TABLE
eTRUNCATE
certas variantes de . Um bloqueio não bloqueia gravadores, mas evita que sessões simultâneas excluam o arquivo de dados que você está lendo no momento.CLUSTER
VACUUM (FULL)
ALTER TABLE
ACCESS SHARE
Agora, se você tiver uma consulta de longa duração, como
pg_dump
no modo de espera, e alguémTRUNCATE
estiver em uma tabela no primário, o PostgreSQL tentará reproduzir a instrução e oACCESS EXCLUSIVE
bloqueio associado no modo de espera. Isso entrará em conflito com a consulta de longa execução e, sepg_dump
não for feito apósmax_standby_streaming_delay
a aprovação, a consulta será cancelada epg_dump
terminará com um erro.Observe que o conflito não precisa ser com uma das afirmações acima: se o autovacuum processar uma tabela no primário e as últimas páginas da tabela ficarem vazias,
VACUUM
tentará remover essas páginas, o que também requer um breveACCESS EXCLUSIVE
bloqueio no mesa. Isso não interrompe o processamento no primário, mas pode fazer com que as consultas sejam canceladas no modo de espera.Defina
max_standby_streaming_delay
como -1 no servidor em espera para evitar o problema.Aqui está um artigo que trata do problema com mais detalhes.