Quanto tempo impiegherà un'operazione di vuoto / autovacuum?


18

Gestisco un grande database (alcune centinaia di concerti) contenente tabelle con vari ruoli, alcuni dei quali contengono milioni di record. Alcune tabelle ricevono solo un numero elevato di inserimenti ed eliminazioni, altri pochi inserimenti e un numero elevato di aggiornamenti.

Il database funziona su PostgreSQL 8.4 su un sistema Debian 6.0 amd64 con 16 gigabyte di RAM.

A volte la domanda è il processo di aspirazione automatica su un tavolo, il completamento richiede molto tempo (giorni). Voglio essere in grado di dire approssimativamente quanto tempo impiegherà un particolare comando del vuoto, per essere in grado di decidere se annullarlo o meno. Anche se ci fosse un indicatore di progresso per le operazioni di vuoto postgres, sarebbe davvero utile.

Modificare:

Non sto cercando una soluzione a prova di proiettile. È sufficiente un semplice suggerimento sul numero di tuple morte o byte I / O necessari per decidere. È davvero fastidioso non avere idea di quando VACUUMfinirà, qualunque cosa.

Ho visto che pg_catalog.pg_stat_all_tablesha una colonna per il numero di tuple morte. Quindi è possibile avere una stima, anche se significa che si deve ANALYZEprima la tabella. D'altra parte, autovacuum_vacuum_thresholde autovacuum_vacuum_scale_factorsolo le impostazioni dimostrano che Postgres stesso sa qualcosa sulla quantità di modifiche sui tavoli e probabilmente lo mette anche nelle mani del DBA.

Non sono sicuro di quale query eseguire, perché quando eseguo VACUUM VERBOSE, vedo che non solo le tabelle, ma anche gli indici su di esse vengono elaborati.

Risposte:


34

Sul mio PostgreSQL (8.3) uso questo trucco:

  1. Ottengo le dimensioni del disco della tabella usando pg_total_relation_size()- questo include gli indici e la dimensione TOAST, che è ciò che VACUUMelabora. Questo mi dà l'idea di quanti byte VACUUMdeve leggere.
  2. Corro VACUUMsul tavolo.
  3. Trovo il piddel VACUUMprocesso (in pg_catalog.pg_stat_activity).
  4. Nella shell di Linux corro while true; do cat /proc/123/io | grep read_bytes; sleep 60; done(dov'è 123il pid) - questo mi mostra i byte letti finora dal processo dal disco.

Questo mi dà un'idea approssimativa di quanti byte vengono elaborati (letti) ogni minuto dal VACUUM. Presumo che sia VACUUMnecessario leggere l'intera tabella (inclusi indici e TOAST), di cui conosco la dimensione del disco dal passaggio 1.

Presumo che la tabella sia abbastanza grande in modo che la maggior parte delle sue pagine debba essere letta dal disco (non sono presenti nella memoria condivisa di Postgres), quindi il read_bytescampo è abbastanza buono da poter essere utilizzato come contatore di avanzamento.

Ogni volta che l'ho fatto, i byte totali letti dal processo non erano più del 5% dalla dimensione della relazione totale, quindi immagino che questo approccio possa essere abbastanza buono per te.


Brutto :) Funziona anche per le versioni successive? E, soprattutto, per l'autovacuum?
dezso

Non l'ho provato per le versioni più recenti. Dovrebbe funzionare per VACUUM FULL9.0+, poiché riscrive completamente la tabella. Dovrebbe funzionare anche regolarmente VACUUM, ma non l'ho ancora testato. Per autovacuumche avrebbe funzionato se foste in grado di catturare il processo di lavoro autovacuum sul determinata tabella, ma non so come raggiungere questo obiettivo.
Roman Hocke,

Hai qualche suggerimento su come raggiungere questo obiettivo con RDS? Ovviamente non abbiamo accesso a una shell Linux quando si usa RDS, ma vorremmo anche essere in grado di stimare anche questo.
jwg2s,

@ jwg2s Cosa intendi con "RDS", per favore? Servizi di database di Amazon? Se è così, sfortunatamente non ne ho familiarità :-( Forse il loro supporto sarebbe d'aiuto.
Roman Hocke

1
Sembra funzionare bene anche su PG 10 con il vuoto pieno.
DylanYoung

9

Questo è molto difficile da determinare. Puoi mettere a punto l'autovacuuming per essere più aggressivo o più mite. Ma quando è impostato su lieve ed è in ritardo e il carico di I / O di base è troppo elevato, può succedere che non raggiunga mai uno stato di vuoto adeguato, quindi vedrai il processo in esecuzione e in esecuzione. Inoltre, le edizioni PostreSQL successive hanno migliorato notevolmente le capacità di autovacuum, questo da solo potrebbe essere sufficiente per passare a una di esse (preferibilmente 9.2 come la più recente).

La barra di avanzamento sembra una buona idea ma immagino che non sia così facile da implementare in modo significativo. Dato che hai un carico costante sui tuoi tavoli, è possibile che i progressi apparentemente stiano andando indietro (intendo che il conteggio delle righe morte / la percentuale aumenta invece di diminuire) - allora quale conclusione trai?


2
Preferisco vedere una sorta di indicatore di progresso, anche se va indietro, piuttosto che niente.
zaadeh,

3
VACUUM ANALYZE VERBOSEalmeno stampa un po 'di attività sulla console come fa. È meglio solo fissare un prompt statico chiedendosi se qualcosa è bloccato per ore.
Nome falso

La domanda riguarda "vuoto / autovacuum". Quanto sopra è utile solo per VACUUM, non per il vuoto automatico, ma è ancora qualcosa.
Nome falso

@FakeName Eh, ho letto male la domanda - ho perso la parte del vuoto manuale. Siamo spiacenti, sto eliminando il mio commento.
dezso

3

Nella nostra produzione uno dei tavoli più grandi aveva questo registro:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

Questo è di gran lunga il peggior consumo di risorse, tutte le altre tabelle hanno impiegato meno di 2 secondi.

Per visualizzare questi tipi di registri è necessario eseguire questo:

alter system set log_autovacuum_min_duration TO 5; 

(per 5 ms), ricaricare il file di configurazione.


3

Ho trovato questo post e questo post , ma come altri hanno già detto, può essere difficile calcolare l'avanzamento complessivo del vuoto, poiché il processo prevede alcune operazioni separate.

Uso questa query per monitorare l'avanzamento della scansione della tabella del vuoto, che sembra essere la maggior parte del lavoro:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

Tuttavia, ciò non include la scansione dell'indice, che si verifica in seguito, e può richiedere altrettanto tempo, se non di più, se si dispone di una tonnellata di indici. Sfortunatamente, non riesco a trovare alcun modo per monitorare la scansione / l'aspirazione dell'indice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.