Um dos recursos interessantes do PostgreSQL desde a versão 9.4 é a capacidade de controlar a remoção de arquivos WAL usando slots de replicação. O lado escuro é que os slots de replicação podem fazer com que os discos fiquem cheios com o WAL antigo, matando o servidor de produção principal. Neste artigo, explico os slots de replicação do PostgreSQL e como um novo recurso do PostgreSQL 13 ajuda a evitar esse problema.
Produção WAL
Como você sabe, o WAL é produzido para alterações de banco de dados em um servidor primário:inserções, atualizações, etc. . Um banco de dados mais ativo produzirá mais WAL — em um servidor muito ativo, pode haver muitos gigabytes de WAL produzidos a cada minuto. O WAL é gravado em arquivos com nomes em uma sequência numérica crescente e os arquivos são sempre do mesmo tamanho (16 MB é o padrão e típico). Quando os dados de um arquivo não forem mais necessários, esse arquivo poderá ser reciclado , o que significa renomeá-lo para uma posição de número mais alto na sequência para que possa ser preenchido com novos dados posteriormente.
(Existem situações especiais, como um aumento na atividade que leva à criação de arquivos adicionais; quando mais tarde o aumento diminui, esses arquivos extras são removidos em vez de reciclados.)
Como toda atividade de gravação do banco de dados produz WAL, é essencial que o espaço em disco esteja disponível. Quando o disco de armazenamento do WAL estiver cheio, o servidor não conseguirá processar novas transações e poderá ficar travado, ou pior:poderá cair completamente. Portanto, esta é uma situação a ser evitada por todos os meios possíveis.
Slots de replicação
A replicação no PostgreSQL funciona processando arquivos WAL. Para que isso funcione, todos os arquivos WAL devem estar disponíveis temporariamente até que sejam processados. Portanto, é necessário um mecanismo para informar ao gerenciamento principal do WAL para não reciclar ou remover arquivos.
Insira os slots de replicação. Os slots são um mecanismo que indica que este o backup que estamos fazendo exigirá isso WAL, e você pode, por favor, não excluí-lo ainda; ou isto a réplica ainda não processou isso WAL, então pode ser deixado sozinho por um tempo.
Por si só, os slots de replicação ocupam muito pouco espaço em disco. Eles apenas armazenam pequenos metadados, incluindo um ponteiro para uma posição no WAL. Mas os dados WAL que ele protege é outra questão:em um servidor altamente ativo, pode ser medido em gigabytes ou pior.
Consumo de WAL
Alimentar dados para uma réplica física significa copiar os dados WAL de seu servidor primário. Da mesma forma, uma réplica lógica precisa ler dados WAL (e transmitir uma versão interpretada para a réplica). A posição WAL que está sendo lida é o que o slot acompanha. Uma vez que a réplica tenha protegido os dados do WAL de alguma forma, o slot pode ser avançado; isso informa ao gerenciamento do WAL no primário que o arquivo WAL está disponível para remoção. Isso acontece continuamente quando a réplica está ativa, para que o WAL no servidor primário use a mesma quantidade de espaço em disco ou talvez um pouco mais. Mesmo o dobro ou dez vezes mais pode ser aceitável, dependendo das condições.
O problema é que se uma réplica morrer completamente e não se recuperar por um longo período de tempo; ou a réplica é destruída e o DBA esquece de remover o slot de replicação; ou o slot é uma sobra esquecida de algum experimento; ou mesmo a réplica está sendo alimentada por um link de rede lento, então o WAL reservado crescerá sem limites. E isso se torna uma bomba-relógio.
Limitando o tamanho do slot
Para combater esse problema, Kyotaro Horiguchi estava trabalhando desde fevereiro de 2017 em um patch do PostgreSQL para limitar o tamanho do WAL reservado por um slot. Após um longo processo de revisão e retrabalho, integrei-o ao PostgreSQL 13, melhorando o gerenciamento de farms PostgreSQL de alta disponibilidade.
O princípio principal é que é melhor matar uma réplica (tornando seu slot inválido de alguma forma; mais sobre isso abaixo) do que matar o servidor primário que alimenta essa réplica e derrubar toda a produção com ela.
A maneira como funciona é bem direta:defina
max_slot_wal_keep_size
(documentação) em postgresql.conf para a quantidade máxima de espaço em disco do WAL que os slots de replicação podem reservar. Se um slot atingir esse ponto e ocorrer um checkpoint, esse slot será marcado como inválido e alguns arquivos WAL poderão ser excluídos. Se o slot estava em uso ativo por um walsender processo, esse processo será sinalizado para que seja finalizado. Se o walsender iniciar novamente, ele descobrirá que os arquivos WAL necessários não estarão mais lá. A réplica usando esse slot terá que ser clonada novamente. Se
max_slot_wal_keep_size
é zero, que é o valor padrão, então não há limite. Eu não recomendo isso, porque leva a falhas quando os slots enchem o disco. Monitorando a integridade do slot
Também estão incluídos alguns recursos de monitoramento. Duas colunas em pg_replication_slots são relevantes. O mais crítico é
wal_status
. Se essa coluna for reserved
, o slot está apontando para dados dentro de max_wal_size
; se for extended
então excedeu max_wal_size
, mas ainda está protegido por wal_keep_size
ou max_slot_wal_keep_size
(incluindo quando max_slot_wal_keep_size
é zero). Qualquer estado é bom e normal. No entanto, quando um slot ultrapassa o limite, ele primeiro se torna unreserved
, o que significa que está em perigo iminente, mas ainda pode se recuperar se for rápido o suficiente. Finalmente, o status se torna lost
quando os arquivos WAL foram removidos e nenhuma recuperação é possível. A outra coluna é
safe_wal_size
:mostra o número de bytes de WAL que podem ser gravados antes que esse slot corra o risco de ter arquivos WAL removidos. Sugerimos ficar de olho nesta coluna em seu sistema de monitoramento e disparar alertas quando estiver baixo. Zero ou negativo significa que sua réplica estará inoperante assim que ocorrer um ponto de verificação:SELECT slot_name, active, wal_status, safe_wal_size FROM pg_catalog.pg_replication_slots;
Acreditamos que este novo recurso torna a manutenção das réplicas mais fácil e robusta; Espero que não vejamos mais desastres com a produção baixa por causa desses problemas.
(Uma observação:
safe_wal_size
foi introduzido no 13beta3, portanto, consulte a documentação atualizada ou verá min_safe_lsn
em vez de. Ignore isso.) Obrigado
Agradecimentos especiais a Kyotaro Horiguchi por trabalhar na solução deste problema. Vários revisores se aprofundaram nisso, entre os quais gostaria de agradecer especialmente Masahiko Sawada, Fujii Masao, Jehan-Guillaume de Rorthais e Amit Kapila (sem ordem específica).