「分散式技術專題」併發系列三:樂觀併發控制之理論研究

Hubble資料庫發表於2023-02-14

以時間軸的方式對不同時期的有代表性的論文(從理論研究、原型系統、 生產系統三個維度分類)進行了梳理,帶你簡要回顧一下 OCC在學術界及工業界的發展歷程。

這裡需要先對 OCC(Optimistic Concurrency Control)指代的概念做一個說明, 從廣義上理解,OCC表示一種樂觀併發控制的思想,只在事務提交時對事務是否符合序列化進行驗證;而悲觀併發控制(Pessimistic Concurrency Control)會對事務執行過程中的每個操作進行序列化驗證。

在這一思想的指導下,應用層的樂觀鎖也屬於 OCC;從狹義上理解,OCC特指一個具體的不依賴加鎖的併發控制技術,與2PL/TO/MVCC等處於同一個概念層次,屬於資料庫核心層。本文以下提到的OCC指代的是狹義的概念。

本文重點在於沿著 OCC發展的時間線的梳理,由於相關論文較多,作者無法深入探究每篇論文的詳細內容,僅描述了論文中的大致思想,可能也有不全面或錯誤的地方,感興趣的同學可以研讀論文原著。

前世

理論研究 ——集中式OCC

On Optimistic Methods for Concurrency Control 1981
OCC技術最早由CMU大學的H.T. KUNG教授提出,當時資料庫併發控制研究的熱點是2PL, 作者直接列舉了基於鎖的併發控制協議的五宗罪:

加鎖協議開銷大,對於不會改變資料庫約束完整性的只讀事務也需要加讀鎖保護以防止別人修改;對於可能造成死鎖的加鎖協議還需要額外增加死鎖檢測開銷
為了避免死鎖,需要定製各種複雜的加鎖協議
在持有鎖的情況下可能會等待 I/O操作,會大幅降低系統整體的併發吞吐量
加鎖事務回滾時必須持有鎖,直到事務回滾結束,降低了系統整體的併發吞吐量
只有在最壞情況下才需要加鎖;很多真實的應用場景往往是高併發低競爭的
作者據此提出了一種新的樂觀併發控制方法用於解決上述問題(所謂的樂觀是針對併發事務衝突機率極低的工作負載場景),該方法將一個事務的生命週期劃分為三個階段:

• 讀取階段
– 所有更新操作緩衝在事務本地記憶體空間中,維護事務的寫集
– 所有讀取操作先訪問事務本地記憶體空間, 若不存在則從資料庫中讀取並可選地快取在事務私有記憶體空間中, 維護事務的讀集

• 驗證階段
根據某種可序列化標準檢查待提交事務是否滿足可序列化排程

• 寫入階段(只讀事務不需要)
將事務私有記憶體中的更新資料寫入資料庫使其全域性可見

假設系統中每個事務能夠被賦予全域性唯一的事務號,則有事務號 Ti和Tj, 且Ti<Tj,可以將系統內是否存在一個與事務號順序等價的併發事務排程式列作為可序列化標準, 則檢查事務Tj是否符合可序列化(即Ti在Tj之前完成),需滿足如下三種條件之一:

Ti在Tj開始讀取階段前完成寫入階段,即Ti在Tj之前提交
Ti的寫集與Tj的讀集不相交,且Ti在Tj開始寫入階段前完成寫入階段
Ti的寫集與Tj的讀集和寫集都不相交,且Ti在Tj完成讀取階段前完成讀取階段
作者提出了兩種滿足上述條件的驗證階段實現方案:
序列方案(事務併發滿足條件 1或2)
事務開始
獲取當前已提交的事務號
事務結束
① 進入臨界區
② 獲取當前已提交的事務號
③ 驗證事務開始和結束期間提交的事務的寫集與待驗證事務的讀集是否相交
④ 相交,則發現衝突,退出臨界區並中止待驗證事務
⑤ 不相交,則驗證成功,執行寫入階段(如果是隻讀事務無需執行)並遞增提交事務號
⑥ 退出臨界區
並行方案(事務併發滿足條件 1或2或3)
事務開始
獲取當前已提交的事務號
事務結束
① 在臨界區內獲取當前已提交的事務號/獲取當前活躍事務列表/將自身加入活躍事務列表
② 驗證事務開始和結束期間提交的事務的寫集與待驗證事務的讀集是否相交
③ 驗證活躍事務(這些活躍事務均已完成讀取階段,讀集和寫集不會再發生變化,可理解為進入驗證的事務列表)的寫集與待驗證事務的讀集和寫集是否相交
④ 相交,則發現衝突,在臨界區內將本事務從活躍事務中去除並中止待驗證事務
⑤ 不相交,則驗證成功,執行寫入階段(如果是隻讀事務無需執行)
⑥ 在臨界區內遞增提交事務號並將本事務從活躍事務中去除
在系統實現中,還需要考慮兩種特殊情況的解決方案:
長事務
根據上述規則,需要檢查長事務開始時未提交的事務的寫集。由於資料庫系統只能維護有限的事務寫集,作者建議只維護最近事務的寫集, 如果驗證時無法找到事務號對應的寫集,則中止待驗證事務並重新執行。
餓死現象
驗證失敗時事務需要中止並重新執行,存在一種極端情況使得事務持續地中止並重新執行, 作者建議記錄事務的失敗驗證次數,若超過一定閾值,則在臨界區內重新執行事務, 徹底排除其它併發事務的干擾。
顯然,上述方案都是針對單資料版本的集中化資料庫系統,在分散式資料庫系統中的 OCC演演算法還有待後人擴充套件。

理論研究 ——分散式OCC

Optimistic Methods for Concurrency Control in Distributed Database Systems 1981
Problems of Optimistic Concurrency Control in Distributed Database Systems 1982
這兩篇論文提出了將原集中化資料庫系統中的 OCC應用到分散式資料庫系統中的解決方案,第一篇論文的內容始終無法找到,本文猜測其基本思想為:
• 讀取階段與集中化資料庫系統中的方案類似
• 全域性事務的驗證階段可以分解為每個結點上的本地子事務的驗證階段,如果所有的子事務驗證透過,則全域性事務驗證透過
• 驗證和寫入階段與分散式系統中的2PC結合,驗證屬於prepare階段,寫入屬於commit階段
作者緊接著在第二篇論文中指出了 OCC在分散式系統中面臨的兩個關鍵問題及可能的解決方案:
• 問題一
全域性事務的驗證階段和寫入階段無法保證在臨界區內順序執行
可能的解決方案
– 強制前一個事務完成寫入階段後才能開始下一個事務的驗證階段
– 採用論文[1]的並行版本
• 問題二
全域性事務中各本地子事務的驗證階段採用的可序列化標準可能不一致
可能的解決方案
使用全域性事務號保證各結點在驗證階段使用相同的可序列化標準

理論研究 ——BOCC和FOCC

Observations on optimistic concurrency control schemes 1984
對論文 [1]中OCC的序列版本進行了擴充套件,由此歸類出兩種OCC驗證方案:
• BOCC(論文[1]方案)
檢查待驗證事務的讀集是否與事務讀取階段完成的事務的寫集有交集
• FOCC
檢查待驗證事務的寫集是否與當前活躍事務的讀集有交集
BOCC有如下缺點:
• 只讀事務也需要驗證階段
• 只能中止當前驗證事務
• 待驗證事務的讀集可能很大
• 對於長事務可能需要保留大量期間已提交事務的寫集
反之, FOCC有如下優點:
• 只讀事務無需驗證階段
• 只需與當前有限的活躍事務進行驗證且驗證事務的寫集通常情況下較小
• 靈活的衝突策略,可選擇延遲或中止驗證事務,也可選擇中止衝突事務
同時,作者從實現角度列舉了 OCC的一些通用問題:
• 高事務中止率
• 依賴同步機制避免事務餓死
• 讀集/寫集的維護浪費記憶體空間
• 讀取階段看到的資料庫檢視不一致
• 幻讀問題不好解決
• 行粒度OCC讀取階段資料可能不一致
• 行粒度OCC寫入階段開銷可能很大
• 行粒度OCC查詢階段流程複雜
• 頁面粒度OCC會浪費空間並增大沖突中止機率
這篇論文總體看來對 OCC的評價是負面的,但羅列出的通用問題也為後續的OCC研究者指出了改進的方向。

 

以上為分散式技術專題之併發系列三:樂觀併發控制之理論研究, 「分散式技術專題」是國產資料庫 hubble 團隊精心整編,專題會持續更新,歡迎大家保持關注。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026685/viewspace-2935042/,如需轉載,請註明出處,否則將追究法律責任。

相關文章