隔離級別和寫衝突磚
表的隔離級別定義事務的程度必須從修改由孤立的並發操作。在磚寫衝突取決於隔離級別。
三角洲湖提供ACID事務讀寫之間的擔保。這意味著:
多個作家跨多個集群可以同時修改一個表分區。作家看到一致的快照視圖的表和寫一個串行順序出現。
讀者繼續看到一致的快照視圖的表數據磚工作開始的,即使在工作表被修改。
看到酸保證磚是什麼?。
請注意
磚使用三角洲湖默認所有表。本文描述了行為三角洲湖磚。
沒有讀表三角洲湖什麼時候提交?
三角洲湖插入
或附加操作不讀表狀態之前如果滿足下列條件:
邏輯是表示使用
插入
SQL邏輯或追加模式。邏輯不包含子查詢或條件,參考表寫操作的目標。
在其他提交、三角洲湖驗證和解析表版本提交使用元數據在事務日誌,但沒有版本的表實際上是閱讀。
請注意
許多常見的模式使用合並
操作根據表插入數據條件。盡管它可能使用重寫這個邏輯插入
聲明,任何引用目標表中的數據觸發條件相同的並發性限製合並
。
寫衝突磚
下表描述了對寫操作可以在每一個衝突隔離級別。
請注意
具有標識列的表不支持並發事務。看到使用標識列在三角洲湖。
插入(1) |
更新、刪除、合並 |
優化 |
|
---|---|---|---|
插入 |
不衝突 |
||
更新、刪除、合並 |
可以在可序列化的衝突,不能WriteSerializable衝突 |
能在序列化和WriteSerializable衝突 |
|
優化 |
不衝突 |
能在序列化和WriteSerializable衝突 |
能在序列化和WriteSerializable衝突 |
重要的
(1)所有插入
操作在上麵的表中描述不讀任何附加操作相同的數據表之前。插入
包含子查詢的操作讀取相同的表支持相同的並發性合並
。
寫可序列化的與可序列化的隔離級別
表的隔離級別定義事務的程度必須隔絕修改由並發事務。三角洲湖上磚支持兩種隔離級別:序列化和WriteSerializable。
可序列化的:最強的隔離級別。它確保承諾寫操作和所有讀取可序列化的。操作是允許的,隻要存在一個連續的序列產生一次執行表中看到的結果一樣。寫操作,串行序列是一模一樣的表的曆史。
WriteSerializable(默認):隔離級別低於可序列化的。它確保隻寫操作(即不會讀)是可序列化的。然而,這仍然是比快照隔離。WriteSerializable是默認的隔離級別,因為它提供了極好的平衡數據一致性和可用性最常見的操作。
在這種模式下,三角洲表的內容可能不同於預計的的操作序列表中看到的曆史。這是因為這種模式允許某對並發寫操作(操作X和Y)繼續等,其結果將是如果Y是之前執行X(即它們之間序列化),盡管曆史會表明,X Y後承諾不允許重新排序,隔離級別設置表導致這些交易失敗是可序列化的。
讀操作總是使用快照隔離。寫隔離級別決定了讀者是否有可能看到一個表的快照,,根據曆史上,“不存在”。
可串行化的水平,讀者總是隻能看到表符合曆史。WriteSerializable水平,讀者可以看到一個表中不存在三角洲日誌。
例如,考慮txn1,一個長時間運行的刪除和txn2插入txn1刪除的數據。txn2和txn1完整記錄在訂單上。根據曆史數據插入txn2表中不應該存在。可串行化的水平,讀者永遠不會看到txn2插入的數據。然而,對於WriteSerializable層麵,讀者可以在某種程度上看到txn2插入的數據。
類型的操作的更多信息可以在每個隔離級別和相互衝突可能的錯誤,明白了避免使用分區和不相交的命令衝突的條件。
設置隔離級別
使用設置隔離級別改變表
命令。
改變表<表- - - - - -的名字>集TBLPROPERTIES(“delta.isolationLevel”=<水平- - - - - -的名字>)
在哪裏<級別名稱>
是可序列化的
或WriteSerializable
。
例如,改變默認的隔離級別WriteSerializable
來可序列化的
運行:
改變表<表- - - - - -的名字>集TBLPROPERTIES(“delta.isolationLevel”=“序列化”)
避免使用分區和不相交的命令衝突的條件
在所有情況下都標記為“衝突”,這兩個操作是否會衝突取決於他們是否使用相同的文件集。你可以不相交的兩套文件分區中使用的表的列的操作條件。例如,這兩個命令更新表在哪裏日期>“2010-01-01”…
和刪除表在哪裏日期<“2010-01-01”
按日期將衝突如果表沒有分區,既可以嚐試修改相同的一組文件。分區的表日期
會避免衝突。因此,分區表根據條件常用命令可以顯著減少衝突。然而,分區表的列,高基數可以導致其他性能問題由於大量的子目錄。
衝突異常
當一個事務衝突發生時,您將觀察以下例外:
ConcurrentAppendException
此異常發生在並發操作添加同一個分區中的文件(或任何一個分區表)讀取你的操作。文件添加可以造成的插入
,刪除
,更新
,或合並
操作。
使用默認隔離級別的WriteSerializable
文件還說,由盲目的插入
操作(也就是說,盲目操作,添加數據沒有閱讀任何數據)不與任何操作衝突,即使他們接觸相同的分區(或者任何一個分區表)。如果設置隔離級別可序列化的
,那麼盲目的附加可能衝突。
這通常是在並發拋出異常刪除
,更新
,或合並
操作。而並發操作可能身體上更新不同分區目錄,其中一個可能讀取相同的分區,同時另一個更新,造成衝突。您可以顯式分離,從而避免這種狀況的操作。考慮下麵的例子。
/ /目標的deltaTable分區按日期和國家deltaTable。作為(“t”)。合並(源。作為(“s”),”年代。user_id = t。user_id和s。日期= t。日期AND s.country = t.country")。whenMatched()。updateAll()。whenNotMatched()。insertAll()。執行()
假設你運行以上代碼同時為不同日期或國家。因為每個工作都是工作在一個獨立的分區目標三角洲表,你別指望任何衝突。然而,條件不夠明確,可以掃描整個表,可以與並發衝突操作更新其他分區。相反,您可以重寫你的聲明中添加特定的日期和國家合並條件,如以下示例所示。
/ /目標的deltaTable分區按日期和國家deltaTable。作為(“t”)。合並(源。作為(“s”),”年代。user_id = t。user_id和s。日期= t。日期AND s.country = t.country AND t.date = '"+<日期>+“和t。國家='"+<國家>+“”)。whenMatched()。updateAll()。whenNotMatched()。insertAll()。執行()
現在這個操作是安全的並發運行在不同的日期和國家。
ProtocolChangedException
這個異常可以在下列情況下發生:
當δ表是版本升級到一個新的協議。未來成功的操作可能需要升級你的磚運行時。
當多個作家創建或替換一個表在同一時間。
當多個作家寫一個空路徑在同一時間。
看到磚三角洲湖管理功能的兼容性如何?為更多的細節。