TiDB Data Migration 黑白名单过滤

使用 TiDB Data Migration (DM) 迁移数据时,你可以配置上游数据库实例表的黑白名单过滤 (Block & Allow List) 规则,用来过滤或者只迁移某些 database/table 的所有操作。

配置黑白名单

在迁移任务配置文件中,添加如下配置:

1. block-allow-list:             # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。
2. rule-1:
3. do-dbs: ["test*"]         # 非 ~ 字符开头,表示规则是通配符;v1.0.5 及后续版本支持通配符规则。
4. do-tables:
5. - db-name: "test[123]"    # 匹配 test1、test2、test3。
6. tbl-name: "t[1-5]"      # 匹配 t1、t2、t3、t4、t5。
7. - db-name: "test"
8. tbl-name: "t"
9. rule-2:
10. do-dbs: ["~^test.*"]      # 以 ~ 字符开头,表示规则是正则表达式。
11. ignore-dbs: ["mysql"]
12. do-tables:
13. - db-name: "~^test.*"
14. tbl-name: "~^t.*"
15. - db-name: "test"
16. tbl-name: "t*"
17. ignore-tables:
18. - db-name: "test"
19. tbl-name: "log"

黑白名单支持通配符和正则表达式来匹配,在简单任务场景下,推荐使用通配符匹配库表名:

  • 支持的通配符包括 *、? 以及 []。注意通配符匹配中的 * 符号只能有一个,且必须在末尾,例如 tbl-name: "t*" 中的 "t*" 表示以 t 开头的表。详情请参考通配符匹配。
  • 正则表达式必须以 ~ 字符开头。

参数解释

  • do-dbs:要迁移的库的白名单,类似于 MySQL 中的 replicate-do-db。
  • ignore-dbs:要迁移的库的黑名单,类似于 MySQL 中的 replicate-ignore-db。
  • do-tables:要迁移的表的白名单,类似于 MySQL 中的 replicate-do-table。必须同时指定 db-name 与 tbl-name。
  • ignore-tables:要迁移的表的黑名单,类似于 MySQL 中的 replicate-ignore-table。必须同时指定 db-name 与 tbl-name。

以上参数值以 ~ 开头时均支持使用正则表达式来匹配库名、表名。

过滤规则

黑白名单 - 图1

注意

DM 中黑白名单过滤规则与 MySQL 中相应规则存在以下区别:

  • MySQL 中存在 replicate-wild-do-table 与 replicate-wild-ignore-table 用于支持通配符,DM 中各配置参数直接支持以 ~ 字符开头的正则表达式。
  • DM 当前只支持 ROW 格式的 binlog,不支持 STATEMENT/MIXED 格式的 binlog,因此应与 MySQL 中 ROW 格式下的规则对应。
  • 对于 DDL,MySQL 仅依据默认的 database 名称(USE 语句显式指定的 database)进行判断,而 DM 优先依据 DDL 中的 database 名称部分进行判断,并当 DDL 中不包含 database 名称时再依据 USE 部分进行判断。假设需要判断的 SQL 为 USE test_db_2; CREATE TABLE test_db_1.test_table (c1 INT PRIMARY KEY),且 MySQL 配置了 replicate-do-db=test_db_1、DM 配置了 do-dbs: ["test_db_1"],则对于 MySQL 该规则不会生效,而对于 DM 该规则会生效。

判断 table test.t 是否应该被过滤的流程如下:

  1. 首先进行 schema 过滤判断

  2. 如果 do-dbs 不为空,判断 do-dbs 中是否存在一个匹配的 schema。

    • 如果存在,则进入 table 过滤判断。
    • 如果不存在,则过滤 test.t。
    • 如果 do-dbs 为空并且 ignore-dbs 不为空,判断 ignore-dbs 中是否存在一个匹配的 schema。

    • 如果存在,则过滤 test.t。

    • 如果不存在,则进入 table 过滤判断。
    • 如果 do-dbs 和 ignore-dbs 都为空,则进入 table 过滤判断。
    • 进行 table 过滤判断
  3. 如果 do-tables 不为空,判断 do-tables 中是否存在一个匹配的 table。

    • 如果存在,则迁移 test.t。
    • 如果不存在,则过滤 test.t。
    • 如果 ignore-tables 不为空,判断 ignore-tables 中是否存在一个匹配的 table。

    • 如果存在,则过滤 test.t.

    • 如果不存在,则迁移 test.t。
    • 如果 do-tables 和 ignore-tables 都为空,则迁移 test.t。

黑白名单 - 图2

注意

如果是判断 schema test 是否应该被过滤,则只进行 schema 过滤判断。

使用示例

假设上游 MySQL 实例包含以下表:

1. `logs`.`messages_2016`
2. `logs`.`messages_2017`
3. `logs`.`messages_2018`
4. `forum`.`users`
5. `forum`.`messages`
6. `forum_backup_2016`.`messages`
7. `forum_backup_2017`.`messages`
8. `forum_backup_2018`.`messages`

配置如下:

1. block-allow-list:  # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。
2. bw-rule:
3. do-dbs: ["forum_backup_2018", "forum"]
4. ignore-dbs: ["~^forum_backup_"]
5. do-tables:
6. - db-name: "logs"
7. tbl-name: "~_2018$"
8. - db-name: "~^forum.*"
9. ​      tbl-name: "messages"
10. ignore-tables:
11. - db-name: "~.*"
12. ​      tbl-name: "^messages.*"

应用 bw-rule 规则后:

table 是否过滤 过滤的原因
logs.messages_2016 是 schema logs 没有匹配到 do-dbs 任意一项
logs.messages_2017 是 schema logs 没有匹配到 do-dbs 任意一项
logs.messages_2018 是 schema logs 没有匹配到 do-dbs 任意一项
forum_backup_2016.messages 是 schema forum_backup_2016 没有匹配到 do-dbs 任意一项
forum_backup_2017.messages 是 schema forum_backup_2017 没有匹配到 do-dbs 任意一项
forum.users 是 1. schema forum 匹配到 do-dbs,进入 table 过滤判断 2. schema 和 table 没有匹配到 do-tables 和 ignore-tables 中任意一项,并且 do-tables 不为空,因此过滤
forum.messages 否 1. schema forum 匹配到 do-dbs,进入 table 过滤判断 2. schema 和 table 匹配到 do-tables 的 db-name: “~^forum.“,tbl-name: “messages”
forum_backup_2018.messages 否 1. schema forum_backup_2018 匹配到 do-dbs,进入 table 过滤判断 2. schema 和 table 匹配到 do-tables 的 db-name: “~^forum.“,tbl-name: “messages”