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

10 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 do banco de dados está diminuindo e eu recebo o seguinte erro: “Error message: 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.”

Resolução

Observação: se sua workload for previsível, ative o escalonamento automático de armazenamento ativo para sua instância. Com o escalonamento automático de armazenamento, o Amazon RDS dimensiona automaticamente seu armazenamento quando o espaço livre no banco de dados é baixo.

Para monitorar seu espaço de armazenamento, verifique a métrica FreeStorageSpace Amazon CloudWatch. Defina um alarme do CloudWatch para liberar espaço de armazenamento para receber uma notificação quando o espaço começar a diminuir. Se você receber um alarme, verifique os seguintes recursos que usam o armazenamento de instâncias de banco de dados Amazon RDS:

  • Tabelas ou arquivos temporários criados por transações do PostgreSQL
  • Arquivos de dados
  • Logs de gravação antecipada (WAL)
  • Slots de replicação
  • Logs de banco de dados como arquivos de erro 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

Se sua instância de banco de dados consumir mais do que o armazenamento esperado, execute as seguintes ações de solução de problemas.

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 logs. Para alterar o período de retenção dos logs do sistema, use 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 1.440, o Amazon RDS reterá os logs por um dia. Para obter mais informações, consulte Arquivos de log do banco de dados PostgreSQL.

Para reduzir logs excessivos, altere o relatório de erros e os parâmetros de logs no grupo de parâmetros do banco de dados. Essa ação resulta na redução do tamanho do arquivo de log. Para obter mais informações, consulte 19.8 Error reporting and logging no site do PostgreSQL.

Verifique se há arquivos temporários

Arquivos temporários são arquivos que o Amazon RDS armazena em cada conexão de back-end ou sessão. O Amazon RDS usa esses arquivos como um pool de recursos. Para revisar as estatísticas dos arquivos temporários, execute o seguinte comando:

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 visualização pg_stat_database coletam estatísticas agregadas. O Amazon RDS redefine esses contadores somente após um desligamento imediato, uma falha no servidor ou uma recuperação pontual (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.

O Amazon RDS cria arquivos temporários para classificações, hashes e resultados de consultas temporárias. Para rastrear a criação de tabelas ou arquivos temporários, em um grupo de parâmetros personalizado, defina log_temp\ _files como 0 para registrar todas as informações do arquivo temporário. Por padrão, log_temp_files é definido como -1; portanto, o Amazon RDS não registra arquivos temporários. Se você definir log_temp_files como um valor positivo, o Amazon RDS registrará somente arquivos iguais ou maiores que essa quantidade de kilobytes.

Use um EXPLAIN ANALYZE em sua consulta para revisar a classificação do disco. Na saída do registro, verifique o tamanho dos arquivos temporários que sua consulta cria. Para obter mais informações, consulte Ajustar as operações de classificação no PostgreSQL com work_mem.

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

Verifique a métrica TransactionLogsDiskUsage para visualizar o espaço em disco que a transação WAL usa. Aumentos no uso do disco de log de transações podem ocorrer pelos seguintes motivos:

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

O AWS Database Migration Service (AWS DMS) pode criar slots de replicação como parte da decodificação lógica. 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 um consumidor externo os consuma. Os exemplos de consumidores incluem trabalhos pg_recvlogical, extração, transformação e carregamento (ETL) e o AWS DMS.

Se você definir rds.logical_replication como 1, o Amazon RDS definirá os parâmetros wal_level, max_wal_senders, max_replication_slots e max_connections. Essas mudanças de parâmetros podem 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 não houver um consumidor para os arquivos WAL retidos, o uso do disco dos logs de transações aumentará e o espaço de armazenamento livre diminuirá consistentemente.

Para verificar a presença e o tamanho dos slots de replicação, execute as seguintes consultas:

  • 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 ;

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

Os slots de replicação que têm um estado ativo definido como f (falso) não estão sendo consumidos. Neste exemplo, o slot xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d tem um estado ativo f que. Esse slot não é usado ativamente, mas usa 129 GB de arquivos de transação.

Para eliminar os slots não utilizados, execute a seguinte consulta:

psql=> SELECT pg_drop_replication_slot('YOUR_SLOTNAME');

Observação: Substitua YOUR_SLOTNAME pelo nome do slot.

Exemplo de saída:

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Se uma tarefa do AWS DMS que você não precisa mais for o consumidor, exclua a tarefa e elimine manualmente o slot de replicação.

Verifique o status das réplicas de leitura entre regiões ou na mesma região

Observação: é possível usar a resolução a seguir para réplicas de leitura na mesma região somente se elas estiverem em execução no PostgreSQL 14.1 ou posterior.

Quando você usa uma replicação de leitura entre regiões ou na mesma região, o Amazon RDS cria um slot de replicação física na instância primária. Uma falha na réplica de leitura pode afetar o espaço de armazenamento na instância de banco de dados primária. Essa situação ocorre quando os arquivos WAL não são replicados na réplica de leitura. Verifique as métricas OldestReplicationSlotLag e TransactionLogsDiskUsage para determinar a que distância está a réplica com maior atraso. Você também pode ver quanto armazenamento os dados do WAL usam.

Para verificar o status da réplica de leitura, execute a seguinte consulta:

psql=> SELECT * FROM pg_replication_slots;

Para obter mais informações sobre pg_replication_slots, consulte 52.19 pg_replication_slots no site do PostgreSQL. Se a saída tiver o estado ativo definido como f, o slot não será usado para replicação.

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 obter mais informações, consulte a Tabela 27.14. pg_stat_replication view no site do PostgreSQL.

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

Nas operações padrão do PostgreSQL, o PostgreSQL não remove linhas mortas (tuplas) que os usuários excluem ou que uma UPDATE torna obsoletas da sua tabela. 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, o PostgreSQL define o campo xmax em um cabeçalho para marcar a linha como excluída. 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, o PostgreSQL mantém diferentes versões de linha como parte do processo MVCC.

As linhas mortas que não são limpas permanecem nos arquivos de dados, mas permanecem invisíveis para as transações. Essas linhas podem causar problemas de espaço em disco. Se uma tabela tiver muitas operações DELETE e UPDATE, as tuplas mortas podem usar uma grande quantidade de espaço em disco (inchaço).

Use a operação VACUUM para liberar o armazenamento usado pelas tuplas mortas. Observe que VACUUM não libera o armazenamento gratuito para o sistema de arquivos. Para liberar o armazenamento para o sistema de arquivos, use VACUUM FULL. Observe que quando você executa VACUUM FULL, o PostgreSQL aplica um bloqueio exclusivo de acesso à tabela. Esse método requer espaço extra em disco porque VACUUM FULL grava uma nova cópia da tabela e não libera a cópia existente até que a operação seja concluída. É uma prática recomendada usar VACUUM FULL 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 VACUUM no site do PostgreSQL.

Para verificar o número estimado de tuplas inativas, use a visualização pg_stat_all_tables. Para obter mais informações, consulte a Tabela 27.29. visualização pg_stat_all_tables no site do PostgreSQL. Na tabela de exemplo a seguir, há 1.999.952 tuplas mortas no registro 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     | 2024-08-16 04:49:52.399546+00
last_analyze        | 2024-08-09 09:44:56.208889+00
last_autoanalyze    | 2024-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 nenhum objeto apontar para um arquivo presente no diretório do banco de dados. Essa situação ocorre quando 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, realize as seguintes etapas:

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

  2. Para obter o tamanho usado do banco de dados, execute a seguinte consulta:

    psql=> SELECT pg_size_pretty(pg_database_size('DATABASE_NAME'));

    Observação: substitua DATABASE_NAME pelo nome do seu banco de dados.

  3. Para obter o tamanho real do banco de dados, execute a seguinte consulta:

    psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;
  4. Compare o tamanho usado e real do banco de dados com as saídas dos comandos anteriores. 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