作者: Hacker_小峰



DM 部署



第 1 步:在中控机上安装 TiUP 组件

使用普通用户登录中控机,以 tidb 用户为例,后续安装 TiUP 及集群管理操作均通过该用户完成:

执行如下命令安装 TiUP 工具:

curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh

安装完成后,​​~/.bashrc​​​ 已将 TiUP 加入到路径中,你需要新开一个终端或重新声明全局变量 ​​source ~/.bashrc​​ 来使用 TiUP。

source /home/tidb/.bash_profile

安装 TiUP DM 组件:

tiup install dm dmctl



第 2 步:编辑初始化配置文件

$ vim dm-test-topology.yaml
# Global variables are applied to all deployments and as the default value of
# them if the specific deployment value missing.
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/data/dm-deploy"
data_dir: "/data/dm-data"

server_configs:
master:
log-level: info
# rpc-timeout: "30s"
# rpc-rate-limit: 10.0
# rpc-rate-burst: 40
worker:
log-level: info

master_servers:
- host: 10.1.1.6
name: master1
ssh_port: 22
port: 8261
peer_port: 8291
deploy_dir: "/data/dm-deploy/dm-master-8261"
data_dir: "/data/dm-data/dm-master-8261"
log_dir: "/data/dm-deploy/dm-master-8261/log"
# numa_node: "0,1"
# # The following configs are used to overwrite the `server_configs.master` values.
# config:
# log-level: info
# rpc-timeout: "30s"
# rpc-rate-limit: 10.0
# rpc-rate-burst: 40
- host: 10.1.1.6
name: master3
ssh_port: 22
port: 8263
peer_port: 8293
deploy_dir: "/data01/dm-deploy/dm-master-8263"
data_dir: "/data01/dm-data/dm-master-8263"
log_dir: "/data01/dm-deploy/dm-master-8263/log"
# numa_node: "0,1"
# # The following configs are used to overwrite the `server_configs.master` values.
# config:
# log-level: info
# rpc-timeout: "30s"
# rpc-rate-limit: 10.0
# rpc-rate-burst: 40
- host: 10.1.1.7
name: master2
ssh_port: 22
port: 8261
peer_port: 8291
deploy_dir: "/data01/dm-deploy/dm-master-8261"
data_dir: "/data01/dm-data/dm-master-8261"
log_dir: "/data01/dm-deploy/dm-master-8261/log"
# numa_node: "0,1"
# # The following configs are used to overwrite the `server_configs.master` values.
# config:
# log-level: info
# rpc-timeout: "30s"
# rpc-rate-limit: 10.0
# rpc-rate-burst: 40
worker_servers:
- host: 10.1.1.6
# ssh_port: 22
# port: 8262
deploy_dir: "/data02/dm-deploy/dm-worker-8262"
log_dir: "/data02/dm-deploy/dm-worker-8262/log"
# numa_node: "0,1"
# # Config is used to overwrite the `server_configs.dm-worker` values
# config:
# log-level: info
- host: 10.1.1.7
# ssh_port: 22
# port: 8262
deploy_dir: "/data02/dm-deploy/dm-worker-8262"
log_dir: "/data02/dm-deploy/dm-worker-8262/log"
# numa_node: "0,1"
# # Config is used to overwrite the `server_configs.dm-worker` values
# config:
# log-level: info
monitoring_servers:
- host: 10.1.1.7
# ssh_port: 22
# port: 9090
# deploy_dir: "/tidb-deploy/prometheus-8249"
# data_dir: "/tidb-data/prometheus-8249"
# log_dir: "/tidb-deploy/prometheus-8249/log"

grafana_servers:
- host: 10.1.1.7
# port: 3000
# deploy_dir: /tidb-deploy/grafana-3000

alertmanager_servers:
- host: 10.1.1.7
# ssh_port: 22
# web_port: 9093
# cluster_port: 9094
# deploy_dir: "/tidb-deploy/alertmanager-9093"
# data_dir: "/tidb-data/alertmanager-9093"
# log_dir: "/tidb-deploy/alertmanager-9093/log"

# if monitored is set, node_exporter and blackbox_exporter will be
# deployed with the port specified, otherwise they are not deployed
# on the server to avoid conflict with tidb clusters
#monitored:
# node_exporter_port: 9100
# blackbox_exporter_port: 9115



第 3 步:执行部署命令

tiup dm deploy dm-test ${version} ./topology.yaml --user root [-p] [-i /home/root/.ssh/gcp_rsa]

首先,用 ​​tiup list dm-master​​ 来查看 TiUP 支持的最新版本。

$ tiup list dm-master
Available versions for dm-master:
Version Installed Release Platforms
------- --------- ------- ---------
nightly -> v6.5.0-alpha-nightly-20221108 2022-11-08T23:51:38+08:00 linux/amd64,linux/arm64
build-debug-mode 2022-06-10T14:27:38+08:00 linux/amd64,linux/arm64
v2.0.0-rc 2020-08-21T17:49:08+08:00 linux/amd64,linux/arm64
v2.0.0-rc.2
......
v6.1.2 2022-10-24T15:14:40+08:00 linux/amd64,linux/arm64
v6.2.0 2022-08-23T09:12:26+08:00 linux/amd64,linux/arm64
v6.3.0 2022-09-30T10:57:42+08:00 linux/amd64,linux/arm64
v6.5.0-alpha-nightly-20221108 2022-11-08T23:51:38+08:00 linux/amd64,linux/arm64

安装最新版本 DM:

tiup dm deploy dm-test v6.5.0-alpha-nightly-20221108 /home/tidb/dm/dm-test-topology.yaml --user tidb -p -i /home/tidb/.ssh/id_rsa



第 4 步:查看 TiUP 管理的集群情况

$ tiup dm list
tiup is checking updates for component dm ...
Starting component `dm`: /home/tidb/.tiup/components/dm/v1.11.0/tiup-dm list
Name User Version Path PrivateKey
---- ---- ------- ---- ----------
dm-test tidb v6.5.0-alpha-nightly-20221108 /home/tidb/.tiup/storage/dm/clusters/dm-test /home/tidb/.tiup/storage/dm/clusters/dm-test/ssh/id_rsa



第 5 步:检查部署的 DM 集群情况

例如,执行如下命令检查 dm-test 集群情况:

tiup dm display dm-test



第 6 步:启动集群

$ tiup dm start dm-test
......
Started cluster `dm-test` successfully



第 7 步:验证集群运行状态

$ tiup dm display dm-test
tiup is checking updates for component dm ...
Starting component `dm`: /home/tidb/.tiup/components/dm/v1.11.0/tiup-dm display dm-test
Cluster type: dm
Cluster name: dm-test
Cluster version: v6.5.0-alpha-nightly-20221108
Deploy user: tidb
SSH type: builtin
Grafana URL: http://10.1.1.7:3000
ID Role Host Ports OS/Arch Status Data Dir Deploy Dir
-- ---- ---- ----- ------- ------ -------- ----------
10.1.1.7:9093 alertmanager 10.1.1.7 9093/9094 linux/x86_64 Up /data/dm-data/alertmanager-9093 /data/dm-deploy/alertmanager-9093
10.1.1.6:8261 dm-master 10.1.1.6 8261/8291 linux/x86_64 Healthy /data/dm-data/dm-master-8261 /data/dm-deploy/dm-master-8261
10.1.1.6:8263 dm-master 10.1.1.6 8263/8293 linux/x86_64 Healthy /data01/dm-data/dm-master-8263 /data01/dm-deploy/dm-master-8263
10.1.1.7:8261 dm-master 10.1.1.7 8261/8291 linux/x86_64 Healthy|L /data01/dm-data/dm-master-8261 /data01/dm-deploy/dm-master-8261
10.1.1.6:8262 dm-worker 10.1.1.6 8262 linux/x86_64 Free /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:8262 dm-worker 10.1.1.7 8262 linux/x86_64 Free /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:3000 grafana 10.1.1.7 3000 linux/x86_64 Up - /data/dm-deploy/grafana-3000
10.1.1.7:9090 prometheus 10.1.1.7 9090 linux/x86_64 Up /data/dm-data/prometheus-9090 /data/dm-deploy/prometheus-9090
Total nodes: 8



第 8 步:使用 dmctl 管理迁移任务

dmctl 是用来控制集群运行命令的工具,推荐​​通过 TiUP 获取该工具​​。

dmctl 支持命令模式与交互模式,具体请见​​使用 dmctl 运维集群​​。



DM 迁移 MySQL 数据库到 TiDB



第 1 步:部署 DM 集群

见上一步。



第 2 步:检查集群信息

  1. DM 集群信息

组件 | 主机 | 端口 ---| ---|--- dm-worker1 | 10.1.1.6| 8262 dm-worker2 | 10.1.1.7| 8262 dm-master1 | 10.1.1.7| 8261 dm-master2 | 10.1.1.6| 8263 dm-master3 | 10.1.1.6| 8261

  1. 检查上下游数据库实例信息

数据库实例| 主机 | 端口 | 用户名| 加密密码 ---| ---|---|---|---|--- 上游 MySQL-1 |10.1.1.2|3327|dm_mysql |BMYKGn9OSFJAO6GnjJKkoECFKdSBIOreAuqSr1Zf 下游 TiDB |10.1.1.10|4000|dm_tidb |7kTuLQ5o8XaFtInawrSDGEDPNTKiGgD89/UnL7Y=

  1. 创建上下游所需权限用户
#上游MySQL数据库需要的权限
CREATE USER 'dm_mysql'@'10.%' IDENTIFIED BY 'dm_mysql@!666';
GRANT REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SELECT ON *.* TO 'dm_mysql'@'10.%';
flush privileges;

#下游tidb数据库需要的权限
CREATE USER 'dm_tidb'@'10.%' IDENTIFIED BY 'dm_tidb@!666';
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,INDEX ON *.* TO 'dm_tidb'@'10.%';
flush privileges;
  1. 上下游账号密码加解密

加密密码:

tiup dmctl -encrypt '明文'

解密密码:

tiup dmctl -decrypt '密文'

使用 dmctl 组件来加密, 对于同一个原始密码,每次加密后密码不同。



第 3 步: 创建数据源

  1. 将上游 MySQL-1 的相关信息写入到 conf/source1.yaml 中:
vim source1.yaml
# MySQL1 Configuration.

source-id: "mysql-replica-01"

# DM-worker 是否使用全局事务标识符 (GTID) 拉取 binlog。使用前提是在上游 MySQL 已开启 GTID 模式。
enable-gtid: false

from:
host: "10.1.1.2"
user: "dm_mysql"
password: "BMYKGn9OSFJAO6GnjJKkoECFKdSBIOreAuqSr1Zf"
port: 3327
  1. 使用 ​​tiup dmctl​​ 将 MySQL-1 的数据源配置加载到 DM 集群:
$ tiup dmctl --master-addr 10.1.1.7:8261 operate-source create /home/tidb/dm/conf/source1.yaml
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262"
}
]
}

【Tips】

  • 每 ​​operate-source create source1.yaml​​​一下,就占用一个 ​​dm-worker​​​,也就是会有一个​​dm-worker​​​处于 ​​Bound​​ 状态。
  • 除了 ​​create source.yaml​​​ 还可以使用 ​​update、stop、show​​​。不过测试无法使用 ​​update​​ 命令,应该和 DM 在 HA 模式有关。



第 4 步:配置任务

假设需要将 MySQL-1 实例的 sbtest 库的 sbtest1 表以全量+增量的模式迁移到下游 TiDB 的 test_db 库的 test_table 表。

编辑任务配置文件 task1-sbtest.yaml:

vim task1-sbtest.yaml
# 任务名,多个同时运行的任务不能重名。
name: "sbtest"
# 全量+增量 (all) 迁移模式。
task-mode: "all"
# 下游 TiDB 配置信息。
target-database:
host: "10.1.1.10"
port: 4000
user: "dm_tidb"
password: "7kTuLQ5o8XaFtInawrSDGEDPNTKiGgD89/UnL7Y=" # 推荐使用经 dmctl encrypt 加密后的密码

# 当前数据迁移任务需要的全部上游 MySQL 实例配置。
mysql-instances:
-
# 上游实例或者复制组 ID,参考 `inventory.ini` 的 `source_id` 或者 `dm-master.toml` 的 `source-id 配置`。
source-id: "mysql-replica-01"
# 需要迁移的库名或表名的黑白名单的配置项名称,用于引用全局的黑白名单配置,全局配置见下面的 `block-allow-list` 的配置。
block-allow-list: "listA" # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。

block-allow-list: # 如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list。
listA:
do-tables: # 需要迁移的上游表的白名单。
- db-name: "sbtest" # 需要迁移的表的库名。
tbl-name: "sbtest1" # 需要迁移的表的名称。



第 5 步:启动任务

  1. 前置检查

为了提前发现数据迁移任务的一些配置错误,DM 中增加了前置检查功能:

  • 启动数据迁移任务时,DM 自动检查相应的权限和配置。
  • 也可使用 check-task 命令手动前置检查上游的 MySQL 实例配置是否符合 DM 的配置要求。

配置好后,可以先使用​​check-task​​检查下配置项:

tiup dmctl --master-addr 10.1.1.7:8261 check-task task1-sbtest.yaml

返回​​pre-check is passed.​​说明检查通过。

  1. 启动任务

使用 tiup dmctl 执行以下命令启动数据迁移任务。其中,task1-sbtest.yaml 是之前编辑的配置文件。

tiup dmctl --master-addr 10.1.1.7:8261  start-task /home/tidb/dm/conf/task1-sbtest.yaml
  • 如果执行该命令后返回的结果如下,则表明任务已成功启动。
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262"
}
],
"checkResult": "pre-check is passed. "
}
  • 如果任务启动失败,可根据返回结果的提示进行配置变更后执行 ​​start-task task.yaml​​ 命令重新启动任务。


第 6 步:查询任务

tiup dmctl --master-addr 10.1.1.7:8261  query-status
{
"result": true,
"msg": "",
"tasks": [
{
"taskName": "sbtest",
"taskStatus": "Running",
"sources": [
"mysql-replica-01"
]
}
]
}



第 7 步:查看任务状态

tiup dmctl --master-addr ${advertise-addr} query-status ${task-name}
$ tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status sbtest
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "sbtest",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "19",
"totalTps": "0",
"recentTps": "0",
"masterBinlog": "(mysql-bin.000204, 635)",
"masterBinlogGtid": "",
"syncerBinlog": "(mysql-bin.000204, 635)",
"syncerBinlogGtid": "",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
},
"validation": null
}
]
}
]
}



第 8 步:查看 DM 集群及监控

查看 DM 集群状态:

$ tiup dm display dm-test
tiup is checking updates for component dm ...
Starting component `dm`: /home/tidb/.tiup/components/dm/v1.11.0/tiup-dm display dm-test
Cluster type: dm
Cluster name: dm-test
Cluster version: v6.5.0-alpha-nightly-20221108
Deploy user: tidb
SSH type: builtin
Grafana URL: http://10.1.1.7:3000
ID Role Host Ports OS/Arch Status Data Dir Deploy Dir
-- ---- ---- ----- ------- ------ -------- ----------
10.1.1.7:9093 alertmanager 10.1.1.7 9093/9094 linux/x86_64 Up /data/dm-data/alertmanager-9093 /data/dm-deploy/alertmanager-9093
10.1.1.6:8261 dm-master 10.1.1.6 8261/8291 linux/x86_64 Healthy /data/dm-data/dm-master-8261 /data/dm-deploy/dm-master-8261
10.1.1.6:8263 dm-master 10.1.1.6 8263/8293 linux/x86_64 Healthy /data01/dm-data/dm-master-8263 /data01/dm-deploy/dm-master-8263
10.1.1.7:8261 dm-master 10.1.1.7 8261/8291 linux/x86_64 Healthy|L /data01/dm-data/dm-master-8261 /data01/dm-deploy/dm-master-8261
10.1.1.6:8262 dm-worker 10.1.1.6 8262 linux/x86_64 Free /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:8262 dm-worker 10.1.1.7 8262 linux/x86_64 Bound /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:3000 grafana 10.1.1.7 3000 linux/x86_64 Up - /data/dm-deploy/grafana-3000
10.1.1.7:9090 prometheus 10.1.1.7 9090 linux/x86_64 Up /data/dm-data/prometheus-9090 /data/dm-deploy/prometheus-9090
Total nodes: 8
  • 可以看到一个 ​​dm-worker​​​ 显示被占用,处于 ​​Bound​​ 状态;
  • 还有一个​​dm-worker​​​ 处于空闲的 ​​Free​​ 状态;
  • 可在浏览器中打开 ​​http://10.1.1.7:9093​​ 进入 Alertmanager 查看 DM 告警信息;
  • 可在浏览器中打开 ​​http://10.1.1.7:3000​​ 进入 Grafana,选择 DM 的 dashboard 查看 DM 相关监控项。


DM 迁移 MySQL 分库分表到下游 TiDB



迁移目标

上游 MySQL:

Schema

Tables

sharding001

user_push01

sharding002

user_push01

迁移目标库的结构如下:

Schema

Tables

sharding_merge

user_push

迁移目标:

  • 将sharding[001-002] 的 user_push01 表合并才下游 tidb 的 sharding_merge 库 user_push 表。


分表数据冲突检查



第 1 步: 创建数据源

新建 ​​source2.yaml​​ 文件:

vim source2.yaml
# 唯一命名,不可重复。
source-id: "mysql-sharding-01"

# DM-worker 是否使用全局事务标识符 (GTID) 拉取 binlog。使用前提是上游 MySQL 已开启 GTID 模式。若上游存在主从自动切换,则必须使用 GTID 模式。
#enable-gtid: true

from:
host: "10.1.1.2" # 例如:172.16.10.81
user: "dm_mysql"
password: "BMYKGn9OSFJAO6GnjJKkoECFKdSBIOreAuqSr1Zf" # 支持但不推荐使用明文密码,建议使用 dmctl encrypt 对明文密码进行加密后使用
port: 3327

创建数据源:

tiup dmctl --master-addr 10.1.1.7:8261 operate-source create source2.yaml



第 2 步:创建迁移任务

新建​​task2-shard-merge.yaml​​文件, 写入以下内容:

name: "shard_merge"
# 任务模式,可设为
# full:只进行全量数据迁移
# incremental: binlog 实时同步
# all: 全量 + binlog 迁移
task-mode: all
# 分库分表合并任务则需要配置 shard-mode。默认使用悲观协调模式 "pessimistic",在深入了解乐观协调模式的原理和使用限制后,也可以设置为乐观协调模式 "optimistic"
# 详细信息可参考:https://docs.pingcap.com/zh/tidb/dev/feature-shard-merge/
shard-mode: "pessimistic"
meta-schema: "dm_meta" # 将在下游数据库创建 schema 用于存放元数据
#ignore-checking-items: ["schema_of_shard_tables"] #任务过程中存在表一致性的报错,加上即可忽略
ignore-checking-items: ["auto_increment_ID"] # 本示例中上游存在自增主键,因此需要忽略掉该检查项

target-database:
host: "10.1.1.10" # 例如:192.168.0.1
port: 4000
user: "dm_tidb"
password: "7kTuLQ5o8XaFtInawrSDGEDPNTKiGgD89/UnL7Y=" # 支持但不推荐使用明文密码,建议使用 dmctl encrypt 对明文密码进行加密后使用

mysql-instances:
-
source-id: "mysql-sharding-01" # 数据源 ID,即 source2.yaml 中的 source-id
route-rules: ["route-rule"] # 应用于该数据源的 table route 规则
filter-rules: ["store-filter-rule","sale-filter-rule"] # 应用于该数据源的 binlog event filter 规则
block-allow-list: "log-bak-ignored" # 应用于该数据源的 Block & Allow Lists 规则
mydumper-config-name: "global" # mydumpers 配置的名称
loader-config-name: "global" # loaders 配置的名称
syncer-config-name: "global" # syncers 配置的名称
# 分表合并配置
routes:
route-rule:
schema-pattern: "sharding*"
table-pattern: "user_push*"
target-schema: "sharding_merge"
target-table: "user_push"

# 过滤部分 DDL 事件
filters:
sale-filter-rule:
schema-pattern: "sharding*"
table-pattern: "user_push*"
events: ["truncate table", "drop table", "delete"]
action: Ignore
store-filter-rule:
schema-pattern: "sharding*"
events: ["drop database"]
action: Ignore

# 黑白名单
block-allow-list:
log-bak-ignored:
do-dbs: ["~^sharding*"] # 非 ~ 字符开头,表示规则是通配符;v1.0.5 及后续版本支持通配符规则。
do-tables:
- db-name: "~^sharding*" # 匹配 sharding001,sharding002。
tbl-name: "~^user_push*" # 匹配 user_push01。

mydumpers: # dump 处理单元的运行配置参数
global: # 配置名称
threads: 4 # dump 处理单元从上游数据库实例导出数据的线程数量,默认值为 4
chunk-filesize: 64 # dump 处理单元生成的数据文件大小,默认值为 64,单位为 MB
# extra-args: "--consistency none" # dump 处理单元的其他参数,不需要在 extra-args 中配置 table-list,DM 会自动生成

loaders: # load 处理单元的运行配置参数
global: # 配置名称
pool-size: 4 # load 处理单元并发执行 dump 处理单元的 SQL 文件的线程数量,默认值为 16,当有多个实例同时向 TiDB 迁移数据时可根据负载情况适当调小该值
# dir: "./dumped_data" # dump 处理单元输出 SQL 文件的目录,同时也是 load 处理单元读取文件的目录。该配置项的默认值为 "./dumped_data"。同实例对应的不同任务必须配置不同的目录


syncers: # sync 处理单元的运行配置参数
global: # 配置名称
worker-count: 4 # 应用已传输到本地的 binlog 的并发线程数量,默认值为 16。调整此参数不会影响上游拉取日志的并发,但会对下游产生显著压力。
batch: 100 # sync 迁移到下游数据库的一个事务批次 SQL 语句数,默认值为 100,建议一般不超过 500。
enable-ansi-quotes: true # 若 `session` 中设置 `sql-mode: "ANSI_QUOTES"`,则需开启此项



第 3 步: 启动任务

在你启动数据迁移任务之前,建议使用check-task命令检查配置是否符合 DM 的配置要求,以降低后期报错的概率。

前置检查:

tiup dmctl --master-addr ${advertise-addr} check-task task2.yaml

启动任务:

$ tiup dmctl --master-addr 10.1.1.7:8261 start-task task2.yaml
tiup is checking updates for component dmctl ...
A new version of dmctl is available:
The latest version: v6.4.0
Local installed version: v6.3.0
Update current component: tiup update dmctl
Update all components: tiup update --all

Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 start-task task2.yaml
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "user-sharding",
"worker": "dm-10.1.1.7-8262"
}
],
"checkResult": "fail to check synchronization configuration with type: no errors but some warnings
detail: {
"results": [
{
"id": 12,
"name": "sharding table `sharding_merge`.`user_push` consistency checking",
"desc": "check consistency of sharding table structures",
"state": "warn",
"errors": [
{
"severity": "fail",
"short_error": "sourceID user-sharding table {sharding001 user_push01} of sharding `sharding_merge`.`user_push` have auto-increment key, please make sure them don't conflict in target table!"
},
{
"severity": "fail",
"short_error": "sourceID user-sharding table {sharding002 user_push01} of sharding `sharding_merge`.`user_push` have auto-increment key, please make sure them don't conflict in target table!"
}
],
"instruction": "If happen conflict, please handle it by yourself. You can refer to https://docs.pingcap.com/tidb-data-migration/stable/shard-merge-best-practices/#handle-conflicts-between-primary-keys-or-unique-indexes-across-multiple-sharded-tables",
"extra": "auto-increment key checking"
}
],
"summary": {
"passed": true,
"total": 13,
"successful": 12,
"failed": 0,
"warning": 1
}
}"
}



第 4 步: 查看任务状态

查看任务:

tiup dmctl --master-addr ${advertise-addr} query-status ${task-name}
$ tiup dmctl --master-addr 10.1.1.7:8261 query-status shard_merge
tiup is checking updates for component dmctl ...
A new version of dmctl is available:
The latest version: v6.4.0
Local installed version: v6.3.0
Update current component: tiup update dmctl
Update all components: tiup update --all

Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status shard_merge
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-sharding-01",
"worker": "dm-10.1.1.6-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "shard_merge",
"stage": "Running",
"unit": "Load",
"result": null,
"unresolvedDDLLockID": "",
"load": {
"finishedBytes": "5826081601",
"totalBytes": "27887789287",
"progress": "20.89 %",
"metaBinlog": "(mysql-bin.000233, 207018196)",
"metaBinlogGTID": ""
},
"validation": null
}
]
}
]
}



第 5 步: 校验上下游数据

  1. 下载工具
wget https://download.pingcap.org/tidb-enterprise-tools-nightly-linux-amd64.tar.gz
tar zxvf tidb-enterprise-tools-nightly-linux-amd64.tar.gz
  1. 编写 sync-diff-inspector 配置文件:
# Diff Configuration.

######################### Global config #########################

# 检查数据的线程数量,上下游数据库的连接数会略大于该值
check-thread-count = 4

# 如果开启,若表存在不一致,则输出用于修复的 SQL 语句
export-fix-sql = true

# 只对比表结构而不对比数据
check-struct-only = false

# dm-master 的地址, 格式为 "http://127.0.0.1:8261"
dm-addr = "http://10.1.1.7:8261"

# 指定 DM 的 `task-name`
dm-task = "shard_merge"
######################### Datasource config #########################
[data-sources]
[data-sources.mysql1] # mysql1 是该数据库实例唯一标识的自定义 id,用于下面 task.source-instances/task.target-instance 中
host = "10.1.1.2"
port = 3327
user = "dm_mysql"
password = "BMYKGn9OSFJAO6GnjJKkoECFKdSBIOreAuqSr1Zf"



[data-sources.tidb0]
host = "10.1.1.10"
port = 4000
user = "dm_tidb"
password = "7kTuLQ5o8XaFtInawrSDGEDPNTKiGgD89/UnL7Y="
#(可选)使用 TiDB 的 snapshot 功能,如果开启的话会使用历史数据进行对比
# snapshot = "386902609362944000"
######################### Task config #########################
[task]
output-dir = "/home/tidb/sync_diff_inspector/output"

# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开
target-check-tables = ["sharding_merge.*"]
  1. 运行 sync-diff-inspector,执行如下命令:
./sync_diff_inspector --config=./config.toml
$ /home/tidb/tidb-enterprise-tools-nightly-linux-amd64/bin/sync_diff_inspector --config=/home/tidb/sync_diff_inspector/config.toml
A total of 2 tables need to be compared

Comparing the table structure of ``sharding_merge`.`user_push`` ... failure
Comparing the table structure of ``sharding_merge`.`comments`` ... failure
Comparing the table data of ``sharding_merge`.`user_push`` ...
Comparing the table data of ``sharding_merge`.`comments`` ...
_____________________________________________________________________________
Progress [>------------------------------------------------------------] 0% 0/1062
......



遇到问题



告警auto-increment key checking

有告警​​auto-increment key checking​​,但是DM 任务已经running起来了。

需要忽略上游存在自增主键,操作如下:

  1. 暂停任务:
tiup dmctl --master-addr 10.1.1.7:8261 pause-task task2-shard-merge.yaml
  1. 修改任务配置文件 ​​task2-shard-merge.yaml​​ ,新增:
ignore-checking-items: ["auto_increment_ID"]
  1. 恢复任务:
$ tiup dmctl --master-addr 10.1.1.7:8261 resume-task task2-shard-merge.yaml
  1. 查看任务:
$ tiup dmctl --master-addr 10.1.1.7:8261 query-status shard_merge
tiup is checking updates for component dmctl ...
A new version of dmctl is available:
The latest version: v6.4.0
Local installed version: v6.3.0
Update current component: tiup update dmctl
Update all components: tiup update --all

Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status shard_merge
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-sharding-01",
"worker": "dm-10.1.1.6-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "shard_merge",
"stage": "Running",
"unit": "Load",
"result": null,
"unresolvedDDLLockID": "",
"load": {
"finishedBytes": "748136267",
"totalBytes": "21404994407",
"progress": "3.50 %",
"metaBinlog": "(mysql-bin.000233, 207017999)",
"metaBinlogGTID": ""
},
"validation": null
}
]
}
]
}



配置任务过滤条件有误,如何重新配置任务

  1. 停止任务:
tiup dmctl --master-addr 10.1.1.7:8261 stop-task shard_merge

此时,观察到 dm-worker 还是 Bound 占用状态:

$ tiup dm display dm-test
tiup is checking updates for component dm ...
Starting component `dm`: /home/tidb/.tiup/components/dm/v1.11.0/tiup-dm display dm-test
Cluster type: dm
Cluster name: dm-test
Cluster version: v6.5.0-alpha-nightly-20221108
Deploy user: tidb
SSH type: builtin
Grafana URL: http://10.1.1.7:3000
ID Role Host Ports OS/Arch Status Data Dir Deploy Dir
-- ---- ---- ----- ------- ------ -------- ----------
10.1.1.7:9093 alertmanager 10.1.1.7 9093/9094 linux/x86_64 Up /data/dm-data/alertmanager-9093 /data/dm-deploy/alertmanager-9093
10.1.1.6:8261 dm-master 10.1.1.6 8261/8291 linux/x86_64 Healthy /data/dm-data/dm-master-8261 /data/dm-deploy/dm-master-8261
10.1.1.6:8263 dm-master 10.1.1.6 8263/8293 linux/x86_64 Healthy /data01/dm-data/dm-master-8263 /data01/dm-deploy/dm-master-8263
10.1.1.7:8261 dm-master 10.1.1.7 8261/8291 linux/x86_64 Healthy|L /data01/dm-data/dm-master-8261 /data01/dm-deploy/dm-master-8261
10.1.1.6:8262 dm-worker 10.1.1.6 8262 linux/x86_64 Bound /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:8262 dm-worker 10.1.1.7 8262 linux/x86_64 Bound /data/dm-data/dm-worker-8262 /data02/dm-deploy/dm-worker-8262
10.1.1.7:3000 grafana 10.1.1.7 3000 linux/x86_64 Up - /data/dm-deploy/grafana-3000
10.1.1.7:9090 prometheus 10.1.1.7 9090 linux/x86_64 Up /data/dm-data/prometheus-9090 /data/dm-deploy/prometheus-9090
Total nodes: 8
  1. 查看 dm-woker 和 数据源关系:
$ tiup dmctl --master-addr 10.1.1.7:8261 operate-source show
tiup is checking updates for component dmctl ...
A new version of dmctl is available:
The latest version: v6.4.0
Local installed version: v6.3.0
Update current component: tiup update dmctl
Update all components: tiup update --all

Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 operate-source show
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262"
},
{
"result": true,
"msg": "",
"source": "mysql-sharding-01",
"worker": "dm-10.1.1.6-8262"
}
]
}
  1. 移除不需要的source:
tiup dmctl --master-addr 10.1.1.7:8261 operate-source stop mysql-sharding-01
  1. 查看到dm-worker 已释放:
$ tiup dm display dm-test
  1. 重新编辑任务配置文件 task2.yaml
vim task2-shard-merge.yaml
  1. 重新创建数据源
tiup dmctl --master-addr 10.1.1.7:8261 operate-source create  source2.yaml
  1. 重建创建迁移任务
tiup dmctl --master-addr 10.1.1.7:8261 start-task task2-shard-merge.yaml



迁移过程中发现tikv IO高

新扩容tikv节点后IO变化不大,最后调整task2.yaml 中的loader、syncer 的 threads ,从16调整到4后,IO有明显下降。

  1. 停止任务:
tiup dmctl --master-addr 10.1.1.7:8261 stop-task shard_merge
  1. 修改配置文件中的loader、syncer 的 threads:
vim task2-shard-merge.yaml
......
mydumper-config-name: "global" # mydumpers 配置的名称
loader-config-name: "global" # loaders 配置的名称
syncer-config-name: "global" # syncers 配置的名称

......
mydumpers: # dump 处理单元的运行配置参数
global: # 配置名称
threads: 4 # dump 处理单元从上游数据库实例导出数据的线程数量,默认值为 4
chunk-filesize: 64 # dump 处理单元生成的数据文件大小,默认值为 64,单位为 MB
# extra-args: "--consistency none" # dump 处理单元的其他参数,不需要在 extra-args 中配置 table-list,DM 会自动生成

loaders: # load 处理单元的运行配置参数
global: # 配置名称
pool-size: 4 # load 处理单元并发执行 dump 处理单元的 SQL 文件的线程数量,默认值为 16,当有多个实例同时向 TiDB 迁移数据时可根据负载情况适当调小该值
# dir: "./dumped_data" # dump 处理单元输出 SQL 文件的目录,同时也是 load 处理单元读取文件的目录。该配置项的默认值为 "./dumped_data"。同实例对应的不同任务必须配置不同的目录


syncers: # sync 处理单元的运行配置参数
global: # 配置名称
worker-count: 4 # 应用已传输到本地的 binlog 的并发线程数量,默认值为 16。调整此参数不会影响上游拉取日志的并发,但会对下游产生显著压力。
batch: 100 # sync 迁移到下游数据库的一个事务批次 SQL 语句数,默认值为 100,建议一般不超过 500。
enable-ansi-quotes: true # 若 `session` 中设置 `sql-mode: "ANSI_QUOTES"`,则需开启此项
  1. 重新开启任务:
tiup dmctl --master-addr 10.1.1.7:8261 start-task task2-shard-merge.yaml



DM WebUI 迁移任务管理界面

1、怎样使用 ​​DM WebUI​

在 DM 集群配置文件中添加

server_configs:
master:
openapi: true

2、访问 DM WebUI

在开启 ​​OpenAPI​​​ 后,你可以从 DM 集群的任意 master 节点访问 ​​DM WebUI​​​,访问端口与 ​​DM OpenAPI​​​ 保持一致,默认为 8261。访问地址示例:​​http://{master_ip}:{master_port}/dashboard/​​。

3、添加上游配置

DM 实践手册_mysql

4、添加迁移任务

DM 实践手册_linux_02

DM WebUI ,界面简单,使用起来易用性强。 不喜欢或不习惯 dmctl 的小伙伴们可以试用起来。

警告

  • DM WebUI 当前为实验特性,不建议在生产环境中使用。
  • DM WebUI 中 task 的生命周期有所改变,不建议与 dmctl 同时使用。



DM 常见问题处理



1、下游 tidb 节点变更导致 DM 中断

首先,DM 任务状态正常

$ tiup dmctl --master-addr 10.1.1.7:8261  query-status
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status
{
"result": true,
"msg": "",
"tasks": [
{
"taskName": "sbtest",
"taskStatus": "Running",
"sources": [
"mysql-replica-01"
]
}
]
}

下线下游 DM 迁移使用的 tidb 节点,让迁移任务中断:

tiup cluster scale-in tidb-test --node 10.1.1.10:4000

查看 DM 任务状态,任务中断:

$ tiup dmctl --master-addr 10.1.1.7:8261  query-status
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status
{
"result": true,
"msg": "",
"tasks": [
{
"taskName": "sbtest",
"taskStatus": "Error - Some error occurred in subtask. Please run `query-status sbtest` to get more details.",
"sources": [
"mysql-replica-01"
]
}
]
}

查看详细报错:

tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
#截取的部分信息
"subTaskStatus": [
{
"name": "sbtest",
"stage": "Paused",
"unit": "Sync",
"result": {
"isCanceled": false,
"errors": [
{
"ErrCode": 10001,
"ErrClass": "database",
"ErrScope": "downstream",
"ErrLevel": "high",
"Message": "database driver error",
"RawCause": "dial tcp 10.1.1.10:4000: connect: connection refused",
"Workaround": "Please check the database connection and the database config in configuration file."
}
],
"detail": null
}

PS :如果上游到下游没有增量需要更新,这样缩容tidb节点,DM是不会报错的,因为上下游的数据还是一致的。只有当缩tidb后,上游到下游有增量同步时,找不到下游tidb server 节点,DM才会报错。



解决

1、暂停任务:

tiup dmctl --master-addr 10.1.1.7:8261 pause-task sbtest

2、停止任务:

tiup dmctl --master-addr 10.1.1.7:8261 stop-task sbtest

3、更新任务配置文件 ​​task1-sbtest.yaml​​ :

vim task1-sbtest.yaml
# 将下游 TiDB 配置信息 从原来10.1.1.10(该节点已缩容) 更新为可用的 10.1.96.171
target-database:
host: "10.1.96.171"
port: 4000

4、重新启动任务:

tiup dmctl --master-addr 10.1.1.7:8261  start-task /home/tidb/dm/conf/task1-sbtest.yaml

5、查看任务状态,已正常

$ tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status sbtest
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "sbtest",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "2",
"totalTps": "2",
"recentTps": "2",
"masterBinlog": "(mysql-bin.000204, 905)",
"masterBinlogGtid": "",
"syncerBinlog": "(mysql-bin.000204, 635)",
"syncerBinlogGtid": "",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": false,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
},
"validation": null
}
]
}
]
}



2、上游 MySQL 意外宕机导致 DM 中断

详见官网 ​​切换 DM-worker 与上游 MySQL 实例的连接​​。



3、停止任务后 dm-worker 未释放(仍处于 Bound 占用状态)

  1. 查看 dm-woker 和 数据源关系:
$ tiup dmctl --master-addr ${advertise-addr}  operate-source show
  1. 移除不需要的 source:
tiup dmctl ---master-addr ${advertise-addr}  operate-source stop ${task-name}
  1. 查看到 dm-worker 已释放(状态从 Bound 更新为 Free):
tiup dm display dm-test



4、DDL 导致 DM 中断处理

使用限制

如果业务不能接受下游 TiDB 跳过异常的 DDL 语句,也不接受使用其他 DDL 语句作为替代,不接受插入其他 DDL 语句,则不适合使用此方式进行处理。

比如:​​DROP PRIMARY KEY​​,这种情况下,只能在下游重建一个(DDL 执行完后的)新表结构对应的表,并将原表的全部数据重新导入该新表。



处理出错的 DDL 命令总结

使用 dmctl 手动处理出错的 DDL 语句时,主要使用的命令包括 ​​query-status​​​、​​binlog​​​ (之前版本可使用 ​​handle-error​​ 命令)。



query-status

用于查询当前 MySQL 实例内子任务及 relay 单元等的状态和错误信息

tiup dmctl --master-addr  <master-addr>  query-status <task-name>



binlog skip

跳过任务报错:

tiup dmctl --master-addr  <master-addr>  binlog  skip <task-name>



binlog replace

执行其他 DDL 语句来作为替代:

tiup dmctl --master-addr  <master-addr>  binlog replace  <task-name> "<DDL SQL>"



handle-error

跳过任务报错:

tiup dmctl --master-addr  <master-addr>  handle-error <task-name> skip

执行其他 DDL 语句来作为替代:

tiup dmctl --master-addr  <master-addr>  handle-error   <task-name> replace "<DDL SQL>"

binlog 命令管理和查看binlog操作。该命令仅在 DM v6.0 及其以后版本支持, 之前版本可使用 handle-error 命令。



案例1:迁移中断执行 handle-error 跳过报错

#建表语句
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=1000002 DEFAULT CHARSET=utf8
  1. 在上游 MySQL 执行一条​​alter table​​ 包含多个 DDL 操作:
alter table sbtest1 
add w int(11) not null default '0',
add addr varchar(50) not null default '',
add index idx_addr(addr);

观察到 DM 同步任务正常,下游 TiDB 能正常同步以上 DDL 操作。

  1. 在上游 MySQL 执行 TiDB 不兼容的DDL:
mysql> alter table sbtest1 modify column id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT'自增主键';

去掉 ​​UNSIGNED​​​ 后则是 TiDB 是可以兼容的语法。 在生产环境中遇到的这个栗子,一开始以为DDL只是主键从int扩展到bigint,应该是兼容的呀。最后看了好久才发现还加了​​UNSIGNED​​ 。

查看 DM 任务状态:

$ tiup dmctl --master-addr 10.1.1.7:8261  query-status
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status
{
"result": true,
"msg": "",
"tasks": [
{
"taskName": "sbtest",
"taskStatus": "Error - Some error occurred in subtask. Please run `query-status sbtest` to get more details.",
"sources": [
"mysql-replica-01"
]
}
]
}
$ tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status sbtest
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "sbtest",
"stage": "Paused",
"unit": "Sync",
"result": {
"isCanceled": false,
"errors": [
{
"ErrCode": 44006,
"ErrClass": "schema-tracker",
"ErrScope": "internal",
"ErrLevel": "high",
"Message": "startLocation: [position: (mysql-bin.000204, 1224), gtid-set: 00000000-0000-0000-0000-000000000000:0], endLocation: [position: (mysql-bin.000204, 1400), gtid-set: 00000000-0000-0000-0000-000000000000:0], origin SQL: [alter table sbtest1 modify column id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT'自增主键']: cannot track DDL: ALTER TABLE `sbtest`.`sbtest1` MODIFY COLUMN `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键'",
"RawCause": "[ddl:8200]Unsupported modify column: this column has primary key flag",
"Workaround": "You can use handle-error to replace or skip this DDL."
}
],
"detail": null
},
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "4700",
"totalTps": "0",
"recentTps": "0",
"masterBinlog": "(mysql-bin.000204, 1400)",
"masterBinlogGtid": "",
"syncerBinlog": "(mysql-bin.000204, 1163)",
"syncerBinlogGtid": "00000000-0000-0000-0000-000000000000:0",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": false,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
},
"validation": null
}
]
}
]
}
  1. 任务中断,报错​​Unsupported modify column: this column has primary key flag​​。

确认了报错的原因,和业务能接受上下游结构不一致。

使用 ​​handle-error <task-name> skip​​​ 或 ​​binlog skip <task-name>​​ 跳过任务报错,以尽快恢复任务同步.

  1. 跳过报错:
tiup dmctl --master-addr 10.1.1.7:8261  handle-error sbtest skip
$ tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
tiup is checking updates for component dmctl ...
Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status sbtest
{
"result": true,
"msg": "",
"sources": [
{
"result": true,
"msg": "",
"sourceStatus": {
"source": "mysql-replica-01",
"worker": "dm-10.1.1.7-8262",
"result": null,
"relayStatus": null
},
"subTaskStatus": [
{
"name": "sbtest",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "4701",
"totalTps": "0",
"recentTps": "0",
"masterBinlog": "(mysql-bin.000204, 1400)",
"masterBinlogGtid": "",
"syncerBinlog": "(mysql-bin.000204, 1400)",
"syncerBinlogGtid": "00000000-0000-0000-0000-000000000000:0",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
},
"validation": null
}
]
}
]
}

观察syncerBinlog有没有追上masterBinlog,直到追上。

  1. 跳过报错后,尽力修复上下游表结构一致

查询了官网:“不支持修改主键列上需要 Reorg-Data 的类型,但是支持修改 Meta-Only 的类型”。也就是说,仅扩展整型从int到bigint,TiDB是支持的。

再次仔细对比上游MySQL和下游TIDB的表结构,发现除id不止从int类型扩展为bigint,还添加 ​​UNSIGNED​​​ 。测试了下,去掉 ​​UNSIGNED​​ 后, DDL 操作就可以在tidb操作成功了。

询问业务不需要存储负数,所以其实压根儿用不上UNSIGNED,可以去掉 UNSIGNED。于是在上游MySQL执行如下DDL,统一上下游表结构

mysql> ALTER TABLE sbtest1 MODIFY COLUMN `id` BIGINT(20)  NOT NULL AUTO_INCREMENT COMMENT '自增主键';



案例2:迁移中断执行 replace 替代操作

  1. 上游 MySQL 执行 TiDB 不兼容的DDL:
alter table sbtest1 add new_col int unique;
mysql> show create table sbtest1;
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| sbtest1 | CREATE TABLE `sbtest1` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
`w` int(11) NOT NULL DEFAULT '0',
`addr` varchar(50) NOT NULL DEFAULT '',
`new_col` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `new_col` (`new_col`),
KEY `k_1` (`k`),
KEY `idx_addr` (`addr`)
) ENGINE=InnoDB AUTO_INCREMENT=1000002 DEFAULT CHARSET=utf8 |
+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
  1. 查看 DM 任务状态:
tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
"errors": [
{
"ErrCode": 10006,
"ErrClass": "database",
"ErrScope": "downstream",
"ErrLevel": "high",
"Message": "startLocation: [position: (mysql-bin.000204, 1461), gtid-set: 00000000-0000-0000-0000-000000000000:0], endLocation: [position: (mysql-bin.000204, 1577), gtid-set: 00000000-0000-0000-0000-000000000000:0], origin SQL: [alter table sbtest1 add new_col int unique]: execute statement failed: ALTER TABLE `sbtest`.`sbtest1` ADD COLUMN `new_col` INT UNIQUE KEY",
"RawCause": "Error 8200: unsupported add column 'new_col' constraint UNIQUE KEY when altering 'sbtest.sbtest1'",
"Workaround": ""
}

DM 任务中断并报错,因为不支持该语法。

  1. 执行 ​​handle-error replace <taskname>​​​ 或 ​​binlog replace <taskname>​​替代操作,将该 DDL 替换成两条等价的 DDL。操作步骤如下:
tiup dmctl --master-addr 10.1.1.7:8261  binlog replace  sbtest "ALTER TABLE sbtest.sbtest1 ADD COLUMN new_col INT;ALTER TABLE sbtest.sbtest1 ADD UNIQUE(new_col)";

tiup dmctl --master-addr 10.1.1.7:8261  handle-error sbtest  replace "ALTER TABLE sbtest.sbtest1 ADD COLUMN new_col2 INT;ALTER TABLE sbtest.sbtest1 ADD UNIQUE(new_col2)";
  1. 使用 ​​query-status <task-name>​​ 查看任务状态
tiup dmctl --master-addr 10.1.1.7:8261  query-status sbtest
{
"name": "sbtest",
"stage": "Running",
"unit": "Sync",
"result": null,
"unresolvedDDLLockID": "",
"sync": {
"totalEvents": "6107",
"totalTps": "86",
"recentTps": "0",
"masterBinlog": "(mysql-bin.000204, 1577)",
"masterBinlogGtid": "",
"syncerBinlog": "(mysql-bin.000204, 1577)",
"syncerBinlogGtid": "00000000-0000-0000-0000-000000000000:0",
"blockingDDLs": [
],
"unresolvedGroups": [
],
"synced": true,
"binlogType": "remote",
"secondsBehindMaster": "0",
"blockDDLOwner": "",
"conflictMsg": ""
},

可以看到任务运行正常,错误的 DDL 已被替换且执行成功。



5、使用 gh-ost/pt-osc 工具变更上游对下游影响

上游 MySQL 通过 gh-ost 新增字段:

gh-ost --host=xx.xx.xx.xx --port=33xx --user='username' --password='xxxx' --allow-on-master --allow-master-master --database=sbtest --table=sbtest1  \
--alter="add create_time datetime not null COMMENT '开始时间'" --chunk-size=5000 --max-load=Threads_connected=2000,Threads_running=80 --ok-to-drop-table=True \
--approve-renamed-columns --max-lag-millis=5000 --switch-to-rbr --nice-ratio=1 --verbose -execute

上游 MySQL 通过 pt-osc 新增字段及修改字段:

pt-online-schema-change -h 10.xx.xx.xx -P33xx -D sbtest -u username -p passwd t=sbtest1 --alter="add  update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录更新时间',modify create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间'" \
--recursion-method=processlist --check-interval=2 --max-lag=2 --max-load="Threads_running=20" --critical-load="Threads_running=80" --charset=utf8 --print --execute

查看 DM 任务状态:

$ tiup dmctl --master-addr 10.1.1.7:8261  query-status
tiup is checking updates for component dmctl ...
A new version of dmctl is available:
The latest version: v6.4.0
Local installed version: v6.3.0
Update current component: tiup update dmctl
Update all components: tiup update --all

Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v6.3.0/dmctl/dmctl --master-addr 10.1.1.7:8261 query-status
{
"result": true,
"msg": "",
"tasks": [
{
"taskName": "sbtest",
"taskStatus": "Running",
"sources": [
"mysql-replica-01"
]
}
]
}

看到任务状态正常。



实践小结

我用的 DM 版本是 ​​v6.5.0​​​,实践显示,在上游 使用 ​​gh-ost/pt-osc​​​ 工具,对下游无影响。虽然任务配置文件 ​​task1.yaml​​​ 中没有显式写明 ​​online-ddl: true​​ ,但看起来这个参数在这版本中默认为 TRUE 啦。 所以,DM 自动支持上游使用​pt-osc/gh-ost​在线 schema 变更工具,无需特别的配置。另,部署 DM 建议最好用近期比较新的版本。

【查看 tiup 支持的 DM 最新版本】:

tiup list dm-master



6、DM 告警



DM 监控指标

使用 TiUP 部署 DM 集群的时候,会默认部署一套监控系统。 可在浏览器中打开 ​​http://10.1.1.7:9093​​ 进入 Alertmanager 查看 DM 告警信息;可在浏览器中打开 ​​http://10.1.1.7:3000​​ 进入 Grafana,选择 DM 的 dashboard 查看 DM 相关监控项。



DM 告警处理

DM 的告警规则及其对应的处理方法可参考​​告警处理​​。

详情请参考官网 ​​DM 告警信息​​ 。



DM 任务状态转换

暂停任务:

tiup dmctl --master-addr 172.16.10.71:8261 pause-task wr-dm-task1

恢复任务:

tiup dmctl --master-addr 172.16.10.71:8261 resume-task wr-dm-task1

停止任务:

tiup dmctl --master-addr 172.16.10.71:8261 stop-task wr-dm-task1



pause-task 与 stop-task 的区别

【Tips】

有关 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 配合以更新配置信息。



状态转换图

error occurs
New --------------------------------|
| |
| resume-task |
| |----------------------------| |
| | | |
| | | |
v v error occurs | v
Finished <-------------- Running -----------------------> Paused
^ | or pause-task |
| | |
start task | | stop task |
| | |
| v stop task |
Stopped <-------------------------|

详见官网 ​​ DM 任务状态​​ 。



参考文档

​​DM 常见故障及处理方法​​

​​处理出错的 DDL 语句​​

​​DM 任务完整配置文件介绍​​

​​DM 告警信息​​

​​使用 TiUP 部署 TiDB 集群​​