Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Risoluzione dei problemi relativi alle prestazioni di vacuum in RDS per PostgreSQL
Questa sezione illustra i fattori che spesso contribuiscono a rallentare le prestazioni di vacuum e spiega come risolvere tali problemi.
Argomenti
Processo di vacuum su indici di grandi dimensioni
Il processo VACUUM funziona in fasi sequenziali: inizializzazione, scansione degli heap, vacuum di indici e heap, pulizia degli indici, troncamento degli heap e pulizia finale. Durante la scansione degli heap, il processo elimina alcune pagine, le deframmenta e le blocca. Dopo aver completato la scansione degli heap, VACUUM pulisce gli indici, restituisce le pagine vuote al sistema operativo ed esegue le attività di pulizia finale, come il vacuum della mappa dello spazio libero e l’aggiornamento delle statistiche.
Il processo di vacuum degli indici può richiedere più passaggi quando maintenance_work_mem (o autovacuum_work_mem) è insufficiente per elaborare l’indice. In PostgreSQL 16 e versioni precedenti, poiché per l’archiviazione degli ID delle tuple morte esisteva un limite di memoria di 1 GB, spesso era obbligatorio eseguire più passaggi sugli indici di grandi dimensioni. In PostgreSQL 17 è stato introdotto TidStore, che alloca la memoria in modo dinamico anziché utilizzare un array con allocazione singola. In questo modo viene eliminato il vincolo di 1 GB, la memoria viene utilizzata in modo più efficiente e viene ridotta la necessità di scansioni multiple per ogni indice.
È comunque possibile che gli indici di grandi dimensioni richiedano più passaggi in PostgreSQL 17 se la memoria disponibile non è in grado di supportare l’elaborazione simultanea degli interi indici. In genere, gli indici di dimensioni maggiori contengono un numero superiore di tuple morte che richiedono più passaggi.
Rilevamento di operazioni di vacuum a esecuzione lenta
La funzione postgres_get_av_diag() è in grado di rilevare le situazioni in cui le operazioni di vacuum vengono eseguite lentamente per memoria insufficiente. Per ulteriori informazioni su questa funzione, consulta Installazione di strumenti di diagnostica e monitoraggio dei processi di autovacuum in RDS per PostgreSQL.
La funzione postgres_get_av_diag() genera i seguenti avvisi quando la memoria disponibile non è sufficiente per completare il processo di vacuum di un indice in un singolo passaggio.
rds_tools 1.8
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory.
Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
rds_tools 1.9
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more
memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual
vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see
Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide
.
Nota
La funzione postgres_get_av_diag() si affida a pg_stat_all_tables.n_dead_tup per stimare la quantità di memoria richiesta per il vacuum dell’indice.
Quando identifica un’operazione di vacuum a esecuzione lenta che richiede più scansioni dell’indice per autovacuum_work_mem insufficiente, la funzione postgres_get_av_diag() genera il seguente messaggio:
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming.
For more information, see Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide.
Linea guida
È possibile avvalersi delle seguenti soluzioni alternative utilizzando il processo VACUUM FREEZE manuale per velocizzare il blocco della tabella.
Incremento della memoria per il processo di vacuum
Come suggerito dalla funzione postgres_get_av_diag(), è consigliabile incrementare il valore del parametro autovacuum_work_mem per superare potenziali vincoli di memoria a livello di istanza. Sebbene autovacuum_work_mem sia un parametro dinamico, per applicare la nuova impostazione di memoria occorre che il daemon di autovacuum riavvii i propri worker. A tale scopo, procedi come segue:
-
Verifica che la nuova impostazione sia effettiva.
-
Termina i processi che hanno in corso un’operazione di autovacuum.
Questo approccio garantisce che la nuova quantità di memoria allocata venga applicata alle successive operazioni di autovacuum.
Per risultati più immediati, valuta la possibilità di eseguire manualmente un’operazione VACUUM FREEZE con un’impostazione maintenance_work_mem incrementata nella sessione in corso:
SET maintenance_work_mem TO '1GB'; VACUUM FREEZE VERBOSEtable_name;
Se utilizzi Amazon RDS e ritieni di aver bisogno di memoria aggiuntiva per supportare valori più elevati per maintenance_work_mem o autovacuum_work_mem, valuta la possibilità di passare a una classe di istanze con più memoria. Tale operazione può fornire le risorse necessarie per ottimizzare sia le operazioni di vacuum manuali che quelle automatiche, con conseguente miglioramento delle prestazioni complessive del database e del processo di vacuum.
Disabilitazione di INDEX_CLEANUP
Il processo VACUUM manuale in PostgreSQL versione 12 e successive consente di saltare la fase di pulizia degli indici, mentre l’autovacuum di emergenza in PostgreSQL versione 14 e successive esegue tale operazione automaticamente in base al parametro vacuum_failsafe_age
avvertimento
La mancata esecuzione della pulizia degli indici può causare il bloat degli indici e influire negativamente sulle prestazioni delle query. Per risolvere questo problema, valuta la possibilità di eseguire una nuova indicizzazione o un’operazione di vacuum sugli indici interessati durante una finestra di manutenzione.
Per ulteriori indicazioni sulla gestione degli indici di grandi dimensioni, consulta la pagina Gestione di autovacuum con indici di grandi dimensioni .
Vacuum degli indici in parallelo
A partire da PostgreSQL 13, gli indici possono essere sottoposti a vacuum e pulizia in parallelo per impostazione predefinita tramite un’operazione VACUUM manuale, con un processo worker di vacuum assegnato a ciascun indice. Tuttavia, affinché PostgreSQL possa determinare se un’operazione di vacuum è idonea per l’esecuzione in parallelo, occorre che siano soddisfatti criteri specifici:
-
Devono esistere almeno due indici.
-
Il parametro
max_parallel_maintenance_workersdeve essere impostato almeno su 2. -
Le dimensioni degli indici devono superare il limite di
min_parallel_index_scan_size, che è di 512 KB per impostazione predefinita.
L’impostazione max_parallel_maintenance_workers può essere modificata in base al numero di vCPU disponibili nell’istanza Amazon RDS in uso e al numero di indici nella tabella per ottimizzare i tempi di risposta del processo di vacuum.
Per ulteriori informazioni, consulta Parallel vacuuming in Amazon RDS per PostgreSQL and Amazon Aurora PostgreSQL
Quantità eccessiva di tabelle o database da sottoporre a vacuum
Come descritto nella sezione The Autovacuum Daemonautovacuum_naptime secondi per database.
Con N database, un nuovo processo worker viene avviato approssimativamente ogni [autovacuum_naptime/N secondi]. Tuttavia, il numero totale di processi worker simultanei è limitato dall’impostazione autovacuum_max_workers. Se il numero di database o di tabelle che richiedono un processo di vacuum supera tale limite, l’elaborazione del database successivo o della tabella successiva avverrà non appena sarà disponibile un processo worker.
Quando è necessario eseguire il processo di vacuum su più tabelle o database di grandi dimensioni contemporaneamente, tutti i processi worker di autovacuum disponibili possono rimanere occupati per un periodo di tempo prolungato, ritardando così la manutenzione di altri database e tabelle. In ambienti con grandi volumi di transazioni, questo collo di bottiglia può peggiorare rapidamente e potenzialmente causare problemi con il processo di vacuum per wraparound nell’istanza Amazon RDS in uso.
Quando postgres_get_av_diag() rileva un numero elevato di tabelle o database, fornisce il seguente suggerimento:
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
Linea guida
Incremento del numero di autovacuum_max_workers
Per velocizzare il processo di vacuum, si consiglia di regolare il parametro autovacuum_max_workers per consentire l’utilizzo simultaneo di più processi worker di autovacuum. Se continuano a verificarsi colli di bottiglia nelle prestazioni, valuta la possibilità di aumentare verticalmente le risorse dell’istanza Amazon RDS in uso passando a una classe con più vCPU, così da migliorare ulteriormente le capacità di elaborazione in parallelo.
Esecuzione di un processo di vacuum aggressivo (per evitare il wraparound)
L’età del database (MaximumUsedTransactionIDs) in PostgreSQL diminuisce solo dopo il corretto completamento di un processo di vacuum aggressivo (per evitare il wraparound). Fino al completamento di tale processo di vacuum, l’età continua ad aumentare in funzione del volume di transazioni.
La funzione postgres_get_av_diag() genera il seguente messaggio NOTICE quando rileva un processo di vacuum aggressivo. ma attiva questo output solo dopo che il processo di vacuum è rimasto attivo per almeno due minuti.
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
Per ulteriori informazioni sui processi di vacuum aggressivi, consulta la sezione Scenario in cui è già in esecuzione un processo di vacuum aggressivo.
È possibile verificare se è in corso un processo di vacuum aggressivo utilizzando la seguente query:
SELECT a.xact_start AS start_time, v.datname "database", a.query, a.wait_event, v.pid, v.phase, v.relid::regclass, pg_size_pretty(pg_relation_size(v.relid)) AS heap_size, ( SELECT string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ') FROM pg_index i WHERE i.indrelid = v.relid ) AS index_sizes, trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct, v.index_vacuum_count || '/' || ( SELECT count(*) FROM pg_index i WHERE i.indrelid = v.relid ) AS step2_vacuum_indexes, trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct, age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar FROM pg_stat_activity a INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
È possibile determinare se si tratta di un processo di vacuum aggressivo (per evitare il wraparound) controllando la colonna della query nell’output. La dicitura “to prevent wraparound” (letteralmente, per evitare il wraparound) indica che si tratta di un processo di vacuum aggressivo.
query | autovacuum: VACUUM public.t3 (to prevent wraparound)
Ad esempio, si supponga di avere un elemento bloccante corrispondente a un’età delle transazioni pari a 1 miliardo e una tabella che richiede un processo di vacuum aggressivo per evitare il wraparound in corrispondenza dello stesso valore di età delle transazioni. Inoltre, esiste un altro elemento bloccante corrispondente a un’età delle transazioni pari a 750 milioni. Una volta eliminato l’elemento bloccante corrispondente a un’età delle transazioni pari a 1 miliardo, l’età delle transazioni non scende immediatamente a 750 milioni, ma rimane elevata fino al completamento della tabella che richiede un processo di vacuum aggressivo o di eventuali transazioni con età superiore a 750 milioni. Durante tale periodo, l’età delle transazioni del cluster PostgreSQL continua a crescere. Una volta completato il processo di vacuum, l’età delle transazioni scende a 750 milioni e quindi ricomincia ad aumentare fino al termine di un ulteriore processo di vacuum. Questo ciclo continua fintanto che persistono le suddette condizioni, ossia finché l’età delle transazioni non sarà scesa al livello configurato per l’istanza Amazon RDS in uso, specificato dal parametro autovacuum_freeze_max_age.