揭秘MySQL生态重要功能,X-Engine引擎核心能力——OnlineDDL
簡介:?作者:雁閑、無哈,阿里云數據庫技術專家
概述
X-Engine是阿里自研的數據庫存儲引擎,以插件的方式接入到MySQL生態,支持行鎖,事務,MVCC等OLTP場景的核心功能。
X-Engine的核心優勢是低成本,高性價比,尤其適用于歷史庫場景,目前阿里巴巴內部的核心交易歷史庫(原來是Hbase),釘釘消息歷史庫(原來是MySQL(InnoDB)),淘寶商家的圖片空間等業務均通過X-Engine解決了成本問題。
同時,X-Engine也賦能阿里云數據庫服務,作為云上RDS-MySQL的存儲引擎,對外售賣,讓更多的用戶享受到新技術帶來的紅利,有關X-Engine的詳細介紹,請移步2019年10月的數據庫內核月報。本文主要介紹X-Engine引擎的一個核心功能,OnlineDDL。
OnlineDDL毫無疑問是MySQL生態的一個重要的功能,想當初MySQL 5.6以前,DBA執行DDL變更時,為了保證7*24小時服務,只能采用最老土的主備切換的方式來進行。數據庫存儲引擎區別于NoSQL引擎的一種重要指標就是是否支持SQL,是否有schema(數據字典)。有了schema,還需靈活地支持在線變更,這樣才能從容應對業務快速變化的需求。MySQL生態中這么多存儲引擎只有InnoDB完整地支持了OnlineDDL,X-Engine作為MySQL生態的新成員,雖然采用了完全不同于InnoDB的存儲架構,但OnlineDDL給用戶的體驗是一樣的 。
整體流程
X-Engine采用類LSM的分層架構,數據按照時序邏輯分成多層,每一層數據有序,新數據在較高的層次,最老的歷史數據在最底層。對于X-Engine來說,每個主表和二級索引數據都是一棵分層的LSM-tree結構,內部稱之為Subtable。每個Subtable分為4層,Memtable,L0,L1和L2,每一層都保持有序,數據按新舊順序依次往更深的層次遷移,其中Memtable在內存中,其它幾層按需可以在不同的存儲介質上。OnlineDDL功能實現充分利用了X-Engine的數據組織特點,將新build數據分為兩部分,基線數據和增量數據。基線數據是指變更開始時,通過拿snapshot能遍歷得到的數據;增量數據是指,變更開始后,用戶寫入的新數據。拿Snapshot過程需要短時間禁寫,因為我們強依賴這個一致性位點,確保基線+增量數據的完整性。
OnlineDDL總共包括了4個階段,包括Prepare階段,Inplace-build階段,Commit階段和Post-ddl階段。
1、Prepare階段,這個階段主要是準備數據字典,構建底層存儲數據的Subtable,為后續的增量寫入做準備。
2、 Inplace-build階段,這個階段OnlineDDL的核心階段,一方面通過Snapshot獲取基線,另一方面還需要實時維護增量數據,利用X-Engine的數據組織的append-only特性,將基線和增量合并,即完成了OnlineDDL新數據構建的過程。這個過程的詳細邏輯會在下一個小節詳細介紹。
3.、Commit階段,這個階段是OnlineDDL引擎層變更生效階段,如果整個OnlineDDL過程中沒有出現異常或錯誤,那么Commit階段會生效新的數據字典,生效新的數據。
4、 Post-ddl階段,這個階段是OnlineDDL真正生效階段,這個階段完成后,才會返回給用戶DDL成功。這個階段的引入,主要是因為MySQL通過Server層+引擎層這樣的一個二層結構實現擴展,而每一層都有自己的數據字典,在Commit階段只能保證引擎層的數據和數據字典是完整的,為了保證DDL變更的原子性(Server層和引擎層數據字典保持一致),引入Post-ddl階段做清理和善后工作,有關DDL原子性的討論會在下面的章節詳細介紹。
核心邏輯
OnlineDDL的核心邏輯在于如何做到執行DDL變更時,不堵塞用戶對該表的DML和SELECT操作。X-Engine實現OnlineDDL有兩個關鍵點,第1,利用X-Engine的數據組織append-only特點,增量維護在Memtable,L0,L1中,而基線數據維護在L2中;第2,維護增量時,采用雙寫,同時維護old-table和new-table中的數據。與InnoDB引擎類似,根據DDL是否涉及到數據記錄格式變更,將DDL變更分為Inplace-rebuild和Inplace-norebuild兩種類型。對于X-Engine來說,兩者本質是一樣的,區別在于維護的索引個數。Inplace-rebuild類型的DDL需要同時維護new-table中所有索引;而Inplace-norebuild類型的DDL只需要維護new-table的新增的索引。
整個Inplace-Build按照時間序有3個關鍵節點,t0時刻是獲取快照的時間點,t1時刻是build基線完成的時間點,t2時刻是唯一約束檢查完成的時間點。那么兩個階段的主要邏輯如下:t0-->t1主要工作是在build新表的基線,通過將old-table的數據結合new-table的數據字典生成新的記錄,最終寫入新表對應的L2層;在build新表基線的過程中,產生的增量寫入到新表的(Mem,L0,L1)。DDL過程中,需要對后臺的Compaction任務做一定的控制,確保不執行合并到L2的Compaction任務。t1-->t2是唯一性校驗階段,確保新增的主鍵或者唯一索引的唯一性,t2時刻將(Mem,L0,L1,L2)中的數據合并,最終得到new-table的全量數據。記錄轉換的過程如下:
其中,DDL事務表示DDL線程,它的任務是掃描基線,生成新表的基線數據;DML事務表示DDL過程中,并發的DML事務,它們的任務是,通過雙寫機制同時維護新表和老表的增量。
對比InnoDB實現邏輯
雖然X-Engine與InnoDB的OnlineDDL都是采用基線+增量的方式實現,但具體邏輯是不同的,主要是因為InnoDB采用的的是原地更新操作并且通過row-log機制來維護增量,而X-Engine是一個append-only的存儲引擎,天然地支持數據的多版本存儲,可以實時維護增量數據,在基線建立完成后只需要將基線與增量數據合并,即使基線中的數據在增量中被修改,但增量中數據的版本比基線數據版本更新,從而在合并時會覆蓋基線中老版本的數據。下圖是InnoDB引擎OnlineDDL過程。
可以看到InnoDB引擎的OnlineDDL也包括3個關鍵時間點,與X-Engine引擎的區別在于,t1-->t2 是InnoDB追row-log過程,而對應X-Engine是唯一約束檢查的過程。當然對于X-Engine來說,t1-->t2不是必需的,因為DDL變更可能并不涉及唯一索引操作。
Instant-DDL
與MySQL8.0(InnoDB)類似,X-Engine同樣也支持Instant-DDL。在所有支持的OnlineDDL中,若DDL操作只涉及修改表的屬性信息,或只是做了加列操作,不需要修改記錄格式,也不需要新增索引,那么這些OnlineDDL操作可以優化成Instant-DDL。這些DDL操作可以“極速”完成,用戶基本無感知。由于Instant-DDL執行時,并沒有真正涉及引擎數據的修改,為了后續查詢結果和DDL操作的正確性,需要對于引擎的記錄格式做一定的調整,加一些控制元信息。新增一個1字節來標示生成這個記錄時,表是否執行過instant-ddl。同時,生成記錄時,還需要記錄有多少個列是已有的,以及有多少個null列等;在讀取解析記錄時,根據字典信息,就能知道有多少個列是需要根據instant列信息來補充,確保instant-DDL后,返回查詢結果的正確性。
DDL原子性保證
從OnlineDDL的整體流程中我們了解到,OnlineDDL最后一個階段是Post-ddl階段。MySQL8.0以前,Server層的元數據都是通過文件來存儲,比如frm文件,par文件以及trg文件等。一個DDL操作修改,涉及到文件修改,引擎數據修改以及引擎字典的修改,這些操作無法做成一個事務,必然導致整個DDL操作無法做到原子性。若DDL過程中出現異常,就可能會導致Server層和引擎層數據不一致,以及殘余的垃圾沒有清理等問題。MySQL8.0將Server層的所有字典信息統一存儲在DD(DataDictionary)中,并且通過InnoDB引擎存儲,那么DDL過程中,我們只要保證Server層數據字典的修改,以及引擎層數據字典的修改封裝成一個事務即可。
對于InnoDB引擎而言,DD數據字典操作,InnoDB引擎數據字典操作都是通過InnoDB引擎存儲,通過InnoDB事務特征來保證原子性。對于X-Engine引擎而言,DD數據字典操作,X-Engine引擎數據字典操作分別采用InnoDB引擎和X-Engine引擎,除了依賴于InnoDB和X-Engine自身是事務引擎特征,還需要借助于內部的2PC協議來保證整個事務的原子性。如果MySQL開啟了binlog,那么就是binlog,X-Engine,InnoDB三者一起通過2PC協議保證事務的原子性。而Post-ddl階段就是做善后和清理工作,如果最終整個事務提交,Post-ddl階段負責真正清理old-table數據;如果最終整個事務回滾,那么Post-ddl階段負責清理臨時產生的new-table數據,確保DDL變更前后,數據庫的狀態是一致的。
使用體驗
X-Engine作為MySQL的一個新引擎,在語法使用層面完全與MySQL(InnoDB)相同,通過algorithm_option指定Online類型,通過lock_option指定DDL過程中,是否允許其它并發的DML和SELECT操作。通常情況下,這兩個選項都不用特別指定,采用默認值即可,MySQL內部會優先選擇Instant類型和Inplace類型,對于不支持Online的DDL操作,選擇Copy類型。在功能層面也與MySQL(InnoDB)相同,目前X-Engine暫時還不支持全文索引,虛擬列,外鍵等功能,因此與這些功能相關的DDL操作會不支持,其它DDL操作與MySQL(InnoDB)相同。常用的DDL操作分類如下:
后續工作
X-Engine作為一個新的數據庫存儲引擎,通過集團業務場景的打磨,已經體現了它的價值,我們希望通過云上RDS場景,讓更多用戶享受到新技術帶來的紅利。當然,目前X-Engine還有一些不足,尤其是相對于傳統成熟的MySQL(InnoDB)和Oracle,所以X-Engine引擎在優化自身的穩定性和性能同時,會持續不斷地豐富數據庫功能,包括支持外鍵,全文索引,虛擬列等。除了公有云的RDS輸出,基于X-Engine的一體化分布式數據庫PolarDB-X也是一個重要方向,我們會以專有云形式輸出,服務更多對分布式數據庫有強需求的用戶。
總結
以上是生活随笔為你收集整理的揭秘MySQL生态重要功能,X-Engine引擎核心能力——OnlineDDL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人工智能改变生活的 10 种方式
- 下一篇: 从上千篇论文脱颖而出,支付宝论文凭什么获