PolarDB MySQL版最佳化了B-tree索引的並發控制機制,有效地提升了高並發讀寫情境下的效能。本文介紹了B-tree並發控制最佳化的使用方法和使用該機制的限制和前提條件等內容。
背景資訊
InnoDB引擎使用索引來組織表結構,每張表的資料均放在一個對應的叢集索引(Clustered index)中,表中的其他索引稱之為二級索引(Secondary Index)。InnoDB使用B-tree作為索引結構,扁平且平衡的樹結構可以保證單次訪問資料的IO次數較少且固定。
InnoDB採用加鎖的方式對物理頁(B-tree節點)的記憶體結構進行並發存取控制。每個物理頁都有一個對應的讀寫鎖(RW latch),而B-tree由多個節點和邊組成,從整體上來看,對單個節點加鎖並不能保證多線程訪問時的讀寫一致性。例如,一個線程在做B-tree結構調整(SMO)時改動了多個物理頁,此時,若有其他線程訪問該B-tree結構,會訪問到不正確的B-tree結構從而導致資料讀寫錯誤。
為瞭解決上述的資料讀寫錯誤問題,InnoDB採用同時持有多個節點鎖的方式來保證B-tree並發讀寫的一致性,並設計了加鎖規則以防止多個線程訪問B-tree結構時出現死結的問題。在B-tree並發控制演算法的實現上,InnoDB進行了多次最佳化迭代,改進的目的都是為了提高B-tree的並發讀寫能力,但目前仍然存在以下問題:
SMO無法並發:即同一時刻只允許一個SMO執行,導致在高並發讀寫情境下index latch成為全域的瓶頸點。
線程加鎖範圍大:為了避免死結,樂觀操作要持有遍曆路徑上所有節點的S鎖,悲觀操作要持有所有可能修改節點的X鎖。線程加鎖範圍大,且並發越高越會加劇鎖與鎖之間的競爭,尤其在一些關鍵節點的競爭會更明顯。
PolarDB MySQL版針對性地最佳化了B-tree索引的並發控制機制,具體最佳化點如下:
提升並發度:允許所有操作並發訪問B-tree,將線程間的衝突控制在Page層級。
降低鎖粒度:所有的操作都實現了latch coupling,縮小加鎖範圍,降低線程間的衝突。
使用限制
該最佳化只針對B-tree主索引和二級索引,不包括全文索引和空間索引等。
使用B-tree並發控制最佳化機制時,需要將參數
innodb_adaptive_hash_index
的值設定為OFF。
版本限制
PolarDB MySQL版產品版本為企業版或標準版,且資料庫引擎版本需滿足如下要求:
資料庫引擎版本為8.0.1,且小版本為8.0.1.1.28及以上。
資料庫引擎版本為8.0.2,且小版本為8.0.2.2.17及以上。
您可以通過查詢版本號碼來確認叢集版本。
使用方法
登入PolarDB控制台。將參數loose_innodb_polar_blink_tree
的值設定為ON來開啟B-tree並發控制最佳化機制。設定參數值的具體操作請參見設定叢集參數和節點參數。loose_innodb_polar_blink_tree
參數的具體說明如下表:
參數名稱 | 層級 | 參數說明 |
loose_innodb_polar_blink_tree | Global | B-tree並發控制最佳化機制控制開關。取值範圍如下:
|
該最佳化機制預設關閉,修改參數loose_innodb_polar_blink_tree
的值後會自動重啟叢集,通常情況下,重啟時服務閃斷時間在一分鐘以內,具體時間與資料量和表數量相關,建議您在業務低穀期進行操作,並確保應用程式具備重連機制。
效能測試
在高並發TPCC情境(1000 warehouse)下,開啟和關閉B-tree並發控制最佳化機制的效能如下所示:
未開啟B-tree並發控制最佳化機制時,InnoDB在並發數為128時達到了效能峰值。
開啟B-tree並發控制最佳化機制後,InnoDB在並發數為256時達到了效能峰值,較未開啟B-tree並發控制最佳化機制時的讀寫效能提升了140%。