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

Misurazione delle statistiche dei checkpoint di PostgreSQL

I checkpoint possono essere un ostacolo importante per le installazioni PostgreSQL che richiedono molta scrittura. Il primo passo per identificare i problemi in quest'area è monitorare la frequenza con cui si verificano, che è appena stata aggiunta al database un'interfaccia più facile da usare di recente.

I checkpoint sono operazioni di manutenzione periodiche eseguite dal database per assicurarsi che tutto ciò che è stato memorizzato nella cache sia stato sincronizzato con il disco. L'idea è che una volta terminato uno, è possibile eliminare la necessità di preoccuparsi delle voci più vecchie inserite nel registro write-ahead del database. Ciò significa meno tempo per il ripristino dopo un arresto anomalo.
Il problema con i checkpoint è che possono essere molto intensi, perché per completarne uno è necessario scrivere su disco ogni singolo bit di dati modificati nella cache del buffer del database. Sono state aggiunte una serie di funzionalità a PostgreSQL 8.3 che consentono di monitorare meglio l'overhead del checkpoint e di ridurlo distribuendo l'attività su un periodo di tempo più lungo. Ho scritto un lungo articolo su quei cambiamenti chiamato Checkpoints and the Background Writer che va oltre ciò che è cambiato, ma è una lettura piuttosto secca.
Quello che probabilmente vorresti sapere è come monitorare i checkpoint sul tuo sistema di produzione e come dirlo se accadono troppo spesso. Anche se le cose sono migliorate, i "picchi di checkpoint" in cui l'I/O del disco diventa davvero pesante sono ancora possibili anche nelle attuali versioni di PostgreSQL. E non aiuta il fatto che la configurazione predefinita sia ottimizzata per uno spazio su disco molto basso e un ripristino rapido degli arresti anomali piuttosto che per le prestazioni. Il parametro checkpoint_segments, che è un input sulla frequenza con cui si verifica un checkpoint, è impostato su 3, il che forza un checkpoint dopo solo 48 MB di scritture.
Puoi scoprire la frequenza del checkpoint in due modi. Puoi attivare log_checkpoints e guardare cosa succede nei log. Puoi anche utilizzare la vista pg_stat_bgwriter, che fornisce un conteggio di ciascuna delle due fonti per i checkpoint (tempo che passa e scritture che si verificano) e statistiche su quanto lavoro hanno svolto.
Il problema principale nel renderlo più facile fino a poco tempo fa era impossibile reimpostare i contatori all'interno di pg_stat_bgwriter. Ciò significa che devi scattare un'istantanea con un timestamp, attendere un po', scattare un'altra istantanea, quindi sottrarre tutti i valori per ricavare eventuali statistiche utili dai dati. È un dolore.
Abbastanza di dolore che ho scritto una patch per renderlo più facile. Con l'attuale versione di sviluppo del database, ora puoi chiamare pg_stat_reset_shared('bgwriter') e riportare tutti questi valori a 0. Ciò consente di seguire una pratica che era comune su PostgreSQL. Prima della 8.3, c'era un parametro chiamato stats_reset_on_server_start che potevi attivare. Ciò ripristina tutte le statistiche interne del server ogni volta che lo avvii. Ciò significava che puoi chiamare la pratica funzione pg_postmaster_start_time(), confrontare con l'ora corrente e avere sempre un conteggio accurato in termini di operazioni/secondo di qualsiasi statistica disponibile sul sistema.
Non è ancora automatico, ma ora che è possibile ripristinare questi pezzi condivisi, puoi farlo da solo. La prima chiave è integrare la cancellazione delle statistiche nella sequenza di avvio del server. Uno script come questo funzionerà:


pg_ctl start -l $PGLOG -w
psql -c "select pg_stat_reset();"
psql -c "select pg_stat_reset_shared('bgwriter');"

Nota "-w" sul comando di avvio lì, che farà attendere pg_ctl fino al termine dell'avvio del server prima di tornare, il che è fondamentale se vuoi eseguire immediatamente un'istruzione contro di esso.
Se hai fatto quello, e l'ora di inizio del tuo server è essenzialmente la stessa di quando lo scrittore in background ha iniziato la raccolta delle statistiche, ora puoi usare questa divertente query:


SELECT
total_checkpoints,
seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints
FROM
(SELECT
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;

E ottieni un semplice rapporto sulla frequenza esatta con cui si verificano i checkpoint sul tuo sistema. L'output è simile a questo:


total_checkpoints           | 9
minutes_between_checkpoints | 3.82999310740741

Quello che fai con queste informazioni è fissare l'intervallo di tempo medio e vedere se sembra troppo veloce. Normalmente, vorresti che un checkpoint si verificasse non più di ogni cinque minuti e su un sistema occupato potresti dover spingerlo a dieci minuti o più per avere una speranza di tenere il passo. Con questo esempio, ogni 3,8 minuti è probabilmente troppo veloce:questo è un sistema che ha bisogno di checkpoint_segments per essere più alto.
L'utilizzo di questa tecnica per misurare l'intervallo di checkpoint ti consente di sapere se è necessario aumentare i parametri checkpoint_segments e checkpoint_timeout in ordine per raggiungere quell'obiettivo. Puoi calcolare i numeri manualmente in questo momento e una volta che la versione 9.0 è stata spedita è qualcosa che puoi considerare di rendere completamente automatico, purché non ti dispiaccia che le tue statistiche scompaiono ogni volta che il server si riavvia.
Ci sono altri modi interessanti per analizzare i dati che lo scrittore in background ti fornisce in pg_stat_bgwriter, ma non ho intenzione di svelare tutti i miei trucchi oggi.