Perché ho ricevuto l'errore “No space left on device” o “DiskFull” su Amazon RDS per PostgreSQL?

9 minuti di lettura
0

Dispongo di un piccolo database Amazon Relational Database Service (Amazon RDS) per PostgreSQL. Lo spazio di archiviazione disponibile per l'istanza database sta diminuendo e ricevo il seguente errore: “Error message: PG::DiskFull: ERROR: could not extend file “base/16394/5139755”: No space left on device. HINT: Check free disk space.”

Risoluzione

Nota: se il carico di lavoro è prevedibile, attiva il dimensionamento automatico dello spazio di archiviazione per la tua istanza. Grazie al dimensionamento automatico dello spazio di archiviazione, Amazon RDS lo ridimensiona automaticamente quando lo spazio disponibile per il database è insufficiente.

Per monitorare lo spazio di archiviazione, controlla la metrica di Amazon CloudWatch FreeStorageSpace. Configura un allarme CloudWatch per lo spazio di archiviazione disponibile in modo da ricevere una notifica quando lo spazio inizia a diminuire. Se ricevi un allarme, controlla le seguenti risorse che utilizzano spazio di archiviazione per le istanze database di Amazon RDS:

  • Tabelle o file temporanei creati da transazioni PostgreSQL
  • File di dati
  • Log WAL (Write-Ahead Log)
  • Slot di replica
  • Log del database come file di errore conservati per troppo tempo
  • Altri file di database o Linux che supportano lo stato coerente delle istanze database RDS

Se l'istanza database consuma più dello spazio di archiviazione previsto, intraprendi le seguenti azioni di risoluzione dei problemi.

Verifica la dimensione dei file di registro del database

Per impostazione predefinita, i file di registro degli errori di Amazon RDS per PostgreSQL vengono conservati per 4.320 minuti (3 giorni). Quelli di grandi dimensioni possono occupare più spazio per via di carichi di lavoro maggiori o eccessiva registrazione. Per modificare il periodo di conservazione dei log di sistema, utilizza il parametro rds.log_retention_period nel gruppo di parametri del database associato all’istanza database. Ad esempio, se imposti il valore su 1.440, Amazon RDS conserva i log per 1 giorno. Per ulteriori informazioni, consulta RDS per i file di registro del database PostgreSQL.

Per ridurre l'eccessiva registrazione, modifica i parametri di segnalazione e registrazione degli errori nel gruppo di parametri del database. Questa azione comporta una riduzione delle dimensioni del file di registro. Per ulteriori informazioni, consulta 19.8 Segnalazione e registrazione degli errori sul sito Web PostgreSQL.

Verifica la presenza di file temporanei

I file temporanei sono file che Amazon RDS archivia in ogni backend o connessione di sessione. Amazon RDS utilizza questi file come pool di risorse. Per esaminare le statistiche dei file temporanei, esegui il seguente comando:

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

Importante: le colonne temp_files e temp_bytes nella vista pg_stat_database raccolgono statistiche aggregate. Amazon RDS azzera questi contatori solo dopo un arresto immediato, un crash del server o un ripristino point-in-time (PITR). Per questo motivo, oltre all'output, è consigliabile monitorare anche la crescita del numero e delle dimensioni di questi file.

Amazon RDS crea file temporanei per ordinamenti, hash e risultati di query temporanei. Per tenere traccia della creazione di tabelle o file temporanei, in un gruppo di parametri personalizzato, imposta log_temp_files su 0 per registrare tutte le informazioni sui file temporanei. Per impostazione predefinita, log_temp_files è impostato su -1, quindi Amazon RDS non registra i file temporanei. Se imposti log_temp_files su un valore positivo, Amazon RDS registra solo i file uguali o superiori a quel numero di kilobyte.

Utilizza EXPLAIN ANALYZE sulla tua query per esaminare l'ordinamento su disco. Nell'output del registro, controlla le dimensioni dei file temporanei creati dalla query. Per ulteriori informazioni, consulta Ottimizzazione delle operazioni di ordinamento in PostgreSQL con work_mem.

Verifica se vi è un aumento costante dell'utilizzo del disco da parte dei log delle transazioni

Controlla la metrica TransactionLogsDiskUsage per visualizzare lo spazio su disco utilizzato dalla transazione WAL. L'aumento dell'utilizzo del disco da parte dei log delle transazioni può verificarsi per i seguenti motivi:

  • Carichi elevati a livello del database causati da scritture e aggiornamenti che generano WAL aggiuntivi
  • Ritardo di lettura della replica in streaming per le repliche nella stessa regione AWS o replica di lettura in stato di spazio di archiviazione pieno
  • Slot di replica

AWS Database Migration Service (AWS DMS) potrebbe creare slot di replica come parte della decodifica logica. Per la replica logica, il parametro dello slot rds.logical_replication è impostato su 1. Gli slot di replica conservano i file WAL fino a quando un utente esterno non li consuma. Esempi di consumatori sono pg_recvlogical, processi di estrazione, trasformazione e caricamento (ETL) e AWS DMS.

Se imposti rds.logical_replication su 1, Amazon RDS imposterà i parametri wal_level, max_wal_senders, max_replication_slots e max_connections. Queste modifiche ai parametri potrebbero aumentare la generazione di WAL. È consigliabile impostare il parametro rds.logical_replication solo quando si utilizzano slot logici. Se non esiste un consumatore per i file WAL conservati, l'utilizzo del disco per i log delle transazioni aumenta e lo spazio di archiviazione disponibile diminuisce costantemente.

Per verificare la presenza e la dimensione degli slot di replica, esegui le seguenti query:

  • 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 versioni successive:

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

Esempio di output:

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

Gli slot di replica con uno stato attivo impostato su f (false) non vengono consumati. In questo esempio, lo slot xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d ha uno stato f attivo. Questo slot non viene utilizzato attivamente, ma utilizza 129 GB di file di transazioni.

Per eliminare gli slot inutilizzati, esegui la seguente query:

psql=> SELECT pg_drop_replication_slot('YOUR_SLOTNAME');

Nota: sostituisci a YOUR_SLOTNAME il nome dello slot.

Esempio di output:

psql=> SELECT pg_drop_replication_slot('xc36ujql35djp_00013322_907c1e0a_9f8b_4c13_89ea_ef0ea1cf143d');

Se un'attività di AWS DMS che non serve più è il consumatore, elimina l'attività e rimuovi manualmente lo slot di replica.

Verifica lo stato delle repliche di lettura tra regioni o nella stessa regione

Nota: puoi utilizzare la seguente risoluzione per le repliche di lettura nella stessa regione solo se sono in esecuzione su PostgreSQL 14.1 o versioni successive.

Quando utilizzi una replica di lettura tra regioni o nella stessa regione, Amazon RDS crea uno slot di replica fisico sull'istanza primaria. Un errore di replica di lettura potrebbe incidere sullo spazio di archiviazione dell'istanza database primaria. Questa situazione si verifica quando i file WAL non vengono replicati nella replica di lettura. Controlla le metriche OldestReplicationSlotLag e TransactionLogsDiskUsage per determinare quanto è indietro la replica con il maggior ritardo. Puoi anche vedere quanto spazio di archiviazione è utilizzato dai dati WAL.

Per verificare lo stato della replica di lettura, esegui la seguente query:

psql=> SELECT * FROM pg_replication_slots;

Per ulteriori informazioni su pg_replication_slots, consulta 52.19 pg_replication_slots sul sito Web PostgreSQL. Se lo stato attivo dell'output è impostato su f, lo slot non viene utilizzato per la replica.

Puoi anche usare la vista pg_stat_replication sull'istanza di origine per verificare le statistiche relative alla replica. Per ulteriori informazioni, consulta Table 27.14. pg_stat_replication view sul sito Web PostgreSQL.

Verifica che non vi sia una proliferazione incontrollata o una rimozione inadeguata di righe inutilizzate

Nelle operazioni PostgreSQL standard, PostgreSQL non rimuove le righe inutilizzate (tuple) che gli utenti eliminano o che un comando UPDATE rende obsolete nella tabella. Per le implementazioni Multi-Version Concurrency Control (MVCC), quando viene eseguita un'operazione DELETE, la riga non viene immediatamente rimossa dal file di dati. Invece, PostgreSQL imposta il campo xmax in un'intestazione per contrassegnare la riga come eliminata. Nel corso di un aggiornamento, prima vengono contrassegnate le righe da eliminare, quindi viene eseguita un'operazione di inserimento. Ciò consente la concorrenza con un blocco minimo tra le diverse transazioni. Di conseguenza, PostgreSQL mantiene diverse versioni delle righe come parte del processo MVCC.

Le righe inutilizzate che non vengono rimosse rimangono nei file di dati, ma sono invisibili alle transazioni. Queste righe possono causare problemi di spazio su disco. Se una tabella ha molte operazioni DELETE e UPDATE, le tuple da eliminare potrebbero utilizzare una grande quantità di spazio su disco (bloat).

Utilizza l'operazione VACUUM per liberare lo spazio di archiviazione utilizzato da queste tuple. Nota: VACUUM non rilascia lo spazio di archiviazione liberato al file system. Per rilasciare l'archiviazione al file system, utilizza VACUUM FULL. Nota: quando esegui VACUUM FULL, PostgreSQL applica un blocco esclusivo di accesso alla tabella. Questo metodo richiede spazio su disco aggiuntivo perché VACUUM FULL scrive una nuova copia della tabella e non rilascia la copia esistente fino al completamento dell'operazione. È consigliabile utilizzare VACUUM FULL solo quando lo spazio da recuperare dalla tabella è significativo. Si raccomanda inoltre di eseguire operazioni periodiche VACUUM e AUTOVACUUM sulle tabelle che vengono aggiornate di frequente. Per ulteriori informazioni, consulta VACUUM sul sito Web PostgreSQL.

Per controllare il numero stimato di tuple inutilizzate, utilizza la vista pg_stat_all_tables. Per ulteriori informazioni, consulta Table 27.29. pg_stat_all_tables view sul sito Web PostgreSQL. Nel seguente esempio di tabella, sono presenti 1.999.952 tuple inutilizzate nel record 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;

Verifica la presenza di file orfani

Quando nessun oggetto punta a un file presente nella directory del database possono crearsi file orfani. Ciò avviene, ad esempio, quando un'istanza esaurisce lo spazio di archiviazione o si verifica un crash nel corso di un'operazione come ALTER TABLE, VACUUM FULL o CLUSTER. Per controllare la presenza di file orfani, completa i seguenti passaggi:

  1. Accedi a PostgreSQL in ogni database.

  2. Per ottenere la dimensione utilizzata del database, esegui la seguente query:

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

    Nota: sostituisci a DATABASE_NAME il nome del tuo database.

  3. Per ottenere le dimensioni reali del database, esegui la seguente query:

    psql=> SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class;
  4. Confronta la dimensione utilizzata e le dimensioni reali del database sulla base degli output dei comandi precedenti. Se la differenza è significativa, è possibile che file orfani stiano utilizzando spazio di archiviazione.

Informazioni correlate

Utilizzo di repliche di lettura per Amazon RDS per PostgreSQL

Strumenti di monitoraggio automatici