Come posso rilevare e sbloccare i blocchi in Amazon Redshift?

4 minuti di lettura
0

Esistono blocchi di tabelle che bloccano le mie richieste in Amazon Redshift. Come posso trovarli e risolvere il problema?

Breve descrizione

Il blocco è un meccanismo di protezione che controlla il numero di sessioni che possono accedere a una tabella contemporaneamente. Il blocco determina anche le operazioni che possono essere eseguite in tali sessioni. La maggior parte dei database relazionali utilizza blocchi a livello di riga. Tuttavia, Amazon Redshift utilizza blocchi a livello di tabella. È possibile che si verifichino conflitti di blocco se si eseguono istruzioni DDL frequenti nelle tabelle utente o query DML.

Amazon Redshift offre tre modalità di blocco:

  • AccessExclusiveLock: acquisito principalmente durante le operazioni DDL, come ALTER TABLE, DROP o TRUNCATE. AccessExclusiveLock blocca tutti gli altri tentativi di blocco.
  • AccessShareLock: acquisito durante le operazioni UNLOAD, SELECT, UPDATE o DELETE. AccessShareLock blocca solo i tentativi di AccessExclusiveLock. AccessShareLock non blocca altre sessioni che stanno tentando di leggere o scrivere nella tabella.
  • ShareRowExclusiveLock: acquisito durante le operazioni COPY, INSERT, UPDATE o DELETE. ShareRowExclusiveLock blocca AccessExclusiveLock e altri tentativi di ShareRowExclusiveLock, ma non blocca i tentativi di AccessShareLock.

Quando una query o una transazione acquisisce un blocco in una tabella, il blocco rimane per tutta la durata della query o della transazione. Altre query o transazioni in attesa di acquisire lo stesso blocco vengono bloccate, ad eccezione di AccessShareLock. Per ulteriori informazioni sul motivo per cui una query potrebbe bloccarsi, consulta Blocco delle query.

Per risolvere un problema di blocco, identifica la sessione (PID) che mantiene il blocco e quindi interrompi la sessione. Se la sessione non termina, riavvia il cluster.

Risoluzione

Esegui una query per identificare le sessioni che contengono blocchi:

select a.txn_owner, a.txn_db, a.xid, a.pid, a.txn_start, a.lock_mode, a.relation as table_id,nvl(trim(c."name"),d.relname) as tablename, a.granted,b.pid as blocking_pid ,datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' as txn_duration
from svv_transactions a
left join (select pid,relation,granted from pg_locks group by 1,2,3) b
on a.relation=b.relation and a.granted='f' and b.granted='t'
left join (select * from stv_tbl_perm where slice=0) c
on a.relation=c.id
left join pg_class d on a.relation=d.oid
where  a.relation is not null;

L'output è simile a:

txn_owner | txn_db |   xid   |  pid  |         txn_start          |      lock_mode      | table_id | tablename | granted | blocking_pid |        txn_duration         |
----------+--------+---------+-------+----------------------------+---------------------+----------+-----------+---------+--------------+-----------------------------+
 usr1     | db1    | 5559898 | 19813 | 2018-06-30 10:51:57.485722 | AccessExclusiveLock |   351959 | lineorder | t       |              | 0 days 0 hrs 0 mins 52 secs |
 usr1     | db1    | 5559927 | 20450 | 2018-06-30 10:52:19.761199 | AccessShareLock     |   351959 | lineorder | f       |        19813 | 0 days 0 hrs 0 mins 30 secs |
 usr1     | db1    | 5559898 | 19813 | 2018-06-30 10:51:57.485722 | AccessShareLock     |   351959 | lineorder | t       |              | 0 days 0 hrs 0 mins 52 secs |

Se il risultato nella colonna concesso è f (false), una transazione in un'altra sessione mantiene il blocco. La colonna blocking\ _pid mostra l'ID del processo della sessione che mantiene il blocco. In questo esempio, il PID 19813 mantiene il blocco.

Per rilasciare un blocco, attendi il completamento della transazione che mantiene il blocco. È anche possibile terminare manualmente la sessione eseguendo il seguente comando:

select pg_terminate_backend(PID);

La chiusura di un PID ripristina tutte le transazioni in esecuzione e rilascia tutti i blocchi della sessione. I blocchi vengono quindi rivendicati dalle altre transazioni in attesa di acquisire il blocco.

Nota: il valore "1" restituito da PG\ _TERMINATE\ _BACKEND (PID) indica in genere una richiesta di terminazione riuscita nel PID. Tuttavia, ciò non garantisce che il PID sia stato effettivamente terminato. In alcuni casi, il PID non può essere determinato in base al suo stato interno. Pertanto, è consigliabile controllare anche STV\ _SESSIONS (e altre tabelle di sistema pertinenti) per confermare se il PID è stato effettivamente terminato.

Se PG\ _TERMINATE\ _BACKEND (PID) non termina correttamente la sessione, riavvia il cluster per terminare il processo. Il riavvio può essere eseguito mediante un riavvio del cluster tramite la console Amazon Redshift o tramite un riavvio del database utilizzando REBOOT\ _CLUSTER.


Informazioni correlate

BLOCCO (Amazon Redshift)

Potenziale situazione di deadlock per transazioni di scrittura simultanee

AWS UFFICIALE
AWS UFFICIALEAggiornata 2 anni fa