巨杉數據庫SequoiaDB】巨杉Tech | SequoiaDB 分布式事務實現原理簡介


1

分布式事務背景

隨着分布式數據庫技術的發展越來越成熟,業內對於分布式數據庫的要求也由曾經只用滿足解決海量數據的存儲和讀取這類邊緣業務向核心交易業務轉變。分布式數據庫如果要滿足核心賬務類交易需求,則其需要完善分布式事務,向傳統關系型數據庫看齊。即分布式事務的實現也需要像傳統關系型數據庫的事務一樣滿足事務的標准要求及定義,即ACID特征。

分布式數據庫的數據是進行多機器多節點分散存儲的,這樣的存儲架構為實現分布式事務帶來了極大的難度。數據事務操作時,事務操作會結合數據分布情況,到不同的存儲位置上去執行,而這個存儲位置位於網絡中的不同機器的不同磁盤上。

 

2

事務基本概念

2.1 事務使用場景

銀行應用是一個經典案例,可以解釋事務應用的必要性。假設銀行數據庫有兩張表,支票賬戶表(check)和存款賬戶表(save)。現在要從LiLei的支票賬戶里轉賬200元到她的存款賬戶,那么需要至少完成3步操作:

1. 檢查支票存款賬戶的余額是否大於200元;

2. 從支票存款賬戶余額中減去200元;

3. 在存款賬戶余額中增加200元;

所有的操作被打包在一個事務里執行,如果某一步失敗,就回滾所有已完成步驟。事務操作一般用 START TRANSACTION 語句開始一個事務,用 COMMIT 語句提交整個事務,永久地修改數據,或者用 ROLLBACK 語句回滾整個事務,取消已做的修改。事務SQL操作樣例如下:

START TRANSACTION;SELECT balance FROM check WHERE customer_id = 10233276 ; UPDATE check SET balance = balance - 200.00 WHERE customer_id = 10233276; UPDATE save SET balance = balance + 200.00 WHERE customer_id = 10233276; COMMIT;

此為銀行對於轉賬類的交易所必須使用的事務操作場景,而在實際的生產環境中,事務操作的復雜度比這復雜得多。

2.2 事務概念和特性

事務是訪問及操作數據庫各類數據項的操作序列集合,如各類增刪改查 SQL 操作組合。它通常由 begin transaction 和 end transaction 語句來界定。

數據庫系統的事務需包含以下特性:

  • 原子性(Atomicity):事務的所有操作在數據庫中要么全部執行成功,要么全部執行失敗。

  • 一致性(Correspondence):事務操作前后,數據的完整性必須保持一致。

  • 隔離性(Isolation):多個用戶並發訪問數據庫時,數據庫為每個用戶開啟事務,不能被其他事務的操作數據所干擾。即每個事務都感覺不到系統中有其他事務在並發地執行。

  • 持久性(Durability):一個事務成功完成后,它對數據庫的改變必須是永久的,即使出現系統故障也不會對事務有影響。

事務隔離級別

針對事務隔離,SQL標准定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。下面介紹四種隔離級:

  • READ UNCOMMITTED(讀取未提交內容)

在READ UNCOMMITTED隔離級別,所有事務都可以“看到”未提交事務的執行結果。讀取未提交數據,也被稱之為“臟讀”。

  • READ COMMITTED(讀取提交內容)

大多數數據庫系統的默認隔離級是read committed。它滿足了隔離的早先單定義:一個事務在開始時,只能“看見”已經提交事務所做的改變,一個事務從開始到提交前,所做的任何數據改變都是不可見的,除非已經提交。此隔離級別不支持“可重復讀”的操作。這意味着用戶運行同一語句兩次,看到的結果是不同的。

  • REPEATABLE READ (可重讀)

REPEATABLE READ隔離級解決了READ UNCOMMITTED隔離級導致的問題。它確保同一事務的多個實例在並發讀取數據時,會“看到同樣的”數據行。不過理論上,這會導致另一個棘手問題:幻讀(Phantom Read)。簡單來說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影”行。數據庫存儲引擎可以通過多版本並發控制 (Multiversion Concurrency Control)機制解決了幻讀問題,如MySQL的InnoDB和Falcon。

  • SERIALIZABLE (可串行化)

SERIALIZABLE是最高級別的隔離級,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,SERIALIZABLE是在每個讀的數據行上加鎖。在這個級別,可能導致大量的超時現象和鎖競爭現象。數據庫應用中很少看到有用戶選擇這種隔離級。但如果用戶的應用為了數據的穩定性,需要強制減少並發的話,也可以選擇這種隔離級。

 

3

分布式事務

分布式事務的實現需要保證事務的原子性、一致性、隔離性和持久性,而實現此ACID屬性的基本技術思路有:

  • 通過“兩階段提交(Two-phase Commit,2PC)”協議實現事務的原子性、一致性和持久性等屬性;

  • 隔離性級別的實現通常使用多版本並發控制機制來保證。實現多版本並發控制常用的方式是“快照隔離(Snapshot Isolation)”技術;

下面先分別介紹一下這兩個概念。

3.1 兩階段提交

兩階段提交(Two-phase Commit,2PC)是為了使基於分布式系統架構下的所有節點在進行事務提交時保持一致性而設計的一種協議。

兩階段提交算法的成立基於以下假設:

  • 該分布式系統中,存在一個節點作為事務協調器,其他節點作為事務管理器,且節點之間可以進行網絡通信。

  • 所有節點都采用預寫式日志(Write Ahead Log),且日志被寫入后即被保持在可靠的存儲設備上,即使節點損壞不會導致日志數據的消失。

  • 所有節點不會永久性損壞,即使損壞后仍然可以恢復。

以下對二階段提交算法分階段進行說明。

第一階段(提交請求階段)

事務協調器節點向所有事務管理器節點詢問是否可以執行提交操作,並開始等待各事務管理器節點的響應。事務管理器節點執行詢問發起為止的所有事務操作,並將Undo信息和Redo信息寫入日志。

各事務管理器節點響應事務協調器節點發起的詢問。如果事務管理器節點的事務操作實際執行成功,則它返回一個“同意”消息;如果事務管理器節點的事務操作實際執行失敗,則它返回一個“中止”消息。有時候,第一階段也被稱作投票階段,即各事務管理器投票是否要繼續接下來的提交操作。

第二階段(提交執行階段)

成功的情況

當事務協調器節點從所有事務管理器節點獲得的相應消息都為“同意”時:

1. 事務協調器節點向所有事務管理器節點發出“正式提交”的請求。

2. 事務管理器節點正式完成操作,並釋放在整個事務期間內占用的資源。

3. 事務管理器節點向事務協調器節點發送“完成”消息。

4. 事務協調器節點受到所有事務管理器節點反饋的“完成”消息后,完成事務。

失敗的情況

如果任一事務管理器節點在第一階段返回的響應消息為“中止”,或者事務協調器節點在第一階段的詢問超時之前無法獲取所有事務管理器節點的響應消息時:

1. 事務協調器節點向所有事務管理器節點發出“回滾操作”的請求。

2. 事務管理器節點利用之前寫入的Undo信息執行回滾,並釋放在整個事務期間內占用的資源。

3. 事務管理器節點向事務協調器節點發送“回滾完成”消息。

4. 事務協調器節點受到所有事務管理器節點反饋的“回滾完成”消息后,取消事務。

有時第二階段也被稱作完成階段,因為無論結果怎樣,事務協調器都必須在此階段結束當前事務。

事務協調器和事務管理器之間的通信流程的示意圖:

​ 

兩階段提交算法的最大缺點就在於:它的執行過程中間,節點都處於阻塞狀態。即節點之間在等待對方的相應消息時,它什么也做不了。特別是,當一個節點在已經占有了某項資源的情況下,為了等待其他節點的響應消息而陷入阻塞狀態時,當第三個節點嘗試訪問該節點占有的資源時,這個節點也將連帶陷入阻塞狀態。

另外,事務協調器節點指示事務管理器節點進行提交等操作時,如有事務管理器節點出現了崩潰等情況而導致事務協調器始終無法獲取所有事務管理器的響應信息,這時事務協調器將只能依賴事務協調器自身的超時機制來生效。但往往超時機制生效時,事務協調器都會指示事務管理器進行回滾操作。這樣的策略顯得比較保守。

 

3.2 快照隔離

快照隔離(Snapshot Isolation)技術是實現多版本並發控制的技術之一。此技術策略的前提就是每條數據都要支持版本化,事務對數據的每次寫操作成功提交后(更新、插入、刪除)都會生成該數據的一個新版本。這里有一個概念,就是寫操作成功提交之后,才會生成數據的新版本。在寫操作沒有成功提交之前,對數據的任何修改,都不算生效的。

什么是快照Snapshot呢?簡單來說就是在某個特定時刻T1,數據庫里面所有數據最新版本的集合。舉個例子,比如數據庫里面只有3條記錄,它們在時間戳T1的時候,狀態如下:

 

即 row1[version 10],row2[version = 1], row3[version=19] 就形成了數據庫在T1時刻的快照。過了幾分鍾之后,到了時間T2,如果在T1和T2之間沒有寫操作成功提交,那么數據庫的狀態沒有變化,即T1時候的快照和T2時候的快照是相等的。再過了幾分鍾之后,到了時間T3,在T2和T3之間,有一條對row2的更新操作、一條對row3的刪除操作、一條row4的插入操作成功提交了,數據庫中的數據狀態變成了: 

​ 

即 row1[version 10],row 2[version = 2], row3[version=20],row4[version=1] 就構成了數據庫在T3時間的快照。因為每條記錄的版本變更是不一樣的,所以需要注意數據版本的變更情況。

另外,請注意在數據多版本的要求下,刪除操作並不是真的刪掉row3,而是生成了一個row3的新版本。在實際實現中,數據庫不一定是按上面示例的一樣把值賦值成null,也可能用一個特殊的標志位標識這是一個“刪除”的版本。

快照永遠和特定的時間相關,脫離時間談論快照是沒有意義的。如果在一段時間內,數據庫沒有任何寫操作成功提交,那么這段時間內,數據庫在任意時間的快照都是相等的。所以,我們可以認為,每一個有包含寫操作的事務成功提交,都會形成數據庫的一個不同的快照。在很多數據庫實現中,version直接使用時間戳,而不是上面例子中的數字。

每個事務在啟動時,都會記錄當時的時間作為啟動時間戳Start-Timestamp。該事務只能讀取啟動時間戳那個時刻的數據快照。然后每個事務在提交時,會記錄當時時間作為提交時間戳Commit-Timestamp,當該事務成功提交后,會形成一個Commit-Timestamp的數據快照。后續啟動的事務才能看到該事務寫的數據(如果該事務有寫操作)。

 

​ 

上圖中,三條橫線代表三個事務。事務T2是看不到事務T1寫的任何數據的,因為事務T2啟動時,事務T1還沒有提交。而事務T3可以看到事務T1和事務T2寫的數據,因為它啟動的時候,事務T1和事務T2都提交了。

快照隔離(Snapshot Isolation)需要通過鎖機制來防止寫沖突,對於讀操作,不加鎖。如果多個事務同時寫一個數據,鎖機制保證最多只有一個事務能提交成功。由於對讀操作不加鎖,Snapshot Isolation的性能會顯著提高。

 

4

SequoiaDB 分布式事務實現

4.1 基本概念和定義

為了實現分布式事務,巨杉數據庫通過采用全局時間來實現全局事務對跨數據分片的事務的協調和管理。基於此需求,為了確定全局時間,巨杉數據庫定義了時間戳的相關概念與定義,引入了時間戳管理機制。具體的定義如下:

  • LLT(Local Logical Timestamp):每個節點(CATALOG、COORD、DATA)維護自己的本地邏輯時間(最小單位:microsecond)

  • ULT(Universal Logical Timestamp): 定義CATALOG主節點的本地時間為全局邏輯時間(最小單位:microsecond)

  • LRT(Local Real Timestamp):本地UTC時間

為了保證整個集群全局時間的一致與准確,協調節點(COORD)和數據節點(DATA)需要定時與編目節點(CATALOG)的主節點進行時間同步。而同步時間定義了以下規則:

1. CATALOG主節點的LLT(即ULT)通過所有機器的CPU Tick計算

2. 其它節點的LLT通過與CATALOG主節點進行同步ULT來維護

3. 同步的間隔為ULTSyncInterval(默認:60秒)

4. 同步結果需要使用差小於全局容忍誤差ULTTolerance(默認: 1ms)

5. ULTTolerance根據時間差同步、網絡狀態進行動態調整

全局時間的定義及規則確認之后,則可以將其用於分布式事務的實現當中。分布式事務采用二段提交機制實現,結合二段提交的原理,定義了以下幾類事務時間:

  • TBT(Transaction Begin Timestamp):事務開始時間

  • TPCT(Transaction Pre-Commit Timestamp):事務的預提交(precommit)時間

  • TCP(Transaction Commit Timestamp):事務的提交時間

其中,同一個事務的TBT和TPCT之間需要有一個事務時間間隔,此間隔取當時ULTTolerance。事務時間間隔也可以定義為不同節點發起的事務時間之間的最小可以容忍的誤差。即如果兩個不同節點的事務時間之間相關小於事務時間間隔,即認為這兩個事務時間有誤差的情況下相等。

 

4.2 二段提交實現

巨杉數據庫對於分布式事務采用的是經典二段提交(2PC)方式實現的。其采用全局時間來實現全局事務的統一協調管理,使分布式集群中的不同節點進行事務的統一操作。在整個事務操作過程中,客戶端發起的事務分為三個部分:

第一部分:事務開始。在這一部分的操作中,客戶端向數據庫服務器發起“事務開始”的請求。數據庫服務器結合其本地邏輯時間生成一個事務開始時間,並記錄在案。

第二部分:事務的增刪改查操作。此部分是整個事務原子包的系列操作,它包含增刪查改四類基本數據操作。在執行事務原子包里面第一條SQL語句時,分布式集群需要判斷和校驗協調節點和數據節點之間的時間差值。如果此差值大於延時容忍值,則要求COORD節點、DATA節點向CATALOG主節點發起時間同步,然后再重新發起SQL操作。如果時間差在容忍范圍內,則直接執行。第一條事務操作執行成功后,說明時間比對成功,接下來的操作則直接執行。

第三部分:事務完成。此部分為事務的結束部分。在此部分中,整個事務執行完成,開始發起事務提交的操作。此操作進入事務的二段提交階段,即先預提交,預提交成功之后再提交一次,整個提交流程才完成。

巨杉數據庫事務實現的具體流程如下圖:

 

4.3 並發控制技術

巨杉數據庫對於多版本控制(MVCC)技術是通過采用事務鎖、內存老版本以及磁盤回滾段重建老版本的設計來實現。此架構設計的理論基礎是通過對內存結構的合理利用,存儲數據和索引的老版本信息,從而實現數據的快速的並發訪問。

此架構的基本原則是:充分利用內存結構緩存老版本以提高讀的訪問速度,同時結合事務可視性條件和MVCC來滿足全局事務的不同隔離級別(RC/RR)的訪問要求。在MVCC的實現中,巨杉數據庫也平衡兼顧運行時的效率和多版本存儲空間的使用,以及回收的開銷。

在多版本控制技術的事務鎖實現中,RR(可重復讀)配置下的讀操作可以在使用完記錄之后立即釋放鎖,不需要一直持有,直到事務提交或者回滾。但是寫事務操作則需要一直持有插入、更改和刪除的鎖,直到事務完成提交或者回滾。巨杉數據庫鎖的實現是采用悲觀鎖機制,與傳統關系型數據庫的采用的主流鎖機制類似。

在多版控制技術的實現中,除了引入悲觀鎖的機制以外,巨杉數據庫還采用了內存老版本機制提升數據庫並發訪問及操作的能力。內存老版本是通過在記錄鎖上附加有一個存儲原版本數據和索引相關的結構,於內存中存儲了老版本的數據。

所有事務寫操作(修改,刪除,插入)會在該結構中保存一個事務開始前的記錄的拷貝,還包含所有改動過索引的原始版本。當讀者試圖獲取記錄鎖時,如果記錄正在被修改,讀者取鎖失敗時將通過回調函數獲得該鎖的老版本結構,從而獲取上次提交后的數據。在事務提交時,釋放記錄鎖之后異步回收存儲老版本記錄和索引的空間,用戶可以選擇打開異步刪除涉及到的待刪除數據。同時在該鎖或記錄被下一個寫操作用到時,他們都會被同步回收。其中老版本的結構如下:

 

 

巨杉數據庫在實現多版本並發控制技術時,除了采用事務鎖和內存老版本機制外,還采用了磁盤回滾段對並發控制策略進行了完善與補充。眾所周知,內存是高速存儲設備,但是其存在存儲空間比較小以及斷電數據丟失的問題。針對此問題,磁盤回滾段機制通過將內存中的“老版本數據”持久化到磁盤上,保證數據庫在掉電等異常情況下不會影響事務的正常操作。

回滾段使用系統集合空間,名為”SYSRBS”。另外,其內部會使用1個集合,命名格式為”SYSRBSXXXX”,其中XXXX為循環編號,范圍為0~4096。同時,回滾段使用第一個集合(即:SYSRBS0000)存儲RBS的元數據,包括當前RBS集合和最后空閑RBS集合。巨杉數據庫會在啟動時檢查是否支持MVCC,如果支持,則會檢查”SYSRBS”集合空間是否存在,不存在的話則會創建此集合空間,同時創建 SYSRBSCL0000 和 SYSRBSCL0001 集合。如果回滾段的集合空間和集合均存在,則會從 SYSRBSCL0000 中讀取元數據信息,根據當前RBS集合和最后空閑RBS集合信息創建下一下 SYSRBSCLXXXX。

為了更進一步提高讀取速度,巨杉數據庫將磁盤回滾段與內存老版本相結合,最新的老版本還是掛在記錄鎖的 oldversionContainer 上,其它更老的版本放磁盤上。這樣滿足大多數據短事務只用讀內存的老版本,無需再讀磁盤,從而提供了讀取速度。考慮到主節點異常的情況,多版本控制需要將記錄老版本數據的回滾段也同步至備節點,當備節點升為主節點后,可以通過回滾段重建老版本。

當事務ID小於全局最小事務ID(lowTranID)時,數據庫后台的異步線程負責回收老版本記錄和索引節點內存。內存老版本清理時要將其保存的老版本寫入RBS。而磁盤老版本的清理則是從最后空閑集合(lastFreeCL)開始,逐個對比表的最大事務ID(MaxGTID),如果小於全局最小事務ID,則可以刪除這個表(即SYSRBSCLXXXX)。

 

5

總結

巨杉數據庫通過采用事務鎖、內存老版本以及磁盤回滾段重建老版本的設計來實現了多版本並發控制技術。此設計通過對內存結構的合理利用,存儲數據和索引的老版本信息,從而實現多版本數據的快速的並發訪問。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM