# 使用 TiDB Data Migration 工具从 MySQL 迁移数据

## 概述

在本实验中，你将使用 `TiDB Data Migration` 工具将数据从 MySQL 迁移到 TiDB，该工具用于支持从上游 MySQL 实例到下游 TiDB 实例的全量数据迁移和增量数据复制。

### 实验时长

+ 完成此练习大约需要 90 分钟。

### 任务

+ 安装 `TiDB Data Migration` 组件。
+ 使用拓扑文件部署并启动 `TiDB Data Migration` 集群。
+ 安装 `dmctl` 工具。
+ 创建 TiDB Data Migration 源配置。
+ 启动上游 MySQL。
+ 创建 TiDB Data Migration 任务配置并启动迁移任务。
+ 验证 TiDB Data Migration 任务的结果。

> [!TIP]
> 点击 **开始** 启动实验环境。
> 环境准备就绪后，点击底部工具栏中的 **前进** 进入 **模块 1**。
> 然后，按照实验指南的步骤连接到实践环境并开始你的任务。

## 模块 1：连接到 MySQL Server 并运行查询以验证数据源

### 步骤 1. 连接到远程 Linux - TiUP 控制机

+ 点击这里 - [终端 1](ssh://monitor1-ssh#1) 打开一个新的终端，连接到为你的实践实验分配的虚拟机。

+ 登录后显示的横幅：

    ```output
     ,     #_
    ~\_  ####_        Amazon Linux 2
    ~~  \_#####\
    ~~     \###|      
    ~~       \#/ ___
    ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
     ~~._.   _/
        _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
      _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    ```

### 步骤 2. 连接到 MySQL server 实例

+ 连接到 MySQL server 节点。如果有提示，回答 `yes`。

   ```bash
   ssh -i /home/ec2-user/.ssh/pe-class-key-oregon.pem rocky@${HOST_MYSQL1_PRIVATE_IP}
   ```
   ```output
   Last login: Thu Aug  1 11:58:47 2024 from 10.90.4.90
   [rocky@ip-10-90-1-235 ~]$
   ```

+ 使用数据库用户 `root` 连接到 MySQL server。

   ```bash
   mysql -h localhost -P 3306 -u root -pq1w2e3R4_ --connect-expired-password
   ```
   ```output
   mysql> 
   ```

### 步骤 3. 查看 MySQL 中的现有的表

+ 验证 `sbtest` 数据库中的表和数据已存在。

   ```sql
   SHOW DATABASES;
   ```
   ```output
   +--------------------+
   | Database           |
   +--------------------+
   | information_schema |
   | mysql              |
   | performance_schema |
   | sbtest             |
   | sys                |
   +--------------------+
   5 rows in set (0.01 sec)
   ```
   ```sql
   SHOW TABLES FROM sbtest;
   ```
   ```output
   +------------------+
   | Tables_in_sbtest |
   +------------------+
   | sbtest1          |
   | sbtest2          |
   | sbtest3          |
   | sbtest4          |
   | sbtest5          |
   | sbtest6          |
   +------------------+
   6 rows in set (0.00 sec)
   ```

+ 查看表 `sbtest.sbtest1` 的结构。 

   ```sql
   DESC sbtest.sbtest1;
   ```
   ```output
   +-------+-----------+------+-----+---------+----------------+
   | Field | Type      | Null | Key | Default | Extra          |
   +-------+-----------+------+-----+---------+----------------+
   | id    | int       | NO   | PRI | NULL    | auto_increment |
   | k     | int       | NO   | MUL | 0       |                |
   | c     | char(120) | NO   |     |         |                |
   | pad   | char(60)  | NO   |     |         |                |
   +-------+-----------+------+-----+---------+----------------+
   4 rows in set (0.00 sec)
   ```

+ 查看表 `sbtest.sbtest1`的行数。这大约需要几秒钟。（请注意，你现在正在连接 MySQL）

   ```sql
   SELECT COUNT(id) FROM sbtest.sbtest1;
   ```
   ```output
   +-----------+
   | COUNT(id) |
   +-----------+
   |  10000000 |
   +-----------+
   1 row in set (29.75 sec)
   ```

### 步骤 4. 了解数据源 MySQL server 中的数据量

+ 在 `sbtest` 数据库上执行 `ANALYZE` 命令。该数据库中除了 `sbtest1`, 还包含 `sbtest2`, `sbtest3`, `sbtest4`, `sbtest5`, 和 `sbtest6`。
   
   ```sql
   ANALYZE TABLE sbtest.sbtest1, sbtest.sbtest2, sbtest.sbtest3, sbtest.sbtest4, sbtest.sbtest5, sbtest.sbtest6;
   ```
   ```output
   +----------------+---------+----------+----------+
   | Table          | Op      | Msg_type | Msg_text |
   +----------------+---------+----------+----------+
   | sbtest.sbtest1 | analyze | status   | OK       |
   | sbtest.sbtest2 | analyze | status   | OK       |
   | sbtest.sbtest3 | analyze | status   | OK       |
   | sbtest.sbtest4 | analyze | status   | OK       |
   | sbtest.sbtest5 | analyze | status   | OK       |
   | sbtest.sbtest6 | analyze | status   | OK       |
   +----------------+---------+----------+----------+
   6 rows in set (34.08 sec)
   ```

+ 获取 `sbtest` 数据库的数据大小，应该约为 `13.43GB`。

   ```sql
   SELECT CONCAT(ROUND(SUM((data_length + index_length)/1024/1024/1024),2), 'GB') AS data
   FROM information_schema.tables
   WHERE table_schema='sbtest';
   ```
   ```output
   +---------+
   | data    |
   +---------+
   | 13.43GB |
   +---------+
   1 row in set (0.00 sec)
   ```

+ 退出到操作系统提示符。

   ```sql
   EXIT
   ```
   ```output
   bye
   ```

+ 保持远程终端与 MySQL server 的连接（你看到的提示符应该以 `[rocky@` 开头），并继续进行下一个模块。

## 模块 2：将示例数据库从 MySQL 迁移到 TiDB

### 步骤 1. 在 MySQL 中创建用于迁移的用户

+ 在[终端 1](ssh://monitor1-ssh#1)上，通过私有 IP 地址连接到 MySQL server。然后，在 MySQL 上创建一个专门用于迁移的用户 `dm_user`。

   ```bash
   X=q1w2e3R4_
   mysql -h localhost -P 3306 -uroot -p$X --connect-expired-password << EOF
   DROP USER IF EXISTS dm_user@'%';
   CREATE USER dm_user@'%' IDENTIFIED BY 'q1w2e3R4_';
   GRANT ALL PRIVILEGES ON *.* TO dm_user@'%';
   EXIT
   EOF
   ```
   ```output
   mysql: [Warning] Using a password on the command line interface can be insecure.
   ```

   + 退出到远程 TiUP 控制机。

   ```bash
   exit
   ```
   ```output
   logout
   Connection to 10.90.1.38 closed.
   ```

### 步骤 2. 检查 TiDB 集群的状态

+ 验证 TiDB 集群是否已启动并正在运行。检查 TiDB 集群状态。请注意 TiDB 集群 `tidb-demo` 中应该有 1 个 TiDB server 和 3 个 TiKV servers，并且 `TiProxy`、`Alert Manager`、`Grafana` 和 `Prometheus` 应该部署在同一节点上。
 
   ```bash
   ~/.tiup/bin/tiup cluster display tidb-demo
   ```
   ```output
   Cluster type:       tidb
   Cluster name:       tidb-demo
   Cluster version:    v6.5.9
   Deploy user:        ec2-user
   SSH type:           builtin
   Dashboard URL:      http://34.221.120.15:2379/dashboard
   Grafana URL:        http://10.90.4.90:3000
   ID                 Role          Host         Ports        OS/Arch       Status  Data Dir                      Deploy Dir
   --                 ----          ----         -----        -------       ------  --------                      ----------
   10.90.4.90:9093    alertmanager  10.90.4.90   9093/9094    linux/x86_64  Up      /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093
   10.90.4.90:3000    grafana       10.90.4.90   3000         linux/x86_64  Up      -                             /tidb-deploy/grafana-3000
   10.90.2.11:2379    pd            10.90.2.11   2379/2380    linux/x86_64  Up|L    /tidb-data/pd-2379            /tidb-deploy/pd-2379
   10.90.4.90:9090    prometheus    10.90.4.90   9090/12020   linux/x86_64  Up      /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090
   10.90.1.173:4000   tidb          10.90.1.173  4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
   10.90.1.233:20160  tikv          10.90.1.233  20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.1.242:20160  tikv          10.90.1.242  20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.1.79:20160   tikv          10.90.1.79   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.4.90:6000    tiproxy       10.90.4.90   6000/3080    linux/x86_64  Up      -                             /tidb-deploy/tiproxy-6000
   Total nodes: 9
   ```

### 步骤 3. 在 TiDB 中创建用于迁移的用户

+ 在 TiDB 中创建一个专门用于迁移的用户 `dm_user`。

   ```bash
   mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -uroot << 'EOF'
   DROP USER IF EXISTS dm_user@'%';
   CREATE USER dm_user@'%' identified by 'q1w2e3R4_';
   GRANT ALL PRIVILEGES ON *.* TO dm_user@'%';
   EXIT
   EOF
   ```

### 步骤 4. 创建名为 `sbtest` 的目标数据库及空表

+ 请注意，列 `id` 设置为 `AUTO_RANDOM` 而非 `AUTO_INCREMENT`。 `AUTO_RANDOM` 是 TiDB 特有的功能，可避免热点性能问题，若要了解更多关于 `AUTO_RANDOM` 的信息，请使用右下角的 `Ask AI` 功能。

   ```bash
   mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -uroot << 'EOF'
   CREATE DATABASE sbtest;
   CREATE TABLE `sbtest`.`sbtest1` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   CREATE TABLE `sbtest`.`sbtest2` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   CREATE TABLE `sbtest`.`sbtest3` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   CREATE TABLE `sbtest`.`sbtest4` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   CREATE TABLE `sbtest`.`sbtest5` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   CREATE TABLE `sbtest`.`sbtest6` (
     `id` bigint NOT NULL AUTO_RANDOM,
     `k` int 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 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
   SET GLOBAL allow_auto_random_explicit_insert = true;
   USE sbtest;
   SHOW TABLES;
   EXIT
   EOF
   ```
   ```output
   Tables_in_sbtest
   sbtest1
   sbtest2
   sbtest3
   sbtest4
   sbtest5
   sbtest6
   ```

### 步骤 5. 安装 TiDB Data Migration 工具

   ```bash
   ~/.tiup/bin/tiup install dm dmctl:vtidb_version dm-master:vtidb_version dm-worker:vtidb_version
   ```
   ```bash
   ~/.tiup/bin/tiup list --verbose | grep dm
   ```
   ```output
   dm                 pingcap  v1.15.1,v1.16.0                     linux/amd64  Data Migration Platform manager
   dm-master          pingcap  v8.0.0,vtidb_version                       linux/amd64  dm-master component of Data Migration Platform.
   dm-worker          pingcap  v8.0.0,vtidb_version                       linux/amd64  dm-worker component of Data Migration Platform.
   dmctl              pingcap  v6.5.1,v6.5.9,v7.5.0,vtidb_version  linux/amd64  dmctl component of Data Migration Platform.
   ```

### 步骤 6. 查看 TiDB Data Migration 集群拓扑配置

+ TiDB Data Migration 集群拓扑配置文件已为你预配置好。请查看配置，无需更改。

   ```bash
   cat dm-topology.yaml 
   ```
   ```output
   global:
     user: "ec2-user"
     ssh_port: 22
     deploy_dir: "/tidb-deploy"
     data_dir: "/tidb-data"
     arch: "amd64"
   master_servers:
     - host: 10.90.4.191
   worker_servers:
     - host: 10.90.3.49
     - host: 10.90.3.71
     - host: 10.90.3.135
   monitoring_servers:
     - host: 10.90.1.7
   grafana_servers:
     - host: 10.90.1.7
   alertmanager_servers:
     - host: 10.90.1.7
   ```

### 步骤 7. 部署并启动 TiDB Data Migration 集群

+ 部署 TiDB Data Migration 集群 - `dm-test`

   ```bash
   ~/.tiup/bin/tiup dm deploy dm-test vtidb_version ./dm-topology.yaml \
    --user ec2-user \
    -i /home/ec2-user/.ssh/pe-class-key-oregon.pem \
    --yes
   ```
   ```output
   Starting component dm: /home/ec2-user/.tiup/components/dm/v1.16.0/tiup-dm deploy dm-test vtidb_version ./dm-topology.yaml --user ec2-user -i /home/ec2-user/.ssh/pe-class-key-oregon.pem --yes
   + Detect CPU Arch Name
     - Detecting node 10.90.4.191 Arch info ... Done
     - Detecting node 10.90.3.49 Arch info ... Done
     - Detecting node 10.90.3.71 Arch info ... Done
     - Detecting node 10.90.3.135 Arch info ... Done
     - Detecting node 10.90.1.7 Arch info ... Done
   .
   .
   .
   Cluster `dm-test` deployed successfully, you can start it with command: `tiup dm start dm-test`
   ```

+ 启动 TiDB Data Migration 集群 - `dm-test`.

   ```bash
   ~/.tiup/bin/tiup dm start dm-test
   ```
   ```output
   Starting component dm: /home/ec2-user/.tiup/components/dm/v1.16.0/tiup-dm start dm-test
   Starting cluster dm-test...
   + [ Serial ] - SSHKeySet: privateKey=/home/ec2-user/.tiup/storage/dm/clusters/dm-test/ssh/id_rsa, publicKey=/home/ec2-user/.tiup/storage/dm/clusters/dm-test/ssh/id_rsa.pub
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.1.7
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.3.71
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.1.7
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.4.191
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.1.7
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.3.49
   + [Parallel] - UserSSH: user=ec2-user, host=10.90.3.135
   + [ Serial ] - StartCluster
   Starting component dm-master
   	Starting instance 10.90.4.191:8261
   	Start instance 10.90.4.191:8261 success
   Starting component dm-worker
   	Starting instance 10.90.3.135:8262
   	Starting instance 10.90.3.49:8262
   	Starting instance 10.90.3.71:8262
   	Start instance 10.90.3.135:8262 success
   	Start instance 10.90.3.71:8262 success
   	Start instance 10.90.3.49:8262 success
   Starting component prometheus
   	Starting instance 10.90.1.7:9090
   	Start instance 10.90.1.7:9090 success
   Starting component grafana
   	Starting instance 10.90.1.7:3000
   	Start instance 10.90.1.7:3000 success
   Starting component alertmanager
   	Starting instance 10.90.1.7:9093
   	Start instance 10.90.1.7:9093 success
   Started cluster `dm-test` successfully
   ```

### 步骤 8. 检查 TiDB Data Migration 集群的状态

+ 确认  TiDB Data Migration 集群已启动并正在运行。
 
   ```bash
   tiup dm display dm-test
   ```
   ```output
   Starting component dm: /home/ec2-user/.tiup/components/dm/v1.16.0/tiup-dm display dm-test
   Cluster type:       dm
   Cluster name:       dm-test
   Cluster version:    vtidb_version
   Deploy user:        ec2-user
   SSH type:           builtin
   Grafana URL:        http://10.90.3.188:3000
   ID                Role          Host         Ports      OS/Arch       Status     Data Dir                      Deploy Dir
   --                ----          ----         -----      -------       ------     --------                      ----------
   10.90.3.188:9093  alertmanager  10.90.3.188  9093/9094  linux/x86_64  Up         /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093
   10.90.4.196:8261  dm-master     10.90.4.196  8261/8291  linux/x86_64  Healthy|L  /tidb-data/dm-master-8261     /tidb-deploy/dm-master-8261
   10.90.4.196:8262  dm-worker     10.90.4.196  8262       linux/x86_64  Free       /tidb-data/dm-worker-8262     /tidb-deploy/dm-worker-8262
   10.90.3.188:3000  grafana       10.90.3.188  3000       linux/x86_64  Up         -                             /tidb-deploy/grafana-3000
   10.90.3.188:9090  prometheus    10.90.3.188  9090       linux/x86_64  Up         /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090
   Total nodes: 5
   ``` 

### 步骤 9. 设置迁移任务源配置

   ```bash
   cat << EOF > mysql-source-conf1.yaml
   source-id: "mysql-replica-01"
   from:
     host: "${HOST_MYSQL1_PRIVATE_IP}"
     port: 3306
     user: "dm_user"
     password: "q1w2e3R4_"
   EOF
   cat mysql-source-conf1.yaml
   ```
   ```output
   source-id: "mysql-replica-01"
   from:
     host: "10.90.1.135"
     port: 3306
     user: "dm_user"
     password: "q1w2e3R4_"
   ```

### 步骤 10. 创建迁移数据源

+ 将 MySQL 实例设置为迁移数据源，并验证 TiDB 数据迁移集群能够识别该数据源。

   ```bash
   ~/.tiup/bin/tiup dmctl:vtidb_version \
    --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 operate-source create mysql-source-conf1.yaml
   ```
   ```output
   Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.66:8261 operate-source create mysql-source-conf1.yaml
   {
       "result": true,
       "msg": "",
       "sources": [
           {
               "result": true,
               "msg": "",
               "source": "mysql-replica-01",
               "worker": "dm-10.90.3.187-8262"
           }
       ]
   }
   ```

### 步骤 11. 检查迁移数据源的状态

   ```bash
   ~/.tiup/bin/tiup dmctl:vtidb_version \
    --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 get-config source mysql-replica-01
   ```
   ```output
   Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.66:8261 get-config source mysql-replica-01
   {
       "result": true,
       "msg": "",
       "cfg": "enable: true\nenable-gtid: false\nauto-fix-gtid: false\nrelay-dir: relay-dir\nmeta-dir: \"\"\nflavor: mysql\ncharset: \"\"\nenable-relay: false\nrelay-binlog-name: \"\"\nrelay-binlog-gtid: \"\"\nsource-id: mysql-replica-01\nfrom:\n  host: 10.90.1.135\n  port: 3306\n  user: dm_user\n  password: '******'\n  max-allowed-packet: null\n  session: {}\n  security: null\npurge:\n  interval: 3600\n  expires: 0\n  remain-space: 15\nchecker:\n  check-enable: true\n  backoff-rollback: 5m0s\n  backoff-max: 5m0s\n  check-interval: 5s\n  backoff-min: 1s\n  backoff-jitter: true\n  backoff-factor: 2\nserver-id: 429530419\ntracer: {}\ncase-sensitive: false\nfilters: []\n"
   }
   ```

### 步骤 12. 检查迁移源的状态

   ```bash
   ~/.tiup/bin/tiup dmctl:vtidb_version \
    --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 operate-source show
   ```
   ```output
   Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.66:8261 operate-source show
   {
       "result": true,
       "msg": "",
       "sources": [
           {
               "result": true,
               "msg": "",
               "source": "mysql-replica-01",
               "worker": "dm-10.90.3.187-8262"
           }
       ]
   }
   ```

### 步骤 13. 创建迁移任务

+ 生成迁移任务配置。

   ```bash
   cat << EOF > dm-task.yaml
   name: "dm-task"
   task-mode: all
   ignore-checking-items: ["auto_increment_ID"]

   target-database:
     host: "${HOST_DB1_PRIVATE_IP}"
     port: 4000
     user: "dm_user"
     password: "q1w2e3R4_"

   mysql-instances:
     - source-id: "mysql-replica-01"
       route-rules: ["instance-1-user-schema-rule"]
       block-allow-list: "rule_1"
       mydumper-config-name: "global"
       loader-config-name: "global"

   routes:
     instance-1-user-schema-rule:
       schema-pattern: "sbtest"
       target-schema: "sbtest"

   block-allow-list:
     rule_1:
       do-dbs: ["sbtest"]

   mydumpers:
     global:
       threads: 32
       chunk-filesize: 64

   loaders:
     global:
       pool-size: 8
       import-mode: "physical"
       pd-addr: "${HOST_PD1_PRIVATE_IP}:2379"
   EOF
   cat dm-task.yaml
   ```
   ```output
   name: "dm-task"
   task-mode: all
   ignore-checking-items: ["auto_increment_ID"]
   .
   .
   .
   loaders:
     global:
       pool-size: 32
       import-mode: "physical"
   ```

+ 预检查迁移任务。mag 应该是 `pre-check is passed`。

  ```bash
  ~/.tiup/bin/tiup dmctl:vtidb_version --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 check-task ./dm-task.yaml
  ```
  ```output
  Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.235:8261 check-task ./dm-task.yaml
  {
  "result": true,
  "msg": "pre-check is passed. "
  }
  ```

### 步骤 14. 启动迁移任务

+ 根据配置，迁移任务包含 3 个子任务单元：`Dump`, `Load` 和 `Sync`。启动迁移任务。
   
   ```bash
   ~/.tiup/bin/tiup dmctl:vtidb_version \
    --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 start-task ./dm-task.yaml
   ```
   ```output
   Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.66:8261 start-task ./dm-task.yaml
   {
       "result": true,
       "msg": "",
       "sources": [
           {
               "result": true,
               "msg": "",
               "source": "mysql-replica-01",
               "worker": "dm-10.90.3.187-8262"
           }
       ],
       "checkResult": "pre-check is passed. "
   }
   ```

### 步骤 15. 使用 `query-status` 操作检查迁移进度

+ 注意 `subTaskStatus` 中的 `stage`, `unit` 和 `progress` 属性。

+ 使用 `watch` 命令监控整个任务的进度。根据实验环境配置（由于这不是一个概念验证，我们在本动手实验中使用低端服务器），可能需要大约 8 分钟（Dump：4 分钟，Load：4 分钟）来使 MySQL 和 TiDB 保持同步。可以去喝杯咖啡，阅读以下更多信息，并在屏幕上观察迁移进度。

   ```bash
   watch -n 1 -d ./.tiup/bin/tiup dmctl:vtidb_version --master-addr=${HOST_MONITOR1_PRIVATE_IP}:8261 query-status ./dm-task.yaml
   ```
  
+ 单元 `Dump`, 阶段 `Running`:
   
    ```output
    Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.235:8261 query-status ./dm-task.yaml
    {
    "result": true,
    "msg": "",
    "sources": [
      {
          "result": true,
          "msg": "",
          "sourceStatus": {
              "source": "mysql-replica-01",
              "worker": "dm-10.90.1.147-8262",
              "result": null,
              "relayStatus": null
          },
          "subTaskStatus": [
              {
                  "name": "dm-task",
                  "stage": "Running",
                  "unit": "Dump",
                  "result": null,
                  "unresolvedDDLLockID": "",
                  "dump": {
                      "totalTables": "6",
                      "completedTables": 3,
                      "finishedBytes": 7949200595,
                      "finishedRows": 39359277,
                      "estimateTotalRows": 59224808,
                      "bps": "57472325",
                      "progress": "64.63 %"
                  },
                  "validation": null
              }
          ]
      }
    ]
    }
    ```

+ 单元 `Load`, 阶段 `Running`:

    ```output
    Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.196:8261 query-status ./dm-task.yaml
    {
     "result": true,
     "msg": "",
     "sources": [
         {
             "result": true,
             "msg": "",
             "sourceStatus": {
                 "source": "mysql-replica-01",
                 "worker": "dm-10.90.4.196-8262",
                 "result": null,
                 "relayStatus": null
             },
             "subTaskStatus": [
                 {
                     "name": "dm-task",
                     "stage": "Running",
                     "unit": "Load",
                     "result": null,
                     "unresolvedDDLLockID": "",
                     "load": {
                         "finishedBytes": "5307344924",
                         "totalBytes": "8161057816",
                         "progress": "65.03 %",
                         "metaBinlog": "(binlog.000008, 157240317)",
                         "metaBinlogGTID": "",
                         "bps": "62882221"
                     },
                     "validation": null
                 }
             ]
         }
     ]
    }
    ```

+ 单元 `Sync`, 阶段 `Running`。请注意目标 TiDB 和源 MySQL 已同步。

    ```output
    Starting component dmctl: /home/ec2-user/.tiup/components/dmctl/vtidb_version/dmctl/dmctl --master-addr=10.90.4.196:8261 query-status ./dm-task.yaml
    {
        "result": true,
        "msg": "",
        "sources": [
            {
                "result": true,
                "msg": "",
                "sourceStatus": {
                    "source": "mysql-replica-01",
                    "worker": "dm-10.90.4.196-8262",
                    "result": null,
                    "relayStatus": null
                },
                "subTaskStatus": [
                    {
                        "name": "dm-task",
                        "stage": "Running",
                        "unit": "Sync",
                        "result": null,
                        "unresolvedDDLLockID": "",
                        "sync": {
                            "totalEvents": "19767046",
                            "totalTps": "21118",
                            "recentTps": "0",
                            "masterBinlog": "(binlog.000011, 706201359)",
                            "masterBinlogGtid": "",
                            "syncerBinlog": "(binlog.000011, 706201359)",
                            "syncerBinlogGtid": "00000000-0000-0000-0000-000000000000:0",
                            "blockingDDLs": [
                            ],
                            "unresolvedGroups": [
                            ],
                            "synced": true,
                            "binlogType": "remote",
                            "secondsBehindMaster": "0",
                            "blockDDLOwner": "",
                            "conflictMsg": "",
                            "totalRows": "19767046",
                            "totalRps": "21118",
                            "recentRps": "0"
                        },
                        "validation": null
                    }
                ]
            }
        ]
    }
    ```

+ 等待并确认迁移任务已达到 `"stage": "Running" and "unit": "Sync"` 状态。保持 `watch` 命令运行，并继续进行下一个模块。

## 模块 3：在源 MySQL 中进行一些更改

### 步骤 1. 连接到 TiUP 控制机，然后连接到 MySQL server

+ 点击这里 - [终端 2](ssh://monitor1-ssh#2) 打开一个新的终端，然后连接到 MySQL server。

+ 登录后显示的横幅：

    ```output
     ,     #_
    ~\_  ####_        Amazon Linux 2
    ~~  \_#####\
    ~~     \###|      
    ~~       \#/ ___
    ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
     ~~._.   _/
        _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
      _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    ```

+ 连接到 MySQL server 节点。

   ```bash
   ssh -i /home/ec2-user/.ssh/pe-class-key-oregon.pem rocky@${HOST_MYSQL1_PRIVATE_IP}
   ```
   ```output
   Last login: Thu Aug  1 11:58:47 2024 from 10.90.4.90
   [rocky@ip-10-90-1-235 ~]$
   ```

   + 通过数据库会话连接到 MySQL server。

   ```bash
   mysql -h localhost -P 3306 -u root -pq1w2e3R4_ --connect-expired-password
   ```
   ```output
   mysql> 
   ```

### 步骤 2. 在 MySQL 执行 UPDATE

+ 在[终端 2](ssh://monitor1-ssh#2)，将特定行的列 `c` 设置为 `Changed on MySQL`。

   ```sql
   SELECT * FROM sbtest.sbtest1 WHERE id=1;
   UPDATE sbtest.sbtest1 SET c='Changed on MySQL' WHERE id=1;
   SELECT * FROM sbtest.sbtest1 WHERE id=1;
   ```
   ```output
   mysql> SELECT * FROM sbtest.sbtest1 WHERE id=1;
   +----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
   | id | k       | c                                                                                                                       | pad                                                         |
   +----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
   |  1 | 5014614 | 68487932199-96439406143-93774651418-41631865787-96406072701-20604855487-25459966574-28203206787-41238978918-19503783441 | 22195207048-70116052123-74140395089-76317954521-98694025897 |
   +----+---------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
   1 row in set (0.00 sec)

   mysql> UPDATE sbtest.sbtest1 SET c='Changed on MySQL' WHERE id=1;
   Query OK, 1 row affected (0.00 sec)
   Rows matched: 1  Changed: 1  Warnings: 0

   mysql> SELECT * FROM sbtest.sbtest1 WHERE id=1;
   +----+---------+------------------+-------------------------------------------------------------+
   | id | k       | c                | pad                                                         |
   +----+---------+------------------+-------------------------------------------------------------+
   |  1 | 5014614 | Changed on MySQL | 22195207048-70116052123-74140395089-76317954521-98694025897 |
   +----+---------+------------------+-------------------------------------------------------------+
   1 row in set (0.00 sec)
   ```

### 步骤 3. 连接到 TiUP 控制机，然后连接到 TiDB 实例

+ 点击这里 - [终端 3](ssh://monitor1-ssh#3) 打开一个新的终端，然后连接到 TiDB 集群。

+ 登录后显示的横幅：

    ```output
     ,     #_
    ~\_  ####_        Amazon Linux 2
    ~~  \_#####\
    ~~     \###|      
    ~~       \#/ ___
    ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
     ~~._.   _/
        _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
      _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    ```

+ 连接到 TiDB 集群。

   ```bash
   export MYSQL_PS1="tidb:db1> "
   mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root
   ```
   ```output
   tidb:db1> 
   ```

### 步骤 4. 从 TiDB 观察 UPDATE 操作结果

+ 在[终端 3](ssh://monitor1-ssh#3)，观察来自 TiDB 端的 `UPDATE` 结果，该更改已从 MySQL 同步过来。
   
   ```sql
   SELECT * FROM sbtest.sbtest1 WHERE id=1;
   ```
   ```output
   tidb:db1> SELECT * FROM sbtest.sbtest1 WHERE id=1;
   +----+---------+------------------+-------------------------------------------------------------+
   | id | k       | c                | pad                                                         |
   +----+---------+------------------+-------------------------------------------------------------+
   |  1 | 5014614 | Changed on MySQL | 22195207048-70116052123-74140395089-76317954521-98694025897 |
   +----+---------+------------------+-------------------------------------------------------------+
   1 row in set (0.01 sec)
   ```

### 步骤 5. 在 MySQL 中执行 INSERT 操作

+ 在[终端 2](ssh://monitor1-ssh#2)（MySQL 端），插入一行新数据。
  
   ```sql
   INSERT INTO sbtest.sbtest1 (k, c, pad) VALUES (102, 'Insert on MySQL', 'Insert on MySQL');
   SELECT * FROM sbtest.sbtest1 WHERE k=102;
   ```
   ```output
   mysql> INSERT INTO sbtest.sbtest1 (k, c, pad) VALUES (102, 'Insert on MySQL', 'Insert on MySQL');
   Query OK, 1 row affected (0.00 sec)

   mysql> SELECT * FROM sbtest.sbtest1 WHERE k=102;
   +----------+-----+-----------------+-----------------+
   | id       | k   | c               | pad             |
   +----------+-----+-----------------+-----------------+
   | 10000002 | 102 | Insert on MySQL | Insert on MySQL |
   +----------+-----+-----------------+-----------------+
   1 row in set (0.00 sec)
   ```

### 步骤 6. 从 TiDB 观察 INSERT 操作结果

+ 在[终端 3](ssh://monitor1-ssh#3)（TiDB 端），观察来自 TiDB 端的 `INSERT` 结果，该更改已从 MySQL 同步过来。
   
   ```sql
   SELECT * FROM sbtest.sbtest1 WHERE k=102;
   ```
   ```output
   tidb:db1> SELECT * from sbtest.sbtest1 where k=102;
   +----------+-----+-----------------+-----------------+
   | id       | k   | c               | pad             |
   +----------+-----+-----------------+-----------------+
   | 10000002 | 102 | Insert on MySQL | Insert on MySQL |
   +----------+-----+-----------------+-----------------+
   1 row in set (0.00 sec)
   ```

+ 如果时间允许，在 MySQL 端尝试更多修改，并从 TiDB 端观察结果。

## 结论

在 TiDB 的工具套件中，TiDB Data Migration (DM) 在简化数据迁移任务方面发挥着关键作用。TiDB DM 不仅仅是一个工具，它是一个集成平台，旨在处理从与 MySQL 兼容的数据库（包括 MySQL、MariaDB 和 Amazon Aurora）到 TiDB 的全量数据迁移和增量数据复制。

TiDB DM 还支持将多个 MySQL 分片合并并迁移到单个 TiDB 数据库中。这使其成为管理跨不同存储系统的大量碎片化数据的组织的理想选择，有效降低了数据管理的复杂性。凭借集中管理功能，TiDB DM 可以处理集群中的数千个节点并同时管理众多迁移任务，凸显了其处理大规模操作的能力。此外，其高可用性确保迁移任务能够抵御节点故障，为数据操作提供了一个稳定可靠的平台。

如需了解更多关于 TiDB Data Migration 的信息，尝试使用 <kbd>Ask AI</kbd>。下次实验再见。再会！