Mysql 官方提供了了一套名为:Employees Sample Database 的测试库(该测试库含有6个表,总计4百万数据记录)
表结构
下载后解压
test_db-master.zip
,然后登录 mysql 导入即可
[mysqld]
##bin-log settings##
#show variables like 'log_%';
log_bin=mysql-bin
server_id=1
binlog_format=ROW
# 创建MySQL数据库
[root@linux30 tidb]# docker run --name mysql-tidb -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /opt/tidb/mysql:/opt -v /opt/tidb/etc/mysql:/etc/mysql mysql:5.7.38
b59ff5c7a4836a2f13c4863842fa73a87c2980efa5537c06c0946d35d47dc392
[root@linux30 tidb]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b59ff5c7a483 mysql:8.0.22 "docker-entrypoint.s…" 3 seconds ago Up 2 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-tidb
[root@linux30 tidb]# docker exec -it mysql-tidb bash
root@b59ff5c7a483:/# cd /opt/test_db-master/ && ls
Changelog images load_salaries1.dump sakila test_versions.sh
README.md load_departments.dump load_salaries2.dump show_elapsed.sql
employees.sql load_dept_emp.dump load_salaries3.dump sql_test.sh
employees_partitioned.sql load_dept_manager.dump load_titles.dump test_employees_md5.sql
employees_partitioned_5.1.sql load_employees.dump objects.sql test_employees_sha.sql
root@b59ff5c7a483:/opt/test_db-master# mysql -uroot -p123456 < employees.sql
root@b59ff5c7a483:/opt/test_db-master# mysql -uroot -p123456 < test_employees_md5.sql
TiDB Data Migration (DM) 是一体化的数据迁移任务管理工具,支持从与 MySQL 协议兼容的数据库(MySQL、MariaDB、Aurora MySQL)到 TiDB 的数据迁移,DM 工具旨在降低数据迁移的运维成本。
Block & allow lists
上游数据库实例表的黑白名单过滤规则,可以用来过滤或者只迁移某些
database/table
的所有操作。
Block & Allow Lists 的过滤规则类似于 MySQL `replication-rules-db`/`replication-rules-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
。ignore-tables
:要迁移的表的黑名单,类似于 MySQL 中的 replicate-ignore-table
。以上参数值以
~
开头时均支持使用正则表达式来匹配库名、表名。
Binlog event filter
Binlog event filter 是比迁移表黑白名单更加细粒度的过滤规则,可以指定只迁移或者过滤掉某些
schema / table
的指定类型 binlog,比如INSERT
、TRUNCATE TABLE
。
Binlog Event Filter 用于过滤源数据库中特定表的特定类型操作,比如过滤掉表 `test`.`sbtest` 的 `INSERT` 操作或者过滤掉库 `test` 下所有表的 `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
中选择一项或多项。
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"
。
Table routing
Table routing 提供将上游 MySQL/MariaDB 实例的某些表迁移到下游指定表的功能。
Table Routing 是将源数据库的表迁移到下游指定表的路由功能,比如将源数据表 `test`.`sbtest1` 的数据同步到 TiDB 的表 `test`.`sbtest2`。它也是分库分表合并迁移所需的一个核心功能。
routes:
rule-1:
schema-pattern: "test_*"
table-pattern: "t_*"
target-schema: "test"
target-table: "t"
rule-2:
schema-pattern: "test_*"
target-schema: "test"
数据库版本
DDL 语法兼容性
[root@linux30 tidb]# tiup install dm
如果已经安装,则更新 TiUP DM 组件至最新版本:
[root@linux30 tidb]# tiup update --self && tiup update dm
预期输出
Update successfully!
字样。
需要根据不同的集群拓扑,编辑 TiUP 所需的集群初始化配置文件。
新建一个配置文件
topology.yaml
,部署 1 个 DM-master、1个 DM-worker 的配置如下
[root@linux30 tidb]# vi topology.yaml
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/opt/tidb/tidb-deploy/dm"
data_dir: "/opt/tidb/tidb-data/dm"
# arch: "amd64"
master_servers:
- host: 192.168.10.30
worker_servers:
- host: 192.168.10.30
注意:
通过 TiUP 进行集群部署可以使用密钥或者交互密码方式来进行安全认证:
-i
或者 --identity_file
来指定密钥的路径;-p
进入密码交互窗口;tiup dm deploy dm-test ${version} ./topology.yaml --user root [-p] [-i /home/root/.ssh/gcp_rsa]
以上部署命令中:
dm-test
。--user root
:通过 root 用户登录到目标主机完成集群部署,该用户需要有 ssh 到目标机器的权限,并且在目标机器有 sudo 权限。也可以用其他有 ssh 和 sudo 权限的用户完成部署。-i
及 -p
:非必选项,如果已经配置免密登录目标机,则不需填写,否则选择其一即可。-i
为可登录到目标机的 root 用户(或 --user
指定的其他用户)的私钥,也可使用 -p
交互式输入该用户的密码。预期日志结尾输出会有
Deployed cluster
dm-testsuccessfully
关键词,表示部署成功。
部署版本为
${version}
,可以通过执行tiup list dm-master
来查看 TiUP 支持的最新版本
[root@linux30 tidb]# tiup list dm-master
我们发现有个版本是v5.3.0
[root@linux30 tidb]# tiup dm deploy dm-test 5.3.0 ./topology.yaml --user root -p
出现如下界面,选择y继续,输入密码后继续安装
继续安装后,安装完成后输出
deployed successfully
代表安装完成
TiUP 支持管理多个 DM 集群,该命令会输出当前通过 TiUP DM 管理的所有集群信息,包括集群名称、部署用户、版本、密钥信息等
[root@linux30 tidb]# tiup dm list
执行如下命令检查
dm-test
集群情况
[root@linux30 tidb]# tiup dm display dm-test
预期输出包括 dm-test
集群中实例 ID、角色、主机、监听端口和状态(由于还未启动,所以状态为 Down/inactive)、目录信息。
预期结果输出
Started cluster
dm-testsuccessfully
表示启动成功。
[root@linux30 tidb]# tiup dm start dm-test
在输出结果中,如果 Status 状态信息为
Up
,说明集群状态正常。
[root@linux30 tidb]# tiup dm display dm-test
dmctl 是用来运维 DM 集群的命令行工具,支持交互模式和命令模式。
通过如下命令可用查看
dmctl
版本列表
[root@linux30 tidb]# tiup list dmctl
我们发现一个版本是
v5.3.0
通过如下命令可用安装dmctl组件,冒号后面是需要安装的版本号
[root@linux30 tidb]# tiup install dmctl:v5.3.0
#创建tidb用户密码是 tidb并授权外部所以IP可以访问
mysql> CREATE USER 'tidb'@'%' IDENTIFIED BY 'tidb';
Query OK, 0 rows affected (0.02 sec)
# 授权SELECT,RELOAD,LOCK TABLES,REPLICATION CLIENT 权限给tidb用户
mysql> GRANT SELECT,RELOAD,LOCK TABLES,REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'tidb'@'%';
Query OK, 0 rows affected (0.01 sec)
# 刷新数据库
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
因为DM同步需要MySQL开启binlog日志,修改my.cnf配置文件,并重启
[mysqld]
##bin-log settings##
#show variables like 'log_%';
log_bin=mysql-bin
server_id=1
binlog_format=ROW
x
SHOW VARIABLES LIKE '%server_id%';
show variables like 'log_bin%';
show variables like 'binlog_format';
在 DM 相关配置文件中,推荐使用经 dmctl 加密后的密码,对于同一个原始密码,每次加密后密码不同。
[root@linux30 tidb]# tiup dmctl -encrypt 'tidb'
加密后的密码是:
l5nO6geu58/BjrOOZpAtAkAjsn/q
使用 TiUP 部署 DM 集群后,相关配置信息如下:
组件 | 主机 | 端口 |
---|---|---|
dm_worker | 192.168.10.30 | 8262 |
dm_master | 192.168.10.30 | 8261 |
数据库实例 | 主机 | 端口 | 用户名 | 加密密码 |
---|---|---|---|---|
上游 MySQL | 192.168.10.30 | 3306 | tidb | l5nO6geu58/BjrOOZpAtAkAjsn/q |
下游 TiDB | 192.168.10.30 | 4000 | root |
将 MySQL 的相关信息写入到
mysql.yaml
中
[root@linux30 tidb]# vi mysql.yaml
# MySQL1 Configuration.
source-id: "mysql-replica"
# DM-worker 是否使用全局事务标识符 (GTID) 拉取 binlog。使用前提是在上游 MySQL 已开启 GTID 模式。
enable-gtid: false
from:
host: "192.168.10.30"
user: "tidb"
password: "l5nO6geu58/BjrOOZpAtAkAjsn/q"
port: 3306
在终端中执行下面的命令,使用
tiup dmctl
将 MySQL 的数据源配置加载到 DM 集群中:
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 operate-source create mysql.yaml
出现如下界面返回
true
表示添加到集群成功
假设需要将 MySQL实例的
employees
库的 所有 表以全量+增量的模式迁移到下游 TiDB 的employees
库 编辑任务配置文件sync_task.yaml
[root@linux30 tidb]# vi sync_task.yaml
# 任务名,多个同时运行的任务不能重名。
name: "tidb_sync"
# 全量+增量 (all) 迁移模式。
task-mode: "all"
# 下游 TiDB 配置信息。
target-database:
host: "192.168.10.30"
port: 4000
user: "root"
password: ""
# 黑白名单全局配置,各实例通过配置项名引用。
#block-allow-list: # 如果 DM 版本 <= v2.0.0-beta.2 则使用 black-white-list。
# global:
# do-tables: # 需要迁移的上游表的白名单。
# - db-name: "test_db" # 需要迁移的表的库名。
# tbl-name: "test_table" # 需要迁移的表的名称。
block-allow-list:
ba-rule1:
do-dbs: ["employees"]
# 当前数据迁移任务需要的全部上游 MySQL 实例配置。
mysql-instances:
# 上游实例或者复制组 ID,参考 `inventory.ini` 的 `source_id` 或者 `dm-master.toml` 的 `source-id 配置`。
- source-id: "mysql-replica"
# 需要迁移的库名或表名的黑白名单的配置项名称,用于引用全局的黑白名单配置,全局配置见下面的 `block-allow-list` 的配置。
block-allow-list: "ba-rule1"
为了提前发现数据迁移任务的一些配置错误,DM 中增加了前置检查功能:
- 启动数据迁移任务时,DM 自动检查相应的权限和配置。
check-task
命令用于对上游 MySQL 实例配置是否满足 DM 要求进行前置检查。
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 check-task sync_task.yaml
如果出现返回结果是true表示检查成功
使用
tiup dmctl
执行以下命令启动数据迁移任务。其中,sync_task.yaml
是之前编辑的配置文件。
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 start-task sync_task.yaml
返回结果为true表示启动成功
如需了解 DM 集群中是否存在正在运行的迁移任务及任务状态等信息,可使用
tiup dmctl
执行以下命令进行查询:
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 query-status
query-status
命令的查询结果、任务状态与子任务状态
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 query-status tidb_sync
任务详情如下
同步文本详情如下
{
"result": true, # 查询是否成功
"msg": "", # 查询失败原因描述
"sources": [ # 上游 MySQL 列表
{
"result": true,
"msg": "",
"sourceStatus": { # 上游 MySQL 的信息
"source": "mysql-replica",
"worker": "dm-192.168.64.152-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [ # 上游 MySQL 所有子任务的信息
{
"name": "tidb_sync", # 子任务名称
"stage": "Running", # 子任务运行状态,包括 “New”,“Running”,“Paused”,“Stopped” 以及 “Finished”
"unit": "Sync", # DM 的处理单元,包括 “Check”,“Dump“,“Load” 以及 “Sync”
"result": null, # 子任务失败时显示错误信息
"unresolvedDDLLockID": "", # sharding DDL lock ID,可用于异常情况下手动处理 sharding DDL lock
"sync": { # 当前 `Sync` 处理单元的迁移信息
"totalEvents": "0", # 该子任务中迁移的 binlog event 总数
"totalTps": "0", # 该子任务中每秒迁移的 binlog event 数量
"recentTps": "0", # 该子任务中最后一秒迁移的 binlog event 数量
"masterBinlog": "(mysql-bin.000001, 154)", # 上游数据库当前的 binlog position
"masterBinlogGtid": "", # 上游数据库当前的 GTID 信息
"syncerBinlog": "(mysql-bin.000001, 154)", # 已被 `Sync` 处理单元迁移的 binlog position
"syncerBinlogGtid": "", # 使用 GTID 迁移的 binlog position
"blockingDDLs": [ # 当前被阻塞的 DDL 列表。该项仅在当前 DM-worker 所有上游表都处于 “synced“ 状态时才有数值,此时该列表包含的是待执行或待跳过的 sharding DDL 语句
],
"unresolvedGroups": [ # 没有被解决的 sharding group 信息
],
"synced": true, # 增量复制是否已追上上游。由于后台 `Sync` 单元并不会实时刷新保存点,当前值为 “false“ 并不一定代表发生了迁移延迟
"binlogType": "remote"
}
}
]
}
]
}
登录TiDB 查看数据库是否同步
[root@linux30 tidb]# mysql -uroot -p -P 4000 -h 192.168.10.30
show databases;
use employees;
show tables;
我们发现数据库已经同步
部门表插入一条数据
mysql> INSERT INTO employees.`departments`(dept_no,dept_name)VALUES('d010','test dept');
Query OK, 1 row affected (0.01 sec)
将
dept_emp
中的d001
改为d010
UPDATE employees.dept_emp SET dept_no='d010' WHERE dept_no='d001';
共 20211 行受到影响
[root@linux30 tidb]# tiup dmctl --master-addr 192.168.10.30:8261 query-status tidb_sync
“synced”: false正在同步
稍等后在进行查看任务状态,发现已经同步完成
登录MySQL后检查MySQL中的数据是否同步到TiDB
[root@linux30 tidb]# mysql -uroot -p -P 4000 -h 192.168.10.30
MySQL [employees]> use employees;
MySQL [employees]> SELECT COUNT(1) FROM dept_emp WHERE dept_no='d010';
+----------+
| COUNT(1) |
+----------+
| 20211 |
+----------+
1 row in set (0.01 sec)
我们发现
d010
的更新数据都已经同步过来了
pause-task
命令用于暂停数据迁移任务。有关
pause-task
与stop-task
的区别如下
pause-task
仅暂停迁移任务的执行,但仍然会在内存中保留任务的状态信息等,且可通过 query-status
进行查询;使用 stop-task
会停止迁移任务的执行,并移除内存中与该任务相关的信息,且不可再通过 query-status
进行查询,但不会移除已经写入到下游数据库中的数据以及其中的 checkpoint 等 dm_meta
信息。pause-task
暂停迁移任务期间,由于任务本身仍然存在,因此不能再启动同名的新任务,且会阻止对该任务所需 relay log 的清理;使用 stop-task
停止任务后,由于任务不再存在,因此可以再启动同名的新任务,且不会阻止对 relay log 的清理。pause-task
一般用于临时暂停迁移任务以排查问题等;stop-task
一般用于永久删除迁移任务或通过与 start-task
配合以更新配置信息。tiup dmctl --master-addr 192.168.64.152:8261 pause-task tidb_sync
resume-task
命令用于恢复处于Paused
状态的数据迁移任务,通常用于在人为处理完造成迁移任务暂停的故障后手动恢复迁移任务。
tiup dmctl --master-addr 192.168.64.152:8261 resume-task tidb_sync
stop-task
命令用于停止数据迁移任务
tiup dmctl --master-addr 192.168.64.152:8261 stop-task tidb_sync