TiDB Data Migration 黑白名单过滤
使用 TiDB Data Migration (DM) 迁移数据时,你可以配置上游数据库实例表的黑白名单过滤 (Block & Allow List) 规则,用来过滤或者只迁移某些 database/table 的所有操作。
配置黑白名单
在迁移任务配置文件中,添加如下配置:
block-allow-list:             # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。
  rule-1:
    do-dbs: ["test*"]         # 非 ~ 字符开头,表示规则是通配符;v1.0.5 及后续版本支持通配符规则。
    do-tables:
    - db-name: "test[123]"    # 匹配 test1、test2、test3。
      tbl-name: "t[1-5]"      # 匹配 t1、t2、t3、t4、t5。
    - db-name: "test"
      tbl-name: "t"
  rule-2:
    do-dbs: ["~^test.*"]      # 以 ~ 字符开头,表示规则是正则表达式。
    ignore-dbs: ["mysql"]
    do-tables:
    - db-name: "~^test.*"
      tbl-name: "~^t.*"
    - db-name: "test"
      tbl-name: "t"
    ignore-tables:
    - db-name: "test"
      tbl-name: "log"
在简单任务场景下,推荐使用通配符匹配库表名,但需注意以下版本差异:
- 对于 v1.0.5 版及后续版本,黑白名单支持通配符匹配。但注意所有版本中通配符匹配中的 
*符号 只能有一个,且必须在末尾。 - 对于 v1.0.5 以前的版本,黑白名单仅支持正则表达式。
 
参数解释
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。
以上参数值以 ~ 开头时均支持使用正则表达式来匹配库名、表名。
过滤规则
do-dbs与ignore-dbs对应的过滤规则与 MySQL 中的 Evaluation of Database-Level Replication and Binary Logging Options 类似。do-tables与ignore-tables对应的过滤规则与 MySQL 中的 Evaluation of Table-Level Replication Options 类似。
判断 table test.t 是否应该被过滤的流程如下:
首先进行 schema 过滤判断
如果
do-dbs不为空,判断do-dbs中是否存在一个匹配的 schema。- 如果存在,则进入 table 过滤判断。
 - 如果不存在,则过滤 
test.t。 
如果
do-dbs为空并且ignore-dbs不为空,判断ignore-dbs中是否存在一个匹配的 schema。- 如果存在,则过滤 
test.t。 - 如果不存在,则进入 table 过滤判断。
 
- 如果存在,则过滤 
 如果
do-dbs和ignore-dbs都为空,则进入 table 过滤判断。
进行 table 过滤判断
如果
do-tables不为空,判断do-tables中是否存在一个匹配的 table。- 如果存在,则迁移 
test.t。 - 如果不存在,则过滤 
test.t。 
- 如果存在,则迁移 
 如果
ignore-tables不为空,判断ignore-tables中是否存在一个匹配的 table。- 如果存在,则过滤 
test.t. - 如果不存在,则迁移 
test.t。 
- 如果存在,则过滤 
 如果
do-tables和ignore-tables都为空,则迁移test.t。
使用示例
假设上游 MySQL 实例包含以下表:
`logs`.`messages_2016`
`logs`.`messages_2017`
`logs`.`messages_2018`
`forum`.`users`
`forum`.`messages`
`forum_backup_2016`.`messages`
`forum_backup_2017`.`messages`
`forum_backup_2018`.`messages`
配置如下:
block-allow-list:  # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。
  bw-rule:
    do-dbs: ["forum_backup_2018", "forum"]
    ignore-dbs: ["~^forum_backup_"]
    do-tables:
    - db-name: "logs"
      tbl-name: "~_2018$"
    - db-name: "~^forum.*"
      tbl-name: "messages"
    ignore-tables:
    - db-name: "~.*"
      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" |