可序列性與「嚴格」可序列化區別

2021-10-03 01:23:27 字數 3775 閱讀 8212

多年來,「可序列化/序列化」(serializability)被稱為資料庫隔離級別的「 **標準 」。它是絕大多數商業資料庫系統中提供的最高隔離級別,一些高度廣泛部署的系統甚至無法提供隔離級別與可序列化一樣高。

在這篇文章中,我們展示了可序列化的可行性,並且說明它從未成為資料庫系統的「**標準」。事實上,嚴格的可序列化才一直是**標準。正如我們將看到的,因為在遺留資料庫系統中實現可序列化提供了關鍵的嚴格保證,所以「可序列化」和「嚴格可序列化」之間的區別大多被忽略了。然而,在以雲為中心的分布式系統的現代世界中,這種差異是顯著的。

這篇文章首先解釋了資料庫系統中隔離的概念,然後說明了這兩個隔離級別之間的重要差異,以及應用程式設計師需要注意的「僅僅」引入可序列化系統導致的正確性bug。

假設我們有乙個售票應用程式,允許人們購買限量**活動的門票。應用程式將以下形式的事務傳送到資料儲存(當客戶嘗試買票時):

如果庫存》 0那麼

庫存=庫存-1;

過程(順序)

返回成功

否則 返回失敗fail

如果資料儲存支援acid事務,則將以原子方式處理上述**: 將處理整個訂單並減少庫存,或者訂單與庫存兩者都不處理。要麼全部處理要麼全部失敗,除此以外其他任何事情都不可能發生。

如果系統中只執行乙個事務,則顯然執行上述**不會出現任何問題。如果庫存足夠,則會處理訂單。否則,它不會。

如果允許上述**在沒有系統級保證的情況下執行,則**中存在明顯的「競爭條件」。兩個並行執行緒可以同時執行第一行,並且都看到庫存為「1」。因此,兩個執行緒都通過if條件並處理訂單,這導致庫存超賣的負面結果。

系統級保證在面對併發請求時防止這些負面結果屬於acid的i - 「隔離」。

隔離的**標準是「可序列化serializability」。保證可序列化的系統能夠同時處理事務,但保證最終結果等同於單獨處理每個事務時發生的事情,乙個接乙個地處理(序列就好像沒有併發)。這是乙個非常強大的保證,它能夠經受住時間的考驗(50年),從而能夠在其上構建健壯且無錯誤的應用程式。

可序列化隔離如此強大的原因是應用程式開發人員根本不需要推理併發性。開發人員只需單獨地關注單個事務的邏輯正確性即可。只要每個單獨的事務不能違反應用程式的語義,開發人員就可以確保同時執行其中許多事務也不會違反應用程式的語義。在我們的示例中,我們只需要確保上面顯示的6行**的正確性。只要在資料庫的任何啟動狀態下處理它們時它們都是正確的,那麼應用程式在併發時將保持正確。

儘管具有令人難以置信的可序列化能力,但確實存在更強的保證,並且保證「僅僅」依靠可序列化的資料庫實際上容易出現與併發性相關的其他型別的錯誤。

可序列化的第乙個限制是:它不限制如何選擇等效的事務序列順序。指定一組併發執行的事務,系統保證它們將被等效地處理為序列順序,但它不保證任何特定的序列順序。

結果,指定一組相同的併發事務處理的兩個副本可能最終處於非常不同的最終狀態,因為他們選擇以不同的等效序列順序處理事務。因此,「僅僅」依靠可序列化的資料庫的複製不能只複製輸入並讓每個複製事務程序同時處理輸入就可以了,這不能保證複製。

相反,乙個複製的程序必須首先處理工作負載,然後處理來自原初始程序發生的一系列狀態改變的複製,這個狀態改變的複製是原初始程序通過網路發布的,因此,資料經過網路延遲到達時間和原始程序中原始資料發生的時間有滯後性。

即使在x完成後的幾周內提交了y,這也是正確的 , 理論上可以為可序列化系統帶來y及時返回,並在x存在之前處理系統狀態(只要沒有提交的事務讀取y寫入的相同資料),從技術上講每個唯讀事務都可以返回空集(即資料庫的初始狀態),並且不會違反序列化保證,這是合法的,因為系統可以使唯讀事務「及時」返回,並在寫入資料b的任何事務之前以序列順序獲得乙個卡位。

任何使用者都不太可能使用始終為每個唯讀查詢返回空集的資料庫。那麼可序列化如何成為「**標準」?

在過去,資料庫只能在一台機器上執行。因此,資料庫系統保證隔離級別保證更強一致性要超過可序列化serializability。事實上,以至於多年來沒有人為這個強大的隔離保證保證(即使幾乎每個資料庫系統都保證它)。隔離級別最終被herlihy和wing命名為: 嚴格可序列化。

嚴格的可序列化在普通可序列化之上新增了乙個簡單的額外約束。如果事務y在事務x完成後啟動(請注意,這意味著x和y根據定義不是併發的),那麼保證嚴格可序列化的系統保證:

(1)最終狀態等同於按順序處理事務和

(2)x必須在該序列順序中的y之前。

因此,如果我要向保證嚴格可序列化的系統提交事務,我知道該事務的任何讀取都將反映由於已提交的事務(至少)到達我的事務處理時的資料庫的狀態。提交。事務可能看不到同時提交的事務的寫入,但至少它會看到在它開始之前完成的所有寫入。

當資料庫位於一台機器上時,保證嚴格的可序列化通常不會增加相對於普通可序列化的工作量。在進行交易之前,每個現有系統(乙個例外是daniel abadi博士的2023年「懶惰交易」**)必須執行該交易事務中涉及的寫入。對於稍後出現的事務,忽略這些寫入(而不是看到它們)通常比看到它們更多的工作。因此,幾乎每個在一台機器上執行的可序列化系統也保證了嚴格的可序列化。這導致了行業現狀,資料庫系統的文件表明它們保證了「可序列性」,但實際上,它們保證了「嚴格的可序列性」。

「嚴格的可序列化」保證消除了系統返回我們在上一節中討論過的陳舊/空資料的可能性。[但是,它沒有消除我們在該部分討論過的副本分歧問題。我們將在以後的帖子中回到這個問題。]

總結到目前為止:實際上,「嚴格可序列化」是資料庫系統中的**標準隔離級別。但是,只要大多數資料庫在一台機器上執行,在保證「可序列化」的系統和保證「嚴格可序列化」的系統中沒有可察覺的差異。因此,通俗地說,「可序列化」被稱為**標準,這種口語化的語義不準確性從未如此重要。

分布式系統使可序列性變得危險

在分布式系統中,從可序列化到嚴格可序列化的跳躍不再是微不足道的。

以我們的售票應用程式的簡單示例為例:

假設票證庫存在兩台機器上覆制 --a和b ----兩者都允許處理交易。客戶向機器a發出減少庫存的事務。此事務完成後,將向計算機b發出另乙個事務,以讀取當前庫存。在一台機器上,第二個事務肯定會讀取第乙個事務的寫入。但是現在他們在不同的機器上執行,如果系統不能保證一致的讀取跨機器,第二個事務很可能會返回乙個陳舊的髒值(例如,如果複製是非同步的,並且第乙個事務的寫入尚未從a複製到b,則可能會發生這種情況)。這種陳舊的讀取不會違反可序列化。它相當於第乙個事務之前的第二個事務的序列順序。但是,由於第二次交易事務是在第一次交易完成後提交的,因此肯定違反了嚴格的可序列性。

因此,當跨機器複製資料時,可序列化和嚴格的可序列化之間存在巨大而實際的差異。在選擇要使用的資料庫系統之前,終端使用者必須意識到這種差異。無法保證嚴格可序列化的分布式系統容易出現許多不同型別的錯誤。​​​​​​​

可序列化和嚴格可序列化之間的區別遠遠超過我之前示例中的「陳舊讀取」錯誤。讓我們看看可能出現的另乙個錯誤,稱為「因果反轉」。

如果您存入的金額(在您的所有賬戶中)超過5000美元,銀行會「free checking免費檢查」。愛麗絲正好5000美元,需要給孩子的保姆簽發支票,所以她將一些額外的錢轉入她的儲蓄賬戶。在確認轉移成功並且錢存入她的儲蓄賬戶後,她從她的支票賬戶中提取支票。當她看大結果時,她發現因為沒有在5000美元以上的賬戶中保持平衡而受到的處罰。

所以發生了什麼事?違反嚴格的可序列性。兩個交易—她的儲蓄賬戶的增加和她的支票賬戶的扣除被重新排序,以便在儲蓄賬戶新增之前發生支票賬戶扣除,即在加法完成之後提交減法。在僅保證普通可序列化的系統中,這種重新排序是完全可能的,但在保證嚴格可序列化的系統中是不可能的。在這種型別的示例中,這種事務重新排序是非常常見的,其中如果不相交的資料位於分布式系統中的不同機器上,則事務訪問不相交的資料(檢查餘額與儲蓄餘額)。交易事務重新排序後,alice在兩個賬戶的餘額暫時低於5000美元,這導致了處罰。如果銀行在乙個保證嚴格可序列化的系統之上構建他們的應用程式,他們將不必處理來自alice的憤怒投訴**。

揭露資料庫隔離級別的骯髒秘密:可序列性與「嚴格」可序列化區別! - matt freels

判斷衝突可序列化

在資料庫中,事務在併發排程過程中,會產生多種結果,什麼樣的排程是正確的?只有序列排程才是正確的結果。併發過程的結果只有與序列排程結果一樣的才是正確的。這種併發排程被稱為可序列化排程。可序列化是併發事務正確排程的基本準則。對於乙個併發排程,當且僅當它是可序列化的時候,才被認為是正確排程。本文主要講解判...

可序列化和自定義序列化

序列化技術的主要兩個目的是 持久化儲存 按值封送。net framework支援三種序列化器 binary xml soap.他們各有優缺點,分別列如下 1.binary序列化是完全保真的,因為除非特殊宣告為nonserialized,那麼所有成員 包括私有的和公有的 都會被序列化。該序列化器的結果...

可擴充套件的序列化協議

oceanbase的序列化協議是一種可擴充套件的協議,其基本單元為 乙個完整的資料報是形如下面的內容 例如 1 trans id 102 1024 cid 21 other abc 接收端解析方式 cpp bool more true while more www.2cto.com 通過這種方式,可...