PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Il mio database PostgreSQL ha esaurito lo spazio su disco

Al giorno d'oggi lo spazio su disco è una risorsa impegnativa. Di solito vorrai archiviare i dati il ​​più a lungo possibile, ma questo potrebbe essere un problema se non intraprendi le azioni necessarie per prevenire un potenziale problema di "spazio su disco insufficiente".

In questo blog, vedremo come possiamo rilevare questo problema per PostgreSQL, prevenirlo e, se è troppo tardi, alcune opzioni che probabilmente ti aiuteranno a risolverlo.

Come identificare i problemi di spazio su disco di PostgreSQL

Se, sfortunatamente, ti trovi in ​​questa situazione di spazio su disco insufficiente, potrai vedere alcuni errori nei log del database PostgreSQL:

2020-02-20 19:18:18.131 UTC [4400] LOG:  could not close temporary statistics file "pg_stat_tmp/global.tmp": No space left on device

o anche nel registro di sistema:

Feb 20 19:29:26 blog-pg1 rsyslogd: imjournal: fclose() failed for path: '/var/lib/rsyslog/imjournal.state.tmp': No space left on device [v8.24.0-41.el7_7.2 try http://www.rsyslog.com/e/2027 ]

PostgreSQL può continuare a funzionare per un po' eseguendo query di sola lettura, ma alla fine non riuscirà a scrivere su disco, quindi vedrai qualcosa di simile nella sessione del client:

WARNING:  terminating connection because of crash of another server process

DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.

HINT:  In a moment you should be able to reconnect to the database and repeat your command.

server closed the connection unexpectedly

This probably means the server terminated abnormally

before or while processing the request.

The connection to the server was lost. Attempting reset: Failed.

Allora, se dai un'occhiata allo spazio su disco, avrai questo output indesiderato...

$ df -h

Filesystem                        Size Used Avail Use% Mounted on

/dev/mapper/pve-vm--125--disk--0   30G 30G 0 100% /

Come prevenire i problemi di spazio su disco di PostgreSQL

Il modo principale per prevenire questo tipo di problema è monitorare l'utilizzo dello spazio su disco e la crescita dell'utilizzo del database o del disco. Per questo, un grafico dovrebbe essere un modo semplice per monitorare l'incremento di spazio su disco:

E lo stesso per la crescita del database:

Un'altra cosa importante da monitorare è lo stato della replica. Se hai una replica e, per qualche motivo, smette di funzionare, a seconda della configurazione, è possibile che PostgreSQL memorizzi tutti i file WAL per ripristinare la replica quando ritorna.

Tutto questo sistema di monitoraggio non ha senso senza un sistema di avviso da sapere quando devi intraprendere delle azioni:

Come risolvere i problemi di spazio su disco di PostgreSQL

Beh, se stai affrontando questo problema di spazio su disco insufficiente anche con il sistema di monitoraggio e avviso implementato (o meno), ci sono molte opzioni per provare a risolvere questo problema senza perdere dati (o meno possibile).

Che cosa sta consumando spazio su disco?

Il primo passo dovrebbe essere determinare dove si trova il mio spazio su disco. Una procedura consigliata consiste nell'avere partizioni separate, almeno una partizione separata per l'archiviazione del database, in modo da poter confermare facilmente se il database o il sistema stanno utilizzando uno spazio su disco eccessivo. Un altro vantaggio di questo è ridurre al minimo i danni. Se la tua partizione di root è piena, il tuo database può ancora scrivere nella sua partizione senza problemi.

Utilizzo dello spazio del database

Vediamo ora alcuni comandi utili per controllare l'utilizzo dello spazio su disco del database.

Un modo semplice per controllare l'utilizzo dello spazio del database è controllare la directory dei dati nel filesystem:

$ du -sh /var/lib/pgsql/11/data/

819M /var/lib/pgsql/11/data/

Oppure, se hai una partizione separata per la tua directory dei dati, puoi usare df -h direttamente.

Il comando PostgreSQL “\l+” elenca i database aggiungendo le informazioni sulla dimensione:

$ postgres=# \l+

                                                               List of databases

   Name    | Owner   | Encoding | Collate | Ctype |   Access privileges | Size | Tablespace

|                Description

-----------+----------+-----------+---------+-------+-----------------------+---------+------------

+--------------------------------------------

 postgres  | postgres | SQL_ASCII | C       | C | | 7965 kB | pg_default

| default administrative connection database

 template0 | postgres | SQL_ASCII | C       | C | =c/postgres +| 7817 kB | pg_default

| unmodifiable empty database

           |          | |         | | postgres=CTc/postgres |         |

|

 template1 | postgres | SQL_ASCII | C       | C | =c/postgres +| 7817 kB | pg_default

| default template for new databases

           |          | |         | | postgres=CTc/postgres |         |

|

 world     | postgres | SQL_ASCII | C       | C | | 8629 kB | pg_default

|

(4 rows)

Utilizzando pg_database_size e il nome del database puoi vedere la dimensione del database:

postgres=# SELECT pg_database_size('world');

 pg_database_size

------------------

          8835743

(1 row)

E usare pg_size_pretty per vedere questo valore in modo leggibile dall'uomo potrebbe essere ancora meglio:

postgres=# SELECT pg_size_pretty(pg_database_size('world'));

 pg_size_pretty

----------------

 8629 kB

(1 row)

Quando sai dove si trova lo spazio, puoi eseguire l'azione corrispondente per risolverlo. Tieni presente che la semplice eliminazione delle righe non è sufficiente per recuperare lo spazio su disco, dovrai eseguire un VACUUM o VACUUM FULL per completare l'attività.

File di registro

Il modo più semplice per recuperare spazio su disco è eliminare i file di registro. Puoi controllare la directory dei log di PostgreSQL o anche i log di sistema per verificare se puoi guadagnare spazio da lì. Se hai qualcosa del genere:

$ du -sh /var/lib/pgsql/11/data/log/

18G /var/lib/pgsql/11/data/log/

Dovresti controllare il contenuto della directory per vedere se c'è un problema di rotazione/conservazione dei log o qualcosa sta accadendo nel tuo database e scriverlo nei log.

$ ls -lah /var/lib/pgsql/11/data/log/

total 18G

drwx------  2 postgres postgres 4.0K Feb 21 00:00 .

drwx------ 21 postgres postgres 4.0K Feb 21 00:00 ..

-rw-------  1 postgres postgres  18G Feb 21 14:46 postgresql-Fri.log

-rw-------  1 postgres postgres 9.3K Feb 20 22:52 postgresql-Thu.log

-rw-------  1 postgres postgres 3.3K Feb 19 22:36 postgresql-Wed.log

Prima di eliminare i log, se ne hai uno di grandi dimensioni, è buona norma conservare le ultime 100 righe circa, quindi eliminarlo. Quindi, puoi controllare cosa sta succedendo dopo aver generato spazio libero.

$ tail -100 postgresql-Fri.log > /tmp/log_temp.log

E poi:

$ cat /dev/null > /var/lib/pgsql/11/data/log/postgresql-Fri.log

Se lo elimini semplicemente con "rm" e il file di registro viene utilizzato dal server PostgreSQL (o da un altro servizio), lo spazio non verrà rilasciato, quindi dovresti troncare questo file usando questo cat / comando dev/null invece.

Questa azione è solo per PostgreSQL e per i file di registro di sistema. Non eliminare il contenuto pg_wal o un altro file PostgreSQL in quanto potrebbe generare danni critici al tuo database.

Gonfia

In una normale operazione PostgreSQL, le tuple cancellate o obsolete da un aggiornamento non vengono rimosse fisicamente dalla tabella; sono presenti fino a quando non viene eseguito un VUOTO. Quindi, è necessario eseguire periodicamente il VACUUM (AUTOVACUUM), soprattutto nelle tabelle aggiornate di frequente.

Il problema qui è che lo spazio non viene restituito al sistema operativo utilizzando solo VACUUM, è disponibile solo per l'uso nella stessa tabella.

VACUUM FULL riscrive la tabella in un nuovo file su disco, restituendo lo spazio inutilizzato al sistema operativo. Sfortunatamente, richiede un blocco esclusivo su ogni tabella mentre è in esecuzione.

Dovresti controllare le tabelle per vedere se è necessario un processo VACUUM (FULL).

Slot di replica

Se stai utilizzando slot di replica e per qualche motivo non è attivo:

postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;

 slot_name | slot_type | active

-----------+-----------+--------

 slot1     | physical  | f

(1 row)

Potrebbe essere un problema per il tuo spazio su disco perché memorizzerà i file WAL fino a quando non saranno stati ricevuti da tutti i nodi in standby.

Il modo per risolverlo è recuperare la replica (se possibile) o eliminare lo slot:

postgres=# SELECT pg_drop_replication_slot('slot1');

 pg_drop_replication_slot

--------------------------

(1 row)

Quindi, lo spazio utilizzato dai file WAL verrà rilasciato.

Conclusione

Come accennato, i sistemi di monitoraggio e di allerta sono le chiavi per evitare questo tipo di problemi. In questo modo, ClusterControl può aiutarti ad avere i tuoi sistemi operativi e operativi, inviandoti allarmi quando necessario o anche intraprendendo azioni di ripristino per mantenere in funzione il tuo cluster di database. Puoi anche distribuire/importare diverse tecnologie di database e ridimensionarle se necessario.