Por que recebi um erro “Não há mais espaço no dispositivo” ou “DiskFull” no Amazon RDS para PostgreSQL?

11 minuto de leitura
0

Eu tenho um pequeno banco de dados do Amazon Relational Database Service (Amazon RDS) para PostgreSQL. O espaço de armazenamento livre da instância está diminuindo e eu recebo o seguinte erro: “Mensagem de erro: PG::DiskFull: ERRO: não foi possível estender o arquivo “base/16394/5139755”: Não há mais espaço no dispositivo. DICA: Verifique o espaço livre em disco.” Quero resolver os erros de DiskFull e evitar problemas de armazenamento.

Breve descrição

O armazenamento da instância de banco de dados do Amazon RDS é usado por:

  • Tabelas ou arquivos temporários criados por transações do PostgreSQL
  • Arquivos de dados
  • Registros de gravação antecipada (registros WAL)
  • Slots de replicação
  • Logs de banco de dados (arquivos de erros) que são retidos por muito tempo
  • Outros arquivos de banco de dados ou Linux que suportam o estado consistente da instância de banco de dados do RDS

Resolução

1.    Use o Amazon CloudWatch para monitorar seu espaço de armazenamento de banco de dados usando a métrica FreeStorageSpace. Ao definir um alarme do CloudWatch para liberar espaço de armazenamento, você recebe uma notificação quando o espaço começa a diminuir. Se você receber um alarme, analise as causas de problemas de armazenamento mencionadas anteriormente.

2.    Se sua instância de banco de dados ainda estiver consumindo mais armazenamento do que o esperado, verifique o seguinte:

  • Tamanho dos arquivos de log do banco de dados
  • Presença de arquivos temporários
  • Aumento constante no uso do disco de logs de transações
  • Slot de replicação:
  • Os slots de replicação física são criados por réplicas de leitura entre regiões ou réplicas de leitura da mesma região somente se estiverem em execução no PostgreSQL 14.1 e versões superiores
  • Os slots de replicação lógica são criados para uma réplica ou assinante
  • Inchaço ou remoção inadequada de linhas inativas
  • Presença de arquivos órfãos

3.    Quando sua workload for previsível, ative o escalonamento automático de armazenamento para sua instância. Com o escalonamento automático de armazenamento ativado, quando o Amazon RDS detectar que você está ficando sem espaço livre no banco de dados, seu armazenamento será escalado automaticamente. O Amazon RDS inicia uma modificação de armazenamento para uma instância de banco de dados com escalonamento automático quando os seguintes fatores se aplicam:

  • O espaço livre disponível representa menos de 10% do armazenamento alocado.
  • A condição de baixo armazenamento dura pelo menos cinco minutos.
  • Passaram pelo menos seis horas desde a última modificação do armazenamento, ou a otimização do armazenamento foi concluída na instância, o que tiver maior duramento.

Você pode definir um limite para o escalonamento automático de sua instância de banco de dados definindo o limite máximo de armazenamento. Para obter mais informações, consulte Gerenciamento automático da capacidade com o escalonamento automático de armazenamento do Amazon RDS.

Verifique o tamanho dos arquivos de log do banco de dados

Por padrão, os arquivos de log de erros do Amazon RDS para PostgreSQL têm um valor de retenção de 4.320 minutos (três dias). Arquivos de log grandes podem usar mais espaço devido ao aumento de workload ou ao excesso de registros em log. Você pode alterar o período de retenção dos logs do sistema usando o parâmetro rds.log\ _retention\ _period no grupo de parâmetros de banco de dados associado à sua instância de banco de dados. Por exemplo, se você definir o valor como 1440, os logs serão retidos por um dia. Para mais informações, consulte Arquivos de log do banco de dados PostgreSQL.

Além disso, você pode alterar o relatório de erros e os parâmetros de registro em log no grupo de parâmetros do banco de dados para reduzir o excesso de registros em log. Isso, por sua vez, reduz o tamanho do arquivo de log. Para mais informações, leia Relatório de erros e registros em log.

Verifique se há arquivos temporários

Arquivos temporários são arquivos armazenados por back-end ou conexão de sessão. Esses arquivos são usados como um pool de recursos. Revise as estatísticas de arquivos temporários executando um comando semelhante a este:

psql=> SELECT datname, temp_files AS "Temporary files",temp_bytes AS "Size of temporary files" FROM pg_stat_database ;

Importante: As colunas temp_files e temp_bytes na exibição pg_stat_database estão coletando estatísticas em agregação (cumulativa). Isso ocorre por projeto porque esses contadores são redefinidos somente pela recuperação na inicialização do servidor. Ou seja, os contadores são reiniciados após um desligamento imediato, uma falha no servidor ou uma recuperação para um ponto no tempo (PITR). Por esse motivo, é uma prática recomendada monitorar o crescimento desses arquivos em número e tamanho, em vez de revisar somente a saída.

Arquivos temporários são criados para classificações, hashes ou resultados de consultas temporárias. Para rastrear a criação de tabelas ou arquivos temporários, defina log_temp_files em um grupo de parâmetros personalizado. Esse parâmetro controla o registro em log de nomes e tamanhos de arquivos temporários. Se você definir o valor de log_temp_files como 0, todas as informações do arquivo temporário serão registradas em log. Se você definir o parâmetro como um valor positivo, somente arquivos iguais ou maiores que o número especificado de kilobytes serão registrados. A configuração padrão é -1, o que desativa o registro em log de arquivos temporários.

Você também pode usar uma instrução EXPLAIN ANALYZE da sua consulta para analisar a classificação do disco. Ao analisar a saída de registro, você pode ver o tamanho dos arquivos temporários criados pela sua consulta. Para mais informações, consulte a documentação do PostgreSQL para Monitoramento da atividade de banco de dados.

Verifique se há um aumento constante no uso do disco de logs de transações

A métrica do CloudWatch para TransactionLogsDiskUsage representa o espaço em disco usado pelos WALs da transação. Aumentos no uso do disco de log de transações podem ocorrer devido a:

  • Cargas elevadas do banco de dados (gravações e atualizações que geram WALs adicionais)
  • Atraso da réplica de leitura do streaming (réplicas na mesma região) ou da réplica de leitura no estado de armazenamento cheio
  • Slots de replicação

Os slots de replicação podem ser criados como parte do recurso de decodificação lógica do AWS Database Migration Service (AWS DMS). Para replicação lógica, o parâmetro de slot rds.logical_replication é definido como 1. Os slots de replicação retêm os arquivos WAL até que eles sejam consumidos externamente por um consumidor. Por exemplo, eles podem ser consumidos por jobs pg_recvlogical; extração, transformação e carregamento (ETL); ou AWS DMS.

Se você definir o valor do parâmetro rds.logical_replication como 1, o AWS RDS definirá os parâmetros wal_level, max_wal_senders, max_replication_slots, e max_connections. Alterar esses parâmetros pode aumentar a geração de WAL. É uma prática recomendada definir o parâmetro rds.logical_replication somente quando você estiver usando slots lógicos. Se esse parâmetro estiver definido como 1 e houver slots de replicação lógica, mas não houver um consumidor para os arquivos WAL retidos pelo slot de replicação, o uso do disco de logs de transações poderá aumentar. Isso também resulta em uma diminuição constante no espaço livre de armazenamento.

Execute esta consulta para confirmar a presença e o tamanho dos slots de replicação:

PostgreSQL v9:

psql=> SELECT slot_name, pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(),restart_lsn)) AS
replicationSlotLag, active FROM pg_replication_slots ;

PostgreSQL v10 e versões posteriores:

psql=> SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag,
active FROM pg_replication_slots ;

Depois de identificar o slot de replicação que não está sendo consumido (com um estado ativo que é False), elimine o slot de replicação executando esta consulta:

psql=> SELECT pg_drop_replication_slot('Your_slotname_name');

Observação: Se uma tarefa do AWS DMS for do consumidor e não for mais necessária, exclua a tarefa e elimine manualmente o slot de replicação.

Exemplo de saída:

slot_name                                                      | replicationslotlag | active
---------------------------------------------------------------+--------------------+--------
xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d    | 129 GB             | f
7pajuy7htthd7sqn_00013322_a27bcebf_7d0f_4124_b336_92d0fb9f5130 | 704 MB             | t
zp2tkfo4ejw3dtlw_00013322_03e77862_689d_41c5_99ba_021c8a3f851a | 624 MB             | t

Neste exemplo, o nome do slot xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d tem um estado ativo que é False. Portanto, esse slot não é usado ativamente e está contribuindo com 129 GB de arquivos de transação.

Elimine a consulta executando o seguinte comando:

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Verifique o status das réplicas de leitura entre Regiões

Quando você usa a replicação de leitura entre Regiões, um slot de replicação física é criado na instância primária. Se a réplica de leitura entre Regiões falhar, o espaço de armazenamento na instância primária do banco de dados poderá ser afetado. Isso acontece porque os arquivos WAL não são replicados na réplica de leitura. Você pode usar as métricas do CloudWatch, o Atraso Mais Antigo do Slot de Replicação e o Uso de Disco de Logs de Transação para determinar o atraso da réplica mais atrasada. Você também pode ver quanto armazenamento é usado para dados WAL.

Para verificar o status da réplica de leitura entre regiões, use a consulta pg_replication_slots. Para mais informações, consulte a documentação do PostgreSQL para pg_replication_slots. Se o estado ativo for retornado como false, o slot não está sendo usado atualmente para replicação.

psql=> SELECT * FROM pg_replication_slots;

Você também pode usar a exibição pg_stat_replication na instância de origem para verificar as estatísticas da replicação. Para mais informações, consulte a documentação do PostgreSQL para pg_stat_replication.

Verifique se há inchaço ou remoção inadequada de linhas inativas (tuplas)

Nas operações normais do PostgreSQL, as tuplas que são excluídas ou tornadas obsoletas por uma operação UPDATE não são removidas de suas tabelas. Para implementações de Controle de Simultaneidade de Várias Versões (MVCC), quando uma operação DELETE é executada, a linha não é removida imediatamente do arquivo de dados. Em vez disso, a linha é marcada como excluída definindo o campo xmax em um cabeçalho. As atualizações marcam as linhas para exclusão primeiro e, em seguida, executam uma operação de inserção. Isso permite uma simultaneidade com bloqueio mínimo entre as diferentes transações. Como resultado, diferentes versões de linha são mantidas como parte do processo de MVCC.

Se as linhas inativas não forem limpas, elas poderão permanecer nos arquivos de dados, mas permanecerão invisíveis para qualquer transação, o que afeta o espaço em disco. Se uma tabela tiver muitas operações DELETE e UPDATE, as tuplas inativas podem usar uma grande quantidade de espaço em disco que às vezes é chamada de “inchaço” no PostgreSQL.

A operação VACUUM pode liberar o armazenamento usado por tuplas inativas para que ele possa ser reutilizado, mas isso não libera o armazenamento livre para o sistema de arquivos. Executar VACUUM FULL libera o armazenamento para o sistema de arquivos. Observe, no entanto, que durante a execução do VACUUM FULL, uma trava exclusiva de acesso é mantida na tabela. Esse método também requer espaço extra em disco porque grava uma nova cópia da tabela e não libera a cópia antiga até que a operação seja concluída. É uma prática recomendada usar esse método somente quando você precisa recuperar uma quantidade significativa de espaço de dentro da tabela. Também é uma prática recomendada realizar operações periódicas de vacuum ou autovacuum em tabelas que são atualizadas com frequência. Para obter mais informações, consulte a documentação do PostgreSQL para VACUUM.

Para verificar o número estimado de tuplas inativas, use a visualização pg_stat_all_tables. Para mais informações, consulte a documentação do PostgreSQL para a visualização pg_stat_all_tables. Neste exemplo, existem 1999952 tuplas inativas (n_dead_tup):

psql => SELECT * FROM pg_stat_all_tables WHERE relname='test';

-[ RECORD 1 ]-------+------------------------------
relid               | 16395
schemaname          | public
relname             | test
seq_scan            | 3
seq_tup_read        | 5280041
idx_scan            |
idx_tup_fetch       |
n_tup_ins           | 2000000
n_tup_upd           | 0
n_tup_del           | 3639911
n_tup_hot_upd       | 0
n_live_tup          | 1635941
n_dead_tup          | 1999952
n_mod_since_analyze | 3999952
last_vacuum         |
last_autovacuum     | 2018-08-16 04:49:52.399546+00
last_analyze        | 2018-08-09 09:44:56.208889+00
last_autoanalyze    | 2018-08-16 04:50:22.581935+00
vacuum_count        | 0
autovacuum_count    | 1
analyze_count       | 1
autoanalyze_count   | 1


psql => VACUUM TEST;

Verifique se há arquivos órfãos

Arquivos órfãos podem ocorrer quando os arquivos estão presentes no diretório do banco de dados, mas não há objetos que apontem para esses arquivos. Isso pode acontecer se sua instância ficar sem armazenamento ou se o mecanismo falhar durante uma operação como ALTER TABLE, VACUUM FULL ou CLUSTER. Para verificar se há arquivos órfãos, siga estas etapas:

1.    Faça login no PostgreSQL em cada banco de dados.

2.    Execute essas consultas para avaliar os tamanhos utilizados e reais.

# Size of the database occupied by files
psql=> SELECT pg_size_pretty(pg_database_size('DATABASE_NAME'));

# Size of database retrieved by summing the objects (real size)
psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;

3.    Observe os resultados. Se a diferença for significativa, os arquivos órfãos podem estar usando espaço de armazenamento.


Informações relacionadas

Trabalho com réplicas de leitura para o Amazon RDS para PostgreSQL

Ferramentas de monitoramento automatizado