

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

# Ottimizzazione degli eventi di attesa per RDS per PostgreSQL
<a name="PostgreSQL.Tuning"></a>

Gli eventi di attesa sono un importante strumento di ottimizzazione per RDS per PostgreSQL. Quando si scopre perché le sessioni sono in attesa di risorse e l'azione svolta, è possibile risolvere i colli di bottiglia in maniera più efficiente. È possibile utilizzare le informazioni contenute in questa sezione per trovare possibili cause e azioni correttive. Questa sezione illustra anche i concetti di base sull'ottimizzazione di PostgreSQL.

Gli eventi di attesa in questa sezione sono specifici di RDS per PostgreSQL.

**Topics**
+ [Concetti essenziali per l'ottimizzazione di RDS per PostgreSQL](PostgreSQL.Tuning.concepts.md)
+ [Eventi di attesa di RDS per PostgreSQL](PostgreSQL.Tuning.concepts.summary.md)
+ [Cliente: ClientRead](wait-event.clientread.md)
+ [Cliente: ClientWrite](wait-event.clientwrite.md)
+ [CPU](wait-event.cpu.md)
+ [IO: BufFileRead e IO: BufFileWrite](wait-event.iobuffile.md)
+ [IO: DataFileRead](wait-event.iodatafileread.md)
+ [IO:WALWrite](wait-event.iowalwrite.md)
+ [Eventi di attesa IPC:parallel](rpg-ipc-parallel.md)
+ [IPC: ProcArrayGroupUpdate](apg-rpg-ipcprocarraygroup.md)
+ [Lock:advisory](wait-event.lockadvisory.md)
+ [Lock:extend](wait-event.lockextend.md)
+ [Lock:Relation](wait-event.lockrelation.md)
+ [Lock:transactionid](wait-event.locktransactionid.md)
+ [Lock:tuple](wait-event.locktuple.md)
+ [LWLock: BufferMapping (:mappatura\$1buffer) LWLock](wait-event.lwl-buffer-mapping.md)
+ [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)
+ [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)
+ [LWLock:lock\$1manager (:lockmanager) LWLock](wait-event.lw-lock-manager.md)
+ [LWLock:pg\$1stat\$1statements](apg-rpg-lwlockpgstat.md)
+ [LWLock:SubTransSLRU (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)
+ [Timeout: PG Sleep](wait-event.timeoutpgsleep.md)
+ [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)

# Concetti essenziali per l'ottimizzazione di RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts"></a>

Prima di ottimizzare il database RDS per PostgreSQL, assicurati di sapere cosa sono gli eventi di attesa e perché si verificano. Esamina anche l'architettura di base della memoria e del disco di RDS per PostgreSQL. Per un utile diagramma architettonico, vedere il wikibook [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture).

**Topics**
+ [Eventi di attesa di RDS per PostgreSQL](PostgreSQL.Tuning.concepts.waits.md)
+ [Memoria RDS per PostgreSQL](PostgreSQL.Tuning.concepts.memory.md)
+ [Processi di RDS per PostgreSQL](PostgreSQL.Tuning.concepts.processes.md)

# Eventi di attesa di RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.waits"></a>

Un *evento di attesa* indica che una sessione è in attesa di una risorsa. Ad esempio, l'evento di attesa `Client:ClientRead` si verifica quando RDS per PostgreSQL è in attesa di ricevere dati dal client. Le sessioni in genere attendono risorse come le seguenti.
+ Accesso a thread singolo a un buffer, ad esempio, quando una sessione sta tentando di modificare un buffer
+ Una riga attualmente bloccata da un'altra sessione
+ Un file di dati letto
+ Scrittura di un file log

Ad esempio, per soddisfare una query, la sessione potrebbe eseguire una scansione completa della tabella. Se i dati non sono già in memoria, la sessione attende il completamento dell'I/O del disco. Quando i buffer vengono letti in memoria, potrebbe essere necessario attendere perché altre sessioni accedono agli stessi buffer. Il database registra le attese utilizzando un evento di attesa predefinito. Questi eventi sono raggruppati in categorie.

Di per sé, un singolo evento di attesa non indica un problema di prestazioni. Ad esempio, se i dati richiesti non sono in memoria, è necessaria la lettura dei dati dal disco. Se una sessione blocca una riga per un aggiornamento, un'altra sessione attende che la riga venga sbloccata in modo che possa aggiornarla. Un commit richiede di attendere il completamento della scrittura su un file di registro. Le attese sono parte integrante del normale funzionamento di un database. 

Un gran numero di eventi di attesa in genere mostrano un problema di prestazioni. In questi casi, è possibile utilizzare i dati degli eventi di attesa per determinare dove stanno trascorrendo il tempo delle sessioni. Ad esempio, se un report che in genere viene eseguito in minuti ora viene eseguito per ore, è possibile identificare gli eventi di attesa che contribuiscono maggiormente al tempo di attesa totale. Se è possibile determinare le cause degli eventi di attesa principali, a volte è possibile apportare modifiche che migliorano le prestazioni. Ad esempio, se la sessione è in attesa su una riga bloccata da un'altra sessione, è possibile terminare la sessione di blocco. 

# Memoria RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.memory"></a>

La memoria RDS per PostgreSQL è divisa in condivisa e locale.

**Topics**
+ [Memoria condivisa in RDS per PostgreSQL](#PostgreSQL.Tuning.concepts.shared)
+ [Memoria locale in RDS per PostgreSQL](#PostgreSQL.Tuning.concepts.local)

## Memoria condivisa in RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.shared"></a>

RDS per PostgreSQL assegna memoria condivisa all'avvio dell'istanza. La memoria condivisa è divisa in più sottoaree. Nelle seguenti sezioni sono descritte le più importanti.

**Topics**
+ [Buffer condivisi](#PostgreSQL.Tuning.concepts.buffer-pool)
+ [Buffer Write ahead log (WAL)](#PostgreSQL.Tuning.concepts.WAL)

### Buffer condivisi
<a name="PostgreSQL.Tuning.concepts.buffer-pool"></a>

Il *pool buffer condiviso* è un'area di memoria RDS per PostgreSQL che contiene tutte le pagine che sono o sono state utilizzate dalle connessioni delle applicazioni. Una *pagina* è la versione di memoria di un blocco disco. Il buffer pool condiviso memorizza nella cache i blocchi di dati letti dal disco. Il pool riduce la necessità di rileggere i dati dal disco, rendendo il database più efficiente.

Ogni tabella e indice vengono memorizzati come una matrice di pagine di dimensioni fisse. Ogni blocco contiene più tuple, che corrispondono alle righe. Una tupla può essere memorizzata in qualsiasi pagina.

Il buffer pool condiviso ha memoria finita. Se una nuova richiesta richiede una pagina che non è in memoria, e non esiste più memoria, RDS per PostgreSQL espelle una pagina utilizzata meno frequentemente per soddisfare la richiesta. La politica di sfratto è implementata da un algoritmo di sweep dell'orologio.

Il parametro `shared_buffers` determina la quantità di memoria che il server dedica alla memorizzazione nella cache dei dati. Il valore predefinito è impostato su `{DBInstanceClassMemory/32768}` byte, in base alla memoria disponibile per l’istanza database.

### Buffer Write ahead log (WAL)
<a name="PostgreSQL.Tuning.concepts.WAL"></a>

Un *Buffer write-ahead log (WAL)* conserva i dati delle transazioni che RDS per PostgreSQL successivamente scrive sull'archiviazione persistente. Utilizzando il meccanismo WAL, RDS per PostgreSQL può effettuare le seguenti operazioni:
+ Recuperare i dati dopo un errore
+ Riduci il disco I/O evitando scritture frequenti su disco

Quando un client modifica i dati, RDS per PostgreSQL scrive le modifiche nel buffer WAL. Quando il client emette un `COMMIT`, il processo di scrittura WAL scrive i dati delle transazioni nel file WAL.

Il parametro `wal_level` determina la quantità di informazioni scritte sul WAL, con valori possibili quali `minimal`, `replica` e `logical`.

## Memoria locale in RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.local"></a>

Ogni processo di back-end assegna memoria locale per l'elaborazione delle query.

**Topics**
+ [Area di memoria di lavoro](#PostgreSQL.Tuning.concepts.local.work_mem)
+ [Area memoria di lavoro di manutenzione](#PostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [Area buffer temporanea](#PostgreSQL.Tuning.concepts.temp)

### Area di memoria di lavoro
<a name="PostgreSQL.Tuning.concepts.local.work_mem"></a>

L’*area di memoria di lavoro* contiene dati temporanei per query che eseguono ordinamenti e hash. Ad esempio, una query con clausola `ORDER BY` esegue un ordinamento. Le query utilizzano tabelle hash nei join e nelle aggregazioni hash.

Il parametro `work_mem` indica la quantità di memoria da utilizzare per le operazioni di ordinamento interno e le tabelle hash prima di scrivere su file di disco temporanei. Il valore predefinito è 4 MB. È possibile eseguire più sessioni contemporaneamente e ogni sessione può eseguire operazioni di manutenzione in parallelo. Per questo motivo, la memoria di lavoro totale utilizzata può essere costituita da multipli dell’impostazione `work_mem`. 

### Area memoria di lavoro di manutenzione
<a name="PostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

L’*area di memoria di lavoro di manutenzione* memorizza nella cache i dati per le operazioni di manutenzione. Queste operazioni includono l'aspirazione, la creazione di un indice e l'aggiunta di chiavi esterne.

Il parametro `maintenance_work_mem` specifica la quantità massima di memoria da utilizzare per le operazioni di manutenzione, espressa in megabyte. Il valore predefinito è 64 MB. Una sessione di database può eseguire solo un'operazione di manutenzione alla volta.

### Area buffer temporanea
<a name="PostgreSQL.Tuning.concepts.temp"></a>

L’*area buffer temporanea* memorizza nella cache le tabelle temporanee per ciascuna sessione del database.

Ogni sessione assegna buffer temporanei secondo necessità fino al limite specificato. Quando la sessione scade, il server cancella i buffer.

Il parametro `temp_buffers` imposta il numero massimo di buffer temporanei utilizzati da ogni sessione, espressi in megabyte. Il valore predefinito è 8 MB. Prima del primo utilizzo di tabelle temporanee all'interno di una sessione, è possibile modificare il valore `temp_buffers`.

# Processi di RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.processes"></a>

RDS per PostgreSQL utilizza più processi.

**Topics**
+ [Processo postmaster](#PostgreSQL.Tuning.concepts.postmaster)
+ [Processi di back-end](#PostgreSQL.Tuning.concepts.backend)
+ [Processi in background](#PostgreSQL.Tuning.concepts.vacuum)

## Processo postmaster
<a name="PostgreSQL.Tuning.concepts.postmaster"></a>

Il *processo postmaster* è il primo processo eseguito quando si avvia RDS per PostgreSQL. Il processo postmaster ha le seguenti responsabilità principali:
+ Forcella e monitoraggio dei processi in background
+ Ricevere le richieste di autenticazione dai processi client e autenticarle prima di consentire al database di servire le richieste

## Processi di back-end
<a name="PostgreSQL.Tuning.concepts.backend"></a>

Se il postmaster autentica una richiesta del cliente, il postmaster forcherà un nuovo processo di back-end, chiamato anche processo postgres. Un processo client si connette esattamente a un processo back-end. Il processo client e il processo di backend comunicano direttamente senza intervento da parte del processo postmaster.

## Processi in background
<a name="PostgreSQL.Tuning.concepts.vacuum"></a>

Il processo postmaster forca diversi processi che eseguono diverse attività di back-end. Alcuni dei più importanti includono quanto segue:
+ Scrittore WAL

  RDS per PostgreSQL scrive i dati nel buffer WAL (write ahead logging) nei file di log. Il principio della registrazione write ahead è che il database non può scrivere modifiche ai file di dati fino a quando il database ha scritto i record di log che descrivono tali modifiche su disco. Il meccanismo WAL riduce l'I/O del disco e consente a RDS per PostgreSQL di utilizzare i log per recuperare il database dopo un errore.
+ Background writer

  Questo processo scrive periodicamente pagine sporche (modificate) dai buffer di memoria ai file di dati. Una pagina diventa sporca quando un processo di back-end la modifica in memoria.
+ Il daemon dell'Autovacuum

  Il daemon include i seguenti elementi:
  + Il lanciatore di autovacuum
  + I processi di autovacuum worker

  Se abilitata, verifica la presenza di tabelle con un numero elevato di tuple inserite, aggiornate o eliminate. Il daemon ha le seguenti responsabilità:
  + Recuperare o riutilizzare lo spazio su disco occupato da righe aggiornate o eliminate
  + Aggiornare le statistiche utilizzate dal planner
  + Proteggere contro la perdita di dati precedenti a causa di un involucro dell'ID transazione

  La funzione autovacuum automatizza l'esecuzione dei comandi `VACUUM` e `ANALYZE`. `VACUUM` ha le seguenti varianti: standard e full. Il vuoto standard funziona in parallelo con altre operazioni di database. `VACUUM FULL` richiede un blocco esclusivo sulla tabella su cui sta lavorando. Pertanto, non può essere eseguito in parallelo con le operazioni che accedono alla stessa tabella. `VACUUM`crea una notevole quantità di I/O traffico, che può causare scarse prestazioni per altre sessioni attive.

# Eventi di attesa di RDS per PostgreSQL
<a name="PostgreSQL.Tuning.concepts.summary"></a>

La seguente tabella elenca gli eventi di attesa per RDS per PostgreSQL che indicano i problemi di prestazioni con le cause più comuni e le azioni correttive.


| Evento di attesa | Definizione | 
| --- | --- | 
|  [Cliente: ClientRead](wait-event.clientread.md)  |  Ad esempio, l'evento di attesa si verifica quando RDS per PostgreSQL è in attesa di ricevere dati dal client.  | 
|  [Cliente: ClientWrite](wait-event.clientwrite.md)  |  Ad esempio, l'evento di attesa si verifica quando RDS per PostgreSQL è in attesa di ricevere dati dal client.  | 
|  [CPU](wait-event.cpu.md)  | Questo evento si verifica quando un thread è attivo nella CPU o è in attesa della CPU.  | 
|  [IO: BufFileRead e IO: BufFileWrite](wait-event.iobuffile.md)  |  Questi eventi si verificano quando RDS per PostgreSQL crea file temporanei.  | 
|  [IO: DataFileRead](wait-event.iodatafileread.md)  |  Questo evento si verifica quando una connessione attende un processo di back-end per leggere una pagina richiesta dalla memoria perché la pagina non è disponibile nella memoria condivisa.   | 
| [IO:WALWrite](wait-event.iowalwrite.md)  | Questo evento si verifica quando RDS per PostgreSQL è in attesa che i buffer WAL (write-ahead log) vengano scritti in un file WAL.  | 
|  [Lock:advisory](wait-event.lockadvisory.md)  |  Questo evento si verifica quando un'applicazione PostgreSQL utilizza un blocco per coordinare l'attività su più sessioni.  | 
|  [Lock:extend](wait-event.lockextend.md) |  Questo evento si verifica quando un processo di back-end è in attesa di bloccare una relazione per estenderla mentre un altro processo ha un blocco su tale relazione per lo stesso scopo.  | 
|  [Lock:Relation](wait-event.lockrelation.md)  |  Questo evento si verifica quando una query è in attesa di acquisire un blocco su una tabella o vista attualmente bloccata da un'altra transazione.  | 
|  [Lock:transactionid](wait-event.locktransactionid.md)  | Questo evento si verifica quando una transazione è in attesa di un blocco a livello di riga. | 
|  [Lock:tuple](wait-event.locktuple.md)  |  Questo evento si verifica quando un processo di backend aspetta di acquisire un blocco su una tupla.  | 
|  [LWLock: BufferMapping (:mappatura\$1buffer) LWLock](wait-event.lwl-buffer-mapping.md)  |  Questo evento si verifica quando un processo di backend è in attesa di associare un blocco di dati a un buffer nel pool di buffer condiviso.  | 
|  [LWLock:BufferIO (IPC:BufferIO)](wait-event.lwlockbufferio.md)  |  Questo evento si verifica quando RDS per PostgreSQL è in attesa che altri processi completino le input/output loro operazioni (I/O) quando tentano contemporaneamente di accedere a una pagina.  | 
|  [LWLock:buffer\$1content (BufferContent)](wait-event.lwlockbuffercontent.md)  |  Questo evento si verifica quando una sessione è in attesa di accedere in lettura o scrittura a una pagina dati in memoria mentre un'altra sessione ha bloccato la pagina in scrittura.  | 
|  [LWLock:lock\$1manager (:lockmanager) LWLock](wait-event.lw-lock-manager.md)  | Questo evento si verifica quando il motore RDS per PostgreSQL mantiene l'area di memoria del blocco condiviso per allocare, controllare e deallocare un blocco quando non è possibile un blocco rapido del percorso. | 
|  [LWLock:SubTransSLRU (:) LWLock SubtransControlLock](wait-event.lwlocksubtransslru.md)  |  Questo evento si verifica quando un processo è in attesa di accedere alla cache SLRU (Simple Least-Recently Used) per una sottotransazione.  | 
|  [Timeout: PG Sleep](wait-event.timeoutpgsleep.md)  |  Questo evento si verifica quando un processo server ha chiamato la funzione `pg_sleep` e sta aspettando la scadenza del timeout del sonno.   | 
|  [Timeout:VacuumDelay](wait-event.timeoutvacuumdelay.md)  | Questo evento indica che il processo vacuum è inattivo perché è stato raggiunto il limite di costo stimato.  | 

# Cliente: ClientRead
<a name="wait-event.clientread"></a>

L'evento `Client:ClientRead` si verifica quando RDS per PostgreSQL è in attesa di ricevere dati dal client.

**Topics**
+ [Versioni del motore supportate](#wait-event.clientread.context.supported)
+ [Contesto](#wait-event.clientread.context)
+ [Probabili cause di aumento delle attese](#wait-event.clientread.causes)
+ [Azioni](#wait-event.clientread.actions)

## Versioni del motore supportate
<a name="wait-event.clientread.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per RDS per PostgreSQL versione 10 e successive.

## Contesto
<a name="wait-event.clientread.context"></a>

Un'istanza database RDS per PostgreSQL è in attesa di ricevere dati dal client. L'istanza database RDS per PostgreSQL deve ricevere i dati dal client prima di poter inviare più dati al client. Il tempo di attesa dell'istanza prima di ricevere i dati dal client è un evento `Client:ClientRead`.

## Probabili cause di aumento delle attese
<a name="wait-event.clientread.causes"></a>

Le cause comuni della comparsa dell'evento `Client:ClientRead` che appare nelle prime attese includono: 

**Maggiore latenza di rete**  
Potrebbe esserci una maggiore latenza di rete tra l'istanza database RDS per PostgreSQL e il client. Una maggiore latenza di rete aumenta il tempo necessario per la ricezione dei dati dal client dell'istanza database.

**Aumento del carico sul client**  
Potrebbe esserci una pressione della CPU o una saturazione della rete sul client. Un aumento del carico sul client può ritardare la trasmissione dei dati dal client all'istanza RDS per PostgreSQL.

**Eccesso di viaggi di andata e ritorno in rete**  
Un numero elevato di round trip di rete tra l'istanza database RDS per PostgreSQL e il client può ritardare la trasmissione dei dati dal client all'istanza database RDS per PostgreSQL.

**Operazione copia di grandi dimensioni**  
Durante un'operazione di copia, i dati vengono trasferiti dal file system del client all'istanza database RDS per PostgreSQL. L'invio di una grande quantità di dati all'istanza database può ritardare la trasmissione dei dati dal client all'istanza database.

**Connessione client inattiva**  
Quando un client si connette all'istanza database RDS per PostgreSQL nello stato `idle in transaction`, l'istanza database potrebbe attendere che il client invii più dati o emetta un comando. Una connessione in questo stato può portare ad un aumento degli eventi `Client:ClientRead`.

**PgBouncer utilizzato per il pool di connessioni**  
PgBouncer ha un'impostazione di configurazione di rete di basso livello denominata`pkt_buf`, che per impostazione predefinita è impostata su 4.096. Se il carico di lavoro consiste nell'invio di pacchetti di query di dimensioni superiori a 4.096 byte PgBouncer, si consiglia di aumentare l'impostazione a 8.192. `pkt_buf` Se la nuova impostazione non diminuisce il numero di eventi `Client:ClientRead`, consigliamo di aumentare l’impostazione `pkt_buf` su valori più grandi, come 16.384 o 32.768. Se il testo della query è grande, l’impostazione più grande può essere particolarmente utile.

## Azioni
<a name="wait-event.clientread.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Posizionamento dei client nella stessa zona di disponibilità e sottorete VPC dell'istanza](#wait-event.clientread.actions.az-vpc-subnet)
+ [Ridimensionare il client](#wait-event.clientread.actions.scale-client)
+ [Utilizza istanze di generazione corrente](#wait-event.clientread.actions.db-instance-class)
+ [Aumentare la larghezza di banda di rete](#wait-event.clientread.actions.increase-network-bandwidth)
+ [Monitora il massimo delle prestazioni di rete](#wait-event.clientread.actions.monitor-network-performance)
+ [Monitorare le transazioni nello stato «inattivo nella transazione»](#wait-event.clientread.actions.check-idle-in-transaction)

### Posizionamento dei client nella stessa zona di disponibilità e sottorete VPC dell'istanza
<a name="wait-event.clientread.actions.az-vpc-subnet"></a>

Per ridurre la latenza di rete e aumentare la velocità di trasmissione effettiva di rete, posiziona i client nella stessa sottorete della zona di disponibilità e cloud privato virtuale (VPC) dell'istanza database RDS per PostgreSQL. Assicurati che i client siano geograficamente il più vicini possibile all'istanza database.

### Ridimensionare il client
<a name="wait-event.clientread.actions.scale-client"></a>

Utilizzando Amazon CloudWatch o altri parametri relativi all'host, stabilisci se il tuo client è attualmente limitato dalla CPU o dalla larghezza di banda della rete o da entrambi. Se il client è vincolato, ridimensionare il client di conseguenza.

### Utilizza istanze di generazione corrente
<a name="wait-event.clientread.actions.db-instance-class"></a>

In alcuni casi, potresti non utilizzare una classe di istanza DB che supporta i frame jumbo. Se stai eseguendo l'applicazione su Amazon EC2, considera l'utilizzo di un'istanza di generazione corrente per il client. Inoltre, configura l'unità di trasmissione massima (MTU) sul sistema operativo client. Questa tecnica potrebbe ridurre il numero di round trip di rete e aumentare il throughput di rete. Per ulteriori informazioni, consulta [Frame jumbo (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) nella *Guida per l’utente di Amazon EC2*.

Per informazioni sulle classi di istanza database, consulta [Classi di istanze DB ](Concepts.DBInstanceClass.md). Per determinare la classe di istanza DB equivalente a un tipo di istanza Amazon EC2, posizionare `db.` prima del nome del tipo di istanza Amazon EC2. Ad esempio, l’istanza Amazon EC2 `r5.8xlarge` è equivalente alla classe di istanza database `db.r5.8xlarge`.

### Aumentare la larghezza di banda di rete
<a name="wait-event.clientread.actions.increase-network-bandwidth"></a>

Usa `NetworkReceiveThroughput` i CloudWatch parametri di `NetworkTransmitThroughput` Amazon per monitorare il traffico di rete in entrata e in uscita sull'istanza DB. Questi parametri possono aiutarti a determinare se la larghezza di banda della rete è sufficiente per il tuo carico di lavoro. 

Se la larghezza di banda della rete non è sufficiente, aumentala. Se il AWS client o l'istanza DB stanno raggiungendo i limiti di larghezza di banda di rete, l'unico modo per aumentare la larghezza di banda è aumentare le dimensioni dell'istanza DB. Per ulteriori informazioni, consulta [Tipi di classi di istanza database](Concepts.DBInstanceClass.Types.md).

Per ulteriori informazioni sulle CloudWatch metriche, consulta. [CloudWatch Parametri Amazon per Amazon RDS](rds-metrics.md) 

### Monitora il massimo delle prestazioni di rete
<a name="wait-event.clientread.actions.monitor-network-performance"></a>

Se utilizzi client Amazon EC2, Amazon EC2 fornisce il massimo per i parametri delle prestazioni di rete, inclusa la larghezza di banda aggregata in entrata e in uscita. Fornisce inoltre il monitoraggio della connessione per garantire che i pacchetti vengano restituiti come previsto e l’accesso ai servizi locali per servizi come il DNS (Domain Name System). Per monitorare questi massimi, utilizza un driver di rete avanzato e monitora le prestazioni di rete per il client. 

Per ulteriori informazioni, consulta [Monitoraggio delle prestazioni di rete per l’istanza EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) nella *Guida per l’utente di Amazon EC2* e [Monitoraggio delle prestazioni di rete per l’istanza EC2](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/monitoring-network-performance-ena.html) nella *Guida per l’utente di Amazon EC2*.

### Monitorare le transazioni nello stato «inattivo nella transazione»
<a name="wait-event.clientread.actions.check-idle-in-transaction"></a>

Controlla se hai un numero crescente di connessioni `idle in transaction`. Per fare ciò, monitora la colonna `state` nella tabella `pg_stat_activity`. Potrebbe essere possibile identificare l’origine della connessione eseguendo una query simile alla seguente.

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Cliente: ClientWrite
<a name="wait-event.clientwrite"></a>

L'evento `Client:ClientWrite` si verifica quando RDS per PostgreSQL è in attesa di scrivere dati sul client.

**Topics**
+ [Versioni del motore supportate](#wait-event.clientwrite.context.supported)
+ [Contesto](#wait-event.clientwrite.context)
+ [Probabili cause di aumento delle attese](#wait-event.clientwrite.causes)
+ [Azioni](#wait-event.clientwrite.actions)

## Versioni del motore supportate
<a name="wait-event.clientwrite.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per RDS per PostgreSQL versione 10 e successive.

## Contesto
<a name="wait-event.clientwrite.context"></a>

Il processo client deve ricevere i dati da un cluster database RDS per PostgreSQL prima di poter inviare più dati. Il tempo in cui il cluster attende prima inviare altri dati al client è un evento `Client:ClientWrite`.

La velocità di trasmissione effettiva di rete ridotto tra l'istanza database RDS per PostgreSQL e il client può causare questo evento. Anche la pressione della CPU e la saturazione della rete sul client possono causare questo evento. *Pressione CPU* è quando la CPU è completamente utilizzata e ci sono attività in attesa del tempo della CPU. *Saturazione rete* è quando la rete tra il database e il client trasporta più dati di quelli che è in grado di gestire. 

## Probabili cause di aumento delle attese
<a name="wait-event.clientwrite.causes"></a>

Le cause comuni della comparsa dell'evento `Client:ClientWrite` che appare nelle prime attese includono: 

**Maggiore latenza di rete**  
Potrebbe esserci una maggiore latenza di rete tra l'istanza database RDS per PostgreSQL e il client. Una maggiore latenza di rete aumenta il tempo necessario per la ricezione dei dati dal client.

**Aumento del carico sul client**  
Potrebbe esserci una pressione della CPU o una saturazione della rete sul client. Un aumento del carico sul client ritarda la ricezione dei dati dall'istanza database RDS per PostgreSQL.

**Ampio volume di dati inviati al client**  
L'istanza database RDS per PostgreSQL DB potrebbe inviare una grande quantità di dati al client. Un client potrebbe non essere in grado di ricevere i dati con la stessa rapidità dell’invio del cluster. Attività come una copia di una tabella di grandi dimensioni possono comportare un aumento degli eventi `Client:ClientWrite`.

## Azioni
<a name="wait-event.clientwrite.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Posizionare i client nella stessa area di disponibilità e subnet VPC del cluster](#wait-event.clientwrite.actions.az-vpc-subnet)
+ [Utilizza istanze di generazione corrente](#wait-event.clientwrite.actions.db-instance-class)
+ [Ridurre la quantità di dati inviati al client](#wait-event.clientwrite.actions.reduce-data)
+ [Ridimensionare il client](#wait-event.clientwrite.actions.scale-client)

### Posizionare i client nella stessa area di disponibilità e subnet VPC del cluster
<a name="wait-event.clientwrite.actions.az-vpc-subnet"></a>

Per ridurre la latenza di rete e aumentare la velocità di trasmissione effettiva di rete, posiziona i client nella stessa sottorete della zona di disponibilità e cloud privato virtuale (VPC) dell'istanza database RDS per PostgreSQL.

### Utilizza istanze di generazione corrente
<a name="wait-event.clientwrite.actions.db-instance-class"></a>

In alcuni casi, potresti non utilizzare una classe di istanza DB che supporta i frame jumbo. Se stai eseguendo l'applicazione su Amazon EC2, considera l'utilizzo di un'istanza di generazione corrente per il client. Inoltre, configura l'unità di trasmissione massima (MTU) sul sistema operativo client. Questa tecnica potrebbe ridurre il numero di round trip di rete e aumentare il throughput di rete. Per ulteriori informazioni, consulta [Frame jumbo (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) nella *Guida per l’utente di Amazon EC2*.

Per informazioni sulle classi di istanza database, consulta [Classi di istanze DB ](Concepts.DBInstanceClass.md). Per determinare la classe di istanza DB equivalente a un tipo di istanza Amazon EC2, posizionare `db.` prima del nome del tipo di istanza Amazon EC2. Ad esempio, l'istanza Amazon EC2 `r5.8xlarge` è equivalente alla classe di istanza DB `db.r5.8xlarge`.

### Ridurre la quantità di dati inviati al client
<a name="wait-event.clientwrite.actions.reduce-data"></a>

Quando possibile, regola l'applicazione per ridurre la quantità di dati che l'istanza database RDS per PostgreSQL invia al client. Effettuare tali regolazioni allevia la contesa della CPU e della rete sul client.

### Ridimensionare il client
<a name="wait-event.clientwrite.actions.scale-client"></a>

Utilizzando Amazon CloudWatch o altri parametri relativi all'host, stabilisci se il tuo client è attualmente limitato dalla CPU o dalla larghezza di banda della rete o da entrambi. Se il client è vincolato, ridimensionare il client di conseguenza.

# CPU
<a name="wait-event.cpu"></a>

Questo evento si verifica quando un thread è attivo nella CPU o è in attesa della CPU.

**Topics**
+ [Versioni del motore supportate](#wait-event.cpu.context.supported)
+ [Contesto](#wait-event.cpu.context)
+ [Probabili cause di aumento delle attese](#wait-event.cpu.causes)
+ [Azioni](#wait-event.cpu.actions)

## Versioni del motore supportate
<a name="wait-event.cpu.context.supported"></a>

Queste informazioni relative all'evento di attesa sono pertinenti per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.cpu.context"></a>

L’*unità di elaborazione centrale (CPU)* è il componente di un computer che esegue le istruzioni. Ad esempio, le istruzioni della CPU eseguono operazioni aritmetiche e scambiano dati in memoria. Se una query aumenta il numero di istruzioni eseguite tramite il motore di database, il tempo impiegato per eseguire la query aumenta. *Pianificazione CPU* sta dando tempo alla CPU a un processo. La pianificazione viene orchestrata dal kernel del sistema operativo.

**Topics**
+ [Come sapere quando si verifica questa attesa](#wait-event.cpu.when-it-occurs)
+ [DBLoadMetrica della CPU](#wait-event.cpu.context.dbloadcpu)
+ [Parametri di utilizzo di OS.CPU](#wait-event.cpu.context.osmetrics)
+ [Probabile causa della pianificazione della CPU](#wait-event.cpu.context.scheduling)

### Come sapere quando si verifica questa attesa
<a name="wait-event.cpu.when-it-occurs"></a>

Questo evento di attesa `CPU` indica che un processo di backend è attivo nella CPU o è in attesa della CPU. Si verifica quando una query mostra le seguenti informazioni:
+ La colonna `pg_stat_activity.state` ha il valore `active`.
+ Le colonne `wait_event_type` e `wait_event` in `pg_stat_activity` sono entrambe `null`.

Per visualizzare i processi di backend in uso o in attesa sulla CPU, eseguire la seguente query.

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### DBLoadMetrica della CPU
<a name="wait-event.cpu.context.dbloadcpu"></a>

Il parametro Performance Insights per la CPU è `DBLoadCPU`. Il valore per `DBLoadCPU` può differire dal valore della CloudWatch metrica `CPUUtilization` Amazon. Quest'ultima metrica viene raccolta da un'istanza HyperVisor di database.

### Parametri di utilizzo di OS.CPU
<a name="wait-event.cpu.context.osmetrics"></a>

I parametri del sistema operativo Performance Insights forniscono informazioni dettagliate sull'utilizzo della CPU. Ad esempio, è possibile visualizzare i seguenti parametri:
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

Performance Insights segnala l'utilizzo della CPU da parte del motore di database come `os.cpuUtilization.nice.avg`.

### Probabile causa della pianificazione della CPU
<a name="wait-event.cpu.context.scheduling"></a>

 Il kernel del sistema operativo (OS) gestisce la pianificazione per la CPU. Quando la CPU è *attiva*, potrebbe essere necessario attendere la pianificazione di un processo. La CPU è attiva durante l'esecuzione dei calcoli. È attivo anche quando ha un thread inattivo che non è in esecuzione, ovvero un thread inattivo in attesa di memoria I/O. This type of I/O domina il tipico carico di lavoro del database. 

È probabile che i processi attendano di essere pianificati su una CPU quando vengono soddisfatte le seguenti condizioni:
+ La CloudWatch `CPUUtilization` metrica è vicina al 100 percento.
+ Il carico medio è maggiore del numero di vCPUs, il che indica un carico pesante. Puoi trovare il parametro `loadAverageMinute` nella sezione parametri del sistema operativo in Performance Insights.

## Probabili cause di aumento delle attese
<a name="wait-event.cpu.causes"></a>

Quando l'evento di attesa della CPU si verifica più del normale, probabilmente indicando un problema di prestazioni, le cause tipiche includono le seguenti.

**Topics**
+ [Probabili cause di picchi improvvisi](#wait-event.cpu.causes.spikes)
+ [Probabili cause di alta frequenza a lungo termine](#wait-event.cpu.causes.long-term)
+ [Casi particolari](#wait-event.cpu.causes.corner-cases)

### Probabili cause di picchi improvvisi
<a name="wait-event.cpu.causes.spikes"></a>

Le cause più probabili di picchi improvvisi sono le seguenti:
+ L'applicazione ha aperto troppe connessioni simultanee al database. Questo scenario è noto come «tempesta di connessione».
+ Il carico di lavoro dell'applicazione è cambiato in uno dei seguenti modi:
  + Nuove query
  + Aumento delle dimensioni del set di dati
  + Manutenzione o creazione dell'indice
  + Nuove funzioni
  + Nuovi operatori
  + Un aumento dell'esecuzione parallela di query
+ I piani di esecuzione delle query sono cambiati. In alcuni casi, un cambiamento può causare un aumento dei buffer. Ad esempio, la query ora utilizza una scansione sequenziale quando in precedenza utilizzava un indice. In questo caso, le query richiedono più CPU per raggiungere lo stesso obiettivo.

### Probabili cause di alta frequenza a lungo termine
<a name="wait-event.cpu.causes.long-term"></a>

Le cause più probabili di eventi che si ripetono per un lungo periodo:
+ Troppi processi backend sono in esecuzione contemporaneamente sulla CPU. Questi processi possono essere lavoratori paralleli.
+ Le query vengono eseguite in modo subottimale perché necessitano di un numero elevato di buffer.

### Casi particolari
<a name="wait-event.cpu.causes.corner-cases"></a>

Se nessuna delle cause probabili risulta essere una causa effettiva, potrebbero verificarsi le seguenti situazioni:
+ La CPU sta scambiando i processi in entrata e in uscita.
+ La CPU potrebbe gestire le voci della tabella della pagina se la funzionalità delle *pagine di grandi dimensioni* è stata disattivata. La funzionalità di gestione della memoria è attivata per impostazione predefinita per tutte le classi di istanza database diverse dalle classi di istanza micro, piccole e medie. Per ulteriori informazioni, consulta [Pagine di grandi dimensioni per RDS for PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.HugePages.md). 

## Azioni
<a name="wait-event.cpu.actions"></a>

Se l’evento di attesa `CPU` domina l'attività del database, non indica necessariamente un problema di prestazioni. Rispondi a questo evento solo quando le prestazioni diminuiscono.

**Topics**
+ [Indagare se il database sta causando l'aumento della CPU](#wait-event.cpu.actions.db-CPU)
+ [Determina se il numero di connessioni è aumentato](#wait-event.cpu.actions.connections)
+ [Rispondere alle modifiche del carico di lavoro](#wait-event.cpu.actions.workload)

### Indagare se il database sta causando l'aumento della CPU
<a name="wait-event.cpu.actions.db-CPU"></a>

Esamina il parametro `os.cpuUtilization.nice.avg` in Performance Insights. Se questo valore è molto inferiore all'utilizzo della CPU, i processi nondatabase sono il principale contributore della CPU.

### Determina se il numero di connessioni è aumentato
<a name="wait-event.cpu.actions.connections"></a>

Esamina la `DatabaseConnections` metrica in Amazon CloudWatch. L'azione dipende dal fatto che il numero sia aumentato o diminuito durante il periodo di aumento degli eventi di attesa della CPU.

#### Le connessioni sono aumentate
<a name="wait-event.cpu.actions.connections.increased"></a>

Se il numero di connessioni è aumentato, confronta il numero di processi di backend che consumano CPU con il numero di v. CPUs Sono possibili i seguenti scenari:
+ Il numero di processi di backend che utilizzano la CPU è inferiore al numero di vCPUs.

  In questo caso, il numero di connessioni non è un problema. Tuttavia, è comunque possibile provare a ridurre l'utilizzo della CPU.
+ Il numero di processi di backend che utilizzano la CPU è maggiore del numero di v. CPUs

  In questo caso, valuta le seguenti opzioni:
  + Riduci il numero di processi back-end collegati al database. Ad esempio, implementa una soluzione di connection pooling come RDS Proxy. Per ulteriori informazioni, consulta [Proxy Amazon RDS ](rds-proxy.md).
  + Aggiorna la dimensione dell'istanza per ottenere un numero maggiore di vCPUs.
  + Reindirizza alcuni carichi di lavoro di sola lettura ai nodi del lettore, se applicabile.

#### Le connessioni sono aumentate
<a name="wait-event.cpu.actions.connections.decreased"></a>

Esamina il parametro `blks_hit` in Performance Insights. Cerca una correlazione tra un aumento `blks_hit` e utilizzo CPU. Gli scenari possibili sono i seguenti:
+ Utilizzo CPU e `blks_hit` sono correlati.

  In questo caso, trova le istruzioni SQL principali collegate all'utilizzo della CPU e cerca le modifiche al piano. Puoi utilizzare una delle seguenti tecniche:
  + Spiegare i piani manualmente e confrontarli con il piano di esecuzione previsto.
  + Cercare un aumento degli hit di blocco al secondo e dei blocchi locali al secondo. Nella sezione **Top SQL** della dashboard Performance Insights, scegli **Preferenze**.
+ Utilizzo CPU e `blks_hit` non sono correlati.

  In questo caso, determinare se si verifica una delle seguenti condizioni:
  + L'applicazione si sta rapidamente connettendo e disconnettendo dal database. 

    Diagnosticare questo comportamento attivando `log_connections` e `log_disconnections`, quindi analizzando i registri PostgreSQL. Considerare l'utilizzo dell’analizzatore di log `pgbadger`. Per ulteriori informazioni, consulta [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + Il sistema operativo è sovraccarico.

    In questo caso, Performance Insights mostra che i processi back-end consumano la CPU per un tempo più lungo del solito. Cerca prove nelle `os.cpuUtilization` metriche di Performance Insights o nella CloudWatch `CPUUtilization` metrica. Se il sistema operativo è sovraccarico, esamina i parametri di Enhanced Monitoring per effettuare ulteriori diagnosi. In particolare, guarda l'elenco dei processi e la percentuale di CPU consumata da ciascun processo.
  + Le istruzioni SQL principali consumano troppa CPU.

    Esaminare le istruzioni collegate all'utilizzo della CPU per verificare se possono utilizzare meno CPU. Esegui il comando `EXPLAIN` e concentrati sui nodi del piano che hanno il maggior impatto. Prendi in considerazione l'utilizzo di un visualizzatore del piano di esecuzione PostgreSQL. Per provare questo strumento, vedi [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Rispondere alle modifiche del carico di lavoro
<a name="wait-event.cpu.actions.workload"></a>

Se il carico di lavoro è cambiato, cerca i seguenti tipi di modifiche:

Nuove query  
Verifica se sono previste le nuove query. In tal caso, assicurarsi che siano previsti i piani di esecuzione e il numero di esecuzioni al secondo.

Aumento delle dimensioni del set di dati  
Determina se il partizionamento, se non è già implementato, potrebbe essere d'aiuto. Questa strategia potrebbe ridurre il numero di pagine che una query deve recuperare.

Manutenzione o creazione dell'indice  
Verificare se è previsto il programma per la manutenzione. Una best practice è pianificare le attività di manutenzione al di fuori delle attività di picco.

Nuove funzioni  
Verifica se queste funzioni funzionano come previsto durante il test. In particolare, controlla se è previsto il numero di esecuzioni al secondo.

Nuovi operatori  
Verifica se queste funzioni funzionano come previsto durante il test.

Un aumento dell'esecuzione di query parallele  
Determina se si è verificata una delle seguenti situazioni:  
+ Le relazioni o gli indici coinvolti sono improvvisamente cresciuti di dimensioni in modo che differiscano in modo significativo da `min_parallel_table_scan_size` o `min_parallel_index_scan_size`.
+ Cambiamenti recenti sono stati apportati a `parallel_setup_cost` o `parallel_tuple_cost`.
+ Cambiamenti recenti sono stati apportati a `max_parallel_workers` o `max_parallel_workers_per_gather`.

# IO: BufFileRead e IO: BufFileWrite
<a name="wait-event.iobuffile"></a>

Gli eventi `IO:BufFileRead` e `IO:BufFileWrite` si verificano quando RDS per PostgreSQL crea file temporanei. Quando le operazioni richiedono più memoria rispetto ai parametri della memoria di lavoro attualmente definiti, scrivono dati temporanei sullo storage persistente. Questa operazione viene talvolta chiamata «*spilling to disk*». Per ulteriori informazioni sui file temporanei e sul loro utilizzo, consulta [Gestione dei file temporanei con PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [Versioni del motore supportate](#wait-event.iobuffile.context.supported)
+ [Contesto](#wait-event.iobuffile.context)
+ [Probabili cause di aumento delle attese](#wait-event.iobuffile.causes)
+ [Azioni](#wait-event.iobuffile.actions)

## Versioni del motore supportate
<a name="wait-event.iobuffile.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.iobuffile.context"></a>

`IO:BufFileRead` e `IO:BufFileWrite` riguardano l'area di memoria di lavoro e l'area di memoria di lavoro di manutenzione. Per ulteriori informazioni su queste aree di memoria locale, consulta [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo di risorse) nella documentazione di PostgreSQL.

Il valore predefinito per `work_mem` è 4 MB. Se una sessione esegue operazioni in parallelo, ogni lavoratore che gestisce il parallelismo utilizza 4 MB di memoria. Per questo motivo, imposta `work_mem` con attenzione. Se si aumenta troppo il valore, un database che esegue molte sessioni potrebbe consumare troppa memoria. Se si imposta il valore troppo basso, RDS per PostgreSQL crea file temporanei nella memoria locale. Il disco I/O per questi file temporanei può ridurre le prestazioni.

Se si osserva la seguente sequenza di eventi, il database potrebbe generare file temporanei:

1. Riduzione improvvisa e brusca della disponibilità

1. Ripristino rapido per lo spazio libero

Potresti vedere anche un motivo a «motosega». Questo modello può indicare che il database sta creando costantemente file di piccole dimensioni.

## Probabili cause di aumento delle attese
<a name="wait-event.iobuffile.causes"></a>

In generale, questi eventi di attesa sono causati da operazioni che consumano più memoria rispetto a quella allocata dai parametri `work_mem` o `maintenance_work_mem`. Per compensare, le operazioni scrivono su file temporanei. Cause comuni degli eventi `IO:BufFileRead` e `IO:BufFileWrite` includono quanto segue:

**Query che richiedono più memoria di quella esistente nell'area della memoria di lavoro**  
Le query con le seguenti caratteristiche utilizzano l'area di memoria di lavoro:  
+ Hash join
+ `ORDER BY`Clausola 
+ `GROUP BY`Clausola 
+ `DISTINCT`
+ Funzioni finestra
+ `CREATE TABLE AS SELECT`
+ Aggiornamento vista materializzata

**Istruzioni che richiedono più memoria di quella esistente nell'area della memoria di lavoro di manutenzione**  
Le istruzioni seguenti utilizzano l'area di memoria di lavoro di manutenzione:  
+ `CREATE INDEX`
+ `CLUSTER`

## Azioni
<a name="wait-event.iobuffile.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Identificare il problema](#wait-event.iobuffile.actions.problem)
+ [Esamina le tue query di join](#wait-event.iobuffile.actions.joins)
+ [Esamina le query ORDER BY e GROUP BY](#wait-event.iobuffile.actions.order-by)
+ [Evitare di utilizzare l'operazione DISTINCT](#wait-event.iobuffile.actions.distinct)
+ [Considera l'utilizzo di funzioni finestra anziché le funzioni GROUP BY](#wait-event.iobuffile.actions.window)
+ [Indagare sulle viste materializzate e le istruzioni CTAS](#wait-event.iobuffile.actions.mv-refresh)
+ [Uso di pg\$1repack per ricostruire gli indici](#wait-event.iobuffile.actions.pg_repack)
+ [Aumenta maintenance\$1work\$1mem quando esegui cluster](#wait-event.iobuffile.actions.cluster)
+ [Ottimizza la memoria per evitare che IO: BufFileRead e IO: BufFileWrite](#wait-event.iobuffile.actions.tuning-memory)

### Identificare il problema
<a name="wait-event.iobuffile.actions.problem"></a>

È possibile visualizzare l'utilizzo dei file temporanei direttamente in Performance Insights. Per ulteriori informazioni, consulta [Visualizzazione dell’utilizzo dei file temporanei con Approfondimenti sulle prestazioni](PostgreSQL.ManagingTempFiles.Example.md). Quando Performance Insights è disabilitato, potresti notare un aumento `IO:BufFileRead` `IO:BufFileWrite` delle operazioni.

Per identificare l'origine del problema, è possibile impostare il parametro `log_temp_files` per registrare tutte le query che generano file temporanei superiori alla soglia di KB specificata. Per impostazione predefinita, `log_temp_files` è impostato su `-1`, il che disattiva la funzionalità di registrazione. Se imposti questo parametro su `0`, RDS for PostgreSQL registra tutti i file temporanei. Se lo imposti su `1024`, RDS per PostgreSQL registra tutte le query che producono file temporanei di dimensioni superiori a 1 MB. Per ulteriori informazioni su `log_temp_files`, consulta [Creazione di log e report di errore](https://www.postgresql.org/docs/current/runtime-config-logging.html) nella documentazione di PostgreSQL.

### Esamina le tue query di join
<a name="wait-event.iobuffile.actions.joins"></a>

È probabile che la tua query utilizzi i join. Ad esempio, la seguente query unisce quattro tabelle.

```
SELECT * 
       FROM "order" 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Una possibile causa di picchi nell'utilizzo temporaneo dei file è un problema nella query stessa. Ad esempio, una clausola interrotta potrebbe non filtrare correttamente i join. Considera il secondo inner join nell'esempio seguente.

```
SELECT * 
       FROM "order"
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

La query precedente unisce erroneamente `customer.id` a `customer.id`, generando un prodotto cartesiano tra ogni cliente e ogni ordine. Questo tipo di join accidentale genera file temporanei di grandi dimensioni. A seconda delle dimensioni delle tabelle, una query cartesiana può anche riempire lo spazio di archiviazione. La domanda potrebbe avere join cartesiani quando vengono soddisfatte le seguenti condizioni:
+ Si notano forti e nitide riduzioni della disponibilità dello storage, seguite da un rapido ripristino.
+ Non sono in fase di creazione di indici.
+ Non vengono rilasciate istruzioni `CREATE TABLE FROM SELECT`.
+ Nessuna vista materializzata viene aggiornata.

Per verificare se le tabelle vengono unite utilizzando le chiavi appropriate, ispezionare le direttive di mappatura relazionale di query e oggetti. Tieni presente che alcune query della tua applicazione non vengono sempre chiamate e alcune query vengono generate dinamicamente.

### Esamina le query ORDER BY e GROUP BY
<a name="wait-event.iobuffile.actions.order-by"></a>

In alcuni casi, una clausola `ORDER BY` può comportare file temporanei eccessivi. Considera le linee guida seguenti:
+ Includi solo colonne in una clausola `ORDER BY` quando devono essere ordinate. Questa linea guida è particolarmente importante per le query che restituiscono migliaia di righe e specificano molte colonne nella clausola `ORDER BY`.
+ Considerando la creazione di indici per accelerare clausole `ORDER BY` quando corrispondono a colonne che hanno lo stesso ordine crescente o decrescente. Gli indici parziali sono preferibili perché sono più piccoli. Gli indici più piccoli vengono letti e attraversati più rapidamente.
+ Se si creano indici per colonne che possono accettare valori nulli, considerare se si desidera che i valori nulli siano memorizzati alla fine o all'inizio degli indici.

  Se possibile, ridurre il numero di righe che devono essere ordinate filtrando il set di risultati. Se utilizzi istruzioni clausole o sottoquery `WITH`, ricorda che una query interna genera un set di risultati e lo passa alla query esterna. Maggiore è il numero di righe che una query può filtrare, minore è la necessità di ordinare la query.
+ Se non è necessario ottenere il set completo di risultati, utilizzare la clausola `LIMIT`. Ad esempio, se si desidera solo le prime cinque righe, una query che utilizza la clausola `LIMIT` non continua a generare risultati. In questo modo, la query richiede meno memoria e file temporanei.

Una query che utilizza una clausola `GROUP BY` può richiedere anche file temporanei. Le query `GROUP BY` riepilogano i valori utilizzando funzioni come le seguenti:
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Per sintonizzare le query `GROUP BY`, segui i consigli per le query `ORDER BY`.

### Evitare di utilizzare l'operazione DISTINCT
<a name="wait-event.iobuffile.actions.distinct"></a>

Se possibile, evitare di utilizzare l’operazione `DISTINCT` per rimuovere righe duplicate. Più righe non necessarie e duplicate restituite dalla tua query, più costosa diventa l’operazione `DISTINCT`. Se possibile, aggiungi filtri nella clausola `WHERE` anche se utilizzi gli stessi filtri per tabelle diverse. Filtrare la query e unirsi correttamente migliora le prestazioni e riduce l'utilizzo delle risorse. Previene inoltre report e risultati errati.

Se devi usare `DISTINCT` per più righe di una stessa tabella, prendi in considerazione la possibilità di creare un indice composito. Il raggruppamento di più colonne in un indice può migliorare il tempo necessario per valutare righe distinte. Inoltre, se utilizzi RDS per PostgreSQL versione 10 o successiva, puoi correlare le statistiche tra più colonne utilizzando il comando `CREATE STATISTICS`.

### Considera l'utilizzo di funzioni finestra anziché le funzioni GROUP BY
<a name="wait-event.iobuffile.actions.window"></a>

Utilizzando `GROUP BY` si modifica il set di risultati e quindi recupera il risultato aggregato. Utilizzando le funzioni della finestra, si aggregano i dati senza modificare il set di risultati. Una funzione finestra utilizza la clausola `OVER` per eseguire calcoli tra i set definiti dalla query, correlando una riga con un'altra. È possibile utilizzare tutte le funzioni `GROUP BY` nelle funzioni di finestra, ma anche funzioni come le seguenti:
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Per ridurre al minimo il numero di file temporanei generati da una funzione di finestra, rimuovere le duplicazioni per lo stesso set di risultati quando sono necessarie due aggregazioni distinte. Considera la query seguente.

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

È possibile riscrivere la query con la clausola `WINDOW` come segue.

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

Per impostazione predefinita, il planner di esecuzione RDS per PostgreSQL consolida nodi simili in modo da non duplicare le operazioni. Tuttavia, utilizzando una dichiarazione esplicita per il blocco finestra, è possibile mantenere la query più facilmente. È inoltre possibile migliorare le prestazioni impedendo la duplicazione.

### Indagare sulle viste materializzate e le istruzioni CTAS
<a name="wait-event.iobuffile.actions.mv-refresh"></a>

Quando una vista materializzata si aggiorna, esegue una query. Questa query può contenere un'operazione come `GROUP BY`, `ORDER BY` oppure`DISTINCT`. Durante un aggiornamento, è possibile osservare un numero elevato di file temporanei e gli eventi di attesa `IO:BufFileWrite` e `IO:BufFileRead`. Allo stesso modo, quando crei una tabella basata su una dichiarazione `SELECT`, l'istruzione `CREATE TABLE` esegue una query. Per ridurre i file temporanei necessari, ottimizza la query.

### Uso di pg\$1repack per ricostruire gli indici
<a name="wait-event.iobuffile.actions.pg_repack"></a>

Quando crei un indice, il motore ordina il set di risultati. Man mano che le tabelle aumentano di dimensioni e man mano che i valori nella colonna indicizzata diventano più diversi, i file temporanei richiedono più spazio. Nella maggior parte dei casi, non è possibile impedire la creazione di file temporanei per tabelle di grandi dimensioni senza modificare l'area della memoria di lavoro di manutenzione. Per ulteriori informazioni su `maintenance_work_mem`, consulta [https://www.postgresql.org/docs/current/runtime-config-resource.html](https://www.postgresql.org/docs/current/runtime-config-resource.html) nella documentazione di PostgreSQL. 

Una possibile soluzione alternativa quando si ricrea un indice di grandi dimensioni consiste nell'utilizzare l'estensione pg\$1repack. Per ulteriori informazioni, consulta [Riorganizzare le tabelle nei database PostgreSQL con blocchi minimi](https://reorg.github.io/pg_repack/) nella documentazione di pg\$1repack. Per informazioni sull'impostazione dell'estensione nell'istanza database RDS per PostgreSQL, consulta [Riduzione della dimensione nelle tabelle e negli indici con l’estensione pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md). 

### Aumenta maintenance\$1work\$1mem quando esegui cluster
<a name="wait-event.iobuffile.actions.cluster"></a>

Il comando `CLUSTER` raggruppa la tabella specificata da *table\$1name* in base a un indice esistente specificato da *index\$1name*. RDS per PostgreSQL ricrea fisicamente la tabella in modo che corrisponda all'ordine di un determinato indice.

Quando lo storage magnetico era prevalente, il clustering era comune perché il throughput di storage era limitato. Ora che lo storage basato su SSD è comune, il clustering è meno popolare. Tuttavia, se si raggruppano le tabelle, è comunque possibile aumentare leggermente le prestazioni a seconda delle dimensioni della tabella, dell'indice, della query e così via. 

Se esegui il comando `CLUSTER` e osservi gli eventi di attesa `IO:BufFileWrite` e `IO:BufFileRead`, sintonizza `maintenance_work_mem`. Aumenta la dimensione della memoria a una quantità abbastanza grande. Un valore elevato significa che il motore può utilizzare più memoria per l'operazione di clustering.

### Ottimizza la memoria per evitare che IO: BufFileRead e IO: BufFileWrite
<a name="wait-event.iobuffile.actions.tuning-memory"></a>

In alcune situazioni, è necessario ottimizzare la memoria. L'obiettivo è bilanciare la memoria tra le seguenti aree di consumo utilizzando i parametri appropriati, come segue.
+ Il valore `work_mem` 
+ La memoria rimanente dopo aver scontato il valore `shared_buffers`
+ Le connessioni massime aperte e in uso, limitate da `max_connections`

Per ulteriori informazioni sull'ottimizzazione della memoria, consulta [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo delle risorse) nella documentazione di PostgreSQL. 

#### Aumentare le dimensioni dell'area di memoria di lavoro
<a name="wait-event.iobuffile.actions.tuning-memory.work-mem"></a>

In alcune situazioni, l'unica opzione è aumentare la memoria utilizzata dalla sessione. Se le tue query sono scritte correttamente e utilizzano i tasti corretti per i join, prendi in considerazione la possibilità di aumentare il valore `work_mem`. 

Per scoprire quanti file temporanei genera una query, imposta `log_temp_files` su `0`. Aumentando il valore `work_mem` al valore massimo identificato nei log, si impedisce alla query di generare file temporanei. Tuttavia, `work_mem` imposta il massimo per nodo piano per ogni connessione o operatore parallelo. Se il database ha 5.000 connessioni e se ciascuna utilizza una memoria di 256 MiB, il motore necessita di 1,2 TiB di RAM. Pertanto, la tua istanza potrebbe esaurirsi dalla memoria.

#### Riserva una memoria sufficiente per il buffer pool condiviso
<a name="wait-event.iobuffile.actions.tuning-memory.shared-pool"></a>

Il database utilizza aree di memoria come il buffer pool condiviso, non solo l'area di memoria di lavoro. Considerare i requisiti di queste aree di memoria aggiuntive prima di aumentare `work_mem`.

Ad esempio, supponi che la classe di istanza RDS per PostgreSQL sia db.r5.2xlarge. Questa classe ha 64 GiB di memoria. Per impostazione predefinita, il 25% della memoria è riservato al buffer pool condiviso. Dopo aver sottratto la quantità allocata all'area di memoria condivisa, rimangono 16.384 MB. Non allocare la memoria rimanente esclusivamente all'area della memoria di lavoro perché anche il sistema operativo e il motore richiedono memoria.

La memoria a cui è possibile allocare per `work_mem` dipende dalla classe di istanza. Se si utilizza una classe di istanza più grande, è disponibile più memoria. Tuttavia, nell'esempio precedente, non è possibile utilizzare più di 16 GiB. In caso contrario, la tua istanza diventa non disponibile quando esaurisce la memoria. Per ripristinare l'istanza dallo stato non disponibile, i servizi di automazione RDS per PostgreSQL si riavviano automaticamente.

#### Gestisci il numero di connessioni
<a name="wait-event.iobuffile.actions.tuning-memory.connections"></a>

Supponiamo che l'istanza del database disponga di 5.000 connessioni simultanee. Ogni connessione utilizza almeno 4 MiB di `work_mem`. L'elevato consumo di memoria delle connessioni rischia di peggiorare le prestazioni. Sono disponibili le seguenti opzioni:
+ Eseguire l'aggiornamento a una classe di istanza più grande
+ Diminuire il numero di connessioni simultanee al database utilizzando un proxy o un pool di connessioni.

Per i proxy, considera Amazon RDS Proxy, PGBouncer o un connection pooler basato sulla tua applicazione. Questa soluzione riduce il carico della CPU. Riduce inoltre il rischio quando tutte le connessioni richiedono l'area di memoria di lavoro. Quando esistono meno connessioni al database, è possibile aumentare il valore di `work_mem`. In questo modo, si riduce il verificarsi degli eventi di attesa `IO:BufFileRead` e `IO:BufFileWrite`. Inoltre, le query in attesa dell'area di memoria di lavoro accelerano in modo significativo.

# IO: DataFileRead
<a name="wait-event.iodatafileread"></a>

L’evento `IO:DataFileRead` si verifica quando una connessione attende un processo di back-end per leggere una pagina richiesta dalla memoria perché la pagina non è disponibile nella memoria condivisa.

**Topics**
+ [Versioni del motore supportate](#wait-event.iodatafileread.context.supported)
+ [Contesto](#wait-event.iodatafileread.context)
+ [Probabili cause di aumento delle attese](#wait-event.iodatafileread.causes)
+ [Azioni](#wait-event.iodatafileread.actions)

## Versioni del motore supportate
<a name="wait-event.iodatafileread.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.iodatafileread.context"></a>

Tutte le query e le operazioni di manipolazione dei dati (DML) accedono alle pagine del buffer pool. Le dichiarazioni che possono indurre letture includono `SELECT`, `UPDATE` e `DELETE`. Ad esempio, un `UPDATE` può leggere pagine da tabelle o indici. Se la pagina richiesta o aggiornata non si trova nel buffer pool condiviso, questa lettura può portare all’evento `IO:DataFileRead`.

Poiché il buffer pool condiviso è finito, può essere riempito. In questo caso, le richieste di pagine che non sono in memoria impongono al database di leggere i blocchi dal disco. Se l’evento `IO:DataFileRead` si verifica frequentemente, il buffer pool condiviso potrebbe essere troppo piccolo per adattarsi al carico di lavoro. Questo problema è particolarmente grave per le query `SELECT` che leggono un numero elevato di righe che non rientrano nel buffer pool. Per ulteriori informazioni sul pool di buffer, consulta [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html) (Consumo delle risorse) nella documentazione di PostgreSQL.

## Probabili cause di aumento delle attese
<a name="wait-event.iodatafileread.causes"></a>

Cause comuni dell’evento `IO:DataFileRead` includono quanto segue:

**Picchi di connessione**  
Potresti trovare più connessioni che generano lo stesso numero di eventi IO: DataFileRead wait. In questo caso, può verificarsi un picco (aumento improvviso e grande) negli eventi `IO:DataFileRead`. 

**Le istruzioni SELECT e DML eseguono scansioni sequenziali**  
L'applicazione potrebbe aver eseguito una nuova operazione. Oppure un'operazione esistente potrebbe cambiare a causa di un nuovo piano di esecuzione. In questi casi, cerca tabelle (in particolare tabelle di grandi dimensioni) che abbiano un valore `seq_scan` maggiore. Puoi trovarli interrogando `pg_stat_user_tables`. Per tenere traccia delle query che generano più operazioni di lettura, utilizzare l'estensione `pg_stat_statements`.

**CTAS e CREATE INDEX per set di dati di grandi dimensioni**  
Un *CTAS* è una `CREATE TABLE AS SELECT`dichiarazione. Se si esegue un CTAS utilizzando un set di dati di grandi dimensioni come origine o si crea un indice su una tabella di grandi dimensioni, l’evento `IO:DataFileRead` può verificarsi. Quando si crea un indice, il database potrebbe dover leggere l'intero oggetto utilizzando una scansione sequenziale. Un CTAS genera letture `IO:DataFile` quando le pagine non sono in memoria.

**Diversi lavoratori sottovuoto in esecuzione contemporaneamente**  
Gli operatori del vuoto possono essere attivati manualmente o automaticamente. Raccomandiamo di adottare una strategia aggressiva per il vuoto. Tuttavia, quando una tabella contiene molte righe aggiornate o cancellate, l’attesa `IO:DataFileRead` aumenta. Dopo aver recuperato lo spazio, il tempo dedicato al vuoto su `IO:DataFileRead` diminuisce.

**Ingresso di grandi quantità di dati**  
Quando l'applicazione acquisisce quantità di dati elevate, le operazioni `ANALYZE` potrebbero verificarsi più spesso. Il processo `ANALYZE` può essere attivato da un launcher automatico o richiamato manualmente.  
L’operazione `ANALYZE` legge un sottoinsieme della tabella. Il numero di pagine che devono essere scansionate viene calcolato moltiplicando 30 per il valore `default_statistics_target`. Per ulteriori informazioni, consultare la [documentazione di PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). Il parametro `default_statistics_target` accetta valori compresi tra 1 e 10.000, dove il valore predefinito è 100.

**Fame di risorse**  
Se si consuma la larghezza di banda di rete dell'istanza o la CPU, l'evento `IO:DataFileRead` potrebbe verificarsi più frequentemente.

## Azioni
<a name="wait-event.iodatafileread.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Controlla i filtri predicati per le query che generano attese](#wait-event.iodatafileread.actions.filters)
+ [Riduci al minimo l'effetto delle operazioni di manutenzione](#wait-event.iodatafileread.actions.maintenance)
+ [Rispondere a un numero elevato di connessioni](#wait-event.iodatafileread.actions.connections)

### Controlla i filtri predicati per le query che generano attese
<a name="wait-event.iodatafileread.actions.filters"></a>

Supponiamo di identificare query specifiche che stanno generando eventi di attesa `IO:DataFileRead`. È possibile identificarli utilizzando le seguenti tecniche:
+ Approfondimenti sulle prestazioni
+ Viste catalogo come quella fornita dall'estensione `pg_stat_statements`
+ La vista catalogo `pg_stat_all_tables`, se mostra periodicamente un numero maggiore di letture fisiche
+ La vista `pg_statio_all_tables`, se lo mostra che i contatori `_read` sono in aumento

Si consiglia di determinare quali filtri vengono utilizzati nel predicato (clausola `WHERE`) di queste query. Seguire queste linee guida:
+ Esegui il comando `EXPLAIN`. Nell'output, identificare quali tipi di scansioni vengono utilizzati. Una scansione sequenziale non indica necessariamente che ci sia un problema. Le query che utilizzano scansioni sequenziali producono naturalmente più eventi `IO:DataFileRead` rispetto alle query che utilizzano filtri.

  Scopri se la colonna elencata nella clausola `WHERE` è indicizzata. In caso contrario, prendi in considerazione la possibilità di creare un indice per questa colonna. Questo approccio evita le scansioni sequenziali e riduce gli eventi `IO:DataFileRead`. Se una query dispone di filtri restrittivi e continua a produrre scansioni sequenziali, valutare se vengono utilizzati gli indici appropriati.
+ Scopri se la query sta accedendo a una tabella molto ampia. In alcuni casi, il partizionamento di una tabella può migliorare le prestazioni, consentendo alla query di leggere solo le partizioni necessarie.
+ Esamina la cardinalità (numero totale di righe) dalle operazioni di join. Nota quanto sono restrittivi i valori che stai passando nei filtri per la tua clausola `WHERE`. Se possibile, sintonizza la query per ridurre il numero di righe passate in ogni fase del piano.

### Riduci al minimo l'effetto delle operazioni di manutenzione
<a name="wait-event.iodatafileread.actions.maintenance"></a>

Operazioni di manutenzione come `VACUUM` e `ANALYZE` sono importanti. Si consiglia di non spegnerli qualora vengano trovati eventi di attesa `IO:DataFileRead` relativi a queste operazioni di manutenzione. I seguenti approcci possono ridurre al minimo l’effetto di queste operazioni:
+ Eseguire manualmente le operazioni di manutenzione durante le ore non di punta. Questa tecnica impedisce al database di raggiungere la soglia per le operazioni automatiche.
+ Per tabelle molto grandi, prendi in considerazione il partizionamento. Questa tecnica riduce il sovraccarico delle operazioni di manutenzione. Il database accede solo alle partizioni che richiedono manutenzione.
+ Quando si acquisiscono grandi quantità di dati, prendere in considerazione la possibilità di disabilitare la funzione di analisi automatica.

La funzione autovacuum viene attivata automaticamente per una tabella quando la formula seguente è vera.

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

La vista `pg_stat_user_tables` e il catalogo `pg_class` hanno più righe. Una riga può corrispondere a una riga della tabella. Questa formula presuppone che i `reltuples` sono per una tabella specifica. I parametri `autovacuum_vacuum_scale_factor` (0,20 per impostazione predefinita) e `autovacuum_vacuum_threshold` (50 tuple per impostazione predefinita) sono generalmente impostate globalmente per l'intera istanza. Tuttavia, è possibile impostare valori diversi per una tabella specifica.

**Topics**
+ [Ricerca delle tabelle che consumano spazio inutile](#wait-event.iodatafileread.actions.maintenance.tables)
+ [Ricerca degli indici che consumano spazio inutile](#wait-event.iodatafileread.actions.maintenance.indexes)
+ [Trova tabelle idonee per l'autovacuum](#wait-event.iodatafileread.actions.maintenance.autovacuumed)

#### Ricerca delle tabelle che consumano spazio inutile
<a name="wait-event.iodatafileread.actions.maintenance.tables"></a>

Per trovare le tabelle che consumano spazio inutilmente, puoi utilizzare le funzioni dell'estensione di PostgreSQL`pgstattuple`. Questa estensione (modulo) è disponibile per impostazione predefinita su tutte le istanze database RDS per PostgreSQL e ne può essere creata un'istanza con il seguente comando.

```
CREATE EXTENSION pgstattuple;
```

Per ulteriori informazioni su questa estensione, consulta [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html) nella documentazione di PostgreSQL.

Puoi verificare l'aumento delle dimensioni della tabella e dell'indice nell'applicazione. Per ulteriori informazioni, consulta [Diagnosi delle dimensioni della tabella e dell'indice](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html).

#### Ricerca degli indici che consumano spazio inutile
<a name="wait-event.iodatafileread.actions.maintenance.indexes"></a>

Per trovare indici cresciuti e stimare la quantità di spazio consumato inutilmente sulle tabelle per le quali si dispone dei privilegi di lettura, è possibile eseguire la seguente query.

```
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functional cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### Trova tabelle idonee per l'autovacuum
<a name="wait-event.iodatafileread.actions.maintenance.autovacuumed"></a>

Per trovare tabelle idonee per l'autovacuum, esegui la query riportata.

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
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
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### Rispondere a un numero elevato di connessioni
<a name="wait-event.iodatafileread.actions.connections"></a>

Quando monitori Amazon CloudWatch, potresti scoprire che la `DatabaseConnections` metrica aumenta. Questo aumento indica un numero maggiore di connessioni al database. Consigliamo quanto segue:
+ Limita il numero di connessioni che l'applicazione può aprire con ciascuna istanza. Se l'applicazione dispone di una funzione di connection pool incorporata, impostare un numero ragionevole di connessioni. Basa il numero su ciò che la v della tua istanza può parallelizzare CPUs in modo efficace.

  Se l’applicazione non utilizza una funzione di connection pool, considera l'utilizzo di Amazon RDS Proxy o un'alternativa. Questo approccio consente all'applicazione di aprire più connessioni con il bilanciamento del carico. Il bilanciatore può quindi aprire un numero limitato di connessioni con il database. Poiché un numero inferiore di connessioni sono in esecuzione in parallelo, l'istanza DB esegue meno commutazione di contesto nel kernel. Le query dovrebbero progredire più velocemente, causando un minor numero di eventi di attesa. Per ulteriori informazioni, consulta [Proxy Amazon RDS ](rds-proxy.md).
+ Quando possibile, approfitta delle repliche di lettura di RDS per PostgreSQL. Quando l'applicazione esegue un'operazione di sola lettura, invia queste richieste alle repliche di lettura. Questa tecnica riduce la I/O pressione sul nodo primario (writer).
+ Prendi in considerazione la possibilità di scalare l'istanza database. Una classe di istanza a maggiore capacità fornisce più memoria, il che offre a RDS per PostgreSQL un buffer pool condiviso più ampio per contenere le pagine. Le dimensioni maggiori offrono inoltre all'istanza DB più v CPUs per gestire le connessioni. More v CPUs sono particolarmente utili quando le operazioni che generano eventi di `IO:DataFileRead` attesa sono scritture.

# IO:WALWrite
<a name="wait-event.iowalwrite"></a>



**Topics**
+ [Versioni del motore supportate](#wait-event.iowalwrite.context.supported)
+ [Context](#wait-event.iowalwrite.context)
+ [Probabili cause di aumento delle attese](#wait-event.iowalwrite.causes)
+ [Azioni](#wait-event.iowalwrite.actions)

## Versioni del motore supportate
<a name="wait-event.iowalwrite.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL 10 e successive.

## Context
<a name="wait-event.iowalwrite.context"></a>

L'attività nel database che genera dati WAL riempie prima i buffer WAL e poi scrive su disco, in modo asincrono. L'evento di attesa `IO:WALWrite` viene generato quando la sessione SQL è in attesa del completamento della scrittura dei dati WAL su disco in modo da poter rilasciare la chiamata COMMIT della transazione. 

## Probabili cause di aumento delle attese
<a name="wait-event.iowalwrite.causes"></a>

Se questo evento di attesa si verifica spesso, è necessario esaminare il carico di lavoro e il tipo di aggiornamenti che il carico di lavoro esegue e la loro frequenza. In particolare, cerca i seguenti tipi di attività.

**Attività DML intensa**  
La modifica dei dati nelle tabelle del database non avviene istantaneamente. Un inserimento in una tabella potrebbe dover attendere l'inserimento o l'aggiornamento della stessa tabella di un altro client. Le istruzioni DML (Data Manipulation Language) per la modifica dei valori dei dati (INSERT, UPDATE, DELETE, COMMIT, ROLLBACK TRANSACTION) possono causare conflitti che fanno sì che il file WAL sia in attesa dello svuotamento dei buffer. Questa situazione è illustrata nelle seguenti metriche di Approfondimenti sulle prestazioni di Amazon RDS che indicano un'attività DML intensa.  
+  `tup_inserted`
+ `tup_updated`
+ `tup_deleted`
+ `xact_rollback`
+ `xact_commit`
Per ulteriori informazioni su questi parametri, consulta [Contatori Performance Insights per Amazon RDS for PostgreSQL](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.PostgreSQL).

**Attività di punti di controllo frequenti**  
I checkpoint frequenti contribuiscono ad aumentare il numero di file WAL. In RDS per PostgreSQL, le scritture di pagina intera sono sempre "attive". Le scritture di pagina intera aiutano a proteggersi dalla perdita di dati. Tuttavia, quando i punti di controllo si verificano troppo spesso, il sistema può presentare problemi generali di prestazioni. Ciò si verifica in particolare nei sistemi con un'attività DML intensa. In alcuni casi, potresti trovare messaggi di errore nel `postgresql.log` in cui si afferma che i punti di controllo si verificano troppo spesso.   
Quando si ottimizzano i punti di controllo, si consiglia di bilanciare attentamente le prestazioni con il tempo previsto necessario per il ripristino in caso di arresto anomalo. 

## Azioni
<a name="wait-event.iowalwrite.actions"></a>

Per ridurre il numero degli eventi di attesa, ti consigliamo di eseguire le seguenti azioni.

**Topics**
+ [Riduzione del numero di commit](#wait-event.iowalwrite.actions.problem)
+ [Monitoraggio dei punti di controllo](#wait-event.iowalwrite.actions.monitor)
+ [Aumento dell'I/O](#wait-event.iowalwrite.actions.scale-io)
+ [Volume di log dedicato (DLV)](#wait-event.iowalwrite.actions.dlv)

### Riduzione del numero di commit
<a name="wait-event.iowalwrite.actions.problem"></a>

Per ridurre il numero di commit, puoi combinare le istruzioni in blocchi di transazione. Usa Approfondimenti sulle prestazioni di Amazon RDS per esaminare il tipo di query eseguite. È inoltre possibile spostare le operazioni di manutenzione di grandi dimensioni nelle ore non di punta. Ad esempio, crea gli indici o utilizza le operazioni `pg_repack` durante le ore non di produzione.

### Monitoraggio dei punti di controllo
<a name="wait-event.iowalwrite.actions.monitor"></a>

È possibile monitorare due parametri per verificare la frequenza con cui l'istanza database RDS per PostgreSQL scrive nel file WAL per i punti di controllo. 
+ `log_checkpoints` - Questo parametro è impostato su "on" (attivo) per impostazione predefinita. Fa sì che venga inviato un messaggio al log di PostgreSQL per ogni punto di controllo. Questi messaggi di log includono il numero di buffer scritti, il tempo impiegato per scriverli e il numero di file WAL aggiunti, rimossi o riciclati per il punto di controllo specificato. 

  Per ulteriori informazioni su questo parametro, consulta [Error Reporting and Logging](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-CHECKPOINTS) (Creazione di report e log degli errori) nella documentazione di PostgreSQL. 
+ `checkpoint_warning` - Questo parametro imposta un valore di soglia (in secondi) per la frequenza dei punti di controllo al di sopra del quale viene generato un avviso. Per impostazione predefinita, questo parametro non è impostato in RDS per PostgreSQL. È possibile impostare il valore di questo parametro per ricevere un avviso quando le modifiche al database nell'istanza database RDS per PostgreSQL vengono scritte a una velocità per la quale i file WAL non sono di dimensioni idonee per la gestione. Ad esempio, supponi di impostare questo parametro su 30. Se l'istanza RDS per PostgreSQL deve scrivere le modifiche con una frequenza maggiore rispetto a ogni 30 secondi, nel log di PostgreSQL  viene inviato un avviso indicante che i checkpoint si verificano con una frequenza eccessiva. Questo può indicare che il valore `max_wal_size` deve essere aumentato. 

  Per ulteriori informazioni consulta [Write Ahead Log](https://www.postgresql.org/docs/current/runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS) nella documentazione di PostgreSQL. 

### Aumento dell'I/O
<a name="wait-event.iowalwrite.actions.scale-io"></a>

Questo tipo di evento di attesa di input/output (I/O) può essere risolto aumentando le operazioni di input/output al secondo (IOPS) per fornire un I/O più rapido. L'aumento dell'I/O è preferibile a quello della CPU, poiché l'aumento della CPU può comportare ancora più conflitti in termini di I/O in quanto può gestire più lavoro e quindi peggiorare ulteriormente il collo di bottiglia dell'I/O. Come regola generale, ti consigliamo di ottimizzare il carico di lavoro prima di eseguire operazioni di scalabilità.

### Volume di log dedicato (DLV)
<a name="wait-event.iowalwrite.actions.dlv"></a>

Puoi utilizzare un volume di log dedicato (DLV) per un'istanza database che usa l'archiviazione della capacità di IOPS allocata tramite la console Amazon RDS, la AWS CLI o l'API Amazon RDS. Un volume di log dedicato sposta i log delle transazioni del database PostgreSQL in un volume di archiviazione separato da quello contenente le tabelle del database. Per ulteriori informazioni, consulta [Volume di log dedicato (DLV)](CHAP_Storage.md#CHAP_Storage.dlv).

# Eventi di attesa IPC:parallel
<a name="rpg-ipc-parallel"></a>

I seguenti `IPC:parallel wait events` indicano che una sessione è in attesa della comunicazione tra processi relativa alle operazioni di esecuzione di query parallele.
+ `IPC:BgWorkerStartup`: un processo è in attesa che un processo worker parallelo completi la sequenza di avvio. Ciò si verifica durante l’inizializzazione dei worker per l’esecuzione di query parallele.
+ `IPC:BgWorkerShutdown`: un processo è in attesa che un processo worker parallelo completi la sequenza di arresto. Ciò si verifica durante la fase di pulizia dell’esecuzione di query parallele.
+ `IPC:ExecuteGather`: un processo è in attesa di ricevere dati da processi worker paralleli durante l’esecuzione di query. Ciò si verifica quando il processo leader deve raccogliere i risultati dai propri worker.
+ `IPC:ParallelFinish`: un processo è in attesa che i worker paralleli completino l’esecuzione e riportino i risultati finali. Ciò avviene durante la fase di completamento dell’esecuzione di query parallele.

**Topics**
+ [Versioni del motore supportate](#rpg-ipc-parallel-context-supported)
+ [Contesto](#rpg-ipc-parallel-context)
+ [Probabili cause di aumento delle attese](#rpg-ipc-parallel-causes)
+ [Azioni](#rpg-ipc-parallel-actions)

## Versioni del motore supportate
<a name="rpg-ipc-parallel-context-supported"></a>

Queste informazioni relative all’evento di attesa sono supportate per tutte le versioni di Aurora PostgreSQL.

## Contesto
<a name="rpg-ipc-parallel-context"></a>

L’esecuzione parallela delle query in PostgreSQL implica la collaborazione di più processi per elaborare una singola query. Quando si determina che una query è adatta alla parallelizzazione, un processo leader si coordina con uno o più processi worker paralleli in base all’impostazione del parametro `max_parallel_workers_per_gather`. Il processo leader divide il lavoro tra i worker, ciascuno dei quali elabora la propria porzione di dati in modo indipendente, e i risultati vengono raccolti dal processo leader.

**Nota**  
Ogni worker parallelo opera come un processo separato con requisiti di risorse simili a quelli di una sessione utente completa. Ciò significa che una query parallela con 4 worker può consumare fino a 5 volte le risorse (CPU, memoria, I/O larghezza di banda) rispetto a una query non parallela, poiché sia il processo leader che ogni processo di lavoro mantengono le proprie allocazioni di risorse. Ad esempio, impostazioni come `work_mem` vengono applicate singolarmente a ciascun worker, moltiplicando potenzialmente l’utilizzo totale della memoria in tutti i processi.

L’architettura di query parallela è composta da tre componenti principali:
+ Processo leader: il processo principale che avvia l’operazione parallela, divide il carico di lavoro e si coordina con i processi worker.
+ Processi worker: processi in background che eseguono parti della query in parallelo.
+ Gather/Gather merge: operazioni che combinano i risultati di più processi worker e li restituiscono al leader

Durante l’esecuzione parallela, i processi devono comunicare tra loro tramite meccanismi di comunicazione tra processi (IPC). Questi eventi di attesa IPC si verificano durante diverse fasi:
+ Avvio del worker: quando i worker paralleli vengono inizializzati
+ Scambio di dati: quando i worker elaborano i dati e inviano i risultati al leader
+ Arresto del worker: quando l’esecuzione parallela viene completata e i worker vengono terminati
+ Punti di sincronizzazione: quando i processi devono coordinarsi o attendere che altri processi completino le proprie attività

La comprensione di questi eventi di attesa è fondamentale per diagnosticare i problemi di prestazioni relativi all’esecuzione di query parallele, specialmente in ambienti ad alta concorrenza in cui più query parallele possono essere eseguite contemporaneamente.

## Probabili cause di aumento delle attese
<a name="rpg-ipc-parallel-causes"></a>

Diversi fattori possono contribuire a un aumento degli eventi di attesa IPC correlati alle query parallele:

**Elevata concorrenza di query parallele**  
L’esecuzione simultanea di più query parallele può portare a un conflitto di risorse e a un aumento dei tempi di attesa per le operazioni IPC. Ciò è particolarmente comune nei sistemi con elevati volumi di transazioni o carichi di lavoro analitici.

**Piani di query parallele non ottimali**  
Se il pianificatore di query sceglie piani paralleli inefficienti, ciò può comportare una parallelizzazione non necessaria o una scarsa distribuzione del lavoro tra i worker. Ciò può portare a un aumento delle attese IPC, in particolare per gli eventi `IPC:ExecuteGather` e `IPC:ParallelFinish`. Questi problemi di pianificazione spesso derivano da statistiche obsolete e dal rigonfiamento. table/index 

**Avvio e arresto frequenti dei worker paralleli**  
Le query di breve durata che avviano e terminano frequentemente i worker paralleli possono causare un aumento degli eventi `IPC:BgWorkerStartup` e `IPC:BgWorkerShutdown`. Ciò si verifica spesso nei carichi di lavoro OLTP con molte query di piccole dimensioni e parallelizzabili.

**Vincoli delle risorse**  
CPU, memoria o I/O capacità limitate possono causare colli di bottiglia nell'esecuzione parallela, con conseguente aumento dei tempi di attesa in tutti gli eventi IPC. Ad esempio, se la CPU è satura, i processi worker potrebbero impiegare più tempo per avviarsi o elaborare la relativa parte di lavoro.

**Strutture di query complesse**  
Le query con più livelli di parallelismo (ad esempio, join paralleli seguiti da aggregazioni parallele) possono portare a modelli IPC più complessi e tempi di attesa potenzialmente maggiori, soprattutto per gli eventi `IPC:ExecuteGather`.

**Serie di risultati di grandi dimensioni**  
Le query che producono set di risultati di grandi dimensioni possono aumentare i tempi di attesa `IPC:ExecuteGather` poiché il processo leader dedica più tempo alla raccolta e all’elaborazione dei risultati dei processi worker.

La comprensione di questi fattori può aiutare a diagnosticare e risolvere i problemi di prestazioni relativi all’esecuzione di query parallele in Aurora PostgreSQL.

## Azioni
<a name="rpg-ipc-parallel-actions"></a>

Quando si verificano attese relative a query parallele, in genere significa che un processo di backend sta coordinando o attendendo processi worker paralleli. Queste attese sono comuni durante l’esecuzione di piani paralleli. È possibile analizzare e mitigare l’impatto di queste attese monitorando l’utilizzo dei worker paralleli, esaminando le impostazioni dei parametri e ottimizzando l’esecuzione delle query e l’allocazione delle risorse.

**Topics**
+ [Analizzare i piani di query per individuare eventuali parallelismi inefficienti](#rpg-ipc-parallel-analyze-plans)
+ [Monitorare l’utilizzo delle query parallele](#rpg-ipc-parallel-monitor)
+ [Esaminare e modificare le impostazioni delle interrogazioni parallele](#rpg-ipc-parallel-adjust-settings)
+ [Ottimizzare l’allocazione delle risorse](#rpg-ipc-parallel-optimize-resources)
+ [Esaminare la gestione delle connessioni](#rpg-ipc-parallel-connection-management)
+ [Esaminare e ottimizzare le operazioni di manutenzione](#rpg-ipc-parallel-maintenance)

### Analizzare i piani di query per individuare eventuali parallelismi inefficienti
<a name="rpg-ipc-parallel-analyze-plans"></a>

L’esecuzione parallela delle query può spesso portare a instabilità del sistema, picchi di CPU e variazioni imprevedibili delle prestazioni delle query. È fondamentale analizzare a fondo se il parallelismo migliora effettivamente il carico di lavoro specifico. Utilizzare EXPLAIN ANALYZE per esaminare i piani di esecuzione delle query parallele.

Disattivare temporaneamente il parallelismo a livello di sessione per confrontare l’efficienza del piano:

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
```

Riattivare il parallelismo e confrontare:

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

Se la disabilitazione del parallelismo produce risultati migliori o più coerenti, prendere in considerazione la possibilità di disabilitarlo per query specifiche a livello di sessione utilizzando i comandi SET. Per un impatto più ampio, può essere opportuno disabilitare il parallelismo a livello di istanza regolando i parametri pertinenti nel gruppo di parametri del database. Per ulteriori informazioni, consulta [Modifica dei parametri in un gruppo di parametri database in Amazon RDS](USER_WorkingWithParamGroups.Modifying.md).

### Monitorare l’utilizzo delle query parallele
<a name="rpg-ipc-parallel-monitor"></a>

Utilizzare le seguenti query per ottenere visibilità sull’attività e sulla capacità delle query parallele:

Controllare i processi worker paralleli attivi:

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

Questa query mostra il numero di processi worker paralleli attivi. Un valore elevato può indicare che `max\$1parallel\$1workers` è configurato con un valore elevato e potrebbe essere opportuno ridurlo.

Controllare le query parallele simultanee:

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

Questa query restituisce il numero di processi leader distinti che hanno avviato query parallele. Un numero elevato indica che più sessioni eseguono query parallele contemporaneamente, il che può aumentare la richiesta di CPU e memoria.

### Esaminare e modificare le impostazioni delle interrogazioni parallele
<a name="rpg-ipc-parallel-adjust-settings"></a>

Controllare i seguenti parametri per assicurarsi che siano in linea con il carico di lavoro:
+ `max_parallel_workers`: numero totale di worker paralleli in tutte le sessioni.
+ `max_parallel_workers_per_gather`: numero massimo di worker per query.

Per i carichi di lavoro OLAP, l’aumento di questi valori può migliorare le prestazioni. Per i carichi di lavoro OLTP, in genere sono preferiti valori inferiori.

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### Ottimizzare l’allocazione delle risorse
<a name="rpg-ipc-parallel-optimize-resources"></a>

Monitora l'utilizzo della CPU e valuta la possibilità di regolare il numero di v CPUs se è costantemente elevato e se l'applicazione trae vantaggio dalle query parallele. Assicurarsi che sia disponibile una memoria adeguata per le operazioni parallele.
+ Utilizzare le metriche di Approfondimenti sulle prestazioni per determinare se il sistema è legato alla CPU.
+ Ogni worker parallelo utilizza il proprio `work_mem`. Assicurarsi che l’utilizzo totale della memoria rientri nei limiti delle istanze.

Le query parallele possono consumare molte più risorse rispetto alle query non parallele, poiché ogni processo worker è un processo completamente separato che ha all’incirca lo stesso impatto sul sistema di una sessione utente aggiuntiva. Questo deve essere tenuto in considerazione quando si sceglie un valore per questa impostazione, nonché quando si configurano altre impostazioni che controllano l’utilizzo delle risorse come `work_mem`. Per ulteriori informazioni, consultare la [documentazione di PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). I limiti delle risorse come `work_mem` vengono applicati individualmente a ciascun worker, il che significa che l’utilizzo totale può essere molto più elevato in tutti i processi rispetto a quanto sarebbe normalmente per ogni singolo processo.

Prendi in considerazione l'aumento di v CPUs o l'ottimizzazione dei parametri di memoria se il carico di lavoro è fortemente parallelizzato.

### Esaminare la gestione delle connessioni
<a name="rpg-ipc-parallel-connection-management"></a>

In caso di esaurimento delle connessioni, esaminare le strategie di pooling delle connessioni dell’applicazione. Prendere in considerazione l’implementazione del pooling delle connessioni a livello di applicazione, se non è già in uso.

### Esaminare e ottimizzare le operazioni di manutenzione
<a name="rpg-ipc-parallel-maintenance"></a>

Coordinare la creazione degli indici e le altre attività di manutenzione per prevenire il conflitto di risorse. Prendere in considerazione la possibilità di pianificare queste operazioni durante le ore non di picco. Evitare di pianificare una manutenzione intensa (ad esempio, build di indici paralleli) durante i periodi di elevato carico di query da parte degli utenti. Queste operazioni possono consumare worker paralleli e influire sulle prestazioni delle query regolari.

# IPC: ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

L'`IPC:ProcArrayGroupUpdate`evento si verifica quando una sessione è in attesa che il capogruppo aggiorni lo stato della transazione al termine dell'operazione. Sebbene PostgreSQL generalmente associ eventi di attesa di tipo IPC a operazioni di query parallele, questo particolare evento di attesa non è specifico delle query parallele.

**Topics**
+ [Versioni del motore supportate](#apg-rpg-ipcprocarraygroup.supported)
+ [Contesto](#apg-rpg-ipcprocarraygroup.context)
+ [Probabili cause di aumento delle attese](#apg-rpg-ipcprocarraygroup.causes)
+ [Azioni](#apg-rpg-ipcprocarraygroup.actions)

## Versioni del motore supportate
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

Queste informazioni relative all’evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**Comprendere l'array di processi** — L'array process (proc) è una struttura di memoria condivisa in PostgreSQL. Contiene informazioni su tutti i processi in esecuzione, inclusi i dettagli delle transazioni. Durante il completamento della transazione (`COMMIT`o`ROLLBACK`), ProcArray deve essere aggiornato per riflettere la modifica e cancellare il TransactionID dall'array. La sessione che tenta di completare la transazione deve acquisire un blocco esclusivo su. ProcArray Ciò impedisce ad altri processi di ottenere blocchi condivisi o esclusivi su di esso.

**Meccanismo di aggiornamento di gruppo**: durante l'esecuzione di un COMMIT o ROLLBACK, se un processo di backend non riesce a ottenerne uno ProcArrayLock in modalità esclusiva, aggiorna un campo speciale chiamato. ProcArrayGroupMember Ciò aggiunge la transazione all'elenco delle sessioni che intendono terminare. Questo processo di backend quindi dorme e il tempo in cui dorme viene utilizzato come evento di attesa. ProcArrayGroupUpdate Il primo processo ProcArray con procArrayGroup Member, denominato processo leader, acquisisce la modalità esclusiva. ProcArrayLock Quindi cancella l'elenco dei processi in attesa della cancellazione del gruppo TransactionID. Una volta completata questa operazione, il leader rilascia ProcArrayLock e quindi riattiva tutti i processi in questo elenco, notificando loro che la transazione è stata completata.

## Probabili cause di aumento delle attese
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Maggiore è il numero di processi in esecuzione, più a lungo un leader rimarrà aggrappato procArrayLock a una modalità esclusiva. Di conseguenza, più transazioni di scrittura finiscono in uno scenario di aggiornamento di gruppo, causando un potenziale accumulo di processi in attesa dell'evento di `ProcArrayGroupUpdate` attesa. Nella visualizzazione SQL principale di Database Insights, vedrete che COMMIT è l'istruzione con la maggior parte di questo evento di attesa. Ciò è previsto, ma richiederà un'analisi più approfondita dello specifico SQL di scrittura in esecuzione per determinare l'azione appropriata da intraprendere.

## Azioni
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa. Identifica `IPC:ProcArrayGroupUpdate` gli eventi utilizzando Amazon RDS Performance Insights o interrogando la vista del sistema PostgreSQL. `pg_stat_activity`

**Topics**
+ [Monitoraggio delle operazioni di conferma e rollback delle transazioni](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [Ridurre la concorrenza](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [Implementazione del pool di connessioni](#apg-rpg-ipcprocarraygroup.actions.pooling)
+ [Utilizzo di uno storage più veloce](#apg-rpg-ipcprocarraygroup.actions.storage)

### Monitoraggio delle operazioni di conferma e rollback delle transazioni
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Monitora i commit e i rollback**: un numero maggiore di commit e rollback può comportare una maggiore pressione su. ProcArray Ad esempio, se un'istruzione SQL inizia a fallire a causa di un aumento delle violazioni di chiavi duplicate, è possibile che si verifichi un aumento dei rollback che può aumentare la contesa e il sovraccarico delle tabelle. ProcArray

Amazon RDS Database Insights fornisce i `xact_commit` parametri di PostgreSQL e riporta il numero di commit `xact_rollback` e rollback al secondo.

### Ridurre la concorrenza
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Transazioni in batch**: ove possibile, operazioni in batch in singole transazioni per ridurre commit/rollback le operazioni.

**Limita la concorrenza**: riduci il numero di transazioni attive contemporaneamente per alleviare la contesa tra blocchi su. ProcArray Sebbene richiederà alcuni test, la riduzione del numero totale di connessioni simultanee può ridurre i conflitti e mantenere la velocità effettiva.

### Implementazione del pool di connessioni
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Soluzioni di pool di connessioni**: utilizza il pool di connessioni per gestire in modo efficiente le connessioni al database, riducendo il numero totale di backend e quindi il carico di lavoro sul. ProcArray Sebbene richieda alcuni test, la riduzione del numero totale di connessioni simultanee può ridurre i conflitti e mantenere la velocità effettiva.

**Riduci le tempeste di connessione**: allo stesso modo, uno schema di creazione e interruzione frequenti delle connessioni causa una pressione aggiuntiva su. ProcArray Riducendo questo modello, si riduce la contesa complessiva.

### Utilizzo di uno storage più veloce
<a name="apg-rpg-ipcprocarraygroup.actions.storage"></a>

**Volume di registro dedicato**: se l'evento di `IPC:ProcArrayGroupUpdate` attesa è accompagnato da eventi di `IO:WALWrite` attesa elevati, l'impostazione di un volume di registro dedicato può ridurre il collo di bottiglia nella scrittura su WAL. A sua volta, ciò migliora le prestazioni dei commit.

Per ulteriori informazioni, consulta [Volume di registro dedicato](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.dlv.html).

# Lock:advisory
<a name="wait-event.lockadvisory"></a>

L’evento `Lock:advisory` si verifica quando un'applicazione PostgreSQL utilizza un blocco per coordinare l'attività su più sessioni.

**Topics**
+ [Versioni di motori pertinenti](#wait-event.lockadvisory.context.supported)
+ [Context](#wait-event.lockadvisory.context)
+ [Cause](#wait-event.lockadvisory.causes)
+ [Azioni](#wait-event.lockadvisory.actions)

## Versioni di motori pertinenti
<a name="wait-event.lockadvisory.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per RDS per PostgreSQL versione 9.6 e successive.

## Context
<a name="wait-event.lockadvisory.context"></a>

I blocchi di consulenza PostgreSQL sono blocchi cooperativi a livello di applicazione esplicitamente bloccati e sbloccati dal codice dell'applicazione dell'utente. Un'applicazione PostgreSQL può utilizzare un blocco per coordinare l'attività su più sessioni. A differenza dei normali blocchi a livello di oggetto o riga, l'applicazione ha il pieno controllo sulla durata del blocco. Per ulteriori informazioni consulta [Blocchi di consulenza](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) nella documentazione di PostgreSQL.

I blocchi di consulenza possono essere rilasciati prima della fine di una transazione o essere trattenuti da una sessione tra le transazioni. Ciò tuttavia non è vero per i blocchi impliciti e applicati al sistema, come un blocco esclusivo di accesso su una tabella acquisita da una dichiarazione `CREATE INDEX`.

Per una descrizione delle funzioni utilizzate per acquisire (bloccare) e rilasciare (sbloccare) i blocchi di consulenza, vedere [Funzioni di Advisory Lock](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS) nella documentazione di PostgreSQL.

I blocchi di consulenza sono implementati sopra il normale sistema di blocco PostgreSQL e sono visibili nella visualizzazione di sistema `pg_locks`.

## Cause
<a name="wait-event.lockadvisory.causes"></a>

Questo tipo di blocco è controllato esclusivamente da un'applicazione che lo utilizza esplicitamente. I blocchi di consulenza acquisiti per ogni riga come parte di una query possono causare un picco di blocchi o un accumulo a lungo termine.

Questi effetti si verificano quando la query viene eseguita in un modo che acquisisce blocchi su più righe di quelle restituite dalla query. L'applicazione dovrà comunque rilasciare ogni blocco, ma se i blocchi vengono acquisiti su righe che non vengono restituite, l'applicazione non riesce a trovare tutti i blocchi.

L'esempio seguente è tratto da [Blocchi di consulenza](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) nella documentazione di PostgreSQL.

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

In questo esempio, la clausola `LIMIT` può arrestare l'output della query solo dopo che le righe sono già state selezionate internamente e i relativi valori ID bloccati. Ciò può accadere improvvisamente quando un volume di dati crescente fa sì che il pianificatore scelga un piano di esecuzione diverso che non è stato testato durante lo sviluppo. L'accumulo in questo caso avviene perché l'applicazione chiama esplicitamente `pg_advisory_unlock` per ogni valore ID bloccato. Tuttavia, in questo caso non è possibile trovare il set di blocchi acquisiti su righe che non sono state restituite. Poiché i blocchi vengono acquisiti a livello di sessione, non vengono rilasciati automaticamente alla fine della transazione.

Un'altra possibile causa di picchi nei tentativi di blocco bloccati sono i conflitti non intenzionali. In questi conflitti, parti non correlate dell'applicazione condividono per errore lo stesso spazio ID di blocco.

## Azioni
<a name="wait-event.lockadvisory.actions"></a>

Esaminare l'utilizzo delle applicazioni dei blocchi di consulenza e i dettagli su dove e quando nel flusso dell'applicazione viene acquisito e rilasciato ogni tipo di blocco consultivo.

Determina se una sessione sta acquisendo troppi blocchi o che una sessione di lunga durata non rilascia blocchi abbastanza presto, causando un lento accumulo di blocchi. È possibile correggere un lento accumulo di blocchi a livello di sessione terminando la sessione utilizzando `pg_terminate_backend(pid)`. 

Viene visualizzato un client in attesa di un blocco di avviso in `pg_stat_activity` con `wait_event_type=Lock` e `wait_event=advisory`. È possibile ottenere valori di blocco specifici eseguendo una query nella vista di sistema `pg_locks` per lo stesso `pid`, cercando `locktype=advisory` e `granted=f`.

È quindi possibile identificare la sessione di blocco interrogando `pg_locks` per lo stesso blocco consultivo `granted=t`, come mostrato nell'esempio seguente.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

Tutte le funzioni API di blocco consultivo hanno due serie di argomenti, un argomento `bigint` o due argomenti `integer`:
+ Per le funzioni API con un argomento `bigint`, i 32 bit superiori sono in `pg_locks.classid` e i 32 bit inferiori sono in `pg_locks.objid`.
+ Per le funzioni API con due argomenti `integer`, il primo argomento è `pg_locks.classid` e il secondo argomento è `pg_locks.objid`.

Il valore `pg_locks.objsubid` indica quale modulo API è stato utilizzato: `1` significa un argomento `bigint`; `2` significa due argomenti `integer`.

# Lock:extend
<a name="wait-event.lockextend"></a>

L’evento `Lock:extend` si verifica quando un processo di back-end è in attesa di bloccare una relazione per estenderla mentre un altro processo ha un blocco su tale relazione per lo stesso scopo.

**Topics**
+ [Versioni del motore supportate](#wait-event.lockextend.context.supported)
+ [Context](#wait-event.lockextend.context)
+ [Probabili cause di aumento delle attese](#wait-event.lockextend.causes)
+ [Azioni](#wait-event.lockextend.actions)

## Versioni del motore supportate
<a name="wait-event.lockextend.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Context
<a name="wait-event.lockextend.context"></a>

L'evento `Lock:extend` indica che un processo di back-end è in attesa di estendere una relazione su cui un altro processo di backend mantiene un blocco mentre sta estendendo tale relazione. Poiché solo un processo alla volta può estendere una relazione, il sistema genera un evento di attesa `Lock:extend`. Le operazioni `INSERT`, `COPY`, e `UPDATE` possono generare questo evento.

## Probabili cause di aumento delle attese
<a name="wait-event.lockextend.causes"></a>

Quando l'evento `Lock:extend` si verifica più del normale, probabilmente indicando un problema di prestazioni, le cause tipiche includono le seguenti.

**Aumento degli inserti simultanei o degli aggiornamenti della stessa tabella **  
Potrebbe esserci un aumento del numero di sessioni simultanee con query che inseriscono o aggiornano la stessa tabella.

**Larghezza di banda di rete insufficiente**  
La larghezza di banda di rete sull'istanza database potrebbe essere insufficiente per le esigenze di comunicazione di storage del carico di lavoro corrente. Ciò può contribuire alla latenza dello storage che causa un aumento degli eventi `Lock:extend`.

## Azioni
<a name="wait-event.lockextend.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell'evento di attesa.

**Topics**
+ [Riduci gli inserti e gli aggiornamenti simultanei alla stessa relazione](#wait-event.lockextend.actions.action1)
+ [Aumentare la larghezza di banda di rete](#wait-event.lockextend.actions.increase-network-bandwidth)

### Riduci gli inserti e gli aggiornamenti simultanei alla stessa relazione
<a name="wait-event.lockextend.actions.action1"></a>

Innanzitutto, determinare se c'è un aumento dei parametri `tup_inserted` e `tup_updated` e un aumento di questi eventi di attesa. In tal caso, verificare quali relazioni sono in forte contesa per le operazioni di inserimento e aggiornamento. Per determinarlo, interrogare la vista `pg_stat_all_tables` per i valori nei campi `n_tup_ins` e `n_tup_upd`. Per ulteriori informazioni sulla vista `pg_stat_all_tables`, consultare [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) nella documentazione PostgreSQL. 

Per ottenere ulteriori informazioni sul blocco e le query bloccate, eseguire una query `pg_stat_activity` come nel seguente esempio:

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

Dopo aver identificato le relazioni che contribuiscono ad aumentare gli eventi `Lock:extend`, utilizza le seguenti tecniche per ridurre la contesa:
+ Scopri se è possibile utilizzare il partizionamento per ridurre le contese per la stessa tabella. La separazione delle tuple inserite o aggiornate in diverse partizioni può ridurre le contese. Per informazioni sulle partizioni, consulta [Gestione delle partizioni PostgreSQL con l'estensione pg\$1partman](PostgreSQL_Partitions.md).
+ Se l'evento di attesa è dovuto principalmente all'attività di aggiornamento, considerare di ridurre il valore del fattore di riempimento della relazione. Ciò può ridurre le richieste di nuovi blocchi durante l'aggiornamento. Il fattore di riempimento è un parametro di archiviazione per una tabella che determina la quantità massima di spazio per l'imballaggio di una pagina di tabella. Viene espresso come percentuale dello spazio totale per una pagina. Per ulteriori informazioni sul parametro fillfactor, consulta [CREA TABELLA](https://www.postgresql.org/docs/13/sql-createtable.html) nella documentazione di PostgreSQL. 
**Importante**  
Si consiglia vivamente di testare il sistema se si modifica il fattore di riempimento perché la modifica di questo valore può influire negativamente sulle prestazioni, a seconda del carico di lavoro.

### Aumentare la larghezza di banda di rete
<a name="wait-event.lockextend.actions.increase-network-bandwidth"></a>

Per vedere se c'è un aumento della latenza di scrittura, controlla il parametro `WriteLatency` in CloudWatch. Se è presente, usa le metriche Amazon CloudWatch `WriteThroughput` e `ReadThroughput` per monitorare il traffico relativo all'archiviazione sull'istanza database. Questi parametri possono aiutarti a determinare se la larghezza di banda della rete è sufficiente per il tuo carico di lavoro.

Se la larghezza di banda della rete non è sufficiente, aumentala. Se il file client o l’istanza DB sta raggiungendo i limiti di larghezza di banda di rete, l'unico modo per aumentare la larghezza di banda è aumentare la dimensione dell'istanza DB.

Per ulteriori informazioni sui parametri CloudWatch, consultare [Parametri a CloudWatch livello di istanza Amazon per Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). Per informazioni sulle prestazioni di rete per una classe di istanza database, consulta [Parametri a CloudWatch livello di istanza Amazon per Amazon RDS](rds-metrics.md#rds-cw-metrics-instance). 

# Lock:Relation
<a name="wait-event.lockrelation"></a>

L’evento `Lock:Relation` si verifica quando una query è in attesa di acquisire un blocco su una tabella o vista (relazione) attualmente bloccata da un’altra transazione.

**Topics**
+ [Versioni del motore supportate](#wait-event.lockrelation.context.supported)
+ [Contesto](#wait-event.lockrelation.context)
+ [Probabili cause di aumento delle attese](#wait-event.lockrelation.causes)
+ [Azioni](#wait-event.lockrelation.actions)

## Versioni del motore supportate
<a name="wait-event.lockrelation.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.lockrelation.context"></a>

La maggior parte dei comandi PostgreSQL utilizza implicitamente i blocchi per controllare l’accesso simultaneo ai dati nelle tabelle. È inoltre possibile utilizzare questi blocchi esplicitamente nel codice dell’applicazione con il comando `LOCK`. Molte modalità di blocco non sono compatibili tra loro e possono bloccare le transazioni quando cercano di accedere allo stesso oggetto. Quando ciò accade, RDS per PostgreSQL genera un evento `Lock:Relation`. Di seguito sono riportati alcuni esempi comuni:
+ Blocchi esclusivi come `ACCESS EXCLUSIVE` possono bloccare tutti gli accessi simultanei. Le operazioni DDL (Data Definition Language) come `DROP TABLE`, `TRUNCATE`, `VACUUM FULL`, e `CLUSTER` acquisiscono implicitamente i blocchi `ACCESS EXCLUSIVE`. `ACCESS EXCLUSIVE` è anche la modalità di blocco predefinita per le istruzioni `LOCK TABLE` che non specificano esplicitamente una modalità.
+ L’uso di `CREATE INDEX (without CONCURRENT)` su una tabella è in conflitto con le istruzioni DML (Data Manipulation Language) `UPDATE`, `DELETE`, e `INSERT`, che acquisiscono i blocchi `ROW EXCLUSIVE`.

Per ulteriori informazioni sui blocchi a livello di tabella e sulle modalità di blocco in conflitto, vedere [Blocco esplicito](https://www.postgresql.org/docs/13/explicit-locking.html) nella documentazione di PostgreSQL.

Il blocco di query e transazioni in genere si sblocca in uno dei seguenti modi:
+ Query di blocco: l’applicazione può annullare la query o l’utente può terminare il processo. Il motore può anche forzare la fine della query a causa del timeout dell’istruzione di una sessione o di un meccanismo di rilevamento del deadlock.
+ Blocco della transazione: una transazione smette di bloccarsi quando esegue un’istruzione `ROLLBACK` o `COMMIT`. I rollback si verificano automaticamente anche quando le sessioni vengono disconnesse da un client o da problemi di rete o terminano. Le sessioni possono essere terminate quando il motore di database è spento, quando il sistema è fuori memoria e così via.

## Probabili cause di aumento delle attese
<a name="wait-event.lockrelation.causes"></a>

Quando l’evento `Lock:Relation` si verifica più frequentemente del normale, può indicare un problema di prestazioni. Le cause tipiche sono:

**Sessioni simultanee aumentate con blocchi di tabella in conflitto**  
Potrebbe esserci un aumento del numero di sessioni simultanee con query che inseriscono o aggiornano la stessa tabella.

**Operazioni di manutenzione**  
Le operazioni di manutenzione Health come `VACUUM` e `ANALYZE` possono aumentare significativamente il numero di blocchi in conflitto. `VACUUM FULL` acquisisce un blocco `ACCESS EXCLUSIVE`, e `ANALYSE` acquisisce un blocco `SHARE UPDATE EXCLUSIVE`. Entrambi i tipi di blocchi possono causare un evento di attesa `Lock:Relation`. Le operazioni di manutenzione dei dati delle applicazioni, come l’aggiornamento di una vista materializzata, possono anche aumentare le query e le transazioni bloccate.

**Blocchi sulle istanze del lettore**  
È possibile che si verifichi un conflitto tra i blocchi di relazione tenuti dallo scrittore e dai lettori. Attualmente solo i blocchi di relazione `ACCESS EXCLUSIVE` vengono replicati nelle istanze del lettore. Tuttavia, il blocco di relazione `ACCESS EXCLUSIVE` sarà in conflitto con qualsiasi blocco di relazione `ACCESS SHARE` tenuto dal lettore. Questo conflitto può causare un aumento degli eventi di attesa della relazione di blocco sul lettore. 

## Azioni
<a name="wait-event.lockrelation.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Riduci l’impatto del blocco delle istruzioni SQL](#wait-event.lockrelation.actions.reduce-blocks)
+ [Riduci al minimo l’effetto delle operazioni di manutenzione](#wait-event.lockrelation.actions.maintenance)

### Riduci l’impatto del blocco delle istruzioni SQL
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

Per ridurre l’impatto del blocco delle istruzioni SQL, modificare il codice dell’applicazione laddove possibile. Di seguito sono riportate due tecniche comuni per ridurre i blocchi:
+ Utilizzo dell’opzione `NOWAIT` — Alcuni comandi SQL, come le istruzioni `SELECT` e `LOCK`, supportano questa opzione. La direttiva `NOWAIT` annulla la query richiedente il blocco se il blocco non può essere acquisito immediatamente. Questa tecnica può aiutare a impedire che una sessione di blocco provochi un accumulo di sessioni bloccate dietro di essa.

  Ad esempio: si supponga che la transazione A sia in attesa di un blocco trattenuto dalla transazione B. Ora, se B richiede un blocco su una tabella bloccata dalla transazione C, la transazione A potrebbe essere bloccata fino al completamento della transazione C. Ma se la transazione B utilizza un `NOWAIT` quando richiede il blocco su C, può fallire rapidamente e garantire che la transazione A non debba attendere indefinitamente.
+ Utilizza `SET lock_timeout` — Imposta un valore `lock_timeout` per limitare il tempo in cui un'istruzione SQL attende di acquisire un blocco su una relazione. Se il blocco non viene acquisito entro il timeout specificato, la transazione che richiede il blocco viene annullata. Impostare questo valore a livello di sessione.

### Riduci al minimo l’effetto delle operazioni di manutenzione
<a name="wait-event.lockrelation.actions.maintenance"></a>

Operazioni di manutenzione come `VACUUM` e `ANALYZE` sono importanti. Si consiglia di non spegnerli qualora vengano trovati eventi di attesa `Lock:Relation` relativi a queste operazioni di manutenzione. I seguenti approcci possono ridurre al minimo l’effetto di queste operazioni:
+ Eseguire manualmente le operazioni di manutenzione durante le ore non di punta.
+ Per ridurre le attese `Lock:Relation` causate da attività autovacuum, eseguire qualsiasi sintonizzazione automatica necessaria. Per informazioni sulla sintonizzazione autovacuum, fai riferimento a [Funzionamento di PostgreSQL Autovacuum in Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) nella *Guida per l’utente di Amazon RDS*.

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

L’evento `Lock:transactionid` si verifica quando una transazione è in attesa di un blocco a livello di riga.

**Topics**
+ [Versioni del motore supportate](#wait-event.locktransactionid.context.supported)
+ [Contesto](#wait-event.locktransactionid.context)
+ [Probabili cause di aumento delle attese](#wait-event.locktransactionid.causes)
+ [Azioni](#wait-event.locktransactionid.actions)

## Versioni del motore supportate
<a name="wait-event.locktransactionid.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.locktransactionid.context"></a>

L'evento `Lock:transactionid` si verifica quando una transazione sta tentando di acquisire un blocco a livello di riga già concesso a una transazione in esecuzione contemporaneamente. La sessione che mostra il l'evento di attesa `Lock:transactionid` è bloccato a causa di questo blocco. Dopo che la transazione di blocco termina in un’istruzione `COMMIT` o `ROLLBACK`, la transazione bloccata può procedere.

La semantica multiversione di controllo della concorrenza di RDS per PostgreSQL garantisce che i lettori non bloccano gli scrittori e gli scrittori non bloccano i lettori. Affinché si verifichino conflitti a livello di riga, le transazioni bloccate e bloccate devono emettere dichiarazioni in conflitto dei seguenti tipi:
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

L’istruzione `SELECT … FOR KEY SHARE` è un caso speciale. Il database utilizza la clausola `FOR KEY SHARE` per ottimizzare le prestazioni dell'integrità referenziale. Un blocco a livello di riga su una fila può bloccare i comandi `INSERT`, `UPDATE`, e `DELETE` su altre tabelle che fanno riferimento alla riga.

## Probabili cause di aumento delle attese
<a name="wait-event.locktransactionid.causes"></a>

Quando questo evento appare più del normale, la causa è in genere un’istruzione `UPDATE`, `SELECT … FOR UPDATE`, oppure `SELECT … FOR KEY SHARE` combinate con le seguenti condizioni.

**Topics**
+ [Elevata concorrenza](#wait-event.locktransactionid.concurrency)
+ [Inattivo in transazione](#wait-event.locktransactionid.idle)
+ [Transazioni di lunga durata](#wait-event.locktransactionid.long-running)

### Elevata concorrenza
<a name="wait-event.locktransactionid.concurrency"></a>

RDS per PostgreSQL può utilizzare la semantica di blocco granulare a livello di riga. La probabilità di conflitti a livello di riga aumenta quando vengono soddisfatte le seguenti condizioni:
+ Un carico di lavoro altamente simultaneo è conteso per le stesse righe.
+ Aumenta la concorrenza.

### Inattivo in transazione
<a name="wait-event.locktransactionid.idle"></a>

A volte la colonna `pg_stat_activity.state` mostra il valore `idle in transaction`. Questo valore viene visualizzato per le sessioni che hanno avviato una transazione, ma non hanno ancora emesso un `COMMIT` o `ROLLBACK`. Se il valore `pg_stat_activity.state` non è `active`, la query mostrata in `pg_stat_activity` è la versione più recente a terminare l’esecuzione. La sessione di blocco non sta elaborando attivamente una query perché una transazione aperta contiene un blocco.

Se una transazione inattiva ha acquisito un blocco a livello di riga, potrebbe impedire ad altre sessioni di acquisirlo. Questa condizione porta al frequente verificarsi dell'evento di attesa `Lock:transactionid`. Per diagnosticare il problema, esaminare l'output da `pg_stat_activity` e `pg_locks`.

### Transazioni di lunga durata
<a name="wait-event.locktransactionid.long-running"></a>

Le transazioni che vengono eseguite a lungo ricevono blocchi per un lungo periodo di tempo. Questi blocchi a tenuta lunga possono impedire l'esecuzione di altre transazioni.

## Azioni
<a name="wait-event.locktransactionid.actions"></a>

Il blocco delle righe è un conflitto tra le istruzioni `UPDATE`, `SELECT … FOR UPDATE`, oppure `SELECT … FOR KEY SHARE`. Prima di tentare una soluzione, scopri quando queste istruzioni sono in esecuzione sulla stessa riga. Utilizzare queste informazioni per scegliere una strategia descritta nelle sezioni seguenti.

**Topics**
+ [Rispondere a un'elevata concorrenza](#wait-event.locktransactionid.actions.problem)
+ [Rispondere alle transazioni inattive](#wait-event.locktransactionid.actions.find-blocker)
+ [Rispondere alle transazioni di lunga durata](#wait-event.locktransactionid.actions.concurrency)

### Rispondere a un'elevata concorrenza
<a name="wait-event.locktransactionid.actions.problem"></a>

Se il problema è la concorrenza, prova una delle seguenti tecniche:
+ Riduci la concorrenza nell'applicazione. Ad esempio, diminuisci il numero di sessioni attive.
+ Implementa un pool di connessioni. Per informazioni su come mettere in pool le connessioni con RDS Proxy, vedere [Proxy Amazon RDS ](rds-proxy.md).
+ Progettare l'applicazione o il modello di dati per evitare di contendere le istruzioni `UPDATE` e `SELECT … FOR UPDATE`. È inoltre possibile ridurre il numero di chiavi esterne a cui accedono le istruzioni `SELECT … FOR KEY SHARE`.

### Rispondere alle transazioni inattive
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

Se `pg_stat_activity.state` mostra `idle in transaction`, utilizza le seguenti strategie:
+ Attiva autocommit laddove possibile. Questo approccio impedisce alle transazioni di bloccare altre transazioni durante l'attesa di un `COMMIT` o `ROLLBACK`.
+ Cerca percorsi di codice a cui manca `COMMIT`, `ROLLBACK`, oppure `END`.
+ Assicurati che la logica di gestione delle eccezioni nell'applicazione abbia sempre un percorso per un `end of transaction` valido.
+ Assicurati che l'applicazione elabori i risultati delle query dopo aver terminato la transazione con `COMMIT` o `ROLLBACK`.

### Rispondere alle transazioni di lunga durata
<a name="wait-event.locktransactionid.actions.concurrency"></a>

Se le transazioni di lunga durata causano il frequente verificarsi di `Lock:transactionid`, prova le seguenti strategie:
+ Tieni i blocchi di riga fuori dalle transazioni di lunga durata.
+ Limita la durata delle query implementando autocommit quando possibile.

# Lock:tuple
<a name="wait-event.locktuple"></a>

L’evento `Lock:tuple` si verifica quando un processo di backend aspetta di acquisire un blocco su una tupla.

**Topics**
+ [Versioni del motore supportate](#wait-event.locktuple.context.supported)
+ [Context](#wait-event.locktuple.context)
+ [Probabili cause di aumento delle attese](#wait-event.locktuple.causes)
+ [Azioni](#wait-event.locktuple.actions)

## Versioni del motore supportate
<a name="wait-event.locktuple.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Context
<a name="wait-event.locktuple.context"></a>

L’evento `Lock:tuple` indica che un backend è in attesa di acquisire un blocco su una tupla mentre un altro backend tiene un blocco in conflitto sulla stessa tupla. Nella tabella seguente viene illustrato uno scenario in cui le sessioni generano l’evento `Lock:tuple`.


|  Orario  |  Sessione 1  |  Sessione 2  |  Sessione 3  | 
| --- | --- | --- | --- | 
|  t1  |  Inizia una transazione.  |    |    | 
|  t2  |  Aggiorna la riga 1.  |    |    | 
|  t3  |    |  Aggiorna la riga 1. La sessione acquisisce un blocco esclusivo sulla tupla e quindi attende che la sessione 1 rilasci il blocco eseguendo il commit o il rollback.  |    | 
|  t4  |    |    |  Aggiorna la riga 1. La sessione attende che la sessione 2 rilasci il blocco esclusivo sulla tupla.  | 

Oppure puoi simulare questo evento di attesa utilizzando lo strumento di benchmarking `pgbench`. Configurare un numero elevato di sessioni simultanee per aggiornare la stessa riga in una tabella con un file SQL personalizzato.

Per ulteriori informazioni sulle modalità di blocco in conflitto, vedere [Blocco esplicito](https://www.postgresql.org/docs/current/explicit-locking.html) nella documentazione di PostgreSQL. Per ulteriori informazioni su `pgbench`, consulta [pgbench](https://www.postgresql.org/docs/current/pgbench.html) nella documentazione di PostgreSQL.

## Probabili cause di aumento delle attese
<a name="wait-event.locktuple.causes"></a>

Quando l'evento si verifica più del normale, probabilmente indicando un problema di prestazioni, le cause tipiche includono le seguenti:
+ Un numero elevato di sessioni simultanee sta cercando di acquisire un blocco in conflitto per la stessa tupla eseguendo istruzioni `UPDATE` o `DELETE`.
+ Sessioni altamente simultanee stanno eseguendo un’istruzione `SELECT` usando le modalità di blocco `FOR UPDATE` o `FOR NO KEY UPDATE`.
+ Diversi fattori spingono le applicazioni o i connection pool ad aprire più sessioni per eseguire le stesse operazioni. Mentre le nuove sessioni stanno tentando di modificare le stesse righe, il carico del DB può aumentare e `Lock:tuple` può apparire.

Per ulteriori informazioni consulta [Blocchi a livello di riga](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS) nella documentazione di PostgreSQL.

## Azioni
<a name="wait-event.locktuple.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell'evento di attesa.

**Topics**
+ [Indagare la logica dell’applicazione](#wait-event.locktuple.actions.problem)
+ [Trova la sessione responsabile del blocco](#wait-event.locktuple.actions.find-blocker)
+ [Riduci la concorrenza quando è alta](#wait-event.locktuple.actions.concurrency)
+ [Risoluzione dei problemi dei colli di bottiglia](#wait-event.locktuple.actions.bottlenecks)

### Indagare la logica dell’applicazione
<a name="wait-event.locktuple.actions.problem"></a>

Scopri se una sessione bloccante è rimasta in stato `idle in transaction` per lungo tempo. In tal caso, considera di terminare la sessione di blocco come soluzione a breve termine. È anche possibile usare la funzione `pg_terminate_backend`. Per ulteriori informazioni su questa funzione, consulta [Funzioni di segnalazione server](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL) nella documentazione di PostgreSQL.

Per una soluzione a lungo termine, fai quanto seguente:
+ Regola la logica dell'applicazione.
+ Utilizzo del parametro `idle_in_transaction_session_timeout`. Questo parametro termina qualsiasi sessione con una transazione aperta che è rimasta inattiva per un periodo di tempo superiore al periodo di tempo specificato. Per ulteriori informazioni, consulta la pagina [Errori connessione client](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT) nella documentazione di PostgreSQL.
+ Usa autocommit il più possibile. Per ulteriori informazioni, consulta la pagina [CONFIGURA AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html) nella documentazione di PostgreSQL.

### Trova la sessione responsabile del blocco
<a name="wait-event.locktuple.actions.find-blocker"></a>

Mentre si verifica l’evento di attesa `Lock:tuple`, identifica il blocco e la sessione bloccata scoprendo quali blocchi dipendono l'uno dall'altro. Per ulteriori informazioni, consulta [Informazioni sulle dipendenze dei blocchi](https://wiki.postgresql.org/wiki/Lock_dependency_information) nel wiki di PostgreSQL. 

L'esempio seguente esegue una query su tutte le sessioni, filtrando su `tuple` e ordinando per `wait_time`.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

### Riduci la concorrenza quando è alta
<a name="wait-event.locktuple.actions.concurrency"></a>

L’evento `Lock:tuple` potrebbe verificarsi costantemente, soprattutto in un tempo di carico di lavoro occupato. In questa situazione, si consideri di ridurre l'elevata concorrenza per le file molto occupate. Spesso, solo poche righe controllano una coda o la logica booleana, il che rende queste righe molto occupate.

È possibile ridurre la concorrenza utilizzando approcci diversi in base ai requisiti aziendali, alla logica dell'applicazione e al tipo di carico di lavoro. Ad esempio, puoi eseguire le operazioni seguenti:
+ Riprogetta la tua tabella e la logica dei dati per ridurre la concorrenza elevata.
+ Modificare la logica dell'applicazione per ridurre la concorrenza elevata a livello di riga.
+ Sfrutta e riprogetta le query con i blocchi a livello di riga.
+ Utilizzo della clausola `NOWAIT` con operazioni di riprova.
+ Prendi in considerazione l'utilizzo di un controllo della concorrenza logico ottimistico e ibrido.
+ Valuta la possibilità di modificare il livello di isolamento del database.

### Risoluzione dei problemi dei colli di bottiglia
<a name="wait-event.locktuple.actions.bottlenecks"></a>

`Lock:tuple` può verificarsi con colli di bottiglia come la fame di CPU o il massimo utilizzo della larghezza di banda Amazon EBS. Per ridurre i colli di bottiglia, valuta i seguenti approcci:
+ Ridimensiona il tipo di classe di istanza.
+ Ottimizza le query a uso intensivo di risorse.
+ Modificare la logica dell'applicazione.
+ Archivia i dati a cui si accede raramente.

# LWLock: BufferMapping (:mappatura\$1buffer) LWLock
<a name="wait-event.lwl-buffer-mapping"></a>

Questo evento si verifica quando un processo di backend è in attesa di associare un blocco di dati a un buffer nel pool di buffer condiviso.

**Nota**  
Questo evento è denominato `LWLock:BufferMapping` per RDS per PostgreSQL versione 13 e successive. Per RDS per PostgreSQL versione 12 e precedenti, questo evento è denominato `LWLock:buffer_mapping`. 

**Topics**
+ [Versioni del motore supportate](#wait-event.lwl-buffer-mapping.context.supported)
+ [Contesto](#wait-event.lwl-buffer-mapping.context)
+ [Cause](#wait-event.lwl-buffer-mapping.causes)
+ [Azioni](#wait-event.lwl-buffer-mapping.actions)

## Versioni del motore supportate
<a name="wait-event.lwl-buffer-mapping.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per RDS per PostgreSQL versione 9.6 e successive.

## Contesto
<a name="wait-event.lwl-buffer-mapping.context"></a>

Il *pool buffer condiviso* è un'area di memoria RDS per PostgreSQL che contiene tutte le pagine che sono o sono state utilizzate dai processi. Quando un processo ha bisogno di una pagina, legge la pagina nel buffer pool condiviso. Il parametro `shared_buffers` imposta le dimensioni del buffer condiviso e riserva un'area di memoria per memorizzare la tabella e le pagine indice. Se modifichi questo parametro, assicurati di riavviare il database.

L’evento di attesa `LWLock:buffer_mapping` si verifica nei seguenti scenari:
+ Un processo ricerca nella tabella buffer una pagina e acquisisce un blocco di mappatura buffer condiviso.
+ Un processo carica una pagina nel buffer pool e acquisisce un esclusivo blocco di mappatura del buffer.
+ Un processo rimuove una pagina dal pool e acquisisce un blocco esclusivo di mappatura del buffer.

## Cause
<a name="wait-event.lwl-buffer-mapping.causes"></a>

Quando questo evento appare più del normale, probabilmente indicando un problema di prestazioni, il database sta eseguendo il paging in entrata e in uscita dal buffer pool condiviso. Le cause tipiche sono:
+ Query di grandi dimensioni
+ Indici e tabelle gonfie
+ Scansioni complete della tabella
+ Dimensioni del pool condiviso più piccole del set di lavoro

## Azioni
<a name="wait-event.lwl-buffer-mapping.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa.

**Topics**
+ [Monitora i parametri relativi al buffer](#wait-event.lwl-buffer-mapping.actions.monitor-metrics)
+ [Valuta la tua strategia di indicizzazione](#wait-event.lwl-buffer-mapping.actions.indexes)
+ [Riduci il numero di buffer che devono essere allocati rapidamente](#wait-event.lwl-buffer-mapping.actions.buffers)

### Monitora i parametri relativi al buffer
<a name="wait-event.lwl-buffer-mapping.actions.monitor-metrics"></a>

Quando `LWLock:buffer_mapping` aspetta il picco, indaga il rapporto di hit del buffer. È possibile utilizzare questi parametri per comprendere meglio cosa sta accadendo nella cache del buffer. Esamina i seguenti parametri:

`blks_hit`  
Questo parametro contatore Performance Insights indica il numero di blocchi recuperati dal buffer pool condiviso. Dopo che appare l’evento di attesa `LWLock:buffer_mapping`, potresti osservare un picco in `blks_hit`.

`blks_read`  
Questa metrica contatore di Performance Insights indica il numero di blocchi che I/O devono essere letti nel pool di buffer condiviso. Potresti osservare un picco in `blks_read` in vista dell’evento di attesa `LWLock:buffer_mapping`.

### Valuta la tua strategia di indicizzazione
<a name="wait-event.lwl-buffer-mapping.actions.indexes"></a>

Per confermare che la strategia di indicizzazione non sta peggiorando le prestazioni, verifica quanto segue:

Index bloat  
Assicurati che il bloat di indice e tabella non porti alla lettura di pagine non necessarie nel buffer condiviso. Se le tabelle contengono righe inutilizzate, considera l'archiviazione dei dati e la rimozione delle righe dalle tabelle. È quindi possibile ricostruire gli indici per le tabelle ridimensionate.

Indici per query utilizzate di frequente  
Per determinare se disponi degli indici ottimali, monitora i parametri del motore DB in Performance Insights. Il parametro `tup_returned` mostra il numero di righe lette. Il parametro `tup_fetched` mostra il numero di righe restituite al client. Se `tup_returned` è significativamente più grande di `tup_fetched`, i dati potrebbero non essere indicizzati correttamente. Inoltre, le statistiche della tabella potrebbero non essere aggiornate.

### Riduci il numero di buffer che devono essere allocati rapidamente
<a name="wait-event.lwl-buffer-mapping.actions.buffers"></a>

Per ridurre gli eventi di attesa `LWLock:buffer_mapping`, cercare di ridurre il numero di buffer che devono essere allocati rapidamente. Una strategia consiste nell'eseguire operazioni di batch di dimensioni ridotte. Potresti essere in grado di ottenere batch più piccoli partizionando le tabelle.

# LWLock:BufferIO (IPC:BufferIO)
<a name="wait-event.lwlockbufferio"></a>

L'evento `LWLock:BufferIO` si verifica quando RDS per PostgreSQL è in attesa che altri processi finiscano le operazioni di input/output (I/O) quando si tenta contemporaneamente di accedere a una pagina. Il suo scopo è quello di leggere la stessa pagina nel buffer condiviso.

**Topics**
+ [Versioni di motori pertinenti](#wait-event.lwlockbufferio.context.supported)
+ [Context](#wait-event.lwlockbufferio.context)
+ [Cause](#wait-event.lwlockbufferio.causes)
+ [Azioni](#wait-event.lwlockbufferio.actions)

## Versioni di motori pertinenti
<a name="wait-event.lwlockbufferio.context.supported"></a>

Queste informazioni relative all'evento di attesa sono pertinenti per tutte le versioni di RDS per PostgreSQL. Per RDS per PostgreSQL 12 e versioni precedenti questo evento di attesa è denominato lwlock:buffer\$1io mentre in RDS per PostgreSQL versione 13 è denominato lwlock:bufferio. In RDS per PostgreSQL versione 14 l'evento di attesa BufferIO è stato spostato da `LWLock` al tipo di evento di attesa `IPC` (IPC:BufferIO). 

## Context
<a name="wait-event.lwlockbufferio.context"></a>

Ogni buffer condiviso ha un blocco I/O associato all’evento di attesa `LWLock:BufferIO`, ogni volta che un blocco (o una pagina) deve essere recuperato all'esterno del buffer pool condiviso.

Questo blocco viene utilizzato per gestire più sessioni che richiedono tutte l'accesso allo stesso blocco. Questo blocco deve essere letto dall'esterno del buffer pool condiviso, definito dal parametro `shared_buffers`.

Non appena la pagina viene letta all'interno del buffer pool condiviso, il blocco `LWLock:BufferIO` viene rilasciato.

**Nota**  
L'evento di attesa `LWLock:BufferIO` precede l’evento di attesa [IO: DataFileRead](wait-event.iodatafileread.md). L’evento di attesa `IO:DataFileRead` si verifica mentre i dati vengono letti dallo storage.

Per ulteriori informazioni sui blocchi leggeri, consulta[Panoramica dei blocchi](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

## Cause
<a name="wait-event.lwlockbufferio.causes"></a>

Le cause comuni della comparsa dell'evento `LWLock:BufferIO` che appare nelle prime attese includono:
+ Più backend o connessioni che tentano di accedere alla stessa pagina in attesa di un'operazione di I/O
+ Il rapporto tra le dimensioni del buffer pool condiviso (definito dal parametro `shared_buffers`) e il numero di buffer necessari per il carico di lavoro corrente
+ La dimensione del buffer pool condiviso non è ben bilanciata con il numero di pagine sfrattate da altre operazioni
+ Indici grandi o gonfi che richiedono al motore di leggere più pagine del necessario nel buffer pool condiviso
+ Mancanza di indici che costringe il motore DB a leggere più pagine dalle tabelle del necessario
+ Checkpoint che si verificano troppo frequentemente o hanno bisogno di scaricare troppe pagine modificate
+ Picchi improvvisi per le connessioni al database che tentano di eseguire operazioni sulla stessa pagina

## Azioni
<a name="wait-event.lwlockbufferio.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell'evento di attesa:
+ Ottimizza `max_wal_size` e `checkpoint_timeout` in base al tempo di picco del carico di lavoro se vedi `LWLock:BufferIO` in coincidenza con cali dei parametri `BufferCacheHitRatio` Quindi identifica quale query potrebbe causarla.
+ Verifica se hai indici inutilizzati, quindi rimuovili.
+ Utilizzare tabelle partizionate (che hanno anche indici partizionati). Ciò aiuta a mantenere basso il riordino dell'indice e ne riduce l'impatto.
+ Evitare di indicizzare inutilmente le colonne.
+ Evita improvvisi picchi di connessione al database utilizzando un connection pool.
+ Limitare il numero massimo di connessioni al database come best practice.

# LWLock:buffer\$1content (BufferContent)
<a name="wait-event.lwlockbuffercontent"></a>

L’evento `LWLock:buffer_content` si verifica quando una sessione è in attesa di accedere in lettura o scrittura a una pagina dati in memoria mentre un'altra sessione ha bloccato la pagina in scrittura. In RDS per PostgreSQL 13 e versioni successive, questo evento di attesa viene chiamato `BufferContent`.

**Topics**
+ [Versioni del motore supportate](#wait-event.lwlockbuffercontent.context.supported)
+ [Context](#wait-event.lwlockbuffercontent.context)
+ [Probabili cause di aumento delle attese](#wait-event.lwlockbuffercontent.causes)
+ [Azioni](#wait-event.lwlockbuffercontent.actions)

## Versioni del motore supportate
<a name="wait-event.lwlockbuffercontent.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Context
<a name="wait-event.lwlockbuffercontent.context"></a>

Per leggere o manipolare i dati, PostgreSQL vi accede tramite buffer di memoria condivisa. Per leggere dal buffer, un processo ottiene un blocco leggero (LWLock) sul contenuto del buffer in modalità condivisa. Per scrivere sul buffer, ottiene quel blocco in modalità esclusiva. I blocchi condivisi consentono ad altri processi di acquisire contemporaneamente blocchi condivisi su quel contenuto. I blocchi esclusivi impediscono ad altri processi di ottenere qualsiasi tipo di blocco.

L’evento `LWLock:buffer_content` (`BufferContent`) indica che più processi stanno tentando di ottenere un blocco sul contenuto di un buffer specifico.

## Probabili cause di aumento delle attese
<a name="wait-event.lwlockbuffercontent.causes"></a>

Quando l'evento `LWLock:buffer_content` (`BufferContent`) si verifica più del normale, probabilmente indicando un problema di prestazioni, le cause tipiche includono le seguenti.

**Aggiornamenti simultanei aumentati degli stessi dati**  
Potrebbe esserci un aumento del numero di sessioni simultanee con query che inseriscono o aggiornano la stessa tabella. Questa contesa può essere più marcata sulle tabelle con molti indici.

**I dati del carico di lavoro non sono in memoria**  
Quando i dati elaborati dal carico di lavoro attivo non sono in memoria, questi eventi di attesa possono aumentare. Questo effetto è dovuto al fatto che i processi che contengono blocchi possono mantenerli più a lungo mentre eseguono operazioni di I/O su disco.

**Uso eccessivo di vincoli di chiave esterna**  
I vincoli di chiave esterna possono aumentare la quantità di tempo che un processo mantiene su un blocco del contenuto del buffer. Questo effetto è dovuto al fatto che le operazioni di lettura richiedono un blocco del contenuto del buffer condiviso sulla chiave di riferimento mentre quella chiave viene aggiornata.

## Azioni
<a name="wait-event.lwlockbuffercontent.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell'evento di attesa. Potresti identificare eventi `LWLock:buffer_content` (`BufferContent`) utilizzando Amazon RDS Performance Insights o interrogando la vista `pg_stat_activity`.

**Topics**
+ [Migliora l'efficienza in memoria](#wait-event.lwlockbuffercontent.actions.in-memory)
+ [Riduzione dell'utilizzo di vincoli di chiave esterna](#wait-event.lwlockbuffercontent.actions.foreignkey)
+ [Rimuovere gli indici inutilizzati](#wait-event.lwlockbuffercontent.actions.indexes)
+ [Aumento della dimensione della cache quando si usano le sequenze](#wait-event.lwlockbuffercontent.actions.sequences)

### Migliora l'efficienza in memoria
<a name="wait-event.lwlockbuffercontent.actions.in-memory"></a>

Per aumentare la probabilità che i dati del carico di lavoro attivo si trovino in memoria, partizionare tabelle o scalare la classe di istanza. Per informazioni sulle classi di istanza database, consulta [Classi di istanze DB ](Concepts.DBInstanceClass.md).

### Riduzione dell'utilizzo di vincoli di chiave esterna
<a name="wait-event.lwlockbuffercontent.actions.foreignkey"></a>

Indagare sui carichi di lavoro con un numero elevato di eventi di attesa `LWLock:buffer_content` (`BufferContent`) per l'utilizzo di vincoli di chiave esterna. Rimuovere i vincoli di chiave esterna non necessari.

### Rimuovere gli indici inutilizzati
<a name="wait-event.lwlockbuffercontent.actions.indexes"></a>

Per carichi di lavoro con un numero elevato di eventi di attesa `LWLock:buffer_content` (`BufferContent`), identificare gli indici inutilizzati e rimuoverli.

### Aumento della dimensione della cache quando si usano le sequenze
<a name="wait-event.lwlockbuffercontent.actions.sequences"></a>

Se le tabelle utilizzano sequenze, aumenta la dimensione della cache per rimuovere i conflitti nelle pagine di sequenza e nelle pagine di indice. Ogni sequenza è una singola pagina nella memoria condivisa. La cache predefinita è per ogni connessione. Potrebbe non essere sufficiente per gestire il carico di lavoro quando molte sessioni simultanee ricevono un valore di sequenza. 

# LWLock:lock\$1manager (:lockmanager) LWLock
<a name="wait-event.lw-lock-manager"></a>

Questo evento si verifica quando il motore RDS per PostgreSQL mantiene l'area di memoria del blocco condiviso per allocare, controllare e deallocare un blocco quando non è possibile un blocco rapido del percorso.

**Topics**
+ [Versioni del motore supportate](#wait-event.lw-lock-manager.context.supported)
+ [Contesto](#wait-event.lw-lock-manager.context)
+ [Probabili cause di aumento delle attese](#wait-event.lw-lock-manager.causes)
+ [Azioni](#wait-event.lw-lock-manager.actions)

## Versioni del motore supportate
<a name="wait-event.lw-lock-manager.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per RDS per PostgreSQL versione 9.6 e successive. Per le versioni di RDS per PostgreSQL precedenti alla 13, il nome di questo evento di attesa è `LWLock:lock_manager`. Per RDS per PostgreSQL versione 13 e successive, il nome di questo evento di attesa è `LWLock:lockmanager`. 

## Contesto
<a name="wait-event.lw-lock-manager.context"></a>

Quando si emette un'istruzione SQL, RDS per PostgreSQL registra i blocchi per proteggere la struttura, i dati e l'integrità del database durante le operazioni simultanee. Il motore può raggiungere questo obiettivo utilizzando un blocco veloce del percorso o un blocco del percorso che non è veloce. Un blocco del percorso che non è veloce è più costoso e crea più sovraccarico di un blocco veloce del percorso.

### Blocco rapido del percorso
<a name="wait-event.lw-lock-manager.context.fast-path"></a>

Per ridurre il sovraccarico dei blocchi che vengono presi e rilasciati frequentemente, ma che raramente sono in conflitto, i processi di backend possono utilizzare il blocco rapido del percorso. Il database utilizza questo meccanismo per i blocchi che soddisfano i seguenti criteri:
+ Usano il metodo di blocco DEFAULT.
+ Rappresentano un blocco su una relazione di database anziché una relazione condivisa.
+ Sono blocchi deboli che difficilmente entrino in conflitto.
+ Il motore può verificare rapidamente che non siano presenti blocchi in conflitto.

Il motore non può utilizzare il blocco rapido del percorso quando una di queste condizioni è vera:
+ Il blocco non soddisfa i criteri precedenti.
+ Non sono disponibili più slot per il processo di backend.

Per ottimizzare le query per il blocco rapido del percorso, è possibile utilizzare la seguente query.

```
SELECT count(*), pid, mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 4,3,2
 ORDER BY pid, mode;
 count | pid  |      mode       | fastpath
-------+------+-----------------+----------
16 | 9185 | AccessShareLock | t
336 | 9185 | AccessShareLock | f
1 | 9185 | ExclusiveLock   | t
```

La seguente query mostra solo il totale per il database.

```
SELECT count(*), mode, fastpath
  FROM pg_locks
 WHERE fastpath IS NOT NULL
 GROUP BY 3,2
 ORDER BY mode,1;
count |      mode       | fastpath
-------+-----------------+----------
16 | AccessShareLock | t
337 | AccessShareLock | f
1 | ExclusiveLock   | t
(3 rows)
```

Per ulteriori informazioni sul blocco rapido del percorso, consulta [percorso rapido](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76) nel gestore di blocco PostgreSQL README e [pg-locks](https://www.postgresql.org/docs/9.3/view-pg-locks.html#AEN98195) nella documentazione di PostgreSQL. 

### Esempio di problema di scalabilità per il blocco manager
<a name="wait-event.lw-lock-manager.context.lock-manager"></a>

In questo esempio, una tabella denominata `purchases` memorizza cinque anni di dati, partizionati per giorno. Ogni partizione ha due indici. Si verifica la seguente sequenza di eventi:

1. Si interrogano dati su diversi giorni, il che richiede al database di leggere molte partizioni.

1. Il database crea una voce di blocco per ogni partizione. Se gli indici di partizione fanno parte del percorso di accesso dell'ottimizzatore, il database crea anche una voce di blocco per loro.

1. Quando il numero di voci di blocco richieste per lo stesso processo di back-end è superiore a 16, ovvero il valore di `FP_LOCK_SLOTS_PER_BACKEND`, il gestore di blocco utilizza il metodo di blocco del percorso non veloce.

Le applicazioni moderne potrebbero avere centinaia di sessioni. Se le sessioni simultanee eseguono una query sul genitore senza un'adeguata scrematura delle partizioni, il database potrebbe creare centinaia o addirittura migliaia di blocchi di percorso non veloci. In genere, quando questa concorrenza è superiore al numero di v, viene visualizzato l'evento di attesa. CPUs `LWLock:lock_manager`

**Nota**  
L’evento di attesa `LWLock:lock_manager` non è correlato al numero di partizioni o indici in uno schema di database. Al contrario, è correlato al numero di blocchi di percorso non veloci che il database deve controllare.

## Probabili cause di aumento delle attese
<a name="wait-event.lw-lock-manager.causes"></a>

Quando l’evento di attesa `LWLock:lock_manager` si verifica più del normale, probabilmente indicando un problema di prestazioni, le cause più probabili di picchi improvvisi sono le seguenti:
+ Le sessioni attive simultanee eseguono query che non utilizzano blocchi di percorso veloci. Queste sessioni superano anche la vCPU massima.
+ Un gran numero di sessioni attive simultanee sta accedendo a una tabella fortemente partizionata. Ogni partizione ha più indici.
+ Il database sta vivendo una tempesta di connessione. Per impostazione predefinita, alcune applicazioni e software del connection pool creano più connessioni quando il database è lento. Questa pratica peggiora il problema. Ottimizza il software del pool di connessioni in modo che non si verifichino tempeste di connessione.
+ Un numero elevato di sessioni esegue una query su una tabella padre senza potare le partizioni.
+ Un DDL (Data Definition Language), DML (Data Manipolation Language) o un comando di manutenzione blocca esclusivamente una relazione occupata o tuple a cui si accede frequentemente o modificate.

## Azioni
<a name="wait-event.lw-lock-manager.actions"></a>

Se l’evento di attesa `CPU` si verifica, ciò non indica necessariamente un problema di prestazioni. Rispondi a questo evento solo quando le prestazioni diminuiscono e questo evento di attesa sta dominando il carico DB.

**Topics**
+ [Usare la potatura delle partizioni](#wait-event.lw-lock-manager.actions.pruning)
+ [Rimuovere indici non necessari](#wait-event.lw-lock-manager.actions.indexes)
+ [Ottimizza le tue query per bloccare rapidamente i percorsi](#wait-event.lw-lock-manager.actions.tuning)
+ [Sintonizzati per altri eventi di attesa](#wait-event.lw-lock-manager.actions.other-waits)
+ [Riduzione dei colli di bottiglia hardware](#wait-event.lw-lock-manager.actions.hw-bottlenecks)
+ [Utilizzare un connection pooler](#wait-event.lw-lock-manager.actions.pooler)
+ [Aggiornamento della versione RDS per PostgreSQL](#wait-event.lw-lock-manager.actions.pg-version)

### Usare la potatura delle partizioni
<a name="wait-event.lw-lock-manager.actions.pruning"></a>

*Potatura delle partizioni* è una strategia di ottimizzazione delle query per le tabelle partizionate in modo dichiarativo che esclude le partizioni non necessarie dalle scansioni di tabelle, migliorando così le prestazioni. La potatura delle partizioni è attivata per impostazione predefinita. Se è spento, accenderlo come segue.

```
SET enable_partition_pruning = on;
```

Le query possono trarre vantaggio dalla potatura delle partizioni quando la clausola `WHERE` contiene la colonna utilizzata per il partizionamento. Per ulteriori informazioni, consulta [Potatura delle partizioni](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING) nella documentazione di PostgreSQL.

### Rimuovere indici non necessari
<a name="wait-event.lw-lock-manager.actions.indexes"></a>

Il database potrebbe contenere indici inutilizzati o usati raramente. In tal caso, considera la possibilità di eliminarli. Esegui una delle operazioni seguenti:
+ Scopri come trovare indici non necessari consultanto [Indici non utilizzati](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) nel wiki di PostgreSQL.
+ Esegui PG Collector. Questo script SQL raccoglie le informazioni del database e le presenta in un report HTML consolidato. Controlla la sezione «Indici non utilizzati». Per ulteriori informazioni, consulta [pg-collector](https://github.com/awslabs/pg-collector) nel repository Labs. AWS GitHub 

### Ottimizza le tue query per bloccare rapidamente i percorsi
<a name="wait-event.lw-lock-manager.actions.tuning"></a>

Per scoprire se le tue query utilizzano il blocco rapido dei percorsi, esegui una query nella colonna `fastpath` della tabella `pg_locks`. Se le query non utilizzano il blocco rapido dei percorsi, provare a ridurre il numero di relazioni per query a meno di 16.

### Sintonizzati per altri eventi di attesa
<a name="wait-event.lw-lock-manager.actions.other-waits"></a>

Se `LWLock:lock_manager` è il primo o il secondo nell'elenco delle prime attese, controlla se nell'elenco vengono visualizzati anche i seguenti eventi di attesa:
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

Se gli eventi precedenti appaiono in alto nell'elenco, prendi in considerazione prima l'ottimizzazione di questi eventi di attesa. Questi eventi possono essere un driver per `LWLock:lock_manager`.

### Riduzione dei colli di bottiglia hardware
<a name="wait-event.lw-lock-manager.actions.hw-bottlenecks"></a>

Potresti avere un collo di bottiglia hardware, come la fame di CPU o il massimo utilizzo della larghezza di banda Amazon EBS. In questi casi, valuta la riduzione dei colli di bottiglia hardware. Prendi in considerazione le seguenti azioni:
+ Ridimensiona la tua classe di istanza.
+ Ottimizza le query che consumano grandi quantità di CPU e memoria.
+ Cambia la logica dell'applicazione.
+ Archivia i tuoi dati.

Per ulteriori informazioni su CPU, memoria e larghezza di banda di rete EBS, vedere [Tipi di istanza Amazon RDS](https://aws.amazon.com/rds/instance-types/).

### Utilizzare un connection pooler
<a name="wait-event.lw-lock-manager.actions.pooler"></a>

Se il numero totale di connessioni attive supera la vCPU massima, più processi del sistema operativo richiedono CPU di quella supportata dal tipo di istanza. In questo caso, valuta l'utilizzo o l'ottimizzazione di un connection pool. Per ulteriori informazioni sulla v CPUs per il tuo tipo di istanza, consulta [Amazon RDS Instance Types](https://aws.amazon.com/rds/instance-types/).

Per ulteriori informazioni sul connection pool, consulta le risorse seguenti:
+ [Proxy Amazon RDS ](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Connection pool e origini dati](https://www.postgresql.org/docs/7.4/jdbc-datasource.html) nella *Documentazione di PostgreSQL*

### Aggiornamento della versione RDS per PostgreSQL
<a name="wait-event.lw-lock-manager.actions.pg-version"></a>

Se la versione attuale di RDS per PostgreSQL è precedente alla 12, esegui l'aggiornamento alla versione 12 o successiva. Le versioni 12 e successive di PostgreSQL hanno un meccanismo di partizione migliorato. Per ulteriori informazioni sui miglioramenti nella versioni 12, consulta [PostgreSQL 12 Release Notes]( https://www.postgresql.org/docs/release/12.0/). Per ulteriori informazioni sull'aggiornamento di RDS per PostgreSQL, consulta [Aggiornamenti del motore di database RDS per PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.md).

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

L'evento di LWLock aspetta:pg\$1stat\$1statements si verifica quando l'estensione blocca in modo esclusivo la tabella hash che tiene traccia delle istruzioni SQL. `pg_stat_statements` Ciò accade nei seguenti scenari:
+ Quando il numero di istruzioni tracciate raggiunge il valore del parametro `pg_stat_statements.max` configurato ed è necessario lasciare spazio a ulteriori voci, l’estensione esegue un ordinamento in base al numero di chiamate, rimuove il 5% delle istruzioni meno eseguite e ripopola l’hash con le voci rimanenti.
+ Quando `pg_stat_statements` esegue un’operazione `garbage collection` sul file `pgss_query_texts.stat` su disco e riscrive il file.

**Topics**
+ [Versioni del motore supportate](#apg-rpg-lwlockpgstat.supported)
+ [Contesto](#apg-rpg-lwlockpgstat.context)
+ [Probabili cause di aumento delle attese](#apg-rpg-lwlockpgstat.causes)
+ [Azioni](#apg-rpg-lwlockpgstat.actions)

## Versioni del motore supportate
<a name="apg-rpg-lwlockpgstat.supported"></a>

 Queste informazioni relative all’evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL. 

## Contesto
<a name="apg-rpg-lwlockpgstat.context"></a>

**Comprendere l’estensione pg\$1stat\$1statements**: l’estensione pg\$1stat\$1statements tiene traccia delle statistiche di esecuzione delle istruzioni SQL in una tabella hash. L’estensione tiene traccia delle istruzioni SQL fino al limite definito dal parametro `pg_stat_statements.max`. Questo parametro determina il numero massimo di istruzioni che possono essere tracciate che corrisponde al numero massimo di righe nella vista pg\$1stat\$1statements.

**Persistenza delle statistiche delle istruzioni**: l’estensione mantiene le statistiche delle istruzioni tra i riavvii dell’istanza mediante:
+ Scrittura di dati in un file denominato pg\$1stat\$1statements.stat
+ Utilizzo del parametro pg\$1statements.save per controllare il comportamento di persistenza

Quando pg\$1statements.save è impostato su:
+ on (impostazione predefinita): le statistiche vengono salvate all’arresto e ricaricate all’avvio del server
+ off: le statistiche non vengono salvate all’arresto né ricaricate all’avvio del server

**Archiviazione del testo delle query**: l’estensione archivia il testo delle query tracciate in un file denominato `pgss_query_texts.stat`. Questo file può aumentare fino a raddoppiare la dimensione media di tutte le istruzioni SQL tracciate prima che si verifichi la rimozione di oggetti inutili. L’estensione richiede un blocco esclusivo sulla tabella hash durante le operazioni di pulizia e riscrittura del file `pgss_query_texts.stat`.

**Processo di deallocazione delle istruzioni**: quando il numero di istruzioni tracciate raggiunge il limite `pg_stat_statements.max` ed è necessario tenere traccia delle nuove istruzioni, l’estensione:
+ Richiede un blocco esclusivo (:pg\$1stat\$1statements) sulla tabella hash. LWLock
+ Carica i dati esistenti nella memoria locale.
+ Esegue un ordinamento rapido in base al numero di chiamate.
+ Rimuove le istruzioni meno chiamate (inferiore al 5%).
+ Ripopola la tabella hash con le voci rimanenti.

**Monitoraggio della deallocazione delle istruzioni**: in PostgreSQL 14 e versioni successive, è possibile monitorare la deallocazione delle istruzioni utilizzando la vista pg\$1stat\$1statements\$1info. Questa visualizzazione include una colonna dealloc che mostra quante volte le istruzioni sono state deallocate per fare spazio a quelle nuove

Se la deallocazione delle istruzioni si verifica frequentemente, ciò comporterà una rimozione di oggetti inutili più frequente del file `pgss_query_texts.stat` su disco.

## Probabili cause di aumento delle attese
<a name="apg-rpg-lwlockpgstat.causes"></a>

Le cause tipiche dell’aumento delle attese di `LWLock:pg_stat_statements` includono:
+ Un aumento del numero di query univoche utilizzate dall’applicazione.
+ Il valore del parametro `pg_stat_statements.max` è piccolo rispetto al numero di query univoche utilizzate.

## Azioni
<a name="apg-rpg-lwlockpgstat.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa. È possibile identificare gli eventi `LWLock:pg_stat_statements` utilizzando Approfondimenti sulle prestazioni di Amazon RDS o eseguendo una query sulla vista `pg_stat_activity`.

Regola i seguenti `pg_stat_statements` parametri per controllare il comportamento di tracciamento e ridurre gli eventi di attesa delle istruzioni pg\$1stat\$1. LWLock

**Topics**
+ [Disabilitare il parametro pg\$1stat\$1statements.track](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [Aumentare il parametro pg\$1stat\$1statements.max](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [Disabilitare il parametro pg\$1stat\$1statements.track\$1utility](#apg-rpg-lwlockpgstat.actions.disableutility)

### Disabilitare il parametro pg\$1stat\$1statements.track
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Se l'evento di LWLock aspetta:pg\$1stat\$1statements ha un impatto negativo sulle prestazioni del database ed è necessaria una soluzione rapida prima di un'ulteriore analisi della vista `pg_stat_statements` per identificare la causa principale, il parametro può essere disabilitato impostandolo su. `pg_stat_statements.track` `none` In questo modo verrà disabilitata la raccolta delle statistiche sulle istruzioni.

### Aumentare il parametro pg\$1stat\$1statements.max
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Per ridurre la deallocazione e minimizzare la rimozione di oggetti inutili del file `pgss_query_texts.stat` su disco, aumentare il valore del parametro `pg_stat_statements.max`. Il valore predefinito è `5,000`.

**Nota**  
Il parametro `pg_stat_statements.max` è statico. È necessario riavviare l’istanza database per applicare le modifiche a questo parametro. 

### Disabilitare il parametro pg\$1stat\$1statements.track\$1utility
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

È possibile analizzare la vista pg\$1stat\$1statements per determinare quali comandi di utilità stanno consumando la maggior parte delle risorse monitorate da `pg_stat_statements`.

Il parametro `pg_stat_statements.track_utility` controlla se il modulo tiene traccia dei comandi di utilità, che includono tutti i comandi tranne SELECT, INSERT, UPDATE, DELETE e MERGE. Il valore del parametro è `on` per impostazione predefinita.

Ad esempio, quando l’applicazione utilizza molte query sui punti di salvataggio, che sono intrinsecamente univoche, può aumentare la deallocazione delle istruzioni. Per risolvere questo problema, è possibile disabilitare il parametro `pg_stat_statements.track_utility` per impedire a `pg_stat_statements` di monitorare le query sui punti di salvataggio.

**Nota**  
Il parametro `pg_stat_statements.track_utility` è un parametro dinamico. È possibile modificarne il valore senza riavviare l’istanza database.

**Example Esempio di query univoche sui punti di salvataggio in pg\$1stat\$1statements**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

PostgreSQL 17 introduce diversi miglioramenti per il tracciamento dei comandi di utilità:
+ I nomi dei punti di salvataggio vengono ora visualizzati come costanti.
+ La transazione globale IDs (GIDs) dei comandi di commit in due fasi viene ora visualizzata come costanti.
+ I nomi delle istruzioni DEALLOCATE vengono visualizzati come costanti.
+ I parametri CALL vengono ora visualizzati come costanti.

# LWLock:SubTransSLRU (:) LWLock SubtransControlLock
<a name="wait-event.lwlocksubtransslru"></a>

Gli eventi `LWLock:SubtransSLRU` and `LWLock:SubtransBuffer` wait indicano che una sessione è in attesa di accedere alla cache SLRU (Simple Least-Recently Used) per le informazioni sulle sottotransazioni. Ciò si verifica quando si determina la visibilità delle transazioni e le relazioni padre-figlio.
+ `LWLock:SubtransSLRU`: Un processo è in attesa di accedere alla cache SLRU (Simple Least-Recently Used) per una sottotransazione. In RDS per PostgreSQL precedente alla versione 13, viene chiamato questo evento di attesa. `SubtransControlLock`
+ `LWLock:SubtransBuffer`: Un processo è in attesa I/O su un semplice buffer SLRU (Least-Recently Used) per una sottotransazione. In RDS per PostgreSQL precedente alla versione 13, viene chiamato questo evento di attesa. `subtrans`

**Topics**
+ [Versioni del motore supportate](#wait-event.lwlocksubtransslru.supported)
+ [Contesto](#wait-event.lwlocksubtransslru.context)
+ [Probabili cause di aumento delle attese](#wait-event.lwlocksubtransslru.causes)
+ [Azioni](#wait-event.lwlocksubtransslru.actions)

## Versioni del motore supportate
<a name="wait-event.lwlocksubtransslru.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Contesto
<a name="wait-event.lwlocksubtransslru.context"></a>

**Comprendere le sottotransazioni**: una sottotransazione è una transazione all'interno di una transazione in PostgreSQL. È anche nota come transazione annidata.

Le sottotransazioni vengono in genere create quando si utilizza:
+ Comandi `SAVEPOINT`
+ Blocchi di eccezioni () `BEGIN/EXCEPTION/END`

Le sottotransazioni consentono di ripristinare parti di una transazione senza influire sull'intera transazione. Questo ti offre un controllo granulare sulla gestione delle transazioni.

**Dettagli di implementazione**: PostgreSQL implementa le sottotransazioni come strutture annidate all'interno delle transazioni principali. Ogni sottotransazione ottiene il proprio ID di transazione.

Aspetti chiave dell'implementazione:
+  IDs Le transazioni vengono tracciate `pg_xact`
+ Le relazioni padre-figlio sono archiviate nella sottodirectory in `pg_subtrans` `PGDATA`
+ Ogni sessione del database può mantenere fino a sottotransazioni attive `64`
+ Il superamento di questo limite causa un overflow delle sottotransazioni, che richiede l'accesso alla cache SLRU (Simple Least-Recently Used) per le informazioni sulle sottotransazioni

## Probabili cause di aumento delle attese
<a name="wait-event.lwlocksubtransslru.causes"></a>

Le cause più comuni di contesa SLRU per le sottotransazioni includono:
+ **Uso eccessivo della gestione di SAVEPOINT e EXCEPTION: PL/pgSQL le procedure con `EXCEPTION` gestori** creano automaticamente punti di salvataggio impliciti, indipendentemente dal fatto che si verifichino eccezioni. Ciascuno avvia una nuova sottotransazione. `SAVEPOINT` Quando una singola transazione accumula più di 64 sottotransazioni, attiva un overflow SLRU di sottotransazione.
+ Configurazioni di **driver e ORM: l'`SAVEPOINT`utilizzo può essere esplicito nel codice dell'applicazione o implicito nelle configurazioni** dei driver. Molti strumenti ORM e framework applicativi di uso comune supportano le transazioni annidate in modo nativo. Ecco alcuni esempi comuni:
  + Il parametro del driver JDBC`autosave`, se impostato su `always` o`conservative`, genera punti di salvataggio prima di ogni query.
  + Definizioni delle transazioni Spring Framework quando impostato su. `propagation_nested`
  + Rails quando `requires_new: true` è impostato.
  + SQLAlchemy quando `session.begin_nested` viene usato.
  + Django quando vengono utilizzati `atomic()` blocchi annidati.
  + GORM quando viene usato`Savepoint`.
  + pSQLodbc quando l'impostazione del livello di rollback è impostata sul rollback a livello di istruzione (ad esempio,). `PROTOCOL=7.4-2`
+ Carichi di **lavoro simultanei elevati con transazioni e sottotransazioni di lunga durata — Quando si verifica un overflow SLRU di sottotransazioni** durante carichi di lavoro simultanei elevati e transazioni e sottotransazioni di lunga durata, PostgreSQL sperimenta un aumento della contesa. Ciò si manifesta con eventi di attesa e blocchi elevati. `LWLock:SubtransBuffer` `LWLock:SubtransSLRU`

## Azioni
<a name="wait-event.lwlocksubtransslru.actions"></a>

Consigliamo azioni diverse a seconda delle cause dell’evento di attesa. Alcune azioni forniscono un sollievo immediato, mentre altre richiedono indagini e correzioni a lungo termine.

**Topics**
+ [Monitoraggio dell'utilizzo delle sottotransazioni](#wait-event.lwlocksubtransslru.actions.monitor)
+ [Configurazione dei parametri di memoria](#wait-event.lwlocksubtransslru.actions.memory)
+ [Azioni a lungo termine](#wait-event.lwlocksubtransslru.actions.longterm)

### Monitoraggio dell'utilizzo delle sottotransazioni
<a name="wait-event.lwlocksubtransslru.actions.monitor"></a>

Per le versioni 16.1 e successive di PostgreSQL, usa la seguente query per monitorare il conteggio delle sottotransazioni e lo stato di overflow per backend. Questa query unisce le statistiche di backend alle informazioni sulle attività per mostrare quali processi utilizzano sottotransazioni:

```
SELECT a.pid, usename, query, state, wait_event_type,
       wait_event, subxact_count, subxact_overflowed
FROM (SELECT id, pg_stat_get_backend_pid(id) pid, subxact_count, subxact_overflowed
      FROM pg_stat_get_backend_idset() id
           JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON true
     ) a
JOIN pg_stat_activity b ON a.pid = b.pid;
```

Per le versioni 13.3 e successive di PostgreSQL, monitora `pg_stat_slru` la visualizzazione per verificare la pressione della cache delle sottotransazioni. La seguente query SQL recupera le statistiche della cache SLRU per il componente Subtrans:

```
SELECT * FROM pg_stat_slru WHERE name = 'Subtrans';
```

Un `blks_read` valore in costante aumento indica un accesso frequente al disco per le sottotransazioni non memorizzate nella cache, segnalando una potenziale pressione sulla cache SLRU.

### Configurazione dei parametri di memoria
<a name="wait-event.lwlocksubtransslru.actions.memory"></a>

Per PostgreSQL 17.1 e versioni successive, è possibile configurare la dimensione della cache SLRU della sottotransazione utilizzando il parametro. `subtransaction_buffers` L'esempio di configurazione seguente mostra come impostare il parametro del buffer delle sottotransazioni:

```
subtransaction_buffers = 128
```

Questo parametro specifica la quantità di memoria condivisa utilizzata per memorizzare nella cache i contenuti delle sottotransazioni (). `pg_subtrans` Se specificato senza unità, il valore rappresenta blocchi di `BLCKSZ` byte, in genere 8 KB ciascuno. Ad esempio, l'impostazione del valore su 128 alloca 1 MB (128 \$1 8 kB) di memoria per la cache delle sottotransazioni.

**Nota**  
È possibile impostare questo parametro a livello di cluster in modo che tutte le istanze rimangano coerenti. Verifica e modifica il valore in base ai requisiti specifici del carico di lavoro e alla classe di istanza. È necessario riavviare l'istanza di writer per rendere effettive le modifiche ai parametri.

### Azioni a lungo termine
<a name="wait-event.lwlocksubtransslru.actions.longterm"></a>
+ **Esamina il codice e le configurazioni dell'applicazione**: esamina le configurazioni del codice dell'applicazione e dei driver del database per l'utilizzo esplicito e implicito e `SAVEPOINT` l'utilizzo delle sottotransazioni in generale. Identifica le transazioni che potrebbero generare oltre 64 sottotransazioni.
+ **Riduci l'utilizzo dei savepoint**: riduci al minimo l'uso dei savepoint nelle transazioni:
  + Rivedi PL/pgSQL le procedure e le funzioni con i blocchi EXCEPTION. I blocchi EXCEPTION creano automaticamente punti di salvataggio impliciti, che possono contribuire all'overflow delle sottotransazioni. Ogni clausola EXCEPTION crea una sottotransazione, indipendentemente dal fatto che si verifichi effettivamente un'eccezione durante l'esecuzione.  
**Example**  

    Esempio 1: utilizzo problematico del blocco EXCEPTION

    Il seguente esempio di codice mostra l'utilizzo problematico del blocco EXCEPTION che crea più sottotransazioni:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            BEGIN
                -- This creates a subtransaction for each iteration
                INSERT INTO user_audit (user_id, action, timestamp)
                VALUES (user_record.id, 'processed', NOW());
                
                UPDATE users 
                SET last_processed = NOW() 
                WHERE id = user_record.id;
                
            EXCEPTION
                WHEN unique_violation THEN
                    -- Handle duplicate audit entries
                    UPDATE user_audit 
                    SET timestamp = NOW() 
                    WHERE user_id = user_record.id AND action = 'processed';
            END;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Il seguente esempio di codice migliorato riduce l'utilizzo delle sottotransazioni utilizzando UPSERT anziché la gestione delle eccezioni:

    ```
    CREATE OR REPLACE FUNCTION process_user_data()
    RETURNS void AS $$
    DECLARE
        user_record RECORD;
    BEGIN
        FOR user_record IN SELECT * FROM users LOOP
            -- Use UPSERT to avoid exception handling
            INSERT INTO user_audit (user_id, action, timestamp)
            VALUES (user_record.id, 'processed', NOW())
            ON CONFLICT (user_id, action) 
            DO UPDATE SET timestamp = NOW();
            
            UPDATE users 
            SET last_processed = NOW() 
            WHERE id = user_record.id;
        END LOOP;
    END;
    $$ LANGUAGE plpgsql;
    ```  
**Example**  

    Esempio 2: gestore di eccezioni STRICT

    Il seguente esempio di codice mostra la gestione problematica delle ECCEZIONI con NO\$1DATA\$1FOUND:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
        BEGIN
            -- STRICT causes an exception if no rows or multiple rows found
            SELECT email INTO STRICT user_email 
            FROM users 
            WHERE id = p_user_id;
            
            RETURN user_email;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                RETURN 'Email not found';
        END;
    END;
    $$ LANGUAGE plpgsql;
    ```

    Il seguente esempio di codice migliorato evita le sottotransazioni utilizzando IF NOT FOUND anziché la gestione delle eccezioni:

    ```
    CREATE OR REPLACE FUNCTION get_user_email(p_user_id INTEGER)
    RETURNS TEXT AS $$
    DECLARE
        user_email TEXT;
    BEGIN
         SELECT email INTO user_email 
         FROM users 
         WHERE id = p_user_id;
            
         IF NOT FOUND THEN
             RETURN 'Email not found';
         ELSE
             RETURN user_email;
         END IF;
    END;
    $$ LANGUAGE plpgsql;
    ```
  + Driver JDBC: il `autosave` parametro, se impostato su `always` o`conservative`, genera punti di salvataggio prima di ogni query. Valuta se l'`never`impostazione è accettabile per la tua applicazione.
  + Driver ODBC PostgreSQL (pSQLOdBC): l'impostazione del livello di rollback (per il rollback a livello di istruzione) crea punti di salvataggio impliciti per abilitare la funzionalità di rollback delle istruzioni. Valuta se il rollback a livello di transazione o nessun rollback è accettabile per la tua applicazione. 
  + Esamina le configurazioni delle transazioni ORM
  + Prendi in considerazione strategie alternative di gestione degli errori che non richiedono punti di salvataggio
+ **Ottimizza la progettazione delle transazioni**: ristruttura le transazioni per evitare un annidamento eccessivo e ridurre la probabilità che si verifichino condizioni di overflow delle sottotransazioni.
+ **Riduzione delle transazioni di lunga durata: le transazioni** di lunga durata possono aggravare i problemi relativi alle sottotransazioni conservando più a lungo le informazioni relative alle sottotransazioni. Monitora le metriche di Performance Insights e configura il `idle_in_transaction_session_timeout` parametro per terminare automaticamente le transazioni inattive.
+ Monitora le metriche di Performance Insights: monitora le metriche tra cui `idle_in_transaction_count` (numero di sessioni inattive nello stato della transazione) e `idle_in_transaction_max_time` (durata della transazione inattiva più lunga) per rilevare le transazioni di lunga durata.
+ Configura`idle_in_transaction_session_timeout`: imposta questo parametro nel tuo gruppo di parametri per terminare automaticamente le transazioni inattive dopo una durata specificata.
+ Monitoraggio proattivo: monitora gli eventi più frequenti `LWLock:SubtransBuffer` e `LWLock:SubtransSLRU` attendi gli eventi per rilevare le controversie relative alle sottotransazioni prima che diventino critiche.

# Timeout: PG Sleep
<a name="wait-event.timeoutpgsleep"></a>

L’evento `Timeout:PgSleep` si verifica quando un processo server ha chiamato la funzione `pg_sleep` e sta aspettando la scadenza del timeout del sonno.

**Topics**
+ [Versioni del motore supportate](#wait-event.timeoutpgsleep.context.supported)
+ [Probabili cause di aumento delle attese](#wait-event.timeoutpgsleep.causes)
+ [Azioni](#wait-event.timeoutpgsleep.actions)

## Versioni del motore supportate
<a name="wait-event.timeoutpgsleep.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Probabili cause di aumento delle attese
<a name="wait-event.timeoutpgsleep.causes"></a>

Questo evento di attesa si verifica quando un'applicazione, una funzione memorizzata o un utente emette un'istruzione SQL che chiama una delle seguenti funzioni:
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

Le funzioni precedenti ritardano l'esecuzione fino a quando non è trascorso il numero di secondi specificato. Ad esempio: `SELECT pg_sleep(1)` si ferma per 1 secondo. Per ulteriori informazioni, consulta [Ritardo dell'esecuzione](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) nella documentazione di PostgreSQL.

## Azioni
<a name="wait-event.timeoutpgsleep.actions"></a>

Identificare la dichiarazione che stava eseguendo la funzione `pg_sleep`. Determina se l'uso della funzione è appropriato.

# Timeout:VacuumDelay
<a name="wait-event.timeoutvacuumdelay"></a>

L'evento `Timeout:VacuumDelay` indica che il limite dei costi per l'I/O vacuum è stato superato e che il processo di vacuum è stato interrotto. Le operazioni di vacuum si interrompono per la durata specificata nel rispettivo parametro di ritardo dei costi, quindi riprendono a funzionare. Per il comando manuale di vacuum, il ritardo è specificato nel parametro `vacuum_cost_delay`. Per il daemon autovacuum, il ritardo è specificato nel `autovacuum_vacuum_cost_delay parameter.` 

**Topics**
+ [Versioni del motore supportate](#wait-event.timeoutvacuumdelay.context.supported)
+ [Context](#wait-event.timeoutvacuumdelay.context)
+ [Probabili cause di aumento delle attese](#wait-event.timeoutvacuumdelay.causes)
+ [Azioni](#wait-event.timeoutvacuumdelay.actions)

## Versioni del motore supportate
<a name="wait-event.timeoutvacuumdelay.context.supported"></a>

Queste informazioni relative all'evento di attesa sono supportate per tutte le versioni di RDS per PostgreSQL.

## Context
<a name="wait-event.timeoutvacuumdelay.context"></a>

PostgreSQL ha sia un daemon autovacuum che un comando di vacuum manuale. Il processo di autovacuum è "attivato" per impostazione predefinita per le istanze database RDS per PostgreSQL. Il comando di vacuum manuale viene utilizzato in base alle necessità, ad esempio per eliminare le tabelle dalle tuple inattive o generare nuove statistiche.

Quando il processo di vacuum è in corso, PostgreSQL utilizza un contatore interno per tenere traccia dei costi stimati mentre il sistema esegue varie operazioni di I/O. Quando il contatore raggiunge il valore specificato dal parametro del limite dei costi, il processo che esegue l'operazione rimane inattivo per la breve durata specificata nel parametro del ritardo dei costi. Quindi ripristina il contatore e continua le operazioni. 

Il processo di vacuum include dei parametri che possono essere utilizzati per regolare il consumo di risorse. Il vacuum automatico e il comando di vacuum manuale hanno i propri parametri per l'impostazione del valore limite dei costi. Hanno anche i propri parametri per specificare un ritardo dei costi, il tempo necessario per mettere il vacuum in sospensione quando viene raggiunto il limite. In questo modo, il parametro di ritardo dei costi funge da meccanismo di limitazione (della larghezza di banda della rete) del consumo di risorse. La descrizione di questi parametri è disponibile nell'elenco seguente. 

**Parametri che influiscono sulla limitazione (della larghezza di banda della rete) del daemon autovacuum**
+ `[autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)`: specifica il valore del limite dei costi da utilizzare nelle operazioni vacuum automatiche. L'aumento dell'impostazione per questo parametro consente al processo di vacuum di utilizzare più risorse e riduce l'evento di attesa `Timeout:VacuumDelay`. 
+ `[autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)`: specifica il valore di ritardo dei costi da utilizzare nelle operazioni vacuum automatiche. Il valore predefinito è 2 millisecondi. L'impostazione del parametro di ritardo su 0 disattiva il meccanismo di limitazione (della larghezza di banda della rete) e quindi l'evento di attesa `Timeout:VacuumDelay` non viene visualizzato. 

Per ulteriori informazioni, consulta la pagina relativa al [vacuum automatico](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY) nella documentazione di PostgreSQL.

**Parametri che influiscono sulla limitazione (della larghezza di banda della rete) del processo di vacuum manuale**
+ `vacuum_cost_limit`: la soglia di interruzione del processo di vacuum. Il limite predefinito è 200. Questo numero rappresenta le stime dei costi accumulati per le operazioni I/O aggiuntive necessarie a varie risorse. L'aumento di questo valore riduce il numero dell'evento di attesa `Timeout:VacuumDelay`. 
+ `vacuum_cost_delay`: il periodo di tempo in cui il processo di vacuum rimane inattivo quando viene raggiunto il limite dei costi del vacuum. L'impostazione predefinita è 0, a indicare che la funzionalità è disattivata. Puoi impostare questo parametro su un valore intero per specificare il numero di millisecondi per attivare questa funzionalità, ma ti consigliamo di lasciare l'impostazione predefinita.

Per ulteriori informazioni sul parametro `vacuum_cost_delay`, consulta [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST) (Consumo delle risorse) nella documentazione di PostgreSQL. 

Per ulteriori informazioni su come configurare e usare la funzione di funzione vacuum automatica con RDS per PostgreSQL, consulta [Utilizzo della funzionalità di autovacuum di PostgreSQL in Amazon RDS per PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

## Probabili cause di aumento delle attese
<a name="wait-event.timeoutvacuumdelay.causes"></a>

`Timeout:VacuumDelay` è influenzato dall'equilibrio tra le impostazioni dei parametri del limite dei costi (`vacuum_cost_limit`, `autovacuum_vacuum_cost_limit`) e i parametri di ritardo dei costi (`vacuum_cost_delay`, `autovacuum_vacuum_cost_delay`) che controllano la durata della sospensione del vacuum. L'aumento del valore del parametro del limite dei costi consente al vacuum di utilizzare più risorse prima di sospenderlo. Ciò si traduce in un minor numero di eventi di attesa `Timeout:VacuumDelay`. L'aumento di uno dei parametri di ritardo fa sì che l'evento di attesa `Timeout:VacuumDelay` si verifichi più frequentemente e per periodi di tempo più lunghi. 

L'impostazione del parametro `autovacuum_max_workers` può anche aumentare il numero di `Timeout:VacuumDelay`. Ogni processo aggiuntivo di worker vacuum automatico contribuisce al meccanismo interno del contatore e quindi il limite può essere raggiunto più rapidamente rispetto a un singolo processo di vacuum automatico. Se il limite dei costi viene raggiunto più rapidamente, il ritardo dei costi viene applicato più frequentemente, con conseguente aumento degli eventi di attesa `Timeout:VacuumDelay`. Per ulteriori informazioni, consulta [autovacuum\$1max\$1worker](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS) nella documentazione di PostgreSQL.

Anche oggetti di grandi dimensioni, quelli di almeno 500 GB, generano questo evento di attesa perché il vacuum può impiegare del tempo per completare l'elaborazione di oggetti di grandi dimensioni.

## Azioni
<a name="wait-event.timeoutvacuumdelay.actions"></a>

Se le operazioni di vacuum vengono completate come previsto, non è necessaria alcuna correzione. In altre parole, questo evento di attesa non indica necessariamente un problema. Indica che il vacuum viene messo in sospensione per il periodo di tempo specificato nel parametro di ritardo in modo che le risorse possano essere applicate ad altri processi che devono essere completati. 

Se si desidera che le operazioni di vacuum vengano completate più rapidamente, è possibile ridurre i parametri di ritardo. In questo modo si riduce il tempo di sospensione del vacuum. 