作者:lan
本文為 DM 原始碼閱讀系列文章的第三篇,上篇文章 介紹了 DM 的整體架構,DM 元件 DM-master 和 DM-worker 的入口程式碼,以及兩者之間的資料互動模型。本篇文章詳細地介紹 DM 資料同步處理單元(DM-worker 內部用來同步資料的邏輯單元),包括資料同步處理單元實現了什麼功能,資料同步流程、執行邏輯,以及資料同步處理單元的 interface 設計。
資料同步處理單元
從上圖可以瞭解到目前 DM 包含 relay log、dump、load、binlog replication(sync) 4 個資料同步處理單元,涵蓋了以下資料同步處理的功能:
處理單元 | 功能 |
---|---|
relay log | 持久化 MySQL/MariaDB Binlog 到磁碟 |
dump | 從 MySQL/MariaDB dump 全量資料 |
load | 載入全量資料到 TiDB cluster |
binlog replication(sync) | 複製 relay log 儲存的 Binlog 到 TiDB cluster |
資料同步流程
Task 資料同步流程初始化操作步驟:
-
DM-master 接收到 task,將 task 拆分成 subtask 後 分發給對應的各個 DM-worker;
-
DM-worker 接收到 subtask 後 建立一個 subtask 物件,然後 初始化資料同步流程。
從 初始化資料同步流程 的程式碼中我們可以看到,根據 task 配置項 task-mode 的不同,DM-worker 會初始化不同的資料同步流程:
task-mode | 同步流程 | 需要的資料同步處理單元 |
---|---|---|
all | 全量同步 -> 增量資料同步 | relay log、dump、load、binlog replication(sync) |
full | 全量同步 | dump、load |
incremental | 增量同步 | relay log,binlog replication(sync) |
執行邏輯
DM 資料同步處理單元 interface 定義在 dm/unit
,relay log、dump、load、binlog replication(sync)都實現了該 interface(golang interface 介紹)。
實際上 DM-worker 中的資料同步處理單元分為兩類:
-
全域性共享單例。dm-worker 啟動的時候只初始化一次這類資料同步處理單元,所有的 subtask 都可以使用這類資料同步處理單元的服務;relay log 屬於這種型別。
-
subtask 獨享。dm-worker 會為每個 subtask 初始化一系列的資料同步處理單元;dump、load、binlog replication(sync)屬於這種型別。
兩類資料同步處理單元的使用邏輯不同,這篇文件會著重講一下 subtask 獨享的資料同步處理單元的使用邏輯,不會囊括更多的 relay log 相關的內容,後面會有單獨一篇文章詳細介紹它。
relay log 相關使用程式碼在 dm/worker/relay.go
、具體功能實現程式碼在 relay/relay.go
,有興趣的同學也可以先行閱讀一下相關程式碼,relay log 的程式碼註釋也是比較豐富,並且簡單易懂。
subtask 獨享資料同步處理單元使用邏輯相關程式碼在 dm/worker/subtask.go
。subtask 物件包含的主要屬性有:
-
units:初始化後要執行的資料同步處理單元。
-
currUnit:當前正在執行的資料同步處理單元。
-
prevUnit:上一個執行的資料同步處理單元。
-
stage:subtask 的執行階段狀態, 包含
New
、Running
、Paused
,Stopped
,Finished
,具體定義的程式碼在dm/proto/dmworker.proto
。 -
result:subtask 當前資料同步處理單元的執行結果,對應著 stage =
Paused/Stopped/Finished
的詳細資訊。
主要的邏輯有:
-
初始化 subtask 物件例項的時候會 編排資料同步處理單元的執行先後順序。所有的資料同步處理單元都實現了
dm/unit
interface,所以接下來的執行中就不需要關心具體的資料同步處理單元的型別,可以按照統一的 interface 方法來執行資料同步處理單元,以及對其進行狀態監控。 -
初始化各個資料同步處理單元。subtask 在執行前集中地初始化所有的資料同步處理單元,我們計劃之後優化成在各個資料同步處理單元執行前再進行初始化,這樣子減少資源的提前或者無效的佔用。
-
資料同步處理單元執行狀態監控。通過監控當前執行的資料同步處理單元的結果,將 subtask 的 stage 設定為
Paused/Stopped/Finished
。-
如果 當前的資料同步處理單元工作已經完成,則會根據 units 來 選取下一個需要執行的資料同步處理單元,如果沒有需要的資料同步處理單元,那麼會將 subtask 的 stage 設定為
Finished
。這裡有個注意點,因為 binlog replication 單元永遠不會結束,所以不會進入Finished
的狀態。 -
如果 返回的 result 裡面包含有錯誤資訊,則會將 subtask 的 stage 設定為
Paused
,並且列印具體的錯誤資訊。 -
如果是使用者手動暫停或者停止,則會將 subtask 的 stage 設定為
Paused/Stopped
。這裡有個注意點,這個時候 stage=Paused
是沒有錯誤資訊的。
-
-
資料同步處理單元之間的執行交接處理邏輯。部分資料同步處理單元在開始工作的時候需要滿足一些前置條件,例如 binlog replication(sync)的執行需要等待 relay log 處理單元已經儲存下來其開始同步需要的 binlog 檔案,否則 subtask 將處於 stage=
Paused
的暫停等待狀態。
小結
本篇文章主要介紹了資料同步處理單元實現了什麼功能,資料同步流程、執行邏輯,以及資料同步處理單元的 interface 設計。後續會分三篇文章詳細地介紹資料同步處理單元的實現,包括:
- dump/load 全量同步實現
- binlog replication 增量同步實現
- relay log 實現