做者:張學程html
TiDB-DM(Data Migration)是用於將數據從 MySQL/MariaDB 遷移到 TiDB 的工具。該工具既支持以全量備份文件的方式將 MySQL/MariaDB 的數據導入到 TiDB,也支持經過解析執行 MySQL/MariaDB binlog 的方式將數據增量同步到 TiDB。特別地,對於有多個 MySQL/MariaDB 實例的分庫分表須要合併後同步到同一個 TiDB 集羣的場景,DM 提供了良好的支持。若是你須要從 MySQL/MariaDB 遷移到 TiDB,或者須要將 TiDB 做爲 MySQL/MariaDB 的從庫,DM 將是一個很是好的選擇。mysql
DM 是集羣模式的,其主要由 DM-master、DM-worker 與 DM-ctl 三個組件組成,可以以多對多的方式將多個上游 MySQL 實例的數據同步到多個下游 TiDB 集羣,其架構圖以下:git
DM-master:管理整個 DM 集羣,維護集羣的拓撲信息,監控各個 DM-worker 實例的運行狀態;進行數據同步任務的拆解與分發,監控數據同步任務的執行狀態;在進行合庫合表的增量數據同步時,協調各 DM-worker 上 DDL 的執行或跳過;提供數據同步任務管理的統一入口。github
DM-worker:與上游 MySQL 實例一一對應,執行具體的全量、增量數據同步任務;將上游 MySQL 的 binlog 拉取到本地並持久化保存;根據定義的數據同步任務,將上游 MySQL 數據全量導出成 SQL 文件後導入到下游 TiDB,或解析本地持久化的 binlog 後增量同步到下游 TiDB;編排 DM-master 拆解後的數據同步子任務,監控子任務的運行狀態。sql
DM-ctl:命令行交互工具,經過鏈接到 DM-master 後,執行 DM 集羣的管理與數據同步任務的管理。數據庫
單個 DM 集羣能夠同時運行多個數據同步任務;對於每個同步任務,能夠拆解爲多個子任務同時由多個 DM-worker 節點承擔,其中每一個 DM-worker 節點負責同步來自對應的上游 MySQL 實例的數據。對於單個 DM-worker 節點上的單個數據同步子任務,其數據遷移流程以下,其中上部的數據流向爲全量數據遷移、下部的數據流向爲增量數據同步:express
在每一個 DM-worker 節點內部,對於特定的數據同步子任務,主要由 dumper、loader、relay 與 syncer(binlog replication)等數據同步處理單元執行具體的數據同步操做。bash
對於全量數據遷移,DM 首先使用 dumper 單元從上游 MySQL 中將表結構與數據導出成 SQL 文件;而後使用 loader 單元讀取這些 SQL 文件並同步到下游 TiDB。架構
對於增量數據同步,首先使用 relay 單元做爲 slave 鏈接到上游 MySQL 並拉取 binlog 數據後做爲 relay log 持久化存儲在本地,而後使用 syncer 單元讀取這些 relay log 並解析構形成 SQL 語句後同步到下游 TiDB。這個增量同步的過程與 MySQL 的主從複製相似,主要區別在於在 DM 中,本地持久化的 relay log 能夠同時供多個不一樣子任務的 syncer 單元所共用,避免了多個任務須要重複從上游 MySQL 拉取 binlog 的問題。併發
爲加快數據導入速度,在 DM 中不管是全量數據遷移,仍是增量數據同步,都在其中部分階段使用了併發處理。
對於全量數據遷移,在導出階段,dumper 單元調用 mydumper 導出工具執行實際的數據導出操做,對應的併發模型能夠直接參考 mydumper 的源碼。在使用 loader 單元執行的導入階段,對應的併發模型結構以下:
使用 mydumper 執行導出時,能夠經過 --chunk-filesize
等參數將單個表拆分紅多個 SQL 文件,這些 SQL 文件對應的都是上游 MySQL 某一個時刻的靜態快照數據,且各 SQL 文件間的數據不存在關聯。所以,在使用 loader 單元執行導入時,能夠直接在一個 loader 單元內啓動多個 worker 工做協程,由各 worker 協程併發、獨立地每次讀取一個待導入的 SQL 文件進行導入。即 loader 導入階段,是以 SQL 文件級別粒度併發進行的。在 DM 的任務配置中,對於 loader 單元,其中的 pool-size
參數即用於控制此處 worker 協程數量。
對於增量數據同步,在從上游拉取 binlog 並持久化到本地的階段,因爲上游 MySQL 上 binlog 的產生與發送是以 stream 形式進行的,所以這部分只能串行處理。在使用 syncer 單元執行的導入階段,在必定的限制條件下,能夠執行併發導入,對應的模型結構以下:
當 syncer 讀取與解析本地 relay log 時,與從上游拉取 binlog 相似,是以 stream 形式進行的,所以也只能串行處理。當 syncer 解析出各 binlog event 並構形成待同步的 job 後,則能夠根據對應行數據的主鍵、索引等信息通過 hash 計算後分發到多個不一樣的待同步 job channel 中;在 channel 的另外一端,與各個 channel 對應的 worker 協程併發地從 channel 中取出 job 後同步到下游的 TiDB。即 syncer 導入階段,是以 binlog event 級別粒度併發進行的。在 DM 的任務配置中,對於 syncer 單元,其中的 worker-count
參數即用於控制此處 worker 協程數量。
但 syncer 併發同步到下游 TiDB 時,存在一些限制,主要包括:
對於 DDL,因爲會變動下游的表結構,所以必須確保在舊錶結構對應的 DML 都同步完成後,才能進行同步。在 DM 中,當解析 binlog event 獲得 DDL 後,會向每個 job channel 發送一個特殊的 flush job;當各 worker 協程遇到 flush job 時,會馬上向下遊 TiDB 同步以前已經取出的全部 job;等各 job channel 中的 job 都同步到下游 TiDB 後,開始同步 DDL;等待 DDL 同步完成後,繼續同步後續的 DML。即 DDL 不能與 DML 併發同步,且 DDL 以前與以後的 DML 也不能併發同步。sharding 場景下 DDL 的同步處理見後文。
對於 DML,多條 DML 可能會修改同一行的數據,甚至是主鍵。若是併發地同步這些 DML,則可能形成同步後數據的不一致。DM 中對於 DML 之間的衝突檢測與處理,與 TiDB-Binlog 中的處理相似,具體原理能夠閱讀《TiDB EcoSystem Tools 原理解讀(一)TiDB-Binlog 架構演進與實現原理》中關於 Drainer 內 SQL 之間衝突檢測的討論。
在使用 MySQL 支撐大量數據時,常常會選擇使用分庫分表的方案。但當將數據同步到 TiDB 後,一般但願邏輯上進行合庫合表。DM 爲支持合庫合表的數據同步,主要實現瞭如下的一些功能。
爲說明 DM 中 table router(表名路由)功能,先看以下圖所示的一個例子:
在這個例子中,上游有 2 個 MySQL 實例,每一個實例有 2 個邏輯庫,每一個庫有 2 個表,總共 8 個表。當同步到下游 TiDB 後,但願全部的這 8 個表最終都合併同步到同一個表中。
但爲了能將 8 個來自不一樣實例、不一樣庫且有不一樣名的表同步到同一個表中,首先要處理的,就是要能根據某些定義好的規則,未來自不一樣表的數據都路由到下游的同一個表中。在 DM 中,這類規則叫作 router-rules。對於上面的示例,其規則以下:
name-of-router-rule:
schema-pattern: "schema_*"
table-pattern: "table_*"
target-schema: "schema"
target-table: "table"
複製代碼
name-of-router-rule
:規則名,用戶指定。當有多個上游實例須要使用相同的規則時,能夠只定義一條規則,多個不一樣的實例經過規則名進行引用。
schema-pattern
:用於匹配上游庫(schema)名的模式,支持在尾部使用通配符(*)。這裏使用 schema_*
便可匹配到示例中的兩個庫名。
table-pattern
:用於匹配上游表名的模式,與 schema-pattern
相似。這裏使用 table_*
便可匹配到示例中的兩個表名。
target-schema
:目標庫名。對於庫名、表名匹配的數據,將被路由到這個庫中。
target-table
:目標表名。對於庫名、表名匹配的數據,將被路由到 target-schema
庫下的這個表中。
在 DM 內部實現上,首先根據 schema-pattern
/ table-pattern
構造對應的 trie 結構,並將規則存儲在 trie 節點中;當有 SQL 須要同步到下游時,經過使用上游庫名、表名查詢 trie 便可獲得對應的規則,並根據規則替換原 SQL 中的庫名、表名;經過向下遊 TiDB 執行替換後的 SQL 即完成了根據表名的路由同步。有關 router-rules
規則的具體實現,能夠閱讀 TiDB-Tools 下的 table-router pkg 源代碼。
有了 table router 功能,已經能夠完成基本的合庫合表數據同步了。但在數據庫中,咱們常常會使用自增類型的列做爲主鍵。若是多個上游分表的主鍵各自獨立地自增,將它們合併同步到下游後,就極可能會出現主鍵衝突,形成數據的不一致。咱們可看一個以下的例子:
在這個例子中,上游 4 個須要合併同步到下游的表中,都存在 id 列值爲 1 的記錄。假設這個 id 列是表的主鍵。在同步到下游的過程當中,因爲相關更新操做是以 id 列做爲條件來肯定須要更新的記錄,所以會形成後同步的數據覆蓋前面已經同步過的數據,致使部分數據的丟失。
在 DM 中,咱們經過 column mapping 功能在數據同步的過程當中依據指定規則對相關列的數據進行轉換改寫來避免數據衝突與丟失。對於上面的示例,其中 MySQL 實例 1 的 column mapping 規則以下:
mapping-rule-of-instance-1:
schema-pattern: "schema_*"
table-pattern: "table_*"
expression: "partition id"
source-column: "id"
target-column: "id"
arguments: ["1", "schema_", "table_"]
複製代碼
mapping-rule-of-instance-1
:規則名,用戶指定。因爲不一樣的上游 MySQL 實例須要轉換獲得不一樣的值,所以一般每一個 MySQL 實例使用一條專有的規則。
schema-pattern
/ table-pattern
:上游庫名、表名匹配模式,與 router-rules
中的對應配置項一致。
expression
:進行數據轉換的表達式名。目前經常使用的表達式即爲 "partition id"
,有關該表達式的具體說明見下文。
source-column
:轉換表達式的輸入數據對應的來源列名,"id"
表示這個表達式將做用於表中名爲 id 的列。暫時只支持對單個來源列進行數據轉換。
target-column
:轉換表達式的輸出數據對應的目標列名,與 source-column
相似。暫時只支持對單個目標列進行數據轉換,且對應的目標列必須已經存在。
arguments
:轉換表達式所依賴的參數。參數個數與含義依具體表達式而定。
partition id
是目前主要受支持的轉換表達式,其經過爲 bigint 類型的值增長二進制前綴來解決來自不一樣表的數據合併同步後可能產生衝突的問題。partition id
的 arguments 包括 3 個參數,分別爲:
MySQL 實例 ID:標識數據的來源 MySQL 實例,用戶自由指定。如 "1"
表示匹配該規則的數據來自於 MySQL 實例 1,且這個標識將被轉換成數值後以二進制的形式做爲前綴的一部分添加到轉換後的值中。
庫名前綴:標識數據的來源邏輯庫。如 "schema_"
應用於 schema_2
邏輯庫時,表示去除前綴後剩下的部分(數字 2
)將以二進制的形式做爲前綴的一部分添加到轉換後的值中。
表名前綴:標識數據的來源表。如 "table_"
應用於 table_3
表時,表示去除前綴後剩下的部分(數字 3
)將以二進制的形式做爲前綴的一部分添加到轉換後的值中。
各部分在通過轉換後的數值中的二進制分佈以下圖所示(各部分默認所佔用的 bits 位數如圖所示):
假如轉換前的原始數據爲 123
,且有如上的 arguments 參數設置,則轉換後的值爲:
1<<(64-1-4) | 2<<(64-1-4-7) | 3<<(64-1-4-7-8) | 123
複製代碼
另外,arguments 中的 3 個參數都可設置爲空字符串(""
),即表示該部分不被添加到轉換後的值中,且不佔用額外的 bits。好比將其設置爲["1", "", "table_"]
,則轉換後的值爲:
1 << (64-1-4) | 3<< (64-1-4-8) | 123
複製代碼
有關 column mapping 功能的具體實現,能夠閱讀 TiDB-Tools 下的 column-mapping pkg 源代碼。
有了 table router 和 column mapping 功能,DML 的合庫合表數據同步已經能夠正常進行了。但若是在增量數據同步的過程當中,上游待合併的分表上執行了 DDL 操做,則可能出現問題。咱們先來看一個簡化後的在分表上執行 DDL 的例子。
在上圖的例子中,分表的合庫合表簡化成了上游只有兩個 MySQL 實例,每一個實例內只有一個表。假設在開始數據同步時,將兩個分表的表結構 schema 的版本記爲 schema V1
,將 DDL 執行完成後的表結構 schema 的版本記爲 schema V2
。
如今,假設數據同步過程當中,從兩個上游分表收到的 binlog 數據有以下的時序:
開始同步時,從兩個分表收到的都是 schema V1
的 DML。
在 t1 時刻,收到實例 1 上分表的 DDL。
從 t2 時刻開始,從實例 1 收到的是 schema V2
的 DML;但從實例 2 收到的還是 schema V1
的 DML。
在 t3 時刻,收到實例 2 上分表的 DDL。
從 t4 時刻開始,從實例 2 收到的也是 schema V2
的 DML。
假設在數據同步過程當中,不對分表的 DDL 進行處理。當將實例 1 的 DDL 同步到下游後,下游的表結構會變動成爲 schema V2
。但對於實例 2,在 t2 時刻到 t3 時刻這段時間內收到的仍然是 schema V1
的 DML。當嘗試把這些與 schema V1
對應的 DML 同步到下游時,就會因爲 DML 與表結構的不一致而發生錯誤,形成數據沒法正確同步。
繼續使用上面的例子,來看看咱們在 DM 中是如何處理合庫合表過程當中的 DDL 同步的。
在這個例子中,DM-worker-1 用於同步來自 MySQL 實例 1 的數據,DM-worker-2 用於同步來自 MySQL 實例 2 的數據,DM-master 用於協調多個 DM-worker 間的 DDL 同步。從 DM-worker-1 收到 DDL 開始,簡化後的 DDL 同步流程爲:
DM-worker-1 在 t1 時刻收到來自 MySQL 實例 1 的 DDL,自身暫停該 DDL 對應任務的 DDL 及 DML 數據同步,並將 DDL 相關信息發送給 DM-master。
DM-master 根據 DDL 信息判斷須要協調該 DDL 的同步,爲該 DDL 建立一個鎖,並將 DDL 鎖信息發回給 DM-worker-1,同時將 DM-worker-1 標記爲這個鎖的 owner。
DM-worker-2 繼續進行 DML 的同步,直到在 t3 時刻收到來自 MySQL 實例 2 的 DDL,自身暫停該 DDL 對應任務的數據同步,並將 DDL 相關信息發送給 DM-master。
DM-master 根據 DDL 信息判斷該 DDL 對應的鎖信息已經存在,直接將對應鎖信息發回給 DM-worker-2。
DM-master 根據啓動任務時的配置信息、上游 MySQL 實例分表信息、部署拓撲信息等,判斷得知已經收到了須要合表的全部上游分表的該 DDL,請求 DDL 鎖的 owner(DM-worker-1)向下遊同步執行該 DDL。
DM-worker-1 根據 step 2 時收到的 DDL 鎖信息驗證 DDL 執行請求;向下遊執行 DDL,並將執行結果反饋給 DM-master;若執行 DDL 成功,則自身開始繼續同步後續的(從 t2 時刻對應的 binlog 開始的)DML。
DM-master 收到來自 owner 執行 DDL 成功的響應,請求在等待該 DDL 鎖的全部其餘 DM-worker(DM-worker-2)忽略該 DDL,直接繼續同步後續的(從 t4 時刻對應的 binlog 開始的)DML。
根據上面 DM 處理多個 DM-worker 間的 DDL 同步的流程,概括一下 DM 內處理多個 DM-worker 間 sharding DDL 同步的特色:
根據任務配置與 DM 集羣部署拓撲信息,在 DM-master 內創建一個須要協調 DDL 同步的邏輯 sharding group,group 中的成員爲處理該任務拆解後各子任務的 DM-worker。
各 DM-worker 在從 binlog event 中獲取到 DDL 後,會將 DDL 信息發送給 DM-master。
DM-master 根據來自 DM-worker 的 DDL 信息及 sharding group 信息建立/更新 DDL 鎖。
若是 sharding group 的全部成員都收到了某一條 DDL,則代表上游分表在該 DDL 執行前的 DML 都已經同步完成,能夠執行 DDL,並繼續後續的 DML 同步。
上游分表的 DDL 在通過 table router 轉換後,對應須要在下游執行的 DDL 應該一致,所以僅需 DDL 鎖的 owner 執行一次便可,其餘 DM-worker 可直接忽略對應的 DDL。
從 DM 處理 DM-worker 間 sharding DDL 同步的特色,能夠看出該功能存在如下一些限制:
上游的分表必須以相同的順序執行(table router 轉換後相同的)DDL,好比表 1 先增長列 a
後再增長列 b
,而表 2 先增長列 b
後再增長列 a
,這種不一樣順序的 DDL 執行方式是不支持的。
一個邏輯 sharding group 內的全部 DM-worker 對應的上游分表,都應該執行對應的 DDL,好比其中有 DM-worker-2 對應的上游分表未執行 DDL,則其餘已執行 DDL 的 DM-worker 都會暫停同步任務,等待 DM-worker-2 收到對應上游的 DDL。
因爲已經收到的 DDL 的 DM-worker 會暫停任務以等待其餘 DM-worker 收到對應的 DDL,所以數據同步延遲會增長。
增量同步開始時,須要合併的全部上游分表結構必須一致,才能確保來自不一樣分表的 DML 能夠同步到一個肯定表結構的下游,也才能確保後續各分表的 DDL 可以正確匹配與同步。
在上面的示例中,每一個 DM-worker 對應的上游 MySQL 實例中只有一個須要進行合併的分表。但在實際場景下,一個 MySQL 實例可能有多個分庫內的多個分表須要進行合併,好比前面介紹 table router 與 column mapping 功能時的例子。當一個 MySQL 實例中有多個分表須要合併時,sharding DDL 的協調同步過程增長了更多的複雜性。
假設同一個 MySQL 實例中有 table_1
和 table_2
兩個分表須要進行合併,以下圖:
因爲數據來自同一個 MySQL 實例,所以全部數據都是從同一個 binlog 流中得到。在這個例子中,時序以下:
開始同步時,兩個分表收到的數據都是 schema V1
的 DML。
在 t1 時刻,收到了 table_1
的 DDL。
從 t2 時刻到 t3 時刻,收到的數據同時包含 table_1 schema V2 的 DML 及 table_2
schema V1
的 DML。
在 t3 時刻,收到了 table_2
的 DDL。
從 t4 時刻開始,兩個分表收到的數據都是 schema V2
的 DML。
假設在數據同步過程當中不對 DDL 進行特殊處理,當 table_1
的 DDL 同步到下游、變動下游表結構後,table_2 schema V1
的 DML 將沒法正常同步。所以,在單個 DM-worker 內部,咱們也構造了與 DM-master 內相似的邏輯 sharding group,但 group 的成員是同一個上游 MySQL 實例的不一樣分表。
但 DM-worker 內協調處理 sharding group 的同步不能徹底與 DM-master 處理時一致,主要緣由包括:
當收到 table_1
的 DDL 時,同步不能暫停,須要繼續解析 binlog 才能得到後續 table_2
的 DDL,即須要從 t2 時刻繼續向前解析直到 t3 時刻。
在繼續解析 t2 時刻到 t3 時刻的 binlog 的過程當中,table_1
的 schema V2
的 DML 不能向下遊同步;但在 sharding DDL 同步並執行成功後,這些 DML 須要同步到下游。
在 DM 中,簡化後的 DM-worker 內 sharding DDL 同步流程爲:
在 t1 時刻收到 table_1
的 DDL,記錄 DDL 信息及此時的 binlog 位置點信息。
繼續向前解析 t2 時刻到 t3 時刻的 binlog。
對於屬於 table_1
的 schema V2
DML,忽略;對於屬於 table_2
的 schema V1
DML,正常同步到下游。
在 t3 時刻收到 table_2
的 DDL,記錄 DDL 信息及此時的 binlog 位置點信息。
根據同步任務配置信息、上游庫表信息等,判斷該 MySQL 實例上全部分表的 DDL 都已經收到;將 DDL 同步到下游執行、變動下游表結構。
設置新的 binlog 流的解析起始位置點爲 step 1 時保存的位置點。
從新開始解析從 t2 時刻到 t3 時刻的 binlog。
對於屬於 table_1
的 schema V2
DML,正常同步到下游;對於屬於 table_2
的 shema V1
DML,忽略。
解析到達 step 4 時保存的 binlog 位置點,可得知在 step 3 時被忽略的全部 DML 都已經從新同步到下游。
繼續從 t4 時刻對應的 binlog 位置點正常同步。
從上面的分析能夠知道,DM 在處理 sharding DDL 同步時,主要經過兩級 sharding group 來進行協調控制,簡化的流程爲:
各 DM-worker 獨立地協調對應上游 MySQL 實例內多個分表組成的 sharding group 的 DDL 同步。
當 DM-worker 內全部分表的 DDL 都收到時,向 DM-master 發送 DDL 相關信息。
DM-master 根據 DM-worker 發來的 DDL 信息,協調由各 DM-worker 組成的 sharing group 的 DDL 同步。
當 DM-master 收到全部 DM-worker 的 DDL 信息時,請求 DDL lock 的 owner(某個 DM-worker)執行 DDL。
owner 執行 DDL,並將結果反饋給 DM-master;自身開始從新同步在內部協調 DDL 同步過程當中被忽略的 DML。
當 DM-master 發現 owner 執行 DDL 成功後,請求其餘全部 DM-worker 開始繼續同步。
其餘全部 DM-worker 各自開始從新同步在內部協調 DDL 同步過程當中被忽略的 DML。
全部 DM-worker 在從新同步完成被忽略的 DML 後,繼續正常同步。
在進行數據同步的過程當中,有時可能並不須要將上游全部的數據都同步到下游,這時通常指望能在同步過程當中根據某些規則,過濾掉部分不指望同步的數據。在 DM 中,支持 2 種不一樣級別的同步過濾方式。
DM 在 dumper、loader、syncer 三個處理單元中都支持配置規則只同步/不一樣步部分庫或表。
對於 dumper 單元,其實際調用 mydumper 來 dump 上游 MySQL 的數據。好比只指望導出 test 庫中的 t一、t2 兩個表的數據,則能夠爲 dumper 單元配置以下規則:
name-of-dump-rule:
extra-args: "-B test -T t1,t2"
複製代碼
name-of-dump-rule
:規則名,用戶指定。當有多個上游實例須要使用相同的規則時,能夠只定義一條規則,多個不一樣的實例經過規則名進行引用。
extra-args
:dumper 單元額外參數。除 dumper 單元中明肯定義的配置項外的其餘全部 mydumper 配置項都經過此參數傳入,格式與使用 mydumper 時一致。
有關 mydumper 對庫表黑白名單的支持,可查看 mydumper 的參數及 mydumper 的源碼。
對於 loader 和 syncer 單元,其對應的庫表黑白名單規則爲 black-white-list
。假設只指望同步 test 庫中的 t一、t2 兩個表的數據,則可配置以下規則:
name-of-bwl-rule:
do-tables:
- db-name: "test"
tbl-name: "t1"
- db-name: "test"
tbl-name: "t2"
複製代碼
示例中只使用了該規則的部分配置項,完整的配置項及各配置項的含義,可閱讀該功能對應的用戶文檔。DM 中該規則與 MySQL 的主從同步過濾規則相似,所以也可參考 Evaluation of Database-Level Replication and Binary Logging Options 與 Evaluation of Table-Level Replication Options。
對於 loader 單元,在解析 SQL 文件名得到庫名錶名後,會與配置的黑白名單規則進行匹配,若是匹配結果爲不須要同步,則會忽略對應的整個 SQL 文件。對於 syncer 單元,在解析 binlog 得到庫名錶名後,會與配置的黑白名單規則進行匹配,若是匹配結果爲不須要同步,則會忽略對應的(部分)binlog event 數據。
在進行增量數據同步時,有時會指望過濾掉某些特定類型的 binlog event,兩個典型的場景包括:
上游執行 TRUNCATE TABLE
時不但願清空下游表中的數據。
上游分表上執行 DROP TABLE
時不但願 DROP
下游合併後的表。
在 DM 中支持根據 binlog event 的類型進行過濾,對於須要過濾 TRUNCATE TABLE
與 DROP TABLE
的場景,可配置規則以下:
name-of-filter-rule:
schema-pattern: "test_*"
table-pattern: "t_*"
events: ["truncate table", "drop table"]
action: Ignore
複製代碼
規則的匹配模式與 table router、column mapping 相似,具體的配置項可閱讀該功能對應的用戶文檔。
在實現上,當解析 binlog event 得到庫名、表名及 binlog event 類型後,與配置的規則進行匹配,並在匹配後依據 action 配置項來決定是否須要進行過濾。有關 binlog event 過濾功能的具體實現,能夠閱讀 TiDB-Tools 下的 binlog-filter pkg 源代碼。