主要特性
本文档介绍 DM 提供的数据迁移功能以及相关的配置选项与使用示例。
Table Routing、Block & Allow Lists、Binlog Event Filter 在匹配库表名时,有以下版本差异:
- 对于 v1.0.5 版及后续版本,以上功能均支持通配符匹配。但注意所有版本中通配符匹配中的
*符号 只能有一个且必须在末尾。 - 对于 v1.0.5 以前的版本,Table Routing 和 Binlog Event Filter 支持通配符,但不支持
[...]与[!...]表达式。Block & Allow Lists 仅支持正则表达式。
在简单任务场景下推荐使用通配符匹配。
Table routing
Table routing 提供将上游 MySQL/MariaDB 实例的某些表迁移到下游指定表的功能。
参数配置
routes:
rule-1:
schema-pattern: "test_*"
table-pattern: "t_*"
target-schema: "test"
target-table: "t"
rule-2:
schema-pattern: "test_*"
target-schema: "test"
参数解释
将根据 schema-pattern/table-pattern 匹配上该规则的上游 MySQL/MariaDB 实例的表迁移到下游的 target-schema/target-table。
使用示例
下面展示了三个不同场景下的配置示例。
分库分表合并
假设存在分库分表场景,需要将上游两个 MySQL 实例的表 test_{1,2,3...}.t_{1,2,3...} 迁移到下游 TiDB 的一张表 test.t。
为了迁移到下游实例的表 test.t,需要创建以下 table routing 规则:
rule-1用来迁移匹配上schema-pattern: "test_*"和table-pattern: "t_*"的表的 DML/DDL 语句到下游的test.t。rule-2用来迁移匹配上schema-pattern: "test_*"的库的 DDL 语句,例如CREATE/DROP SCHEMA xx。
rule-1:
schema-pattern: "test_*"
table-pattern: "t_*"
target-schema: "test"
target-table: "t"
rule-2:
schema-pattern: "test_*"
target-schema: "test"
分库合并
假设存在分库场景,将上游两个 MySQL 实例 test_{1,2,3...}.t_{1,2,3...} 迁移到下游 TiDB 的 test.t_{1,2,3...},创建一条路由规则即可:
rule-1:
schema-pattern: "test_*"
target-schema: "test"
错误的 table routing
假设存在下面两个路由规则,test_1_bak.t_1_bak 可以匹配上 rule-1 和 rule-2,违反 table 路由的限制而报错。
rule-0:
schema-pattern: "test_*"
target-schema: "test"
rule-1:
schema-pattern: "test_*"
table-pattern: "t_*"
target-schema: "test"
target-table: "t"
rule-2:
schema-pattern: "test_1_bak"
table-pattern: "t_1_bak"
target-schema: "test"
target-table: "t_bak"
Block & Allow Table Lists
上游数据库实例表的黑白名单过滤规则,可以用来过滤或者只迁移某些 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"
参数解释
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 规则后:
Binlog event filter
Binlog event filter 是比迁移表黑白名单更加细粒度的过滤规则,可以指定只迁移或者过滤掉某些 schema / table 的指定类型 binlog,比如 INSERT、TRUNCATE TABLE。
参数配置
filters:
rule-1:
schema-pattern: "test_*"
table-pattern: "t_*"
events: ["truncate table", "drop table"]
sql-pattern: ["^DROP\\s+PROCEDURE", "^CREATE\\s+PROCEDURE"]
action: Ignore
参数解释
schema-pattern/table-pattern:对匹配上的上游 MySQL/MariaDB 实例的表的 binlog events 或者 DDL SQL 语句通过以下规则进行过滤。events:binlog events 数组,仅支持从以下Event中选择一项或多项。sql-pattern:用于过滤指定的 DDL SQL 语句,支持正则表达式匹配,例如上面示例中的"^DROP\\s+PROCEDURE"。action:string (Do/Ignore);进行下面规则判断,满足其中之一则过滤,否则不过滤。Do:白名单。binlog event 如果满足下面两个条件之一就会被过滤掉:- 不在该 rule 的
events中。 - 如果规则的
sql-pattern不为空的话,对应的 SQL 没有匹配上sql-pattern中任意一项。
- 不在该 rule 的
Ignore:黑名单。如果满足下面两个条件之一就会被过滤掉:- 在该 rule 的
events中。 - 如果规则的
sql-pattern不为空的话,对应的 SQL 可以匹配上sql-pattern中任意一项。
- 在该 rule 的
使用示例
过滤分库分表的所有删除操作
需要设置下面两个 Binlog event filter rule 来过滤掉所有的删除操作:
filter-table-rule过滤掉所有匹配到 patterntest_*.t_*的 table 的turncate table、drop table、delete statement操作。filter-schema-rule过滤掉所有匹配到 patterntest_*的 schema 的drop database操作。
filters:
filter-table-rule:
schema-pattern: "test_*"
table-pattern: "t_*"
events: ["truncate table", "drop table", "delete"]
action: Ignore
filter-schema-rule:
schema-pattern: "test_*"
events: ["drop database"]
action: Ignore
只迁移分库分表的 DML 操作
需要设置下面两个 Binlog event filter rule 只迁移 DML 操作:
do-table-rule只迁移所有匹配到 patterntest_*.t_*的 table 的create table、insert、update、delete操作。do-schema-rule只迁移所有匹配到 patterntest_*的 schema 的create database操作。
filters:
do-table-rule:
schema-pattern: "test_*"
table-pattern: "t_*"
events: ["create table", "all dml"]
action: Do
do-schema-rule:
schema-pattern: "test_*"
events: ["create database"]
action: Do
过滤 TiDB 不支持的 SQL 语句
可设置如下规则过滤 TiDB 不支持的 PROCEDURE 语句:
filters:
filter-procedure-rule:
schema-pattern: "test_*"
table-pattern: "t_*"
sql-pattern: ["^DROP\\s+PROCEDURE", "^CREATE\\s+PROCEDURE"]
action: Ignore
过滤 TiDB parser 不支持的 SQL 语句
对于 TiDB parser 不支持的 SQL 语句,DM 无法解析获得 schema/table 信息,因此需要使用全局过滤规则:schema-pattern: "*"。
可设置如下规则过滤某些版本的 TiDB parser 不支持的 PARTITION 语句:
filters:
filter-partition-rule:
schema-pattern: "*"
sql-pattern: ["ALTER\\s+TABLE[\\s\\S]*ADD\\s+PARTITION", "ALTER\\s+TABLE[\\s\\S]*DROP\\s+PARTITION"]
action: Ignore
online DDL 工具支持
在 MySQL 生态中,gh-ost 与 pt-osc 等工具较广泛地被使用,DM 对其提供了特殊的支持以避免对不必要的中间数据进行迁移。
有关 DM 对 online DDL 工具支持的原理、处理流程等,可参考 online-ddl。
使用限制
- DM 仅针对 gh-ost 与 pt-osc 做了特殊支持。
- 在开启
online-ddl时,增量复制对应的 checkpoint 应不处于 online DDL 执行过程中。如上游某次 online DDL 操作开始于 binlogposition-A、结束于position-B,则增量复制的起始点应早于position-A或晚于position-B,否则可能出现迁移出错,具体可参考 FAQ。
参数配置
如上游 MySQL/MariaDB (同时)使用 gh-ost 或 pt-osc 工具,则在 task 的配置文件中设置:
online-ddl: true
在 v2.0.5 之前的版本(不含 v2.0.5),请在 task 配置文件中使用 online-ddl-scheme 配置项。
如上游 MySQL/MariaDB 使用的是 gh-ost 工具,则在 task 的配置文件中设置:
online-ddl-scheme: "gh-ost"
如上游 MySQL/MariaDB 使用的是 pt-osc 工具,则在 task 的配置文件中设置:
online-ddl-scheme: "pt"
分库分表合并
DM 支持将上游 MySQL/MariaDB 各分库分表中的 DML、DDL 数据合并后迁移到下游 TiDB 的库表中。
使用限制
目前分库分表合并功能仅支持有限的场景,使用该功能前,请仔细阅读悲观模式分库分表合并迁移使用限制和乐观模式分库分表合并迁移使用限制。
参数配置
在 task 的配置文件中设置:
shard-mode: "pessimistic" # 默认值为 "" 即无需协调。如果为分库分表合并任务,请设置为悲观协调模式 "pessimistic"。在深入了解乐观协调模式的原理和使用限制后,也可以设置为乐观协调模式 "optimistic"
手动处理 Sharding DDL Lock
如果分库分表合并迁移过程中发生了异常,对于部分场景,可尝试参考手动处理 Sharding DDL Lock进行处理。