

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à.

# Utilizzo della funzionalità di autovacuum di PostgreSQL in Amazon RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum"></a>

Consigliamo vivamente di usare la caratteristica di autovacuum per mantenere l'integrità dell'istanza database di PostgreSQL. La funzione di autovaacuum automatizza l'esecuzione del comando VACUUM e ANALYZE. Verifica la presenza di tabelle con un numero elevato di tuple inserite, aggiornate o eliminate. Dopo questa verifica, recupera lo storage rimuovendo i dati obsoleti o le tuple da database PostgreSQL.

Per impostazione predefinita, la funzionalità di autovacuum è abilitata per le istanze database di RDS per PostgreSQL create utilizzando uno dei gruppi di parametri di database PostgreSQL predefiniti. Per impostazione predefinita vengono impostati anche altri parametri di configurazione associati alla caratteristica di autovacuum. Poiché questi valori di default sono in qualche modo generici, è possibile trarre vantaggio dalla regolazione di alcuni parametri associati alla caratteristica di autovacuum per il carico di lavoro specifico. 

Di seguito, puoi trovare ulteriori informazioni sulla funzionalità di autovacuum e su come regolare alcuni dei relativi parametri sulla tua istanza database di RDS per PostgreSQL. Per informazioni generali, consulta [Best practice per l'utilizzo di PostgreSQL](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL).

**Topics**
+ [

## Allocazione di memoria per il vacuum
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory)
+ [

## Riduzione della probabilità che si verifichi il wraparound dell’ID delle transazioni
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)
+ [

# Determinare se le tabelle nel database devono essere sottoposte a vacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming.md)
+ [

# Determinare quali tabelle sono attualmente idonee per l'Autovacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables.md)
+ [

# Determinare se l'Auotvacuum è attualmente in esecuzione e per quanto tempo
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning.md)
+ [

# Esecuzione di un congelamento manuale del vacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)
+ [

# Indicizzare di nuovo una tabella quando l'autovacuum è in esecuzione
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing.md)
+ [

# Gestione di autovacuum con indici di grandi dimensioni
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)
+ [

# Altri parametri che influenzano l'autovacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms.md)
+ [

# Impostazione dei parametri di autovacuum a livello tabella
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters.md)
+ [

# Registrazione delle attività di autovacuum e vacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)
+ [

# Comprensione del comportamento della funzionalità di autovacuum con database non validi
](appendix.postgresql.commondbatasks.autovacuumbehavior.md)
+ [

# Identificazione e risoluzione dei blocchi per i processi di vacuum aggressivi in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.md)

## Allocazione di memoria per il vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory"></a>

Uno dei parametri più importanti che influenzano le prestazioni dell'autovacuum è il parametro [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM). Nelle versioni 14 e precedenti di RDS per PostgreSQL, il parametro `autovacuum_work_mem` è impostato su -1, a indicare che al suo posto viene utilizzata l’impostazione `maintenance_work_mem`. Per tutte le altre versioni, `autovacuum_work_mem` è determinato da GREATEST (\$1DBInstanceClassMemory/32768\$1, 65536).

Le operazioni manuali di aspirazione utilizzano sempre l'`maintenance_work_mem`impostazione, con un'impostazione predefinita di GREATEST (\$1DBInstanceClassMemory/63963136 \$11024\$1, 65536), e può anche essere regolata a livello di sessione utilizzando il comando per operazioni manuali più mirate. `SET` `VACUUM`

`autovacuum_work_mem` determina la memoria di autovacuum per contenere gli identificatori delle tuple inattive (`pg_stat_all_tables.n_dead_tup`) per gli indici dell’attività di vacuum.

Quando esegui i calcoli per determinare il valore del parametro `autovacuum_work_mem`, tieni presente quanto segue:
+ Se imposti il parametro su un valore troppo basso, il processo di vacuum potrebbe dover eseguire la scansione della tabella più volte per completare il lavoro. Queste scansioni multiple possono avere un impatto negativo sulle prestazioni Per le istanze più grandi, impostare `maintenance_work_mem` o `autovacuum_work_mem` su almeno 1 GB può migliorare le prestazioni delle tabelle di vacuum con un numero elevato di tuple morte. Tuttavia, nelle versioni 16 e precedenti di PostgreSQL, l’utilizzo della memoria di vacuum è limitato a 1 GB, il che è sufficiente per elaborare circa 179 milioni di tuple morte in un unico passaggio. Se una tabella ha una quantità superiore di tuple morte, il vacuum dovrà effettuare più passaggi tra gli indici della tabella, facendo aumentare notevolmente il tempo necessario. A partire dalla versione 17 di PostgreSQL, non esiste un limite di 1 GB e la funzionalità di autovacuum può elaborare più di 179 milioni di tuple utilizzando strutture radice.

  Un identificatore di tuple ha dimensioni di 6 byte. Per stimare la memoria necessaria per il processo di vacuum di un indice di una tabella, esegui una query `pg_stat_all_tables.n_dead_tup` per trovare il numero di tuple morte, quindi moltiplica questo numero per 6 per determinare la memoria richiesta per svuotare l’indice in un unico passaggio. Puoi utilizzare la seguente query.

  ```
  SELECT
      relname AS table_name,
      n_dead_tup,
      pg_size_pretty(n_dead_tup * 6) AS estimated_memory
  FROM
      pg_stat_all_tables
  WHERE
      relname = 'name_of_the_table';
  ```
+ Il parametro `autovacuum_work_mem` funziona insieme al parametro `autovacuum_max_workers`. Ogni nodo worker tra `autovacuum_max_workers` può utilizzare la memoria allocata. Se si dispone di molte tabelle di piccole dimensioni, assegna più `autovacuum_max_workers` e meno `autovacuum_work_mem`. Se disponi di tabelle di grandi dimensioni (ad esempio, dimensioni superiori a 100 GB), alloca più memoria e meno processi worker. Si deve avere abbastanza memoria allocata affinché si abbia esito positivo sulle tabelle più grandi. Quindi assicurati che la combinazione di processi worker e memoria sia uguale alla memoria totale che desideri allocare.

## Riduzione della probabilità che si verifichi il wraparound dell’ID delle transazioni
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming"></a>

In alcuni casi, le impostazioni del gruppo di parametri correlate all'autovacuum potrebbero non essere abbastanza aggressive da prevenire il wraparound dell'ID delle transazioni. Per risolvere questo problema, RDS per PostgreSQL offre un meccanismo che adatta automaticamente i valori del parametro di autovacuum. *Ottimizzazione adattiva del parametro di autovacuum* è una funzionalità di RDS per PostgreSQL. Una spiegazione dettagliata di [Wraparound della transazione](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND) si trova nella documentazione di PostgreSQL. 

La regolazione adattiva del parametro di autovacuum è attivata per impostazione predefinita per le istanze RDS per PostgreSQL con il parametro dinamico `rds.adaptive_autovacuum` impostato su ON. Si consiglia di tenere questa opzione attivata. Tuttavia, per disattivare l'ottimizzazione adattiva del parametro di autovacuum, impostare il parametro `rds.adaptive_autovacuum` su 0 o OFF. 

Il wraparound degli ID di transazione è ancora possibile quando Amazon RDS Amazon RDS regola i parametri di autovacuum. Ti invitiamo a implementare un CloudWatch allarme Amazon per il wraparound degli ID delle transazioni. Per ulteriori informazioni, consulta il post [Implementazione di un sistema di avviso rapido per il wraparound degli ID delle transazioni in RDS per PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/) sul blog del database. AWS 

Con l'ottimizzazione adattiva dei parametri dell'autovacuum attivata, Amazon RDS inizia a regolare i parametri dell'autovacuum quando la CloudWatch metrica `MaximumUsedTransactionIDs` raggiunge il valore del parametro o 500.000.000, a seconda di quale sia il maggiore. `autovacuum_freeze_max_age` 

Amazon RDS continua ad adattare i parametri per l’autovacuum se una tabella continua a tendere verso i wraparound dell’ID della transazione. Ognuno di questi aggiustamenti dedica più risorse all’autovacuum per evitare il wraparound. Amazon RDS aggiorna i seguenti parametri correlati all’autovacuum: 
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)
+  [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 
+  [autovacuum\$1naptime](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME) 

RDS modifica questi parametri solo se il nuovo valore rende l’autovacuum più aggressivo. I parametri vengono modificati nella memoria sull’istanza database. I valori nel gruppo di parametri non vengono modificati. Per visualizzare le impostazioni in memoria correnti, utilizzare il comando SQL PostgreSQL [SHOW](https://www.postgresql.org/docs/current/sql-show.html). 

Quando Amazon RDS modifica uno qualsiasi dei parametri autovacuum, genera un evento per l’istanza database interessata. Questo evento è visibile su Console di gestione AWS e tramite l'API Amazon RDS. Dopo che la `MaximumUsedTransactionIDs` CloudWatch metrica è tornata al di sotto della soglia, Amazon RDS ripristina i parametri relativi all'autovacuum in memoria ai valori specificati nel gruppo di parametri. Quindi genera un altro evento corrispondente a questa modifica.

# Determinare se le tabelle nel database devono essere sottoposte a vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming"></a>

La seguente query può essere utilizzata per mostrare il numero di transazioni sbloccate in un database. La `datfrozenxid` colonna della `pg_database` riga di un database è un limite inferiore della normale transazione che IDs appare in quel database. Questa colonna è il minimo dei valori `relfrozenxid` per tabella all’interno del database. 

```
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
```

Ad esempio, i risultati dell'esecuzione della query precedente potrebbero essere i seguenti.

```
datname    | age
mydb       | 1771757888
template0  | 1721757888
template1  | 1721757888
rdsadmin   | 1694008527
postgres   | 1693881061
(5 rows)
```

Quando l'età di un database raggiunge i 2 miliardi di transazioni IDs, si verifica l'aggiustamento dell'ID della transazione (XID) e il database diventa di sola lettura. Puoi utilizzare questa query per produrre un parametro ed eseguirla alcune volte al giorno. Per impostazione predefinita, l'autovacuum è impostato per mantenere l'età delle transazioni a non più di 200,000,000 ([https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)).

Un esempio di strategia di monitoraggio potrebbe avere questo aspetto:
+ Impostare il valore `autovacuum_freeze_max_age` su 200 milioni di transazioni.
+ Se una tabella raggiunge 500 milioni di transazioni sbloccate, viene attivato un allarme a bassa gravità. Questo non è un valore irragionevole, ma può indicare che l'autovacuum non riesce a mantenere il passo.
+ Se una tabella invecchia a un miliardo, questo dovrebbe essere trattato come un allarme per cui intervenire. In generale, si desidera mantenere le età più vicine a `autovacuum_freeze_max_age` per motivi di prestazioni. Si consiglia di investigare utilizzando le raccomandazioni che seguono.
+ Se una tabella raggiunge 1,5 milioni di transazioni senza vacuum, viene attivato un allarme a gravità elevata. A seconda della velocità con cui il database utilizza la transazione IDs, questo allarme può indicare che il sistema sta per scadere il tempo necessario per eseguire l'autovacuum. In questo caso, consigliamo di risolvere il problema immediatamente.

Se una tabella superando costantemente queste soglie, modifica ulteriormente i parametri dell'autovacuum. Per impostazione predefinita, l’utilizzo manuale di VACUUM (che ha disabilitato i ritardi basati sui costi) è più aggressivo dell'autovacuum predefinito, ma è anche più intrusivo per il sistema nel suo complesso.

Consigliamo quanto segue:
+ Attiva un meccanismo di monitoraggio in modo da essere consapevole dell'età delle transazioni più vecchie.

  Per informazioni sulla creazione di un processo che ti avvisa in merito al wraparound degli ID delle transazioni, consulta il post del AWS Database Blog [Implementa an early warning system for Transaction ID wraparound in Amazon RDS for](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/) PostgreSQL.
+ Per le tabelle più occupate, eseguire regolarmente un congelamento manuale del vacuum durante una finestra di manutenzione, oltre a fare affidamento sull'autovacuum. Per informazioni sull'esecuzione di un congelamento manuale del vacuum, consulta [Esecuzione di un congelamento manuale del vacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

# Determinare quali tabelle sono attualmente idonee per l'Autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables"></a>

Spesso, una o due tabelle hanno bisogno del vacuum. Le tabelle il cui valore `relfrozenxid` sia maggiore del numero di transazioni in `autovacuum_freeze_max_age` sono sempre destinate all’autovacuum. Altrimenti, se il numero di tuple reso obsoleto dall'ultimo VACUUM supera la soglia del vacuum, la tabella viene sottoposta a vacuum.

La [autovacuum threshold (soglia di autovacuum)](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM) viene definita come:

```
Vacuum-threshold = vacuum-base-threshold + vacuum-scale-factor * number-of-tuples
```

dove `vacuum base threshold` è `autovacuum_vacuum_threshold`, `vacuum scale factor` è `autovacuum_vacuum_scale_factor` e `number of tuples` è `pg_class.reltuples`.

Mentre sei connesso al database, esegui la seguente query per visualizzare un elenco di tabelle che Autovacuum vede come idonee per il vacuuming.

```
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM 
pg_settings WHERE name = 'autovacuum_vacuum_threshold'),
vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM 
pg_settings WHERE name = 'autovacuum_vacuum_scale_factor'), 
fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age'),
sto AS (select opt_oid, split_part(setting, '=', 1) as param,
split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt)
SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation,
pg_size_pretty(pg_table_size(c.oid)) as table_size,
age(relfrozenxid) as xid_age,
coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age,
(coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) +
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples)
AS autovacuum_vacuum_tuples, n_dead_tup as dead_tuples FROM
pg_class c join pg_namespace ns on ns.oid = c.relnamespace 
join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1)
left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid 
left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid
left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid
WHERE c.relkind = 'r' and nspname <> 'pg_catalog'
AND (age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
OR coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * 
c.reltuples <= n_dead_tup)
ORDER BY age(relfrozenxid) DESC LIMIT 50;
```

# Determinare se l'Auotvacuum è attualmente in esecuzione e per quanto tempo
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning"></a>

Se è necessario procedere manualmente con il vacuum in una tabella, devi determinare se l'autovacuum è attualmente in esecuzione. In tal caso, potrebbe essere necessario regolare i parametri per farlo eseguire in modo più efficiente oppure disattivare l'autovacuum temporaneamente in modo da poter eseguire manualmente il VACUUM.

Utilizzare la seguente query per determinare se l'autovacuum è in esecuzione, da quanto tempo è in esecuzione e se è in attesa su un'altra sessione. 

```
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query
FROM pg_stat_activity 
WHERE upper(query) LIKE '%VACUUM%' 
ORDER BY xact_start;
```

Dopo l'esecuzione della query, si dovrebbe visualizzare un output simile a quello riportato di seguito.

```
 datname | usename  |  pid  | state  | wait_event |      xact_runtime       | query  
 --------+----------+-------+--------+------------+-------------------------+--------------------------------------------------------------------------------------------------------
 mydb    | rdsadmin | 16473 | active |            | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound)
 mydb    | rdsadmin | 22553 | active |            | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound)
 mydb    | rdsadmin | 41909 | active |            | 3 days 02:43:54.203349  | autovacuum: VACUUM ANALYZE public.mytable3
 mydb    | rdsadmin |   618 | active |            | 00:00:00                | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+
         |          |       |        |            |                         | FROM pg_stat_activity                                                                                 +
         |          |       |        |            |                         | WHERE query like '%VACUUM%'                                                                           +
         |          |       |        |            |                         | ORDER BY xact_start;                                                                                  +
```

Diversi problemi possono provocare sessioni di autovacuum di lunga esecuzione (che durano più giorni). Il problema più comune è che il valore del parametro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) è impostato come troppo basso per la dimensione della tabella o la frequenza degli aggiornamenti. 

Consigliamo di utilizzare la seguente formula per impostare il valore del parametro `maintenance_work_mem`.

```
GREATEST({DBInstanceClassMemory/63963136*1024},65536)
```

Le sessioni autovacuum a breve esecuzioni possono anche indicare dei problemi:
+ Può indicare che non ci sono abbastanza `autovacuum_max_workers` per il carico di lavoro. In questo caso, sarà necessario indicare il numero di lavoratori.
+ Può indicare che esiste un danneggiamento dell'indice (l'autovacuum si blocca e si riavvia sulla stessa relazione ma non ci sono progressi). In questo caso, esegui un `vacuum freeze verbose table` manuale per vedere la causa esatta. 

# Esecuzione di un congelamento manuale del vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

Si potrebbe voler eseguire un vacuum manuale su una tabella che ha già un processo di vacuum in esecuzione. Ciò è utile se hai identificato una tabella con un'età che si avvicina a 2 miliardi (o al di sopra di qualsiasi soglia monitorata).

I seguenti passaggi sono delle linea guida, con diverse varianti del processo. Ad esempio, durante la verifica, supporre che il valore del parametro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) sia stato impostato come troppo piccolo e che sia necessario agire immediatamente su una tabella. Tuttavia, probabilmente al momento non desideri che l’istanza non venga recapitata. Utilizzando le query delle sezioni precedenti, si determina quale tabella rappresenta il problema e si nota una sessione autovacuum a lunga esecuzione. Si sa che è necessario cambiare l'impostazione del parametro `maintenance_work_mem`, ma è necessario anche agire immediatamente ed eseguire il vacuum della tabella in questione. La procedura seguente mostra cosa fare in questa situazione.

**Per eseguire manualmente un congelamento del vacuum**

1. Aprire due sessioni nel database che contiene la tabella che si desidera sottoporre a vacuum. Per la seconda sessione, utilizzare "screen" o un'altra utility che mantiene la sessione se la connessione viene interrotta.

1. Nella sessione uno, ottieni l’ID di processo (PID) della sessione di autovacuum in esecuzione sulla tabella. 

   Eseguire la query seguente per ottenere il PID della sessione di autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. Nella sessione due, calcoli la quantità di memoria necessaria per questa operazione. In questo esempio, stabiliamo che è possibile permettersi di utilizzare fino a 2 GB di memoria per questa operazione, pertanto abbiamo impostato [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) per la sessione corrente su 2 GB.

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. Nella sessione 2, inviare un comando `vacuum freeze verbose` per la tabella. L'impostazione di verbose è utile perché, anche se al momento non vi è alcun rapporto sullo stato di avanzamento in PostgreSQL, è possibile visualizzare l'attività.

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. Nella sessione uno, se il processo di autovacuum bloccava la sessione di vacuum, `pg_stat_activity` mostra che l’attesa è `T` per la sessione di vacuum. In questo caso, termina il processo di autovacuum come segue.

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**Nota**  
Alcune versioni precedenti di Amazon RDS non possono terminare un processo di autovacuum utilizzando il comando precedente e viene generato il seguente errore: `ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`. 

   In questo momento, inizia la sessione. La funzionalità di autovacuum si riavvia immediatamente poiché questa tabella ha probabilmente la posizione superiore nella lista di lavoro. 

1. Avvia il comando `vacuum freeze verbose` nella sessione due, quindi termina il processo di autovacuum nella sessione uno.

# Indicizzare di nuovo una tabella quando l'autovacuum è in esecuzione
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

Se un indice diventa corrotto, l'autovacuum continua a elaborare la tabella e avrà esito negativo. Setenti di eseguire un vacuum manuale in questa situazione, riceverai un messaggio di errore come il seguente.

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

Quando l'indice è corrotto e l'autovacuum sta tentando l'esecuzione sulla tabella, ci sarà una contesa con una sessione di autovacuum già in esecuzione. Quando si immette un comando [REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html), si richiede un blocco esclusivo sulla tabella. Le operazioni in scrittura sono bloccate e anche quelle in lettura che utilizzano l’indice specifico.

**Per indicizzare di nuovo una tabella quando l'autovacuum è in esecuzione sulla tabella**

1. Apri due sessioni nel database che contiene la tabella da sottoporre a vacuum. Per la seconda sessione, utilizzare "screen" o un'altra utility che mantiene la sessione se la connessione viene interrotta.

1. Nella sessione numero uno, ottenere il PID della sessione di autovacuum in esecuzione sulla tabella.

   Eseguire la query seguente per ottenere il PID della sessione di autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. Nella sessione due, rilasciare il comando di reindicizzazione.

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. Nella sessione uno, se l'autovacuum bloccava il processo, in `pg_stat_activity` vedi che l'attesa è "T" per la sessione di vacuum. In questo caso, termina il processo di autovacuum. 

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   In questo momento, inizia la sessione. È importante notare che l'autovacuum si riavvia immediatamente poiché questa tabella è probabilmente la più alta nella lista di lavori. 

1. Avvia il comando nella sessione due, quindi termina il processo di autovacuum nella sessione 1.

# Gestione di autovacuum con indici di grandi dimensioni
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes"></a>

Come parte del funzionamento, *autovacuum* esegue diverse [fasi di vacuum](https://www.postgresql.org/docs/current/progress-reporting.html#VACUUM-PHASES) mentre viene eseguito su una tabella. Prima che la tabella venga pulita, tutti i suoi indici vengono prima sottoposti al vacuum. Quando si rimuovono più indici di grandi dimensioni, questa fase richiede una notevole quantità di tempo e risorse. Pertanto, come best practice, assicurati di controllare il numero di indici in una tabella ed eliminare gli indici non utilizzati.

Per questo processo, controlla innanzitutto la dimensione complessiva degli indici. Quindi, determina se ci sono indici potenzialmente inutilizzati da rimuovere come mostrato negli esempi seguenti.

**Per verificare la dimensione della tabella e dei relativi indici**

```
postgres=> select pg_size_pretty(pg_relation_size('pgbench_accounts'));
pg_size_pretty
6404 MB
(1 row)
```

```
postgres=> select pg_size_pretty(pg_indexes_size('pgbench_accounts'));
pg_size_pretty
11 GB
(1 row)
```

In questo esempio, la dimensione degli indici è maggiore della tabella. Questa differenza può causare problemi di prestazioni perché gli indici sono aumentati in dimensioni o inutilizzati, il che influisce sull'autovacuum e sulle operazioni di inserimento.

**Per verificare la presenza di indici non utilizzati**

Utilizzando la visualizzazione [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW), è possibile verificare la frequenza con cui viene utilizzato un indice con la colonna `idx_scan`. Nell'esempio seguente, gli indici non utilizzati hanno `idx_scan` con il valore `0`.

```
postgres=> select * from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
relid  | indexrelid | schemaname | relname          | indexrelname          | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+------------------+-----------------------+----------+--------------+---------------
16433  | 16454      | public     | pgbench_accounts | index_f               | 6        | 6            | 0
16433  | 16450      | public     | pgbench_accounts | index_b               | 3        | 199999       | 0
16433  | 16447      | public     | pgbench_accounts | pgbench_accounts_pkey | 0        | 0            | 0
16433  | 16452      | public     | pgbench_accounts | index_d               | 0        | 0            | 0
16433  | 16453      | public     | pgbench_accounts | index_e               | 0        | 0            | 0
16433  | 16451      | public     | pgbench_accounts | index_c               | 0        | 0            | 0
16433  | 16449      | public     | pgbench_accounts | index_a               | 0        | 0            | 0
(7 rows)
```

```
postgres=> select schemaname, relname, indexrelname, idx_scan from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
schemaname  | relname          | indexrelname          | idx_scan
------------+------------------+-----------------------+----------
public      | pgbench_accounts | index_f               | 6
public      | pgbench_accounts | index_b               | 3
public      | pgbench_accounts | pgbench_accounts_pkey | 0
public      | pgbench_accounts | index_d               | 0
public      | pgbench_accounts | index_e               | 0
public      | pgbench_accounts | index_c               | 0
public      | pgbench_accounts | index_a               | 0
(7 rows)
```

**Nota**  
Queste statistiche sono incrementali dal momento in cui vengono ripristinate. Supponi di avere un indice utilizzato solo alla fine di un trimestre lavorativo o solo per un report specifico. È possibile che questo indice non sia stato utilizzato da quando le statistiche sono state ripristinate. Per ulteriori informazioni, consulta [Funzioni statistiche](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-STATS-FUNCTIONS). Gli indici utilizzati per garantire l'univocità non vengono sottoposti ad analisi e non devono essere identificati come indici non utilizzati. Per identificare gli indici non utilizzati, è necessario avere una conoscenza approfondita dell'applicazione e delle relative query.

Per verificare quando le statistiche sono state ripristinate l'ultima volta per un database, usa [ https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW]( https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)

```
postgres=> select datname, stats_reset from pg_stat_database where datname = 'postgres';
    
datname   | stats_reset
----------+-------------------------------
postgres  | 2022-11-17 08:58:11.427224+00
(1 row)
```

## Vacuum di una tabella il più rapidamente possibile
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing"></a>

**RDS per PostgreSQL 12 e versioni successive**

Se sono presenti troppi indici in una tabella di grandi dimensioni, l'istanza database potrebbe essere vicina al wraparound dell'ID di transazione (XID), ovvero quando il contatore XID arriva a zero. Se non controllata, questa situazione potrebbe causare la perdita di dati. Tuttavia, è possibile eseguire rapidamente il vacuum della tabella senza ripulire gli indici. In RDS per PostgreSQL 12 e versioni successive, puoi usare VACUUM con la clausola [https://www.postgresql.org/docs/current/sql-vacuum.html](https://www.postgresql.org/docs/current/sql-vacuum.html).

```
postgres=> VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) pgbench_accounts;
        
INFO: vacuuming "public.pgbench_accounts"
INFO: table "pgbench_accounts": found 0 removable, 8 nonremovable row versions in 1 out of 819673 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 7517
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
```

Se è già in esecuzione una sessione di autovacuum, è necessario interromperla per iniziare il VACUUM manuale. Per informazioni sull'esecuzione di un congelamento manuale del vacuum, consulta [Esecuzione di un congelamento manuale del vacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

**Nota**  
Se si evita di eseguire regolarmente la pulizia, si verifica il bloat dell’indice, con ripercussioni sulle prestazioni della scansione. L’indice mantiene le righe morte e la tabella mantiene i puntatori delle linee morte. Di conseguenza, `pg_stat_all_tables.n_dead_tup` aumenta finché non viene eseguito un processo di autovacuum o un VACUUM manuale con pulizia dell’indice. Come best practice, utilizza questa procedura solo per evitare il wraparound degli ID di transazione.

**RDS per PostgreSQL 11 e versioni precedenti**

Tuttavia, in RDS per PostgreSQL 11 e versioni precedenti, l'unico modo per eseguire il vacuum più rapidamente è riducendo il numero di indici su una tabella. L'eliminazione di un indice può influire sui piani di query. Ti consigliamo di eliminare prima gli indici inutilizzati, quindi quelli che hanno il wraparound XID molto vicino. Una volta completato il processo di vacuum, è possibile ricreare questi indici.

# Altri parametri che influenzano l'autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms"></a>

La query seguente mostra i valori di alcuni dei parametri che influenzano direttamente l'autovacuum e il suo comportamento. I [parametri di autovacuum](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html) vengono descritti in forma completa nella documentazione di PostgreSQL.

```
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'autovacuum_max_workers',
'autovacuum_analyze_scale_factor',
'autovacuum_naptime',
'autovacuum_analyze_threshold',
'autovacuum_analyze_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_cost_delay',
'autovacuum_vacuum_cost_limit',
'vacuum_cost_limit',
'autovacuum_freeze_max_age',
'maintenance_work_mem',
'vacuum_freeze_min_age');
```

Mentre questi riguardano tutti l'autovacuum, alcuni dei più importanti sono:
+ [maintenance\$1work\$1mem](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE_WORK_MEM)
+ [autovacuum\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)
+ [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)

# Impostazione dei parametri di autovacuum a livello tabella
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters"></a>

Puoi impostare i [parametri di archiviazione](https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS) correlati all'autovacuum a livello di tabella, che può essere meglio di alterare il comportamento dell'intero database. Per le tabelle di grandi dimensioni, potrebbe essere necessario regolare impostazioni aggressive e si potrebbe non desiderare di eseguire l'autovacuum in questo modo per tutte le tabelle.

La query seguente mostra quali tabelle attualmente dispongono di opzioni a livello di tabella.

```
SELECT relname, reloptions
FROM pg_class
WHERE reloptions IS NOT null;
```

Un esempio in cui ciò potrebbe essere utile è per tabelle che sono molto più grandi rispetto al resto delle tabelle. Supponi di disporre di una tabella da 300 GB e di altre 30 tabelle da meno di un GB. Se disponi di una tabella da 300 GB e di altre 30 tabelle da meno di 1 GB, puoi impostare alcuni parametri specifici per la tabella di grandi dimensioni in modo da non alterare il comportamento dell'intero sistema.

```
ALTER TABLE mytable set (autovacuum_vacuum_cost_delay=0);
```

In questo modo si disattiva il ritardo dell'autovacuum basato sul costo per questa tabella a spese di un maggiore utilizzo delle risorse sul sistema. Normalmente, l'autovacuum si ferma per `autovacuum_vacuum_cost_delay` ogni volta che viene raggiunto `autovacuum_cost_limit`. Per ulteriori dettagli, consulta la documentazione di PostegreSQL relativa al [vacuuming basato sul costo](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST).

# Registrazione delle attività di autovacuum e vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging"></a>

Le informazioni sulle attività dell'autovacuum vengono inviate a `postgresql.log` in base al livello specificato nel parametro `rds.force_autovacuum_logging_level`. Di seguito sono riportati i valori consentiti per questo parametro e le versioni di PostgreSQL per le quali tale valore è l'impostazione predefinita:
+ `disabled` (PostgreSQL 10, PostgreSQL 9.6)
+ `debug5`, `debug4`, `debug3`, `debug2`, `debug1`
+ `info` (PostgreSQL 12, PostgreSQL 11)
+ `notice`
+ `warning` (PostgreSQL 13 e versioni successive)
+ `error`, log, `fatal`, `panic`

`rds.force_autovacuum_logging_level` funziona con il parametro `log_autovacuum_min_duration`. Il valore del parametro `log_autovacuum_min_duration` è la soglia (in millisecondi) al di sopra della quale vengono registrate le azioni dell'autovacuum. Un ambiente di `-1` non registra nulla, mentre un'impostazione di 0 registra tutte le azioni. Come con `rds.force_autovacuum_logging_level`, i valori predefiniti per `log_autovacuum_min_duration` dipendono dalla versione, come segue: 
+ `10000 ms` – PostgreSQL 14, PostgreSQL 13, PostgreSQL 12 e PostgreSQL 11 
+ `(empty)` – Nessun valore predefinito per PostgreSQL 10 e PostgreSQL 9.6

Consigliamo di impostare `rds.force_autovacuum_logging_level` su `WARNING`. Consigliamo anche di impostare `log_autovacuum_min_duration` su un valore compreso tra 1000 e 5000. Un'impostazione di 5000 registri di attività che richiede più di 5000 millisecondi. Qualsiasi impostazione diversa da -1 registra anche i messaggi se l'azione dell'autovacuum viene ignorata a causa di un blocco in conflitto o di relazioni interrotte simultaneamente. Per ulteriori informazioni, consulta la pagina relativa al [vacuum automatico](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html) nella documentazione di PostgreSQL. 

Per risolvere i problemi, è possibile modificare il parametro `rds.force_autovacuum_logging_level` in uno dei livelli di debug, da `debug1` fino a `debug5` per le informazioni più dettagliate. Si consiglia di utilizzare le impostazioni di debug per brevi periodi di tempo e solo per la risoluzione dei problemi. Per ulteriori informazioni, consulta [Quando registrare](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN) nella documentazione di PostgreSQL. 

**Nota**  
PostgreSQL consente all'account `rds_superuser` di visualizzare le sessioni di autovacuum in `pg_stat_activity`. Ad esempio, è possibile identificare e terminare una sessione di autovacuum che blocca l'esecuzione di un comando o l'esecuzione più lenta di un comando vacuum emesso manualmente.

# Comprensione del comportamento della funzionalità di autovacuum con database non validi
<a name="appendix.postgresql.commondbatasks.autovacuumbehavior"></a>

 Viene introdotto un nuovo valore `-2` nella colonna `datconnlimit` del catalogo `pg_database` per indicare come non validi i database che sono stati interrotti durante l’operazione DROP DATABASE. 

 Questo nuovo valore è disponibile nelle seguenti versioni di RDS per PostgreSQL: 
+ 15.4 e tutte le versioni successive
+ 14.9 e versioni successive
+ 13.12 e versioni successive
+ 12.16 e versioni successive
+ 11.21 e versioni successive

I database non validi non influiscono sulla capacità della funzionalità di autovacuum di bloccare le funzionalità dei database validi. La funzionalità autovacuum ignora i database non validi. Di conseguenza, le normali operazioni di vacuum continueranno a funzionare correttamente ed efficacemente per tutti i database validi nell’ambiente PostgreSQL.

**Topics**
+ [

## Monitoraggio dell’ID di transazione
](#appendix.postgresql.commondbatasks.autovacuum.monitorxid)
+ [

## Modifica della query di monitoraggio
](#appendix.postgresql.commondbatasks.autovacuum.monitoradjust)
+ [

## Risoluzione dei problemi relativi a database non validi
](#appendix.postgresql.commondbatasks.autovacuum.connissue)

## Monitoraggio dell’ID di transazione
<a name="appendix.postgresql.commondbatasks.autovacuum.monitorxid"></a>

 La funzione `age(datfrozenxid)` viene comunemente utilizzata per monitorare l’età degli ID di transazione (XID) dei database per evitare che si verifichi il wraparound degli ID. 

 Poiché i database non validi vengono esclusi dall’autovacuum, il relativo contatore dell’ID di transazione (XID) può raggiungere il valore massimo di `2 billion`, eseguire il wraparound a `- 2 billion` e continuare questo ciclo all’infinito. Una tipica query per monitorare il wraparound degli ID di transazione potrebbe essere simile a: 

```
SELECT max(age(datfrozenxid)) FROM pg_database;
```

Tuttavia, con l’introduzione del valore -2 per `datconnlimit`, i database non validi possono alterare i risultati di questa query. Poiché questi database non sono validi e non devono essere sottoposti a regolari controlli di manutenzione, possono causare falsi positivi, inducendo a credere che il valore `age(datfrozenxid)` sia superiore a quello reale.

## Modifica della query di monitoraggio
<a name="appendix.postgresql.commondbatasks.autovacuum.monitoradjust"></a>

 Per garantire l’accuratezza del monitoraggio, è necessario modificare la query di monitoraggio per escludere i database non validi. Segui questa query consigliata: 

```
SELECT
    max(age(datfrozenxid))
FROM
    pg_database
WHERE
    datconnlimit <> -2;
```

Questa query garantisce che nel calcolo di `age(datfrozenxid)` vengano presi in considerazione solo i database validi, fornendo un riflesso fedele dell’età degli ID di transazione nell’ambiente PostgreSQL.

## Risoluzione dei problemi relativi a database non validi
<a name="appendix.postgresql.commondbatasks.autovacuum.connissue"></a>

 Quando tenti di connetterti a un database non valido, potrebbe essere visualizzato un messaggio di errore simile al seguente: 

```
postgres=> \c db1
connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL:  cannot connect to invalid database "db1"
HINT:  Use DROP DATABASE to drop invalid databases.
Previous connection kept
```

 Inoltre, se il parametro `log_min_messages` è impostato su `DEBUG2` o successivo, è possibile che vengano visualizzate le seguenti voci di log che indicano che il processo autovacuum sta ignorando il database non valido: 

```
       
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db6"
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db1"
```

Per risolvere il problema, segui il valore `HINT` fornito durante il tentativo di connessione. Connettiti a qualsiasi database valido utilizzando l’account master RDS o un account di database con il ruolo `rds_superuser` ed elimina i database non validi.

```
SELECT
    'DROP DATABASE ' || quote_ident(datname) || ';'
FROM
    pg_database
WHERE
    datconnlimit = -2 \gexec
```

# Identificazione e risoluzione dei blocchi per i processi di vacuum aggressivi in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring"></a>

In PostgreSQL, il processo di vacuum è fondamentale per garantire l’integrità del database poiché consente di recuperare spazio di archiviazione e previene eventuali problemi di [wraparound degli ID transazione](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND). Tuttavia, in alcune situazioni è possibile che il processo di vacuum non funzioni come desiderato; le conseguenze possono essere: riduzione delle prestazioni, bloat dello spazio di archiviazione e impatto sulla disponibilità dell’istanza database in uso a causa del wraparound degli ID transazione. Pertanto, l’identificazione e la risoluzione dei suddetti problemi sono essenziali per garantire prestazioni e disponibilità ottimali del database. Per ulteriori informazioni sul processo di autovacuum, consulta [Understanding autovacuum in Amazon RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/).

La funzione `postgres_get_av_diag()` aiuta a identificare i problemi che impediscono o ritardano l’avanzamento dei processi di vacuum aggressivi. Vengono forniti dei suggerimenti, che possono includere comandi per risolvere il problema laddove esso sia identificabile o indicazioni per ulteriori operazioni di diagnosi laddove il problema non sia identificabile. I [vacuobloccanti aggressivi vengono segnalati quando l'età supera la soglia di autovuoto adattivo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) di RDS di 500 milioni di transazioni. IDs

**Qual è l’età dell’ID transazione?**

La `age()` funzione per la transazione IDs calcola il numero di transazioni avvenute dal più vecchio ID di transazione non bloccato per un database () o una tabella (). `pg_database.datfrozenxid` `pg_class.relfrozenxid` Questo valore indica l’attività del database dall’ultima operazione di vacuum aggressiva ed evidenzia il probabile carico di lavoro per i successivi processi VACUUM. 

**In cosa consiste un processo di vacuum aggressivo?**

Un'operazione VACUUM aggressiva esegue una scansione completa di tutte le pagine all'interno di una tabella, comprese quelle normalmente saltate durante la normale procedura. VACUUMs [Questa scansione approfondita mira a «congelare» le transazioni che IDs si avvicinano alla loro età massima, prevenendo efficacemente una situazione nota come transazione ID wraparound.](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND)

Affinché `postgres_get_av_diag()` li segnali, gli elementi bloccanti devono avere un’età di almeno 500 milioni di transazioni.

**Topics**
+ [

# Installazione di strumenti di diagnostica e monitoraggio dei processi di autovacuum in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)
+ [

# Funzioni di postgres\$1get\$1av\$1diag() in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.md)
+ [

# Risoluzione dei blocchi identificabili per i processi di vacuum in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md)
+ [

# Risoluzione dei blocchi non identificabili per i processi di vacuum in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers.md)
+ [

# Risoluzione dei problemi relativi alle prestazioni di vacuum in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md)
+ [

# Spiegazione dei messaggi NOTICE in RDS per PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

# Installazione di strumenti di diagnostica e monitoraggio dei processi di autovacuum in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation"></a>

La funzione `postgres_get_av_diag()` è attualmente disponibile nelle seguenti versioni di RDS per PostgreSQL:
+ 17.2 o versioni successive alla 17
+ 16.7 e versioni successive alla 16
+ 15.11 o versioni successive alla 15
+ 14.16 o versioni successive alla 14
+ 13.19 o versioni successive alla 13

 Per utilizzare `postgres_get_av_diag()`, crea l’estensione `rds_tools`.

```
postgres=> CREATE EXTENSION rds_tools ;
CREATE EXTENSION
```

Verifica che l’estensione sia stata installata.

```
postgres=> \dx rds_tools
             List of installed extensions
   Name    | Version |  Schema   |                    Description
 ----------+---------+-----------+----------------------------------------------------------
 rds_tools |   1.8   | rds_tools | miscellaneous administrative functions for RDS PostgreSQL
 1 row
```

Verifica che la funzione sia stata creata.

```
postgres=> SELECT
    proname function_name,
    pronamespace::regnamespace function_schema,
    proowner::regrole function_owner
FROM
    pg_proc
WHERE
    proname = 'postgres_get_av_diag';
    function_name     | function_schema | function_owner
----------------------+-----------------+----------------
 postgres_get_av_diag | rds_tools       | rds_superuser
(1 row)
```

# Funzioni di postgres\$1get\$1av\$1diag() in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions"></a>

La funzione `postgres_get_av_diag()` recupera informazioni diagnostiche sui processi di autovacuum che si bloccano o sono in ritardo in un database RDS per PostgreSQL. Per ottenere risultati accurati, la query deve essere eseguita nel database con l’ID transazione meno recente. Per ulteriori informazioni sull’utilizzo del database con l’ID transazione meno recente, consulta [Mancata connessione al database con l’età dell’ID transazione meno recente](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md).

```
SELECT
    blocker,
    DATABASE,
    blocker_identifier,
    wait_event,
    TO_CHAR(autovacuum_lagging_by, 'FM9,999,999,999') AS autovacuum_lagging_by,
    suggestion,
    suggested_action
FROM (
    SELECT
        *
    FROM
        rds_tools.postgres_get_av_diag ()
    ORDER BY
        autovacuum_lagging_by DESC) q;
```

La funzione `postgres_get_av_diag()` restituisce una tabella con le seguenti informazioni:

**elemento bloccante**  
Specifica la categoria di attività del database che blocca il processo di vacuum.  
+ [Istruzione attiva](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [Inattivo in transazione](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [Transazione preparata](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [Slot di replica logica](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [Replica di lettura con slot di replica fisica](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Replica di lettura con replica in streaming](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Tabelle temporanee](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

**database**  
Specifica il nome del database, ove pertinente e supportato. Si tratta del database in cui l’attività è in corso e che blocca o bloccherà il processo di autovacuum. È il database a cui devi connetterti e sul quale devi agire.

**blocker\$1identifier**  
Specifica l’identificatore dell’attività che blocca o bloccherà il processo di autovacuum. L’identificatore può essere un ID processo insieme a un’istruzione SQL, una transazione preparata, un indirizzo IP di una replica di lettura e il nome dello slot di replica (logica o fisica).

**wait\$1event**  
Specifica l’[evento di attesa](PostgreSQL.Tuning.md) della sessione di blocco ed è applicabile ai seguenti elementi bloccanti:  
+ Istruzione attiva
+ Inattivo in transazione

**autovacum\$1lagging\$1by**  
Specifica il numero di transazioni di cui il processo di autovacuum è in ritardo nel lavoro di backlog per categoria.

**suggestion**  
Specifica i suggerimenti per risolvere il blocco. Queste istruzioni includono il nome del database in cui esistono l’attività (ove applicabile), l’ID processo (PID) della sessione (ove applicabile) e l’azione da intraprendere.

**suggested\$1action**  
Suggerisci l’azione che è necessario intraprendere per risolvere il blocco.

# Risoluzione dei blocchi identificabili per i processi di vacuum in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers"></a>

La funzionalità di autovacuum esegue processi di vacuum aggressivi e porta l’età degli ID transazione al di sotto della soglia specificata dal parametro `autovacuum_freeze_max_age` dell’istanza RDS in uso. Puoi tenere traccia del valore di età utilizzando la metrica `MaximumUsedTransactionIDs` di Amazon CloudWatch.

Per trovare l’impostazione di `autovacuum_freeze_max_age` (che ha un valore predefinito di 200 milioni di ID transazione) per la tua istanza Amazon RDS, puoi utilizzare la seguente query:

```
SELECT
    TO_CHAR(setting::bigint, 'FM9,999,999,999') autovacuum_freeze_max_age
FROM
    pg_settings
WHERE
    name = 'autovacuum_freeze_max_age';
```

`postgres_get_av_diag()` verifica la presenza di eventuali elementi bloccanti per i processi di vacuum aggressivi solo quando l’età supera la soglia di [autovacuum adattivo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) di Amazon RDS, che corrisponde a 500 milioni di ID transazione. Affinché `postgres_get_av_diag()` li rilevi, gli elementi bloccanti devono avere un’età di almeno 500 milioni di transazioni.

La funzione `postgres_get_av_diag()` identifica i seguenti tipi di elementi bloccanti:

**Topics**
+ [

## Istruzione attiva
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [

## Inattivo in transazione
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [

## Transazione preparata
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [

## Slot di replica logica
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [

## Repliche di lettura
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [

## Tabelle temporanee
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

## Istruzione attiva
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement"></a>

In PostgreSQL, un’istruzione attiva è un’istruzione SQL attualmente che è in fase di esecuzione da parte del database. Sono incluse query, transazioni o eventuali operazione in corso. Durante il monitoraggio tramite `pg_stat_activity`, la colonna dello stato indica che il processo con il PID corrispondente è attivo.

La funzione `postgres_get_av_diag()` visualizza un output simile a quanto segue quando identifica un’istruzione che è attiva.

```
blocker               | Active statement
database              | my_database
blocker_identifier    | SELECT pg_sleep(20000);
wait_event            | Timeout:PgSleep
autovacuum_lagging_by | 568,600,871
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (29621);"}
```

**Azione suggerita**

Seguendo le indicazioni riportate nella colonna `suggestion`, l’utente può connettersi al database in cui è presente l’istruzione attiva e, come specificato nella colonna `suggested_action`, è consigliabile esaminare attentamente l’opzione per terminare la sessione. Se è sicuro eseguire la terminazione, è possibile utilizzare la funzione `pg_terminate_backend()` per terminare la sessione. Questa azione può essere eseguita da un utente amministratore (come l’account principale RDS) o da un utente con il privilegio `pg_terminate_backend()` richiesto.

**avvertimento**  
Una sessione terminata annullerà (`ROLLBACK`) le modifiche apportate. A seconda delle esigenze del caso, potresti voler eseguire nuovamente l’istruzione. Tuttavia, si consiglia di eseguire tale operazione solo dopo che il processo di autovacuum ha terminato il processo di vacuum aggressivo.

## Inattivo in transazione
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction"></a>

Un’istruzione di inattività in transazione si riferisce a una sessione che ha aperto una transazione esplicita (ad esempio, emettendo un’istruzione `BEGIN`), ha eseguito del lavoro e ora è in attesa che il client passi altro lavoro o segnali la fine della transazione emettendo un’istruzione `COMMIT`, `ROLLBACK` o `END` (che darebbe luogo a un’operazione `COMMIT` implicita).

La funzione `postgres_get_av_diag()` visualizza un output simile a quanto segue quando identifica un’istruzione `idle in transaction` come elemento bloccante.

```
blocker               | idle in transaction
database              | my_database
blocker_identifier    | INSERT INTO tt SELECT * FROM tt;
wait_event            | Client:ClientRead
autovacuum_lagging_by | 1,237,201,759
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (28438);"}
```

**Azione suggerita**

Come indicato nella colonna `suggestion`, è possibile connettersi al database in cui è presente una sessione di inattività in transazione e terminare la sessione utilizzando la funzione `pg_terminate_backend()`. L’utente può essere l’utente amministratore (account principale RDS) o un utente con il privilegio `pg_terminate_backend()`.

**avvertimento**  
Una sessione terminata annullerà (`ROLLBACK`) le modifiche apportate. A seconda delle esigenze del caso, potresti voler eseguire nuovamente l’istruzione. Tuttavia, si consiglia di eseguire tale operazione solo dopo che il processo di autovacuum ha terminato il processo di vacuum aggressivo.

## Transazione preparata
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction"></a>

PostgreSQL consente le transazioni che fanno parte di una strategia di commit in due fasi, denominate [transazioni preparate](https://www.postgresql.org/docs/current/sql-prepare-transaction.html). Queste vengono abilitate impostando il parametro `max_prepared_transactions` su un valore diverso da zero. Le transazioni preparate sono concepite per garantire che una transazione sia duratura e rimanga disponibile anche dopo crash del database, riavvii o disconnessioni del client. Così come avviene con le transazioni standard, anche le transazioni preparate ricevono in assegnazione un ID transazione e possono influire sul processo di autovacuum. Se lasciato in stato preparato, il processo di autovacuum non può eseguire il blocco e può portare al wraparound degli ID transazione.

Quando le transazioni vengono lasciate in stato preparato indefinitamente senza essere risolte da un gestore di transazioni, diventano transazioni preparate orfane. L’unica soluzione consiste nell’eseguire il commit o il rollback della transazione utilizzando rispettivamente i comandi `COMMIT PREPARED` o `ROLLBACK PREPARED`.

**Nota**  
Tieni presente che un backup eseguito durante una transazione preparata conterrà comunque tale transazione dopo il ripristino. Consulta le seguenti informazioni su come individuare e chiudere tali transazioni.

La funzione `postgres_get_av_diag()` visualizza il seguente output quando identifica un elemento bloccante che è una transazione preparata.

```
blocker               | Prepared transaction
database              | my_database
blocker_identifier    | myptx
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database" and consider either COMMIT or ROLLBACK the prepared transaction using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"COMMIT PREPARED 'myptx';",[OR],"ROLLBACK PREPARED 'myptx';"}
```

**Azione suggerita**

Come indicato nella colonna dei suggerimenti, connettiti al database in cui si trova la transazione preparata. In base alla colonna `suggested_action`, valuta attentamente se eseguire un’operazione di `COMMIT` o `ROLLBACK` e poi l’azione appropriata.

Per monitorare le transazioni preparate in generale, PostgreSQL offre una vista in stile catalogo denominata `pg_prepared_xacts`. La seguente query può essere utilizzata per trovare le transazioni preparate.

```
SELECT
    gid,
    prepared,
    owner,
    database,
    transaction AS oldest_xmin
FROM
    pg_prepared_xacts
ORDER BY
    age(transaction) DESC;
```

## Slot di replica logica
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot"></a>

Lo scopo di uno slot di replica è conservare le modifiche non utilizzate finché non vengono replicate su un server di destinazione. Per ulteriori informazioni, consulta la pagina relativa alla [replica logica](https://www.postgresql.org/docs/current/logical-replication.html) di PostgreSQL.

Esistono due tipi di slot di replica logica.

**Slot di replica logica inattivi**

Quando la replica viene terminata, i log delle transazioni non utilizzati non possono essere rimossi e lo slot di replica diventa inattivo. Gli slot di replica logica inattivi non vengono utilizzati dai nodi subscriber, ma rimangono comunque sul server, il che comporta la conservazione dei file WAL e impedisce la rimozione dei log delle transazioni meno recenti. Ciò può aumentare l’utilizzo del disco e, nello specifico, impedire al processo di autovacuum di eseguire la pulizia delle tabelle interne del catalogo, poiché il sistema deve impedire che le informazioni LSN vengano sovrascritte. Se il problema non viene risolto, possono verificarsi conseguenze come bloat del catalogo, riduzione delle prestazioni, aumento del rischio di wraparound nel processo di vacuum e quindi potenziali tempi di inattività per le transazioni.

**Slot di replica logica attivi ma lenti**

Talvolta la rimozione delle tuple morte del catalogo viene ritardata a causa della riduzione delle prestazioni della replica logica. Questo ritardo nella replica, che rallenta l’aggiornamento di `catalog_xmin`, può causare bloat del catalogo e wraparound nel processo di vacuum.

La funzione `postgres_get_av_diag()` visualizza un output simile a quanto segue quando individua in uno slot di replica logica un elemento bloccante.

```
blocker               | Logical replication slot
database              | my_database
blocker_identifier    | slot1
wait_event            | Not applicable
autovacuum_lagging_by | 1,940,103,068
suggestion            | Ensure replication is active and resolve any lag for the slot if active. If inactive, consider dropping it using the command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_drop_replication_slot('slot1') FROM pg_replication_slots WHERE active = 'f';"}
```

**Azione suggerita**

Per risolvere la situazione, controlla la configurazione di replica per individuare eventuali problemi con i dati o lo schema di destinazione che potrebbero determinare la terminazione del processo di applicazione. I problemi più comuni sono i seguenti: 
+ Colonne mancanti
+ Tipi di dati incompatibili
+ Mancata corrispondenza dei dati
+ Tabella mancante

Se il problema è legato a problemi relativi all’infrastruttura:
+ Problemi di rete: consulta [Come posso risolvere i problemi relativi a un database Amazon RDS in uno stato di rete incompatibile?](https://repost.aws/knowledge-center/rds-incompatible-network)
+ Il database o l’istanza database non è disponibile per i seguenti motivi:
  + L’istanza di replica ha esaurito lo spazio di archiviazione: per informazioni su come aggiungere spazio di archiviazione, consulta la pagina che spiega [cosa fare quando le istanze database Amazon RDS esauriscono lo spazio di archiviazione](https://repost.aws/knowledge-center/rds-out-of-storage).
  + Parametri incompatibili: per ulteriori informazioni su cosa fare, consulta [Come posso risolvere i problemi di un’istanza database Amazon RDS bloccata nello stato parametri incompatibili?](https://repost.aws/knowledge-center/rds-incompatible-parameters)

Se l’istanza si trova al di fuori della rete AWS oppure su AWS EC2, contatta l’utente amministratore per sapere come risolvere i problemi relativi alla disponibilità o all’infrastruttura.

**Eliminazione dello slot inattivo**

**avvertimento**  
Attenzione: prima di eliminare uno slot di replica, verifica con attenzione che non vi sia alcun processo di replica in esecuzione, e che lo slot sia inattivo e sia in uno stato irreversibile. Se uno slot viene eliminato troppo presto, la replica potrebbe interrompersi oppure potrebbe verificarsi una perdita di dati.

Dopo aver verificato che lo slot di replica non è più necessario, eliminalo per far sì che il processo di autovacuum possa continuare. La condizione `active = 'f'` garantisce che uno slot venga eliminato solo se inattivo.

```
SELECT pg_drop_replication_slot('slot1') WHERE active ='f'
```

## Repliche di lettura
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas"></a>

Quando l’impostazione `hot_standby_feedback` è abilitata per le [repliche di lettura di Amazon RDS](USER_PostgreSQL.Replication.ReadReplicas.md), il processo di autovacuum sul database primario non riesce a rimuovere le righe morte che potrebbero essere ancora necessarie per le query in esecuzione sulla replica di lettura. Questo influisce su tutti i tipi di replica di lettura fisica, inclusi quelli gestiti con o senza slot di replica. Questo comportamento è necessario perché le query in esecuzione sulla replica in standby richiedono che tali righe rimangano disponibili sul nodo primario, prevenendo [conflitti](https://www.postgresql.org/docs/current/hot-standby.html#HOT-STANDBY-CONFLICT) e annullamenti delle query.

**Replica di lettura con slot di replica fisica**  
Le repliche di lettura con slot di replica fisica migliorano in modo significativo l’affidabilità e la stabilità della replica in RDS per PostgreSQL. Questi slot assicurano che il database primario conservi i file WAL (Write-Ahead Log) essenziali finché il processo di replica non li elabora, mantenendo la coerenza dei dati anche durante le interruzioni della rete.

A partire dalla versione 14 di RDS per PostgreSQL, tutte le repliche utilizzano slot di replica. Nelle versioni precedenti, solo le repliche tra Regioni utilizzavano slot di replica.

La funzione `postgres_get_av_diag()` visualizza un output simile a quando segue quando individua in una replica di lettura con slot di replica fisica un elemento bloccante.

```
blocker               | Read replica with physical replication slot
database              |
blocker_identifier    | rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxxx
wait_event            | Not applicable
autovacuum_lagging_by | 554,080,689
suggestion            | Run the following query on the replica "rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxx" to find the long running query:                           
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;                                                       
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                 +                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;","                                                                                 +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                   +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Delete the read replica if not needed"}
```

**Replica di lettura con replica in streaming**  
Amazon RDS consente di configurare repliche di lettura senza uno slot di replica fisica nelle versioni precedenti, fino alla versione 13. Questo approccio riduce il sovraccarico consentendo al nodo primario di riciclare i file WAL in modo più aggressivo, il che è vantaggioso in ambienti con spazio su disco limitato e può tollerare ReplicaLag occasionali. Tuttavia, senza uno slot, la replica in standby deve rimanere sincronizzata per evitare file WAL mancanti. Amazon RDS utilizza file WAL archiviati per consentire alla replica di recuperare gli eventuali ritardi, ma questo processo richiede un monitoraggio accurato e può essere lento.

La funzione `postgres_get_av_diag()` visualizza un output simile a quanto segue quando individua in una replica di lettura in streaming un elemento bloccante.

```
blocker               | Read replica with streaming replication slot
database              | Not applicable
blocker_identifier    | xx.x.x.xxx/xx
wait_event            | Not applicable
autovacuum_lagging_by | 610,146,760
suggestion            | Run the following query on the replica "xx.x.x.xxx" to find the long running query:                                                                                                                                                         +
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;                                                                                                                                                     +
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                       +
                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;","                                                                                                                        +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                                                          +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Delete the read replica if not needed"}
```

**Azione suggerita**

Come consigliato nella colonna `suggested_action`, esamina attentamente queste opzioni per sbloccare il processo di autovacuum.
+ **Terminare la query**: seguendo le indicazioni riportate nella colonna dei suggerimenti, puoi connetterti alla replica di lettura, come specificato nella colonna suggested\$1action; è consigliabile esaminare attentamente l’opzione per terminare la sessione. Se è sicuro eseguire la terminazione, è possibile utilizzare la funzione `pg_terminate_backend()` per terminare la sessione. Questa azione può essere eseguita da un utente amministratore (come l’account principale RDS) o da un utente con il privilegio pg\$1terminate\$1backend() richiesto.

  È possibile eseguire il seguente comando SQL sulla replica di lettura per terminare la query che impedisce al processo di autovacuum sul nodo primario di eseguire la pulizia delle righe meno recenti. Il valore di `backend_xmin` è riportato nell’output della funzione:

  ```
  SELECT
      pg_terminate_backend(pid)
  FROM
      pg_catalog.pg_stat_activity
  WHERE
      backend_xmin::text::bigint = backend_xmin;
  ```
+ **Disabilitare il feedback in modalità hot standby**: valuta la possibilità di disabilitare il parametro `hot_standby_feedback` se causa ritardi significativi nel processo di vacuum.

  Il parametro `hot_standby_feedback` consente a una replica di lettura di informare il nodo primario sulla relativa attività di query, impedendo al nodo primario di eseguire il processo di vacuum sulle tabelle o sulle righe in uso sulla replica in standby. Se da un lato ciò garantisce la stabilità delle query sulla replica in standby, dall’altro può ritardare in modo significativo il processo di vacuum sul nodo primario. Disabilitando questa funzionalità il nodo primario può eseguire il processo di vacuum senza attendere la riattivazione dallo stato di standby. Tuttavia, ciò può comportare l’annullamento delle query o errori della replica in standby in caso di tentativo di accedere alle righe che sono state sottoposte a vacuum dal nodo primario.
+ **Eliminare la replica di lettura se non è più necessaria**: se la replica di lettura non è più necessaria, è possibile eliminarla. In questo modo, viene rimosso il sovraccarico di replica associato e il nodo primario può riciclare i log delle transazioni senza alcun ostacolo da parte della replica.

## Tabelle temporanee
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables"></a>

Le [tabelle temporanee](https://www.postgresql.org/docs/current/sql-createtable.html), create utilizzando la parola chiave `TEMPORARY`, risiedono nello schema temporaneo (ad esempio, pg\$1temp\$1xxx) e sono accessibili solo alla sessione che le ha create. Le tabelle temporanee vengono eliminate al termine della sessione. Tuttavia, queste tabelle sono invisibili al processo di autovacuum di PostgreSQL e devono sottoposte manualmente a vacuum dalla sessione che le ha create. Il tentativo di eseguire il processo di vacuum sulla tabella temporanea da un’altra sessione non ha alcun effetto.

In circostanze insolite, una tabella temporanea esiste senza che una sessione attiva ne sia proprietaria. Se la sessione proprietaria si conclude inaspettatamente a causa di un crash irreversibile, di un problema di rete o di un evento simile, è possibile che la pulizia della tabella temporanea non venga eseguita e che di conseguenza la tabella rimanga “orfana”. Quando il processo di autovacuum di PostgreSQL rileva una tabella temporanea orfana, registra il seguente messaggio:

```
LOG: autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"
```

La funzione `postgres_get_av_diag()` visualizza un output simile a quanto segue quando identifica in una tabella temporanea un elemento bloccante. Affinché la funzione mostri correttamente l’output relativo alle tabelle temporanee, deve essere eseguita all’interno dello stesso database in cui esistono tali tabelle.

```
blocker               | Temporary table
database              | my_database
blocker_identifier    | pg_temp_14.ttemp
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database". Review carefully, you may consider dropping temporary table using command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"DROP TABLE ttemp;"}
```

**Azione suggerita**

Segui le istruzioni fornite nella colonna `suggestion` dell’output per identificare e rimuovere la tabella temporanea che impedisce l’esecuzione del processo di autovacuum. Utilizza il comando seguente per eliminare la tabella temporanea riportata da `postgres_get_av_diag()`. Sostituisci il nome della tabella in base all’output fornito dalla funzione `postgres_get_av_diag()`.

```
DROP TABLE my_temp_schema.my_temp_table;
```

La seguente query può essere utilizzata per identificare le tabelle temporanee:

```
SELECT
    oid,
    relname,
    relnamespace::regnamespace,
    age(relfrozenxid)
FROM
    pg_class
WHERE
relpersistence = 't'
ORDER BY
    age(relfrozenxid) DESC;
```

# Risoluzione dei blocchi non identificabili per i processi di vacuum in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers"></a>

Questa sezione esplora ulteriori motivi che possono impedire l’avanzamento del processo di autovacuum. Al momento tali problemi non sono direttamente identificabili tramite la funzione `postgres_get_av_diag()`. 

**Topics**
+ [

## Pagine non valide
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)
+ [

## Incoerenza dell’indice
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency)
+ [

## Tasso di transazione eccezionalmente elevato
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate)

## Pagine non valide
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages"></a>

Un errore di pagina non valida si verifica quando PostgreSQL rileva una mancata corrispondenza nel checksum di una pagina durante l’accesso a tale pagina. I contenuti sono illeggibili, il che impedisce al processo di autovacuum di bloccare le tuple. Ciò arresta in modo efficace il processo di pulizia. Il seguente errore è scritto nel log di PostgreSQL:

```
WARNING:  page verification failed, calculated checksum YYYYY but expected XXXX
ERROR:  invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT:  automatic vacuum of table myschema.mytable
```

**Come determinare il tipo di oggetto**

```
ERROR: invalid page in block 4305910 of relation base/16403/186752608 
WARNING: page verification failed, calculated checksum 50065 but expected 60033
```

Dal messaggio di errore, il percorso `base/16403/186752608` fornisce le seguenti informazioni:
+ “base” è il nome della directory all’interno della directory di dati PostgreSQL.
+ “16403” è l’OID del database, che puoi cercare nel catalogo di sistema `pg_database`.
+ “186752608” è il `relfilenode`, che puoi utilizzare per cercare lo schema e il nome dell’oggetto nel catalogo di sistema `pg_class`.

Controllando l’output della seguente query nel database interessato, è possibile determinare il tipo di oggetto. La seguente query recupera le informazioni sull’oggetto per oid: 186752608. Sostituisci l’OID con quello relativo all’errore riscontrato.

```
SELECT
    relname AS object_name,
    relkind AS object_type,
    nspname AS schema_name
FROM
    pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
    c.oid = 186752608;
```

Per ulteriori informazioni, consulta [https://www.postgresql.org/docs/current/catalog-pg-class.html](https://www.postgresql.org/docs/current/catalog-pg-class.html) nella documentazione di PostgreSQL per trovare tutti i tipi di oggetto supportati, indicati nella colonna `relkind` in `pg_class`.

**Linea guida**

La soluzione più efficace per questo problema dipende dalla configurazione dell’istanza Amazon RDS specifica e dal tipo di dati interessati dalla pagina incoerente.

**Se il tipo di oggetto è un indice:**

Si consiglia di ricreare l’indice.
+ **Utilizzo dell’opzione `CONCURRENTLY`**: prima della versione 12 di PostgreSQL, per ricreare un indice era richiesto un blocco di tabella esclusivo, che limitava l’accesso alla tabella. Con la versione 12 di PostgreSQL e le versioni successive, l’opzione `CONCURRENTLY` consente di eseguire il blocco a livello di riga e ciò migliora la disponibilità della tabella in modo significativo. Il comando è il seguente:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Sebbene `CONCURRENTLY` sia meno dannoso, può essere più lento sulle tabelle particolarmente utilizzate. Se possibile, valuta la possibilità di creare l’indice durante i periodi di traffico ridotto.

  Per ulteriori informazioni, consulta [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) nella documentazione di PostgreSQL.
+ **Utilizzo dell’opzione `INDEX_CLEANUP FALSE`**: se gli indici sono di grandi dimensioni e si stima che richiedano un lungo lasso di tempo per completare l’operazione, puoi sbloccare l’autovacuum eseguendo un `VACUUM FREEZE` manuale escludendo gli indici. Questa funzionalità è disponibile in PostgreSQL 12 e versioni successive. 

  Bypassare gli indici ti consentirà di saltare il processo di vacuum dell’indice incoerente e mitigare il problema di wraparound. Tuttavia, ciò non risolverà il problema presente alla base e relativo alla pagina non valida. Per risolvere completamente il problema relativo alla pagina non valida, dovrai comunque ricreare l’indice.

**Se il tipo di oggetto è una vista materializzata:**

Se si verifica un errore di pagina non valida in una vista materializzata, accedi al database interessato e aggiornalo per risolvere la pagina non valida.

Aggiorna la vista materializzata.

```
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
```

Se l’aggiornamento non riesce, prova a eseguire una nuova creazione:

```
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
```

L’aggiornamento o la nuova creazione della vista materializzata la ripristina senza influire sui dati della tabella sottostante.

**Per tutti gli altri tipi di oggetto:**

Per tutti gli altri tipi di oggetto, contatta l’assistenza AWS.

## Incoerenza dell’indice
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency"></a>

Un indice logicamente incoerente può impedire il progresso del processo di autovacuum. I seguenti errori o errori simili vengono registrati durante la fase di vacuum dell’indice o quando si accede all’indice tramite istruzioni SQL.

```
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
```

```
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT:  while vacuuming index index_name of relation schema.table
```

**Linea guida**

Ricrea l’indice o salta gli indici utilizzando `INDEX_CLEANUP` sul `VACUUM FREEZE` manuale. Per informazioni su come creare nuovamente l’indice, consulta [Se il tipo di oggetto è un indice](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages).
+ **Utilizzo dell’opzione CONCURRENTLY**: prima della versione 12 di PostgreSQL, per ricreare un indice era richiesto un blocco di tabella esclusivo, che limitava l’accesso alla tabella Con la versione 12 di PostgreSQL e le versioni successive, l’opzione CONCURRENTLY consente di eseguire il blocco a livello di riga e ciò migliora la disponibilità della tabella in modo significativo. Il comando è il seguente:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Sebbene CONCURRENTLY sia meno dannoso, può essere più lento sulle tabelle particolarmente utilizzate. Se possibile, valuta la possibilità di creare l’indice durante i periodi di traffico ridotto. Per ulteriori informazioni, consulta [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) nella documentazione di *PostgreSQL*.
+ **Utilizzo dell’opzione INDEX\$1CLEANUP FALSE**: se gli indici sono di grandi dimensioni e si stima che richiedano un lungo lasso di tempo per completare l’operazione, puoi sbloccare l’autovacuum eseguendo un VACUUM FREEZE manuale escludendo gli indici. Questa funzionalità è disponibile in PostgreSQL 12 e versioni successive.

  Bypassare gli indici ti consentirà di saltare il processo di vacuum dell’indice incoerente e mitigare il problema di wraparound. Tuttavia, ciò non risolverà il problema presente alla base e relativo alla pagina non valida. Per risolvere completamente il problema relativo alla pagina non valida, dovrai comunque ricreare l’indice.

## Tasso di transazione eccezionalmente elevato
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate"></a>

In PostgreSQL, i tassi di transazione elevati possono influire in modo significativo sulle prestazioni di autovacuum, portando a una pulizia più lenta delle tuple inattive e a un aumento del rischio di wraparound dell’ID di transazione. È possibile monitorare il tasso di transazione misurando la differenza in `max(age(datfrozenxid))` tra due periodi di tempo, in genere al secondo. Inoltre, puoi utilizzare le seguenti metriche dei contatori di Approfondimenti sulle prestazioni di RDS per misurare il tasso di transazione (la somma di xact\$1commit e xact\$1rollback) che è il numero totale delle transazioni.


|  Contatore  |  Tipo  |  Unità  |  Parametro  | 
| --- | --- | --- | --- | 
|  xact\$1commit  |  Transazioni  |  Commit al secondo  |  db.Transactions.xact\$1commit  | 
|  xact\$1rollback  |  Transazioni  |  Rollback al secondo  |  db.Transactions.xact\$1rollback  | 

Un aumento rapido indica un carico di transazioni elevato, che può sovraccaricare il processo di autovacuum, con conseguenti aumento di dimensioni, conflitti di blocco e potenziali problemi di prestazioni. Ciò può influire negativamente sul processo di autovacuum in due modi:
+ **Attività delle tabelle:** la tabella specifica in fase di vacuum potrebbe registrare un volume elevato di transazioni, con conseguenti ritardi.
+ **Risorse di sistema:** l’intero sistema potrebbe essere sovraccarico e ciò rende difficile per l’autovacuum accedere alle risorse necessarie per garantire un funzionamento efficiente.

Esamina le seguenti strategie per consentire all’autovacuum di funzionare in modo più efficace e tenere il passo con le sue attività:

1. Riduzione, se possibile, del tasso di transazioni. Possibilità di raggruppare le transazioni simili, ove applicabile.

1. Concentrazione delle tabelle aggiornate di frequente con operazioni `VACUUM FREEZE` manuali con frequenza notturna, settimanale o bisettimanale nelle ore non di punta. 

1. Possibilità di aumentare verticalmente la classe di istanza per allocare più risorse di sistema al fine di gestire l’elevato volume di transazioni e l’autovacuum.

# Risoluzione dei problemi relativi alle prestazioni di vacuum in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance"></a>

Questa sezione illustra i fattori che spesso contribuiscono a rallentare le prestazioni di vacuum e spiega come risolvere tali problemi.

**Topics**
+ [

## Processo di vacuum su indici di grandi dimensioni
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes)
+ [

## Quantità eccessiva di tabelle o database da sottoporre a vacuum
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables)
+ [

## Esecuzione di un processo di vacuum aggressivo (per evitare il wraparound)
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

## Processo di vacuum su indici di grandi dimensioni
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes"></a>

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](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md).

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](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
        .
```

**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](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html).
```

**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:

1. Verifica che la nuova impostazione sia effettiva.

1. 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 VERBOSE table_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\$1CLEANUP**

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 [https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-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](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md).

**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_workers` deve 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](https://aws.amazon.com/blogs/database/parallel-vacuuming-in-amazon-rds-for-postgresql-and-amazon-aurora-postgresql/).

## Quantità eccessiva di tabelle o database da sottoporre a vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables"></a>

Come descritto nella sezione [The Autovacuum Daemon](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM') della documentazione di PostgreSQL, il daemon di autovacuum opera attraverso l’esecuzione di più processi. È incluso un programma di avvio automatico persistente responsabile dell’avvio dei processi worker di autovacuum per ogni database all’interno del sistema. Il programma di avvio pianifica l’avvio dei worker affinché si verifichi all’incirca ogni `autovacuum_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\$1max\$1workers**

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)
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum"></a>

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](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md).

È 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`.

# Spiegazione dei messaggi NOTICE in RDS per PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE"></a>

 La funzione `postgres_get_av_diag()` fornisce i seguenti messaggi NOTICE:

**Scenario in cui l’età non ha ancora raggiunto la soglia di monitoraggio**  
Per impostazione predefinita, la soglia di monitoraggio per `postgres_get_av_diag()` che consente di identificare gli elementi bloccanti è di 500 milioni di transazioni. Se `postgres_get_av_diag()` genera il seguente messaggio NOTICE, significa che l’età delle transazioni non ha ancora raggiunto tale soglia.  

```
NOTICE: postgres_get_av_diag() checks for blockers that prevent aggressive vacuums only, it does so only after exceeding dvb_threshold which is 500,000,000 and age of this PostgreSQL cluster is currently at 2.
```

**Mancata connessione al database con l’età dell’ID transazione meno recente**  
La funzione `postgres_get_av_diag()` fornisce l’output più accurato quando è connessa al database con l’età dell’ID transazione meno recente. Nel caso in questione, il database con l’età dell’ID transazione meno recente riportato da `postgres_get_av_diag()` è diverso da “my\$1database”. In caso di mancata connessione al database corretto, viene generato il seguente messaggio NOTICE:  

```
NOTICE: You are not connected to the database with the age of oldest transaction ID. Connect to my_database database and run postgres_get_av_diag() for accurate reporting.
```
La connessione al database con l’età della transazione meno recente è importante per i seguenti motivi:  
+ **Identificazione degli elementi bloccanti costituiti da tabelle temporanee:** i metadati per le tabelle temporanee sono specifici di ogni database, pertanto solitamente sono contenuti nel database in cui sono stati creati. Tuttavia, se una tabella temporanea è l’elemento bloccante principale ed è contenuta nel database con la transazione meno recente, la situazione potrebbe risultare fuorviante. La connessione al database corretto garantisce l’identificazione accurata dell’elemento bloccante costituito da una tabella temporanea.
+ **Diagnosi dei problemi correlati a processi di vacuum a esecuzione lenta:** le informazioni sul numero di tabelle e i metadati degli indici sono specifici di ogni database e sono necessari per diagnosticare eventuali problemi correlati a processi di vacuum a esecuzione lenta.

**Scenario in cui il database con la transazione meno recente per età è un database rdsadmin o template0**  
In alcuni casi, è possibile che un database `rdsadmin` o `template0` venga identificato come il database con l’età dell’ID transazione meno recente. In tali casi, `postgres_get_av_diag()` genera il seguente messaggio NOTICE:  

```
NOTICE: The database with the age of oldest transaction ID is rdsadmin or template0, reach out to support if the reported blocker is in rdsadmin or template0.
```
Verifica che l’elemento bloccante indicato non provenga da nessuno di questi due database. Se viene segnalata la presenza dell’elemento bloccante nel database `rdsadmin` o `template0`, contatta il supporto poiché tali database non sono accessibili all’utente e richiedono un intervento.  
È altamente improbabile che il database `rdsadmin` o `template0` contenga un elemento bloccante principale.

**Scenario in cui è già in esecuzione un processo di vacuum aggressivo**  
La funzione `postgres_get_av_diag()` è progettata per segnalare quando è in corso un processo di vacuum aggressivo, ma attiva questo output solo dopo che il processo di vacuum è rimasto attivo per almeno 1 minuto. Questo ritardo intenzionale aiuta a ridurre le possibilità di falsi positivi. L’attesa fa sì che la funzione segnali solo i processi di vacuum efficaci e significativi, permettendo un monitoraggio più accurato e affidabile dell’attività di vacuum.  
La funzione `postgres_get_av_diag()` genera il seguente messaggio NOTICE quando rileva uno o più processi di vacuum aggressivi in esecuzione.   

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```
Come indicato nel messaggio NOTICE, occorre continuare a monitorare le prestazioni dell’attività di vacuum. Per ulteriori informazioni sui processi di vacuum aggressivi, consulta [Esecuzione di un processo di vacuum aggressivo (per evitare il wraparound)](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum).

**Scenario in cui la funzionalità di autovacuum è disattivata**  
La funzione `postgres_get_av_diag()` genera il seguente messaggio NOTICE se la funzionalità di autovacuum è disabilitata in un’istanza database:  

```
NOTICE: Autovacuum is OFF, we strongly recommend to enable it, no restart is necessary.
```
Autovacuum è una funzionalità fondamentale delle istanze database RDS per PostgreSQL in quanto garantisce il corretto funzionamento del database. Essa rimuove automaticamente le versioni precedenti delle righe, recupera spazio di archiviazione e impedisce il bloat delle tabelle, garantendo così l’efficacia di tabelle e indici per prestazioni ottimali. Inoltre, evita il wraparound degli ID transazione, che può interrompere le transazioni sulle istanze Amazon RDS. Disabilitando la funzionalità di autovacuum, è possibile che la stabilità e le prestazioni del database subiscano una riduzione a lungo termine. Pertanto suggeriamo di lasciarla sempre attivata. Per ulteriori informazioni, consulta [Informazioni sull’autovacuum in ambienti RDS per PostgreSQL](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/).  
La disattivazione della funzionalità di autovacuum non blocca i processi di vacuum aggressivi. Tali problemi continueranno a verificarsi quando le tabelle raggiungeranno la soglia `autovacuum_freeze_max_age`. 

**Scenario in cui il numero di transazioni rimanenti è estremamente basso**  
La funzione `postgres_get_av_diag()` genera il seguente messaggio NOTICE quando è imminente un processo di vacuum per wraparound. Questo messaggio NOTICE viene generato quando, in un’istanza Amazon RDS, mancano solo 100 milioni di transazioni prima che possa verificarsi il rifiuto di nuove transazioni.  

```
WARNING: Number of transactions remaining is critically low, resolve issues with autovacuum or perform manual VACUUM FREEZE before your instance stops accepting transactions.
```
È necessaria un’azione immediata per evitare un tempo di inattività del database. Occorre monitorare attentamente le operazioni di vacuum e valutare la possibilità di avviare manualmente un processo `VACUUM FREEZE` sul database interessato per evitare errori nelle transazioni.