主要特性
本文档介绍 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 实例的某些表迁移到下游指定表的功能。
注意:
- 不支持对同一个表设置多个不同的路由规则。
- Schema 的匹配规则需要单独设置,用来迁移
CREATE/DROP SCHEMA xx,例如下面参数配置中的 rule-2。
参数配置
1. routes:
2. rule-1:
3. schema-pattern: "test_*"
4. table-pattern: "t_*"
5. target-schema: "test"
6. target-table: "t"
7. rule-2:
8. schema-pattern: "test_*"
9. 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。
注意:
- 如果下游 TiDB
schema: test已经存在,并且不会被删除,则可以省略rule-2。- 如果下游 TiDB
schema: test不存在,只设置了rule_1,则迁移会报错schema test doesn't exist。
1. rule-1:
2. schema-pattern: "test_*"
3. table-pattern: "t_*"
4. target-schema: "test"
5. target-table: "t"
6. rule-2:
7. schema-pattern: "test_*"
8. target-schema: "test"
分库合并
假设存在分库场景,将上游两个 MySQL 实例 test_{1,2,3...}.t_{1,2,3...} 迁移到下游 TiDB 的 test.t_{1,2,3...},创建一条路由规则即可:
1. rule-1:
2. schema-pattern: "test_*"
3. target-schema: "test"
错误的 table routing
假设存在下面两个路由规则,test_1_bak.t_1_bak 可以匹配上 rule-1 和 rule-2,违反 table 路由的限制而报错。
1. rule-0:
2. schema-pattern: "test_*"
3. target-schema: "test"
4. rule-1:
5. schema-pattern: "test_*"
6. table-pattern: "t_*"
7. target-schema: "test"
8. target-table: "t"
9. rule-2:
10. schema-pattern: "test_1_bak"
11. table-pattern: "t_1_bak"
12. target-schema: "test"
13. target-table: "t_bak"
Block & Allow Table Lists
上游数据库实例表的黑白名单过滤规则,可以用来过滤或者只迁移某些 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"
参数解释
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 类似。
注意:
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 是否应该被过滤的流程如下:
-
首先进行 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。
- 如果存在,则迁移
注意:
如果是判断 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" |
Binlog event filter
Binlog event filter 是比迁移表黑白名单更加细粒度的过滤规则,可以指定只迁移或者过滤掉某些 schema / table 的指定类型 binlog,比如 INSERT、TRUNCATE TABLE。
注意:
- 同一个表匹配上多个规则,将会顺序应用这些规则,并且黑名单的优先级高于白名单,即如果同时存在规则
Ignore和Do应用在某个 table 上,那么Ignore生效。- 从 DM v2.0.2 开始,Binlog event filter 也可以在上游数据库配置文件中进行配置。见上游数据库配置文件介绍。
参数配置
1. filters:
2. rule-1:
3. schema-pattern: "test_*"
4. table-pattern: "t_*"
5. events: ["truncate table", "drop table"]
6. sql-pattern: ["^DROP\\s+PROCEDURE", "^CREATE\\s+PROCEDURE"]
7. action: Ignore
参数解释
schema-pattern/table-pattern:对匹配上的上游 MySQL/MariaDB 实例的表的 binlog events 或者 DDL SQL 语句通过以下规则进行过滤。events:binlog events 数组,仅支持从以下Event中选择一项或多项。
| Event | 分类 | 解释 |
| ———————- | —— | ——————————————- |
| all | | 代表包含下面所有的 events |
| all dml | | 代表包含下面所有 DML events |
| all ddl | | 代表包含下面所有 DDL events |
| none | | 代表不包含下面所有 events |
| none ddl | | 代表不包含下面所有 DDL events |
| none dml | | 代表不包含下面所有 DML events |
| insert | DML | insert DML event |
| update | DML | update DML event |
| delete | DML | delete DML event |
| create database | DDL | create database event |
| drop database | DDL | drop database event |
| create table | DDL | create table event |
| create index | DDL | create index event |
| drop table | DDL | drop table event |
| truncate table | DDL | truncate table event |
| rename table | DDL | rename table event |
| drop index | DDL | drop index event |
| alter table | DDL | alter table 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操作。
1. filters:
2. filter-table-rule:
3. schema-pattern: "test_*"
4. table-pattern: "t_*"
5. events: ["truncate table", "drop table", "delete"]
6. action: Ignore
7. filter-schema-rule:
8. schema-pattern: "test_*"
9. events: ["drop database"]
10. 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操作。
注意:
迁移
create database/table的原因是创建库和表后才能迁移DML。
1. filters:
2. do-table-rule:
3. schema-pattern: "test_*"
4. table-pattern: "t_*"
5. events: ["create table", "all dml"]
6. action: Do
7. do-schema-rule:
8. schema-pattern: "test_*"
9. events: ["create database"]
10. action: Do
过滤 TiDB 不支持的 SQL 语句
可设置如下规则过滤 TiDB 不支持的 PROCEDURE 语句:
1. filters:
2. filter-procedure-rule:
3. schema-pattern: "test_*"
4. table-pattern: "t_*"
5. sql-pattern: ["^DROP\\s+PROCEDURE", "^CREATE\\s+PROCEDURE"]
6. action: Ignore
过滤 TiDB parser 不支持的 SQL 语句
对于 TiDB parser 不支持的 SQL 语句,DM 无法解析获得 schema/table 信息,因此需要使用全局过滤规则:schema-pattern: "*"。
注意:
全局过滤规则的设置必须尽可能严格,以避免过滤掉需要迁移的数据。
可设置如下规则过滤某些版本的 TiDB parser 不支持的 PARTITION 语句:
1. filters:
2. filter-partition-rule:
3. schema-pattern: "*"
4. sql-pattern: ["ALTER\\s+TABLE[\\s\\S]*ADD\\s+PARTITION", "ALTER\\s+TABLE[\\s\\S]*DROP\\s+PARTITION"]
5. 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。
参数配置
在 v2.0.5 及之后的版本,请在 task 配置文件中使用 online-ddl 配置项。
如上游 MySQL/MariaDB (同时)使用 gh-ost 或 pt-osc 工具,则在 task 的配置文件中设置:
yml
online-ddl: true
注意:
自 v2.0.5 起,
online-ddl-scheme已被弃用,请使用online-ddl代替online-ddl-scheme。如设置online-ddl: true会覆盖掉online-ddl-scheme。如设置online-ddl-scheme: "pt"或online-ddl-scheme: "gh-ost"会被转换为online-ddl: true。
在 v2.0.5 之前的版本(不含 v2.0.5),请在 task 配置文件中使用 online-ddl-scheme 配置项。
如上游 MySQL/MariaDB 使用的是 gh-ost 工具,则在 task 的配置文件中设置:
yml
online-ddl-scheme: "gh-ost"
如上游 MySQL/MariaDB 使用的是 pt-osc 工具,则在 task 的配置文件中设置:
yml
online-ddl-scheme: "pt"
分库分表合并
DM 支持将上游 MySQL/MariaDB 各分库分表中的 DML、DDL 数据合并后迁移到下游 TiDB 的库表中。
使用限制
目前分库分表合并功能仅支持有限的场景,使用该功能前,请仔细阅读悲观模式分库分表合并迁移使用限制和乐观模式分库分表合并迁移使用限制。
参数配置
在 task 的配置文件中设置:
1. shard-mode: "pessimistic" # 默认值为 "" 即无需协调。如果为分库分表合并任务,请设置为悲观协调模式 "pessimistic"。在深入了解乐观协调模式的原理和使用限制后,也可以设置为乐观协调模式 "optimistic"
手动处理 Sharding DDL Lock
如果分库分表合并迁移过程中发生了异常,对于部分场景,可尝试参考手动处理 Sharding DDL Lock进行处理。
