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à.
Isolamento serializzabile
Alcune applicazioni richiedono non solo query e caricamento simultanei, ma anche la possibilità di scrivere simultaneamente su più tabelle o sulla stessa tabella. In questo contesto, simultaneamente significa una sovrapposizione non pianificata per l'esecuzione simultanea. Due transazioni sono considerate simultanee se la seconda inizia prima del primo commit. Le operazioni simultanee possono provenire da sessioni diverse controllate dallo stesso utente o da utenti diversi.
Nota
Amazon Redshift supporta un comportamento di commit automatico predefinito in cui ogni commit di SQL comando esegue separatamente i commit di comando singolarmente. Se si racchiude un set di comandi in un blocco di transazione (definito dalle istruzioni BEGIN e END), viene eseguito il commit del blocco come una transazione, quindi è possibile eseguirne il rollback se necessario. Le eccezioni a questo comportamento sono i VACUUM comandi TRUNCATE and, che eseguono automaticamente il commit di tutte le modifiche in sospeso apportate alla transazione corrente.
Alcuni SQL client emettono COMMIT comandi BEGIN e comandi automaticamente, quindi il client controlla se un gruppo di istruzioni viene eseguito come transazione o se ogni singola istruzione viene eseguita come transazione a sé stante. Controlla la documentazione per l'interfaccia che stai utilizzando. Ad esempio, quando si utilizza il JDBC driver Amazon Redshift, un comando JDBC PreparedStatement
con una stringa di query che contiene più SQL comandi (separati da punto e virgola) esegue tutte le istruzioni come un'unica transazione. Al contrario, se usi SQL Workbench/J e imposti AUTO COMMIT ON, se esegui più istruzioni, ogni istruzione viene eseguita come transazione distinta.
Le operazioni di scrittura simultanee sono supportate in Amazon Redshift in modo protettivo utilizzando i blocchi di scrittura sulle tabelle e il principio di isolamento serializzabile. L'isolamento serializzabile mantiene l'illusione che una transazione in esecuzione su una tabella sia l'unica transazione in esecuzione su quella tabella. Ad esempio, due transazioni in esecuzione simultanea, T1 e T2, devono produrre gli stessi risultati di almeno uno dei seguenti esempi:
-
T1 e T2 vengono eseguite in serie in questo ordine
-
T2 e T1 vengono eseguite in serie in questo ordine
Le transazioni simultanee sono invisibili l'una all'altra; non possono rilevare le reciproche modifiche. Ogni transazione simultanea creerà una snapshot del database all'inizio della transazione. Uno snapshot del database viene creato all'interno di una transazione alla prima occorrenza della maggior parte delle SELECT istruzioni, dei DML comandi comeCOPY,DELETE, INSERT UPDATETRUNCATE, e e dei seguenti comandi: DDL
-
ALTERTABLE(per aggiungere o eliminare colonne)
-
CREATE TABLE
-
DROP TABLE
-
TRUNCATE TABLE
Se qualsiasi esecuzione seriale delle transazioni simultanee produce gli stessi risultati della loro esecuzione simultanea, tali transazioni sono considerate "serializzabili" e possono essere eseguite in modo sicuro. Se nessuna esecuzione seriale di tali transazioni produce gli stessi risultati, la transazione che esegue un'istruzione che potrebbe interrompere la serializzabilità viene arrestata e ne viene eseguito il rollback.
Le tabelle del catalogo di sistema (PG) e le altre tabelle di sistema Amazon Redshift (STLeSTV) non sono bloccate in una transazione. Pertanto, le modifiche agli oggetti del database DDL e alle TRUNCATE operazioni sono visibili al momento del commit di qualsiasi transazione concorrente.
Ad esempio, supponiamo che la tabella A esiste nel database quando iniziano due transazioni simultanee, T1 e T2. Supponiamo che T2 restituisca un elenco di tabelle selezionando dalla tabella del catalogo TABLES PG_. Quindi T1 rilascia la tabella A ed esegue il commit, quindi T2 elenca nuovamente le tabelle. La tabella A non è più elencata. Se T2 prova a eseguire una query sulla tabella rilasciata, Amazon Redshift restituisce un errore di relazione inesistente. La query di catalogo che restituisce l'elenco di tabelle a T2 o verifica che la tabella A esista non è soggetta alle stesse regole di isolamento delle operazioni sulle tabelle utente.
Le transazioni per gli aggiornamenti a queste tabelle vengono eseguite in modalità di isolamento con lettura sottoposta al commit. Le tabelle del catalogo dei prefissi PG non supportano l'isolamento dello snapshot.
Isolamento serializzabile per tabelle di sistema e tabelle di catalogo
In una transazione viene inoltre creato uno snapshot del database per qualsiasi SELECT query che fa riferimento a una tabella creata dall'utente o a una tabella di sistema Amazon Redshift (o). STL STV SELECTle query che non fanno riferimento a nessuna tabella non creano una nuova istantanea del database delle transazioni. INSERTDELETE, e UPDATE le istruzioni che operano esclusivamente sulle tabelle del catalogo di sistema (PG) non creano inoltre una nuova istantanea del database delle transazioni.
Come correggere errori di isolamento serializzabile
ERROR:1023DETAIL: violazione dell'isolamento serializzabile su una tabella in Redshift
Quando Amazon Redshift rileva un errore di isolamento serializzabile, compare un messaggio di errore simile al seguente.
ERROR:1023 DETAIL: Serializable isolation violation on table in Redshift
Per risolvere un errore di isolamento serializzabile, si possono tentare i seguenti metodi:
-
Riprovare la transazione annullata.
Amazon Redshift ha rilevato che un carico di lavoro simultaneo non è serializzabile. Suggerisce lacune nella logica dell'applicazione, che di solito possono essere risolte provando a eseguire di nuovo la transazione che ha riscontrato l'errore. Se il problema persiste, provare uno degli altri metodi.
-
Spostare al di fuori della transazione tutte le operazioni che non devono essere nella stessa transazione atomica.
Questo metodo si applica quando singole operazioni all'interno di due transazioni fanno riferimento reciprocamente in modo tale da influire sul risultato dell'altra transazione. Ad esempio, ciascuna delle seguenti due sessioni avvia una transazione.
Session1_Redshift=# begin;
Session2_Redshift=# begin;
Il risultato di un'SELECTistruzione in ogni transazione potrebbe essere influenzato da un'INSERTistruzione nell'altra. In altre parole, si presuppone che le seguenti istruzioni vengano eseguite in serie, in qualunque ordine. In ogni caso, il risultato è che una delle SELECT istruzioni restituisce una riga in più rispetto a quando le transazioni fossero eseguite contemporaneamente. Non esiste un ordine in cui le operazioni in serie possono produrre lo stesso risultato dell'esecuzione simultanea. Di conseguenza, l'ultima operazione eseguita genera un errore di isolamento serializzabile.
Session1_Redshift=# select * from tab1; Session1_Redshift=# insert into tab2 values (1);
Session2_Redshift=# insert into tab1 values (1); Session2_Redshift=# select * from tab2;
In molti casi, il risultato delle SELECT dichiarazioni non è importante. In altre parole, l'atomicità delle operazioni nelle transazioni non è importante. In questi casi, SELECT spostate le dichiarazioni al di fuori delle relative transazioni, come illustrato negli esempi seguenti.
Session1_Redshift=# begin; Session1_Redshift=# insert into tab1 values (1) Session1_Redshift=# end; Session1_Redshift=# select * from tab2;
Session2_Redshift # select * from tab1; Session2_Redshift=# begin; Session2_Redshift=# insert into tab2 values (1) Session2_Redshift=# end;
In questi esempi non ci sono riferimenti reciproci nelle transazioni. Le due INSERT affermazioni non si influenzano a vicenda. In questi esempi c'è almeno un ordine in cui le transazioni possono essere eseguite in serie producendo lo stesso risultato dell'esecuzione simultanea. Ciò vuol dire che le transazioni sono serializzabili.
-
Forzare la serializzazione bloccando tutte le tabelle in ciascuna sessione.
Il comando LOCK blocca le operazioni che possono generare errori di isolamento serializzabile. Quando usate il LOCK comando, assicuratevi di fare quanto segue:
-
Blocca tutte le tabelle interessate dalla transazione, incluse quelle interessate dalle SELECT istruzioni di sola lettura all'interno della transazione.
-
Bloccare le tabelle nello stesso ordine, indipendentemente da quello in cui vengono eseguite le operazioni.
-
Bloccare tutte le tabelle all'inizio delle transazione, prima di eseguire qualunque operazione.
-
Utilizzo dell'isolamento degli snapshot per le transazioni simultanee
Utilizzate un ALTER DATABASE comando con isolamento delle istantanee. Per ulteriori informazioni sul SNAPSHOT parametro for ALTERDATABASE, vedereParametri.
ERRORPer DETAIL ulteriori informazioni sul parametro for, vedere. ----sep----:1018: La relazione non esiste
Quando le operazioni simultanee di Amazon Redshift vengono eseguite in sessioni diverse, viene visualizzato un messaggio di errore simile al seguente.
ERROR: 1018 DETAIL: Relation does not exist.
Le transazioni in Amazon Redshift seguono l'isolamento degli snapshot. Dopo l'inizio di una transazione, Amazon Redshift acquisisce uno snapshot del database. Per l'intero ciclo di vita della transazione, la transazione opera sullo stato del database come indicato nello snapshot. Se la transazione legge da una tabella che non esiste nello snapshot, genera il messaggio di errore 1018 mostrato in precedenza. Anche quando un'altra transazione simultanea crea una tabella dopo che la transazione ha acquisito lo snapshot, la transazione non può leggere dalla tabella appena creata.
Per risolvere questo errore di isolamento della serializzazione, è possibile provare a spostare l'inizio della transazione in un punto in cui si sa che la tabella esiste.
Se la tabella viene creata da un'altra transazione, questo punto è almeno dopo il commit della transazione. Inoltre, assicurarsi che non sia stata eseguita alcuna transazione simultanea che potrebbe aver eliminato la tabella.
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
session2 = # BEGIN;
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
session2 = # SELECT * FROM A;
Di conseguenza, l'ultima operazione eseguita come operazione di lettura da session2 genera un errore di isolamento serializzabile. Questo errore si verifica quando session2 esegue uno snapshot e la tabella è già stata eliminata da una sessione di commit 1. In altre parole, anche se una session3 simultanea ha creato la tabella, session2 non vede la tabella perché non è nello snapshot.
Per risolvere questo errore, è possibile ordinare nuovamente le sessioni come segue.
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
session3 = # BEGIN; session3 = # CREATE TABLE A (id INT); session3 = # COMMIT;
session2 = # BEGIN;
session2 = # SELECT * FROM A;
Ora, quando session2 effettua il suo snapshot, per session3 è già stato eseguito il commit e la tabella è nel database. Session2 può leggere dalla tabella senza alcun errore.