本文分享自華為雲社群《【GaussTech技術專欄】GaussDB邏輯解碼技術原理》,作者:GaussDB 資料庫。
1.背景
隨著國內各大行業數字化改造步伐的加快,異構資料庫資料同步的需求場景越來越多。
異構資料庫同步,即將不同型別、不同結構的資料庫之間的資料進行同步處理,以確保資料在不同資料庫之間的一致性。比如,將當前資料庫的資料遷移到其他型別的資料庫中,或者將當前資料庫中的資料實時備份到另一個資料庫,從而提升資料的安全性和可靠性。
華為雲提供了DRS服務,該服務涵蓋了異構資料庫之間的遷移、同步、災備、訂閱、錄製回放等功能。目前DRS支援超過20種關係型和非關係型資料庫作為源端,其中就包括了GaussDB。以GaussDB作為源資料庫的DRS資料同步的原理如下圖所示。
DRS驅動源端資料庫GaussDB實時解析WAL日誌,生成邏輯日誌,隨後DRS服務接收並解析邏輯日誌,將其轉換為目標資料庫的SQL語句,並驅動目標資料庫執行SQL語句,該過程被稱為邏輯複製。
對於源端資料庫來說,核心要解決的問題是如何將WAL日誌轉換成邏輯日誌,該過程叫邏輯解碼。本文我們為大家介紹GaussDB邏輯解碼的技術原理。
2. GaussDB邏輯解碼
WAL日誌包含資料庫中發生的所有資料變更,包括插入、更新和刪除等操作,同時還包含了諸多資料庫內部細節和特有實現。
邏輯解碼用於將WAL日誌解析為易於理解和處理的邏輯日誌格式,包括JSON、二進位制或者固定的text格式。使用者和邏輯複製工具(如DRS)可以根據自身需求來解析和處理這些邏輯日誌。
當啟用邏輯解碼時,GaussDB除了將每個事務的基本操作寫入WAL日誌,還會將少量的解碼輔助資訊(例如csn快照,用於解碼階段的可見性判斷)記錄到WAL日誌中,以支援邏輯解碼過程。同時還需要建立一個邏輯複製槽。邏輯複製槽的作用是阻止資料庫將已落盤的WAL日誌刪除,並防止解碼所需的系統表記錄被清理。
如上圖所示,邏輯解碼主要包括資料來源、讀取/載入、解碼、重排/傳送幾個模組。WAL日誌和系統表中儲存的表的後設資料是邏輯解碼的內容來源。邏輯解碼從WAL日誌捕獲使用者表DML的變更記錄,依據其中的物理儲存標識(block number和offset等)和提交序列號(csn),載入系統表對應時刻的表的後設資料,再將物理變更記錄中強耦合的內部資訊轉換為使用者可理解的表內容,生成和資料庫實現無關的邏輯變更記錄,最後重排和傳送邏輯變更記錄。
GaussDB邏輯解碼有兩種方式,分別為序列解碼和並行解碼。序列解碼流程分為讀取、解碼、傳送三個步驟,整個序列解碼流程均在同一個執行緒內完成,其中解碼的耗時佔據全流程的70%以上。序列解碼效能約3-5M/s。而並行解碼是透過多執行緒並行執行的方式,極大壓縮瞭解碼過程耗時。因為序列解碼效率較低,我們不推薦使用序列解碼,而是推薦效率更高的並行解碼,而且當前透過華為雲DRS服務啟動的GaussDB邏輯解碼任務均為並行解碼,下面我們重點介紹並行解碼。
3. 並行解碼
並行解碼是透過多執行緒併發執行來提升邏輯解碼效能。
如上圖所示,並行邏輯解碼包含三類執行緒:
Reader執行緒
讀取WAL日誌,抽取業務DML操作以及解碼輔助資訊對應的record,構建LogicalLogChange記憶體物件,如果該條DML涉及toast資料,還需要將toast資料拼接到該dml操作的LogicalLogChange物件中,然後按照日誌序列號(LSN,WAL日誌的唯一識別符號,是一個有序值)順序輪流分發到解碼輸入佇列。
如果解碼到了DDL,DDL更新了系統表,Reader執行緒此時會失效localsyscache,並將失效訊息加入Decoder執行緒輸入佇列中,廣播通知Decoder執行緒失效本地快取。後續decoder執行緒在解碼到失效訊息時,同樣對執行緒內的localsyscache作失效處理。
Decoder執行緒
從解碼輸入佇列獲取LogicalLogChange物件,根據日誌版本內容載入資料表的元資訊,將日誌中的物理資料轉換成表名、列名、列資料等使用者易理解的邏輯資料,解碼後的內容存放在LogicalLog記憶體物件中,並將LogicalLog物件加入到解碼輸出佇列。
前面介紹到,Reader執行緒在將LogicalLogChange物件入隊時是按LSN序將其放入解碼輸入佇列,decoder解碼完成後也會將LogicalLog按LSN需放入解碼輸出佇列,供後面的Sender執行緒讀取。
Sender執行緒
按照DML日誌生成順序,從解碼輸出佇列拿取LogicalLog物件,根據每個物件的事務ID構建hash桶,按照每個LogicalLog物件在解碼輸出佇列中的順序(佇列中已按LSN序排序),把同一個事務的LogicalLog物件,歸類到對應的hash桶中,再以事務的提交順序把每個事務的所有LogicalLog物件傳送給邏輯日誌接收端(例如DRS)。
並行解碼可按需配置解碼併發度,併發度引數取值範圍為1-20,最大可配置20個併發解碼執行緒。
GaussDB並行解碼能極大地提升解碼效能。典型tpcc場景下,解碼速率可達到100MB/s。
4. DDL解碼
GaussDB邏輯解碼支援DDL解碼。如果GaussDB開啟了邏輯解碼,則會在DDL SQL執行階段對DDL語句的解析樹進行解析,解析的結果組裝為Json格式的字串(示例),並新增一種WAL日誌型別,用於將該Json字串寫入WAL日誌。邏輯解碼執行緒解析到該WAL日誌型別時,按照原Json格式輸出DDL的解碼邏輯日誌。DDL語句alter table t1 add column col3 varchar(64)的Json格式解碼結果如下圖所示。
5. 多版本資料字典與指定位點解碼
邏輯解碼在解碼DML過程中依賴表的後設資料資訊,因此需要訪問系統表(也叫資料字典),這種解碼模式也叫online catalog模式。GaussDB將系統表資訊快取在syscache中,當DDL語句更新了系統表時,需要對syscache進行失效處理。執行DDL時會往WAL中寫一條失效訊息日誌,邏輯解碼的每個執行緒都在本執行緒內儲存了一份syscache的副本,即localcache,解碼到失效訊息日誌時,會對localcache做相應的失效處理。
online catalog模式的邏輯解碼依賴錶的歷史後設資料資訊,因此需要利用邏輯複製槽來保留系統表的舊版本元組。如果想對任意歷史日誌進行指定位點解碼,邏輯解碼依賴的系統表舊版本元組需要需要一直保留,這樣會嚴重影響資料庫的效能。
因此,GaussDB單獨增加了一套邏輯解碼專用的系統表,叫做邏輯解碼多版本資料字典。邏輯解碼多版本資料字典參考核心系統表,表結構與核心系統表結構基本保持一致,保留了解碼過程中表的後設資料的所有歷史版本,並單獨實現了清理機制。
新安裝的例項會自動建立好邏輯解碼多版本資料字典,非新安裝的例項,首次初始化邏輯解碼多版本資料字典時,需要呼叫一個系統函式進行初始化,該系統函式將核心系統表的資料同步到邏輯解碼多版本資料字典中。當DDL語句執行完,事務提交前,往核心系統表插入後設資料的同時往邏輯解碼多版本資料字典插入後設資料。解碼的時候,解碼執行緒根據當前csn快照,從邏輯解碼多版本資料字典中將後設資料資訊讀取到localcache快取中使用。同時邏輯解碼實現了多版本資料字典清理的定時任務,透過guc引數,配置保留時間,將超過保留時間的元組刪除。而且,透過該guc引數,我們可以保留任意時間的舊元組,從而在不影響資料庫效能的基礎上實現從指定位點(即WAL的物理位置)進行邏輯解碼,位點可以是包括歸檔WAL日誌在內的任意位置。
透過這種單獨增加一套邏輯解碼多版本資料字典的方式,可以將邏輯解碼與核心系統表解耦,核心系統表無需為邏輯解碼保留大量的舊版本元組,保障了核心的執行效能。
6. 分散式CN解碼
GaussDB支援分散式解碼能力。分散式解碼又分為直連DN解碼與CN解碼。直連DN解碼即不透過CN,解碼工具直接連線到DN節點上進行DN解碼,該解碼方式和集中式解碼原理一致,只能解本DN分片的資料。分散式解碼主要是指連CN進行解碼,可以完整解碼整個叢集的增量資料。
事務提交順序(CommitCSN)代表事務完成的先後順序。對於有依賴的兩個事務,後執行事務的CommitCSN大於先執行事務的CommitCSN。分散式邏輯解碼按照事務提交順序有序返回事務的邏輯日誌。
如圖所示,DN各自按照事務提交順序返回區域性事務的邏輯日誌,CN透過堆排序協調彙總來自各DN的事務邏輯日誌,按堆排序的順序輸出邏輯日誌。
相比於直連DN解碼,具有鏈路數少、能保證強一致性、易用性強等優點。
7. 總結
GaussDB核心提供的邏輯解碼技術,配合DRS服務,可以實現異構資料庫之間的邏輯複製。GaussDB邏輯解碼不僅支援DML解碼,還支援DDL解碼,極大提高了邏輯複製的易用性。支援獨立的多版本資料字典模式進行解碼,並支援指定位點解碼與資料找回。透過開啟並行解碼,可以極大提高WAL日誌解碼速率,保證資料同步的高效能。
華為開發者空間,匯聚鴻蒙、昇騰、鯤鵬、GaussDB、尤拉等各項根技術的開發資源及工具,致力於為每位開發者提供一臺雲主機、一套開發工具及雲上儲存空間,讓開發者基於華為根生態創新。
點選連結,免費領取您的專屬雲主機~