當我在不同的工作階段中執行並行 Amazon Redshift 作業時,收到 "Serializable isolation violation on table" 或 "Relation does not exist" 錯誤。
簡短描述
Amazon Redshift 中的並行寫入作業必須是可序列化的,以便交易可以依序執行。序列化執行所產生的結果,必須與交易並行執行時的結果相同。如需詳細資訊,請參閱可序列化隔離。
解決方法
若要解決可序列化隔離錯誤,請使用以下其中一種方法。
重試已取消的交易
如果 Amazon Redshift 偵測到並行工作負載無法序列化,則應用程式邏輯中可能存在缺陷。請重試導致錯誤的已取消交易。
使用中間提交
當發出提交或回復時,交易完成。如果交易在從資料表刪除作業執行前已提交,則會建立新交易,並維持可序列化隔離性。
以下範例使用中間的 COMMIT 命令:
DELETE FROM XXXXX WHERE date = XXXXX';
→COMMIT;
BEGIN TRANSACTION;
DELETE FROM XXXXX WHERE date = XXXXX';
將非原子作業移至交易之外
當兩個交易內的個別作業相互參照,且可能影響彼此的結果時,請使用此方法。
當結果不需要與其他作業保持原子性時,請將 SELECT 陳述式移至其交易之外。
以下範例將 SELECT 陳述式移到其交易之外:
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;
前述的交易是可序列化的。如果您按順序執行交易,則結果會與並行執行時相同。
鎖定每個工作階段中的所有資料表以強制序列化
LOCK 命令會封鎖可能導致可序列化隔離錯誤的作業。執行 LOCK 命令時,請完成下列步驟:
- 鎖定交易所影響的所有資料表,並包括交易內部受唯讀 SELECT 陳述式影響的資料表。
- 無論作業執行順序如何,都以相同的順序鎖定資料表。
- 在執行作業之前,請在交易開始時鎖定所有資料表。
對並行交易使用快照隔離
可序列化隔離實現了嚴格的序列化。當 Amazon Redshift 無法將結果對應至並行執行交易的序列順序時,交易可能會失敗。
快照隔離允許較高的並行性,因此對同一資料表中不同資料列的並行修改可順利完成。
交易會繼續在資料庫的最新提交版本或快照上運作。
您可以在資料庫上設定快照隔離,並在 CREATE DATABASE 或 ALTER DATABASE 命令中包含 ISOLATION LEVEL 參數。
若要查看資料庫使用的並行模型,請執行以下 STV_DB_ISOLATION_LEVEL 查詢:
SELECT * FROM stv_db_isolation_level;
The database can then be altered to SNAPSHOT ISOLATION:
ALTER DATABASE sampledb ISOLATION LEVEL SNAPSHOT;
變更資料庫的隔離層級時,請使用下列最佳做法:
- 若要變更資料庫隔離層級,您必須具有超級使用者或 CREATE DATABASE 權限。
- 您無法更改資料庫環境的隔離層級。
- 您無法更改交易區塊中的隔離層級。
- 當其他使用者連線到資料庫時,更改隔離層級命令會失敗。
- alter isolation level 命令可以更改目前工作階段的隔離層級設定。
如需詳細資訊,請參閱如何修正可序列化隔離錯誤。
相關資訊
ERROR:1023 DETAIL: Serializable isolation violation on a table in Redshift
ERROR:1018 DETAIL: Relation does not exist
管理並行寫入作業