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

PostgreSQL VACUUM e ANALYZE Suggerimenti per le migliori pratiche

VACUUM e ANALYZE sono le due più importanti operazioni di manutenzione del database PostgreSQL.

Un vuoto viene utilizzato per recuperare lo spazio occupato da "tuple morte" in una tabella. Una tupla morta viene creata quando un record viene eliminato o aggiornato (un'eliminazione seguita da un inserimento). PostgreSQL non rimuove fisicamente la vecchia riga dalla tabella ma inserisce un "marcatore" su di essa in modo che le query non restituiscano quella riga. Quando viene eseguito un processo di vuoto, lo spazio occupato da queste tuple morte viene contrassegnato come riutilizzabile da altre tuple.

Un'operazione di "analisi" fa ciò che dice il suo nome:analizza il contenuto delle tabelle di un database e raccoglie statistiche sulla distribuzione dei valori in ogni colonna di ogni tabella. Il motore di query PostgreSQL utilizza queste statistiche per trovare il miglior piano di query. Quando le righe vengono inserite, eliminate e aggiornate in un database, cambiano anche le statistiche delle colonne. ANALIZZA, eseguito manualmente dal DBA o automaticamente da PostgreSQL dopo un autovacuum, assicura che le statistiche siano aggiornate.

Sebbene suonino relativamente semplici, dietro le quinte, passare l'aspirapolvere e analizzare sono due processi complessi. Fortunatamente, i DBA non devono preoccuparsi molto dei loro interni. Tuttavia, sono spesso confusi sull'esecuzione manuale di questi processi o sull'impostazione dei valori ottimali per i parametri di configurazione.

In questo articolo condivideremo alcune best practice per VACUUM e ANALYZE.

Suggerimento 1:non eseguire l'ASPIRAZIONE o ANALISI manuale senza motivo

L'aspirazione PostgreSQL (autovuoto o vuoto manuale) riduce al minimo i rigonfiamenti del tavolo e impedisce il wrapping dell'ID transazione. Autovacuum non recupera lo spazio su disco occupato dalle tuple morte. Tuttavia, eseguire un VUOTO PIENO il comando lo farà. VACUUM FULL ha le sue implicazioni sulle prestazioni, però. La tabella di destinazione è bloccata esclusivamente durante l'operazione, impedendo anche letture sulla tabella. Il processo esegue anche una copia completa della tabella, che richiede spazio su disco aggiuntivo durante l'esecuzione. Si consiglia di non eseguire VACUUM FULL a meno che non vi sia una percentuale molto alta di rigonfiamento e le query stiano soffrendo gravemente. Ti consigliamo inoltre di utilizzare i periodi di attività del database più bassa per questo.

È inoltre consigliabile non eseguire aspirapolvere manuali troppo spesso sull'intero database; il database di destinazione potrebbe già essere aspirato in modo ottimale dal processo di autovacuum. Di conseguenza, un vuoto manuale potrebbe non rimuovere le tuple morte ma causare carichi di I/O o picchi di CPU non necessari. Se necessario, gli aspiratori manuali dovrebbero essere eseguiti solo tabella per tabella quando ce n'è bisogno, come rapporti bassi tra file attive e file morte o ampi spazi tra gli autovacuum. Inoltre, l'aspirazione manuale dovrebbe essere eseguita quando l'attività dell'utente è minima.

Autovacuum mantiene anche aggiornate le statistiche di distribuzione dei dati di una tabella (non le ricostruisce). Quando viene eseguito manualmente, ANALYZE command ricostruisce effettivamente queste statistiche invece di aggiornarle. Anche in questo caso, la ricostruzione delle statistiche quando sono già aggiornate in modo ottimale da un normale autovacuum potrebbe causare una pressione non necessaria sulle risorse di sistema.

Il momento in cui è necessario eseguire ANALYZE manualmente è immediatamente successivo al caricamento in blocco dei dati nella tabella di destinazione. Un numero elevato (anche poche centinaia) di nuove righe in una tabella esistente distorcerà notevolmente la distribuzione dei dati delle colonne. Le nuove righe renderanno obsolete tutte le statistiche di colonna esistenti. Quando Query Optimizer utilizza tali statistiche, le prestazioni delle query possono essere molto lente. In questi casi, eseguire il comando ANALYZE subito dopo un caricamento di dati per ricostruire completamente le statistiche è un'opzione migliore rispetto all'attesa dell'avvio dell'autovacuum.

Suggerimento 2:perfeziona la soglia di autovuoto

È essenziale controllare o ottimizzare l'autovacuum e analizzare i parametri di configurazione in postgresql.conf file o nelle singole proprietà della tabella per trovare un equilibrio tra autovacuum e aumento delle prestazioni.

PostgreSQL utilizza due parametri di configurazione per decidere quando avviare un autovacuum:

  • autovacuum_vacuum_threshold :ha un valore predefinito di 50
  • autovacuum_vacuum_scale_factor :ha un valore predefinito di 0,2

Insieme, questi parametri indicano a PostgreSQL di avviare un autovacuum quando il numero di righe morte in una tabella supera il numero di righe in quella tabella moltiplicato per il fattore di scala, più la soglia di vuoto. In altre parole, PostgreSQL avvierà l'autovacuum su una tabella quando:

pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor)  + autovacuum_vacuum_threshold

Per tavoli di piccole e medie dimensioni, questo può essere sufficiente. Ad esempio, una tabella con 10.000 righe, il numero di righe morte deve essere superiore a 2.050 ((10.000 x 0,2) + 50) prima che inizi un autovacuum.

Non tutte le tabelle di un database presentano la stessa velocità di modifica dei dati. Di solito, alcune tabelle di grandi dimensioni subiranno frequenti modifiche ai dati e, di conseguenza, avranno un numero maggiore di righe morte. I valori predefiniti potrebbero non funzionare per tali tabelle. Ad esempio, con i valori predefiniti, una tabella con 1 milione di righe dovrà avere più di 200.050 righe morte prima che inizi un vuoto automatico ((1000.000 x 0,2) + 50). Ciò può significare intervalli più lunghi tra gli autovacuum, tempi di autovacuum sempre più lunghi e, peggio ancora, che l'autovacuum non funziona affatto se le transazioni attive sul tavolo lo bloccano.

Pertanto, l'obiettivo dovrebbe essere impostare queste soglie su valori ottimali in modo che l'autovacuum possa avvenire a intervalli regolari e non richieda molto tempo (e influisca sulle sessioni utente) mantenendo il numero di righe morte relativamente basso.

Un approccio consiste nell'utilizzare l'uno o l'altro parametro. Quindi, se impostiamo autovacuum_vacuum_scale_factor su 0 e invece autovacuum_vacuum_threshold su, diciamo, 5.000, una tabella verrà sottoposta a vuoto automatico quando il numero di righe morte è superiore a 5.000.

Suggerimento 3:perfeziona la soglia di analisi automatica

Simile all'autovacuum, anche autoanalyze utilizza due parametri che decidono quando l'autovacuum attiverà anche un'autoanalisi:

  • autovacuum_analyze_threshold :ha un valore predefinito di 50
  • autovacuum_analyze_scale_factor :ha un valore predefinito di 0,1

Come autovacuum, il parametro autovacuum_analyze_threshold può essere impostato su un valore che determina il numero di tuple inserite, eliminate o aggiornate in una tabella prima dell'avvio di un'analisi automatica. Si consiglia di impostare questo parametro separatamente su tabelle di grandi dimensioni e di transazioni elevate. La configurazione della tabella sovrascriverà i valori postgresql.conf.

Il frammento di codice seguente mostra la sintassi SQL per modificare l'impostazione autovacuum_analyze_threshold per una tabella.

ALTER TABLE <table_name> 
SET (autovacuum_analyze_threshold = <threshold rows>)

Suggerimento 4:perfeziona i lavoratori dell'autovacuum

Un altro parametro spesso trascurato dai DBA è autovacuum_max_workers , che ha un valore predefinito di 3. Autovacuum non è un singolo processo, ma un numero di singoli thread del vuoto che funzionano in parallelo. Il motivo per specificare più lavoratori è garantire che l'aspirazione di tavoli di grandi dimensioni non impedisca l'aspirazione di tavoli più piccoli e sessioni utente. Il parametro autovacuum_max_workers dice a PostgreSQL di aumentare il numero di thread di lavoro di autovacuum per eseguire la pulizia.

Una pratica comune dei DBA di PostgreSQL è aumentare il numero di thread di lavoro massimi nella speranza che acceleri l'autovacuum. Questo non funziona poiché tutti i thread condividono lo stesso autovacuum_vacuum_cost_limit , che ha un valore predefinito di 200. A ogni thread di autovacuum viene assegnato un limite di costo utilizzando questa formula mostrata di seguito:

individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers

Il costo del lavoro svolto da un thread di autovacuum viene calcolato utilizzando tre parametri:

  • vacuum_cost_page_hit :ha un valore predefinito di 1
  • vacuum_cost_page_miss :ha un valore predefinito di 10
  • vacuum_cost_page_dirty :ha un valore predefinito di 20

Il significato di questi parametri è questo:

  • Quando un thread di vuoto trova la pagina di dati che dovrebbe pulire nel buffer condiviso, il costo è 1. 
  • Se la pagina dei dati non è nel buffer condiviso, ma nella cache del sistema operativo, il costo sarà di 10. 
  • Se la pagina deve essere contrassegnata come sporca perché il thread del vuoto ha dovuto eliminare le righe morte, il costo sarà di 20.

Un numero maggiore di thread di lavoro abbasserà il limite di costo per ogni thread. Poiché a ogni thread viene assegnato un limite di costo inferiore, andrà a dormire più spesso poiché la soglia di costo viene facilmente raggiunta, causando in definitiva un rallentamento dell'intero processo di vuoto. Ti consigliamo di aumentare autovacuum_vacuum_cost_limit a un valore più alto, ad esempio 2000, e quindi di regolare il numero massimo di thread di lavoro.

Un modo migliore è ottimizzare questi parametri per le singole tabelle solo quando necessario. Ad esempio, se l'autovuoto di una tabella transazionale di grandi dimensioni impiega troppo tempo, la tabella potrebbe essere configurata temporaneamente per utilizzare il proprio limite di costo del vuoto e ritardi di costo. Il limite di costo e il ritardo sovrascriveranno i valori a livello di sistema impostati in postgresql.conf.

Il frammento di codice seguente mostra come configurare le singole tabelle.

ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>)
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)

L'uso del primo parametro assicurerà che il thread di autovacuum assegnato alla tabella esegua più lavoro prima di andare a dormire. Abbassare l'autovacuum_vacuum_cost_delay significherà anche che il thread sta dormendo meno tempo.

Pensieri finali

Come puoi vedere, la modifica dei parametri di configurazione per il vuoto e l'analisi è semplice, ma richiede prima un'attenta osservazione. Ogni database è diverso in termini di dimensioni, modello di traffico e velocità delle transazioni. Raccomandiamo ai DBA di iniziare raccogliendo informazioni sufficienti sul loro database prima di modificare i parametri o implementare un regime di analisi/vuoto manuale. Tali informazioni potrebbero essere:

  • Numero di righe in ogni tabella
  • Numero di tuple morte in ogni tabella
  • Il tempo dell'ultimo vuoto per ogni tavolo
  • L'ora dell'ultima analisi per ogni tabella
  • La velocità di inserimento/aggiornamento/eliminazione dei dati in ogni tabella
  • Il tempo impiegato dall'autovacuum per ogni tabella
  • Avvisi sui tavoli non aspirati
  • Prestazioni attuali della maggior parte delle query critiche e delle tabelle a cui accedono
  • Prestazioni delle stesse query dopo un vuoto/analisi manuale

Da qui, i DBA possono selezionare alcune tabelle "pilota" per iniziare l'ottimizzazione. Possono iniziare a modificare le proprietà di vuoto/analisi per le tabelle e verificare le prestazioni. PostgreSQL è un motore di database intelligente:i DBA spesso scopriranno che è probabilmente meglio lasciare che PostgreSQL esegua l'aspirazione e l'analisi piuttosto che eseguirle manualmente.