PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Evita i blocchi di accesso esclusivi sulle tabelle referenziate durante il DROPPing in PostgreSQL

Per chiunque cerchi su Google e cerchi di capire perché la loro tabella di rilascio (o elimina la chiave esterna o aggiunge la chiave esterna) è rimasta bloccata per molto tempo:

PostgreSQL (Ho esaminato le versioni da 9.4 a 13) I vincoli di chiave esterna vengono effettivamente implementati utilizzando trigger su entrambe le estremità della chiave esterna .

Se hai una tabella azienda (id come chiave primaria) e una tabella bank_account (id come chiave primaria, company_id come chiave esterna che punta a company.id), allora ci sono in realtà 2 trigger sulla tabella bank_account e anche 2 trigger sull'azienda tabella.

nome_tabella tempistica nome_trigger nome_funzione
conto_bancario DOPO L'AGGIORNAMENTO RI_ConstraintTrigger_c_1515961 RI_FKey_check_upd
conto_bancario DOPO L'INSERIMENTO RI_ConstraintTrigger_c_1515960 RI_FKey_check_ins
azienda DOPO L'AGGIORNAMENTO RI_ConstraintTrigger_a_1515959 RI_FKey_noaction_upd
azienda DOPO L'ELIMINAZIONE RI_ConstraintTrigger_a_1515958 RI_FKey_noaction_del

La creazione iniziale di tali trigger (durante la creazione della chiave esterna) richiede il blocco SHARE ROW EXCLUSIVE su tali tabelle (in passato era il blocco ACCESS EXCLUSIVE nella versione 9.4 e precedenti). Questo blocco non è in conflitto con i "blocchi di lettura dei dati", ma entrerà in conflitto con tutti gli altri blocchi, ad esempio un semplice INSERT/UPDATE/DELETE nella tabella dell'azienda.

L'eliminazione di tali trigger (quando si elimina la chiave esterna o l'intera tabella) richiede il blocco ACCESS EXCLUSIVE su quelle tabelle. Questo blocco è in conflitto con ogni altro blocco!

Quindi immagina uno scenario, in cui hai una transazione A in esecuzione che prima ha eseguito un semplice SELECT dalla tabella dell'azienda (facendo in modo che mantenga un blocco ACCESS SHARE per la tabella dell'azienda fino a quando la transazione non viene confermata o annullata) e ora sta facendo un altro lavoro per 3 minuti. Si tenta di eliminare la tabella bank_account nella transazione B. Ciò richiede il blocco ACCESS EXCLUSIVE, che dovrà attendere fino a quando il blocco ACCESS SHARE viene rilasciato prima. Inoltre, tutte le altre transazioni, che desiderano accedere alla tabella dell'azienda (solo SELEZIONA, o forse INSERT/UPDATE/DELETE), verrà messo in coda per attendere il blocco ACCESS EXCLUSIVE, che è in attesa del blocco ACCESS SHARE.

Le transazioni di lunga durata e le modifiche DDL richiedono una gestione delicata.