## 模块 1: TiDB 集群和数据初始化

### 步骤 1. 连接至 TiUP 控制机

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

### 步骤 2. 确认 TiDB 集群状态

+ 通过TiProxy观察集群运行状态，其中包括一个`tidb`服务器，一个`pd`服务器和三个`tikv`服务器。

   ```bash
   ~/.tiup/bin/tiup cluster display tidb-demo
   ```

   ```output
   Cluster type:       tidb
   Cluster name:       tidb-demo
   Cluster version:    v${LAB:TIDB_VERSION}
   Deploy user:        ec2-user
   SSH type:           builtin
   Dashboard URL:      http://35.74.236.1:2379/dashboard
   Grafana URL:        http://10.90.4.196:3000
   ID                 Role          Host         Ports        OS/Arch       Status  Data Dir                      Deploy Dir
   --                 ----          ----         -----        -------       ------  --------                      ----------
   10.90.4.196:9093   alertmanager  10.90.4.196  9093/9094    linux/x86_64  Up      /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093
   10.90.4.196:3000   grafana       10.90.4.196  3000         linux/x86_64  Up      -                             /tidb-deploy/grafana-3000
   10.90.2.178:2379   pd            10.90.2.178  2379/2380    linux/x86_64  Up|L    /tidb-data/pd-2379            /tidb-deploy/pd-2379
   10.90.4.196:9090   prometheus    10.90.4.196  9090/12020   linux/x86_64  Up      /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090
   10.90.1.140:4000   tidb          10.90.1.140  4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
   10.90.1.169:20160  tikv          10.90.1.169  20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.1.88:20160   tikv          10.90.1.88   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.1.99:20160   tikv          10.90.1.99   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
   10.90.4.196:6000   tiproxy       10.90.4.196  6000/3080    linux/x86_64  Up      -                             /tidb-deploy/tiproxy-6000
   Total nodes: 9
   ```

> [!TIP]
> 请注意！如果开启了模块 1，建议从开始到模块 1 的第 7 步，每一步之间不要有太长的时间间隔（10 分钟以上），比如中间插入其它工作再回来继续操作，以防止 PD 组件自动进行数据分布调整，这样可能无法出现希望的实验效果。

### 步骤 3. 创建 sysbench 配置

   ```bash
   cat << EOF > sysbench_config
   mysql-host=${HOST_MONITOR1_PRIVATE_IP}
   mysql-port=6000
   mysql-user=root
   mysql-password=
   mysql-db=sbtest
   time=120
   threads=14
   report-interval=5
   EOF
   cat sysbench_config
   ```

   ```output
   mysql-host=${HOST_MONITOR1_PRIVATE_IP}
   mysql-port=6000
   mysql-user=root
   mysql-password=
   mysql-db=sbtest
   time=120
   threads=14
   report-interval=5
   ```

### 步骤 4. 连接TiDB集群并创建空数据库 `sbtest`

   ```bash
   mysql -h ${HOST_MONITOR1_PRIVATE_IP} -P 6000 -uroot
   ```

   ```output
   Welcome to the MySQL monitor.  Commands end with ; or \g.
   Your MySQL connection id is 0
   Server version: 8.0.11-TiDB-v${LAB:TIDB_VERSION} TiDB Server (Apache License 2.0) Community Edition, MySQL 8.0 compatible

   Copyright (c) 2000, 2023, Oracle and/or its affiliates.

   Oracle is a registered trademark of Oracle Corporation and/or its
   affiliates. Other names may be trademarks of their respective
   owners.

   Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

   mysql>
   ```

   ```sql
   CREATE DATABASE sbtest;
   EXIT;
   ```

   ```output
   Query OK, 0 rows affected (0.11 sec)
   Bye
   ```

### 步骤 5. 准备数据

+ 准备`sysbench`数据，需约 5 至 10 分钟完成。在等待数据导入过程中，可以跳到下一步骤，了解在后面步骤中需要使用的相关监控。

   ```bash
   sysbench --config-file=sysbench_config oltp_read_only --tables=10 --table-size=3000000 prepare
   ```

   ```output
   sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)

   Initializing worker threads...

   Creating table 'sbtest2'...
   Creating table 'sbtest8'...
   Creating table 'sbtest5'...
   Creating table 'sbtest6'...
   Creating table 'sbtest7'...
   Creating table 'sbtest9'...
   Creating table 'sbtest1'...
   Creating table 'sbtest4'...
   Creating table 'sbtest3'...
   Creating table 'sbtest10'...
   Inserting 3000000 records into 'sbtest10'
   Inserting 3000000 records into 'sbtest1'
   Inserting 3000000 records into 'sbtest5'
   Inserting 3000000 records into 'sbtest7'
   Inserting 3000000 records into 'sbtest4'
   Inserting 3000000 records into 'sbtest8'
   Inserting 3000000 records into 'sbtest2'
   Inserting 3000000 records into 'sbtest6'
   Inserting 3000000 records into 'sbtest3'
   Inserting 3000000 records into 'sbtest9'
   ```

### 步骤 6. 学习与 TiKV 扩容/缩容相关的监控

+ 下面讲介绍与 TiKV 扩容/缩容相关的监控，如果参与者了解这些监控项目，请跳到步骤 7。登录 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，建议参与者保留本步骤中打开的监控页面，并设置监控时间范围为最近 5 分钟或者 15 分钟，同时将刷新频率改为 5 秒。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/9c787410ab425dd7eb7e7297cc46711ec63ccc22.png)

+ 了解整个 TiDB 集群的数据总量，在 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，进入`Home`，然后选择`tidb-demo`，接着选择`tidb-demo-PD`。在`tidb-demo-PD`上半部分，可以看到 `Current storage size` 表示当前 TiDB 集群的数据总量，`Normal Stores` 表示当前 TiKV 节点的数量，`Number of Regions` 表示当前 Leader 的数量，`Current peer count` 表示当前所有 region 的数量。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/f5789ae1bf0d0012aadb2efd25ebb019aced7755.png)

+ 观察扩容/缩容的进度，在`tidb-demo-PD`上半部分，可以看到 `Online store progress` 表示当前扩容命令执行后平衡的进度，`Offline store progress` 表示当前缩容命令执行后平衡的进度，`Left time` 表示对于当前扩容/缩容过程中平衡完成时间的预测，`Current scaling spee` 表示当前扩容或者缩容过程中平衡的速率，单位是 MB/s。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/33ca440cdffeacf0f0c761c01569128f4095568b.png)

+ 观察 PD 中对于扩容和缩容的相关设置，在`tidb-demo-PD`下半部分，打开 `Cluster` 标签，可以看到 `PD scheduler config` 面板列出了 PD 组件中与 Schedule 相关的设置, `Store limit` 面板列出了所有 TiKV 节点的 Store limit 设置。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/abe91e672688c726ab01f31d5a328ea16c519d59.png)

+ 如何监控 PD 组件产生调度指令的效率，在`tidb-demo-PD`下半部分，打开 `Operator` 标签，可以看到 `Scheduler operator create` 面板显示了 PD 组件产生 operator 的效率，`Scheduler operator finish` 面板显示了 PD 组件产生的 operator 被执行完毕的效率。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/166bae9064df01fac2ea5ebcbab5da006b303d0f.png)

+ 如何监控 PD 组件开启的 Schedule，在`tidb-demo-PD`下半部分，打开 `Scheduler` 标签，可以看到 `Scheduler` 面板显示了 PD 组件当前开启的 Scheduler。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/0dc48adba12cd619c1504728f9e4af549ddbd5a5.png)

+ 如何监控 TiKV 集群的数据分布情况，在`tidb-demo-PD`下半部分，打开 `Statistics - balance` 标签，可以看到 `Store available` 面板表示了当前各个 TiKV 节点的可用数据量和 `Store available ratio`面板表示了当前各个 TiKV 节点的可用存储空间百分比。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/8f9c5b2cd165337e7b1685e8a905bc0e32ddf951.png)

+ 如何监控 TiKV 集群的 IO 负载，登录 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，进入`Home`，然后选择`tidb-demo`，接着选择`tidb-demo-TiKV-Details`， 打开 `Cluster` 标签， 在 `Cluster` 标签下可以看到 `CPU` 面板中有各个 TiKV 节点的 CPU 使用率情况， 在 `IO utillzation` 面板中有各个节点的 IO 使用率情况。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/4731b3d2183b8d351eae72b449cb547bf23f52ec.png)

### 步骤 7. 设置 TiDB 集群

+ 等待 `步骤 5` 的数据导入完毕，检查 PD 组件的 scheduler 配置， 第一次执行时会等待 1 至 2 分钟时间，原因是需要下载 `PD ctl` 组件。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 scheduler show
   ```

   ```output
   The component `ctl` version v${LAB:TIDB_VERSION} is not installed; downloading from repository.
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.2.178:2379 scheduler show
   [
   "evict-slow-store-scheduler",
   "balance-region-scheduler",
   "balance-leader-scheduler",
   "balance-hot-region-scheduler"
   ]
   ```

+ 删除 PD 组件的 `balance-region-scheduler`，为下面的模块做准备。删除 PD 组件 `balance-region-scheduler` 的原因将在接下来的步骤中解释。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 scheduler remove balance-region-scheduler
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.2.178:2379 scheduler remove balance-region-scheduler
   Success!
   ```

+ 确认 PD 组件的 `balance-region-scheduler` 已经被删除。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 scheduler show
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.3.229:2379 scheduler show
   [
   "balance-leader-scheduler",
   "balance-hot-region-scheduler",
   "evict-slow-store-scheduler"
   ]
   ```

+ 登录 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，进入`Home`，然后选择`tidb-demo`，接着选择`tidb-demo-PD`。 在`tidb-demo-PD`下半部分，打开 `Scheduler` 标签，可以看到 PD 组件的 `balance-region-scheduler` Scheduler 被移除了。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/d39ff1e27d81d847844986d80fba45691a8036db.png)

+ 修改 PD 组件的 `region-schedule-limit` 变量为 `0`，为下面的模块做准备。下一个步骤中将会解释为什么修改 PD 组件的 `region-schedule-limit` 变量为 `0`。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 config set region-schedule-limit 0
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.2.178:2379 config set region-schedule-limit 0
   Success!
   ```

+ 确认 PD 组件的 region-schedule-limit 变量已经修改为 `0`。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 config show
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.2.178:2379 config show
   {
      "replication": {
         "enable-placement-rules": "true",
         "enable-placement-rules-cache": "false",
         "isolation-level": "",
         "location-labels": "",
         "max-replicas": 3,
         "strictly-match-label": "false"
      },
      "schedule": {
         "enable-cross-table-merge": "true",
         "enable-diagnostic": "true",
         "enable-heartbeat-breakdown-metrics": "true",
         "enable-heartbeat-concurrent-runner": "true",
         "enable-joint-consensus": "true",
         "enable-tikv-split-region": "true",
         "enable-witness": "false",
         "high-space-ratio": 0.7,
         "hot-region-cache-hits-threshold": 3,
         "hot-region-schedule-limit": 4,
         "hot-regions-reserved-days": 7,
         "hot-regions-write-interval": "10m0s",
         "leader-schedule-limit": 4,
         "leader-schedule-policy": "count",
         "low-space-ratio": 0.8,
         "max-merge-region-keys": 540000,
         "max-merge-region-size": 54,
         "max-movable-hot-peer-size": 512,
         "max-pending-peer-count": 64,
         "max-snapshot-count": 64,
         "max-store-down-time": "30m0s",
         "max-store-preparing-time": "48h0m0s",
         "merge-schedule-limit": 8,
         "patrol-region-interval": "10ms",
         "patrol-region-worker-count": 1,
         "region-schedule-limit": 0,
         "region-score-formula-version": "v2",
         "replica-schedule-limit": 64,
         "slow-store-evicting-affected-store-ratio-threshold": 0.3,
         "split-merge-interval": "1h0m0s",
         "store-limit-version": "v1",
         "switch-witness-interval": "1h0m0s",
         "tolerant-size-ratio": 0,
         "witness-schedule-limit": 4
      }
   }
   ```

+ 回到 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) 的 `tidb-demo-PD`。 在`tidb-demo-PD`下半部分，打开 `Operator` 标签，可以看到 `Scheduler operator create` 面板和 `Scheduler operator finish` 面板目前没有任何 operator 产生。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/41b41866585731f9bd597a4e19180e3465da3fff.png)

+ 将所有 TiKV 节点的 `store limit` 的项目设置为 `1`，为下面的步骤做准备。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 store limit all 1
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION} /ctl pd -u http://10.90.2.178:2379 store limit all 1
   Success! Set store limit successfully.
   ```

+ 确认所有 TiKV 节点的 `store limit` 的所有项目已经被设置为 `1`。

   ```bash
   ~/.tiup/bin/tiup ctl:v${LAB:TIDB_VERSION} pd -u http://${HOST_PD1_PRIVATE_IP}:2379 store limit
   ```

   ```output
   Starting component ctl: /home/ec2-user/.tiup/components/ctl/v${LAB:TIDB_VERSION}/ctl pd -u http://10.90.2.178:2379 store limit
   {
   "1": {
      "add-peer": 1,
      "remove-peer": 1
   },
   "4": {
      "add-peer": 1,
      "remove-peer": 1
   },
   "7": {
      "add-peer": 1,
      "remove-peer": 1
   }
   }
   ```

+ 回到 [Grafana 监控](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000) 的 `tidb-demo-PD`， 在`tidb-demo-PD`下半部分，打开 `Cluster` 标签，可以看到 `PD scheduler config` 面板中 `region-schedule-limit` 为 `0`, `Store limit` 面板中所有的项目为 `1`。

  ![70%](https://lab-static.pingcap.com/images/2025/7/24/95665cbee2ec67dd9104e8508364a2379b9d6ead.png)

+ 到此为止，TiDB 集群的配置和数据已经准备完毕，可以开始进行扩容和缩容操作了。

### 步骤 8. 关于 “删除 PD 组件的 `balance-region-scheduler` ,设置 PD 组件的 `region-schedule-limit` 变量为 `0` 和修改 `Store limit` 为 `1` ” 的说明

+ 这里以 TiKV 的扩容为例，说明在此过程中 PD 和 TiKV 如何相互协作保持数据的平衡分布的。下图中，所有的 TiKV 节点和 Leader 角色的 Region 副本会以心跳的方式将相关信息发送给 PD 组件，PD 组件因此可以了解到数据在各个 TiKV 节点上的分布情况。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/aba924da1fff5a1a82ae02d05393a50a4358b9d6.png)

+ 当有新的 TiKV 节点加入以后，PD 组件会收到其心跳信息，当 PD 组件判定当前数据分布不平衡后，其 `balance-region-scheduler` 组件就会创建多个 `balance-region-operator`，每个 `balance-region-operator` 中包含如何进行数据平衡的具体步骤，这些步骤会发送给相关 Leader 角色的 Region 副本， 之后，其所在的 Region Group 开始进行数据的平衡。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/52c6ded417e9c8bcbae6621023f4b39349c3b5a9.png)

+ 在上一个步骤中，删除 PD 组件的 `balance-region-scheduler` 后，PD 组件即使发现数据分布不平衡，也无法发出 `balance-region-operator`，所以，在扩容后会发现，必须将 `balance-region-scheduler` 重新加入才会开始进行数据的平衡。

+ `region-schedule-limit` 表示 PD 组件同时生成各种 operator 的个数，其为`0` ，PD 组件同样无法生成 `balance-region-operator`，必须将其设置为大于 `0` 的值，数据的平衡操作才会开启。

+ `Store limit` 定义了 TiKV 每分钟执行 PD 发来的 Operator 操作的最大数量，所以它可以调节数据平衡动作的快慢。

+ 在后面的模块和步骤中，会观察到由于 “删除 PD 组件的 `balance-region-scheduler` ,设置 PD 组件的 `region-schedule-limit` 变量为 `0` 和修改 `Store limit` 为 `1`”带来的现象，并进行相应调整。

+ 关于 `region-schedule-limit` ，请参考：<https://docs.pingcap.com/tidb/stable/pd-configuration-file/#region-schedule-limit>

+ 关于 `Store limit`，请参考：<https://docs.pingcap.com/tidb/stable/configure-store-limit/#store-limit>

+ 如果 PD 的 `balance-region-scheduler` 组件创建 `balance-region-operator` 成功，则第一步会通知选中的 Leader 角色的 Region 副本将数据拷贝并发送到新的 TiKV 节点（TiKV Node 4）上，新的 TiKV 节点（TiKV Node 4）上会拥有一个 Learner 角色的数据副本。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/e7874791484e5f440de4f9a5e9763043c23399f9.png)

+ 接下来，PD 组件的 `balance-region-operator` 会进行第二步，将同一个 Raft Group 中的 Learner 角色副本和 Follower 角色副本进行角色交换，如图，新加入的 TiKV 节点（TiKV Node 4）中的 Region3 副本变为了 Follower 角色，已有 TiKV 节点（TiKV Node 1）中的 Region3 副本变为了 Learner 角色。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/223b9ba88e98391b1cd31e419b7558c78d75a576.png)

+ 接下来，PD 组件的 `balance-region-operator` 会进行第三步，删除 Raft Group 中的 Learner 角色的副本。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/6e66f0bc2fd1eddfe263bf1f7800da9fbc543c99.png)

+ 最后，在 PD 组件和 TiKV 组件共同协作下，完成了扩容之后的数据平衡操作。

  ![85%](https://lab-static.pingcap.com/images/2025/7/24/f7bfe57d10aaaee6ffb7a3e6f1f6467f42c71514.png)

+ 对于缩容操作，同一个 Raft Group 中 Region 副本的迁移原理和扩容操作相同，不同之处在于 PD 组件发出的 operator 名称为 `replace-rule-offline-peer` 或 `replace-rule-offline-leader-peer`。更详细的内容请参考课程内容。
