

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

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