From b3f34673deec4a6b9751a3457f646d2a642f6788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E5=B2=9A?= <36239017+YuJuncen@users.noreply.github.com> Date: Tue, 28 Nov 2023 20:19:17 +0800 Subject: [PATCH 1/3] This is an automated cherry-pick of #15528 Signed-off-by: ti-chi-bot --- migrate-from-tidb-to-tidb.md | 303 +++++++++++++++++ ...-between-primary-and-secondary-clusters.md | 318 ++++++++++++++++++ sql-statements/sql-statement-backup.md | 4 + sql-statements/sql-statement-restore.md | 4 + 4 files changed, 629 insertions(+) create mode 100644 migrate-from-tidb-to-tidb.md create mode 100644 replicate-between-primary-and-secondary-clusters.md diff --git a/migrate-from-tidb-to-tidb.md b/migrate-from-tidb-to-tidb.md new file mode 100644 index 000000000000..9a0c3cc7eaf0 --- /dev/null +++ b/migrate-from-tidb-to-tidb.md @@ -0,0 +1,303 @@ +--- +title: 从 TiDB 集群迁移数据至另一 TiDB 集群 +summary: 了解如何将数据从一个 TiDB 集群迁移至另一 TiDB 集群。 +aliases: ['/zh/tidb/dev/incremental-replication-between-clusters/'] +--- + +# 从 TiDB 集群迁移数据至另一 TiDB 集群 + +本文档介绍如何将数据从一个 TiDB 集群迁移至另一 TiDB。在如下场景中,你可以将数据从一个 TiDB 集群迁移至另一个 TiDB 集群: + +- 拆库:原 TiDB 集群体量过大,或者为了避免原有的 TiDB 集群所承载的数个业务之间互相影响,将原 TiDB 集群中的部分表迁到另一个 TiDB 集群。 +- 迁库:是对数据库的物理位置进行迁移,比如更换数据中心。 +- 升级:在对数据正确性要求严苛的场景下,可以将数据迁移到一个更高版本的 TiDB 集群,确保数据安全。 + +本文将模拟整个迁移过程,具体包括以下四个步骤: + +1. 搭建环境 +2. 迁移全量数据 +3. 迁移增量数据 +4. 平滑切换业务 + +## 第 1 步:搭建环境 + +1. 部署集群。 + + 使用 TiUP Playground 快速部署上下游测试集群。更多部署信息,请参考 [TiUP 官方文档](/tiup/tiup-cluster.md)。 + + {{< copyable "shell-regular" >}} + + ```shell + # 创建上游集群 + tiup --tag upstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 + # 创建下游集群 + tiup --tag downstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 + # 查看集群状态 + tiup status + ``` + +2. 初始化数据。 + + 测试集群中默认创建了 test 数据库,因此可以使用 [sysbench](https://github.com/akopytov/sysbench#linux) 工具生成测试数据,用以模拟真实集群中的历史数据。 + + {{< copyable "shell-regular" >}} + + ```shell + sysbench oltp_write_only --config-file=./tidb-config --tables=10 --table-size=10000 prepare + ``` + + 这里通过 sysbench 运行 oltp_write_only 脚本,其将在测试数据库中生成 10 张表,每张表包含 10000 行初始数据。tidb-config 的配置如下: + + ```yaml + mysql-host=172.16.6.122 # 这里需要替换为实际上游集群 ip + mysql-port=4000 + mysql-user=root + mysql-password= + db-driver=mysql # 设置数据库驱动为 mysql + mysql-db=test # 设置测试数据库为 test + report-interval=10 # 设置定期统计的时间间隔为 10 秒 + threads=10 # 设置 worker 线程数量为 10 + time=0 # 设置脚本总执行时间,0 表示不限制 + rate=100 # 设置平均事务速率 tps = 100 + ``` + +3. 模拟业务负载。 + + 实际生产集群的数据迁移过程中,通常原集群还会写入新的业务数据,本文中可以通过 sysbench 工具模拟持续的写入负载,下面的命令会使用 10 个 worker 在数据库中的 sbtest1、sbtest2 和 sbtest3 三张表中持续写入数据,其总 tps 限制为 100。 + + {{< copyable "shell-regular" >}} + + ```shell + sysbench oltp_write_only --config-file=./tidb-config --tables=3 run + ``` + +4. 准备外部存储。 + + 在全量数据备份中,上下游集群均需访问备份文件,因此推荐使用[备份存储](/br/backup-and-restore-storages.md)存储备份文件,本文中通过 Minio 模拟兼容 S3 的存储服务: + + {{< copyable "shell-regular" >}} + + ```shell + wget https://dl.min.io/server/minio/release/linux-amd64/minio + chmod +x minio + # 配置访问 minio 的 access-key access-screct-id + export HOST_IP='172.16.6.122' # 替换为实际上游集群 ip + export MINIO_ROOT_USER='minio' + export MINIO_ROOT_PASSWORD='miniostorage' + # 创建数据目录, 其中 backup 为 bucket 的名称 + mkdir -p data/backup + # 启动 minio, 暴露端口在 6060 + ./minio server ./data --address :6060 & + ``` + + 上述命令行启动了一个单节点的 minio server 模拟 S3 服务,其相关参数为: + + - Endpoint: + - Access-key: minio + - Secret-access-key: miniostorage + - Bucket: backup + + 相应的访问链接为: + + {{< copyable "shell-regular" >}} + + ```shell + s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true + ``` + +## 第 2 步:迁移全量数据 + +搭建好测试环境后,可以使用 [BR](https://github.com/pingcap/tidb/tree/master/br) 工具的备份和恢复功能迁移全量数据。BR 工具有多种[使用方式](/br/br-use-overview.md#部署和使用-br),本文中使用 SQL 语句 [`BACKUP`](/sql-statements/sql-statement-backup.md) 和 [`RESTORE`](/sql-statements/sql-statement-restore.md) 进行备份恢复。 + +> **注意:** +> +> - `BACKUP` 和 `RESTORE` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 +> - 在生产集群中,关闭 GC 机制和备份操作会一定程度上降低集群的读性能,建议在业务低峰期进行备份,并设置合适的 `RATE_LIMIT` 限制备份操作对线上业务的影响。 +> - 上下游集群版本不一致时,应检查 BR 工具的[兼容性](/br/backup-and-restore-overview.md#使用须知)。本文假设上下游集群版本相同。 + +1. 关闭 GC。 + + 为了保证增量迁移过程中新写入的数据不丢失,在开始备份之前,需要关闭上游集群的垃圾回收 (GC) 机制,以确保系统不再清理历史数据。 + + 执行如下命令关闭 GC: + + ```sql + MySQL [test]> SET GLOBAL tidb_gc_enable=FALSE; + ``` + + ``` + Query OK, 0 rows affected (0.01 sec) + ``` + + 查询 `tidb_gc_enable` 的取值,判断 GC 是否已关闭: + + ```sql + MySQL [test]> SELECT @@global.tidb_gc_enable; + ``` + + ``` + +-------------------------+: + | @@global.tidb_gc_enable | + +-------------------------+ + | 0 | + +-------------------------+ + 1 row in set (0.00 sec) + ``` + +2. 备份数据。 + + 在上游集群中执行 BACKUP 语句备份数据: + + ```sql + MySQL [(none)]> BACKUP DATABASE * TO 's3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true' RATE_LIMIT = 120 MB/SECOND; + ``` + + ``` + +---------------+----------+--------------------+---------------------+---------------------+ + | Destination | Size | BackupTS | Queue Time | Execution Time | + +---------------+----------+--------------------+---------------------+---------------------+ + | s3://backup | 10315858 | 431434047157698561 | 2022-02-25 19:57:59 | 2022-02-25 19:57:59 | + +---------------+----------+--------------------+---------------------+---------------------+ + 1 row in set (2.11 sec) + ``` + + 备份语句提交成功后,TiDB 会返回关于备份数据的元信息,这里需要重点关注 BackupTS,它意味着该时间点之前数据会被备份,后边的教程中,本文将使用 BackupTS 作为**数据校验截止时间**和 **TiCDC 增量扫描的开始时间**。 + +3. 恢复数据。 + + 在下游集群中执行 RESTORE 语句恢复数据: + + ```sql + mysql> RESTORE DATABASE * FROM 's3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true'; + ``` + + ``` + +--------------+-----------+--------------------+---------------------+---------------------+ + | Destination | Size | BackupTS | Queue Time | Execution Time | + +--------------+-----------+--------------------+---------------------+---------------------+ + | s3://backup | 10315858 | 431434141450371074 | 2022-02-25 20:03:59 | 2022-02-25 20:03:59 | + +--------------+-----------+--------------------+---------------------+---------------------+ + 1 row in set (41.85 sec) + ``` + +4. (可选)校验数据。 + + 通过 [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) 工具,可以验证上下游数据在某个时间点的一致性。从上述备份和恢复命令的输出可以看到,上游集群备份的时间点为 431434047157698561,下游集群完成数据恢复的时间点为 431434141450371074。 + + ```shell + sync_diff_inspector -C ./config.yaml + ``` + + 关于 sync-diff-inspector 的配置方法,请参考[配置文件说明](/sync-diff-inspector/sync-diff-inspector-overview.md#配置文件说明),在本文中,相应的配置如下: + + ```toml + # Diff Configuration. + ######################### Datasource config ######################### + [data-sources] + [data-sources.upstream] + host = "172.16.6.122" # 需要替换为实际上游集群 ip + port = 4000 + user = "root" + password = "" + snapshot = "431434047157698561" # 配置为实际的备份时间点(参见「备份」小节的 BackupTS) + [data-sources.downstream] + host = "172.16.6.125" # 需要替换为实际下游集群 ip + port = 4000 + user = "root" + password = "" + + ######################### Task config ######################### + [task] + output-dir = "./output" + source-instances = ["upstream"] + target-instance = "downstream" + target-check-tables = ["*.*"] + ``` + +## 第 3 步:迁移增量数据 + +1. 部署 TiCDC。 + + 完成全量数据迁移后,就可以部署并配置 TiCDC 集群同步增量数据,实际生产集群中请参考 [TiCDC 部署](/ticdc/deploy-ticdc.md)。本文在创建测试集群时,已经启动了一个 TiCDC 节点,因此可以直接进行 changefeed 的配置。 + +2. 创建同步任务。 + + 在上游集群中,执行以下命令创建从上游到下游集群的同步链路: + + ```shell + tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="upstream-to-downstream" --start-ts="431434047157698561" + ``` + + 以上命令中: + + - `--server`:TiCDC 集群中任意一个节点的地址 + - `--sink-uri`:同步任务下游的地址 + - `--changefeed-id`:同步任务的 ID,格式需要符合正则表达式 ^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$ + - `--start-ts`:TiCDC 同步的起点,需要设置为实际的备份时间点,也就是[第 2 步:迁移全量数据](/migrate-from-tidb-to-mysql.md#第-2-步迁移全量数据)中 “备份数据” 提到的 BackupTS + + 更多关于 changefeed 的配置,请参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 + +3. 重新开启 GC。 + + TiCDC 可以保证 GC 只回收已经同步的历史数据。因此,创建完从上游到下游集群的 changefeed 之后,就可以执行如下命令恢复集群的垃圾回收功能。详情请参考 [TiCDC GC safepoint 的完整行为](/ticdc/ticdc-faq.md#ticdc-gc-safepoint-的完整行为是什么)。 + + 执行如下命令打开 GC: + + ```sql + MySQL [test]> SET GLOBAL tidb_gc_enable=TRUE; + ``` + + ``` + Query OK, 0 rows affected (0.01 sec) + ``` + + 查询 `tidb_gc_enable` 的取值,判断 GC 是否已开启: + + ```sql + MySQL [test]> SELECT @@global.tidb_gc_enable; + ``` + + ``` + +-------------------------+ + | @@global.tidb_gc_enable | + +-------------------------+ + | 1 | + +-------------------------+ + 1 row in set (0.00 sec) + ``` + +## 第 4 步:平滑切换业务 + +通过 TiCDC 创建上下游的同步链路后,原集群的写入数据会以非常低的延迟同步到新集群,此时可以逐步将读流量迁移到新集群了。观察一段时间,如果新集群表现稳定,就可以将写流量接入新集群,步骤如下: + +1. 停止上游集群的写业务。确认上游数据已全部同步到下游后,停止上游到下游集群的 changefeed。 + + ```shell + # 停止旧集群到新集群的 changefeed + tiup cdc cli changefeed pause -c "upstream-to-downstream" --server=http://172.16.6.122:8300 + + # 查看 changefeed 状态 + tiup cdc cli changefeed list + ``` + + ``` + [ + { + "id": "upstream-to-downstream", + "summary": { + "state": "stopped", # 需要确认这里的状态为 stopped + "tso": 431747241184329729, + "checkpoint": "2022-03-11 15:50:20.387", # 确认这里的时间晚于停写的时间 + "error": null + } + } + ] + ``` + +2. 创建下游到上游集群的 changefeed。由于此时上下游数据是一致的,且没有新数据写入,因此可以不指定 start-ts,默认为当前时间: + + ```shell + tiup cdc cli changefeed create --server=http://172.16.6.125:8300 --sink-uri="mysql://root:@172.16.6.122:4000" --changefeed-id="downstream -to-upstream" + ``` + +3. 将写业务迁移到下游集群,观察一段时间后,等新集群表现稳定,便可以弃用原集群。 diff --git a/replicate-between-primary-and-secondary-clusters.md b/replicate-between-primary-and-secondary-clusters.md new file mode 100644 index 000000000000..b27355e9d385 --- /dev/null +++ b/replicate-between-primary-and-secondary-clusters.md @@ -0,0 +1,318 @@ +--- +title: 搭建双集群主从复制 +summary: 了解如何配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群,并将增量数据实时从主集群同步到从集群, +--- + +# 搭建双集群主从复制 + +本文档介绍如何配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群,并将增量数据实时从主集群同步到从集群,主要包含以下内容: + +1. 配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群。 +2. 将增量数据实时从主集群同步到从集群。 +3. 在主集群发生灾难利用 Redo log 恢复一致性数据。 + +如果你需要配置一个运行中的 TiDB 集群和其从集群,以进行实时增量数据同步,可使用 [Backup & Restore (BR)](/br/backup-and-restore-overview.md) 和 [TiCDC](/ticdc/ticdc-overview.md)。 + +## 第 1 步:搭建环境 + +1. 部署集群。 + + 使用 tiup playground 快速部署 TiDB 上下游测试集群。生产环境可以参考 [tiup 官方文档](/tiup/tiup-cluster.md)根据业务需求来部署集群。 + + 为了方便展示和理解,我们简化部署结构,需要准备以下两台机器,分别来部署上游主集群和下游从集群。假设 IP 地址分别为: + + - NodeA: `172.16.6.123`,部署上游 TiDB + + - NodeB: `172.16.6.124`,部署下游 TiDB + + {{< copyable "shell-regular" >}} + + ```shell + + # 在 NodeA 上创建上游集群 + tiup --tag upstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 + # 在 NodeB 上创建下游集群 + tiup --tag downstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 0 + # 查看集群状态 + tiup status + ``` + +2. 初始化数据。 + + 测试集群中默认创建了 test 数据库,因此可以使用 [sysbench](https://github.com/akopytov/sysbench#linux) 工具生成测试数据,用以模拟真实集群中的历史数据。 + + ```shell + sysbench oltp_write_only --config-file=./tidb-config --tables=10 --table-size=10000 prepare + ``` + + 这里通过 sysbench 运行 oltp_write_only 脚本,其将在测试数据库中生成 10 张表,每张表包含 10000 行初始数据。tidb-config 的配置如下: + + ```yaml + mysql-host=172.16.6.122 # 这里需要替换为实际上游集群 ip + mysql-port=4000 + mysql-user=root + mysql-password= + db-driver=mysql # 设置数据库驱动为 mysql + mysql-db=test # 设置测试数据库为 test + report-interval=10 # 设置定期统计的时间间隔为 10 秒 + threads=10 # 设置 worker 线程数量为 10 + time=0 # 设置脚本总执行时间,0 表示不限制 + rate=100 # 设置平均事务速率 tps = 100 + ``` + +3. 模拟业务负载。 + + 实际生产集群的数据迁移过程中,通常原集群还会写入新的业务数据,本文中可以通过 sysbench 工具模拟持续的写入负载,下面的命令会使用 10 个 worker 在数据库中的 sbtest1、sbtest2 和 sbtest3 三张表中持续写入数据,其总 tps 限制为 100。 + + ```shell + sysbench oltp_write_only --config-file=./tidb-config --tables=3 run + ``` + +4. 准备外部存储。 + + 在全量数据备份中,上下游集群均需访问备份文件,因此推荐使用[外部存储](/br/backup-and-restore-storages.md)存储备份文件,本文中通过 Minio 模拟兼容 S3 的存储服务: + + ```shell + wget https://dl.min.io/server/minio/release/linux-amd64/minio + chmod +x minio + # 配置访问 minio 的 access-key access-secret-id + export `HOST_IP`='172.16.6.123' # 替换为实际部署 minio 的机器 ip + export** **MINIO_ROOT_USER**='**minio' + export MINIO_ROOT_PASSWORD='miniostorage' + # 创建 redo 和 backup 数据目录, 其中 redo, backup 为 bucket 名字 + mkdir -p data/redo + mkdir -p data/backup + # 启动 minio, 暴露端口在 6060 + nohup ./minio server ./data --address :6060 & + ``` + + 上述命令行启动了一个单节点的 minio server 模拟 S3 服务,其相关参数为: + + * Endpoint : `http://${HOST_IP}:6060/` + * Access-key : `minio` + * Secret-access-key: `miniostorage` + * Bucket: `redo` + + 其访问链接为如下: + + ```shell + s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true + ``` + +## 第 2 步:迁移全量数据 + +搭建好测试环境后,可以使用 [BR](https://github.com/pingcap/tidb/tree/master/br) 工具的备份和恢复功能迁移全量数据。BR 工具有多种[使用方式](/br/br-use-overview.md#部署和使用-br),本文中使用 SQL 语句 [`BACKUP`](/sql-statements/sql-statement-backup.md) 和 [`RESTORE`](/sql-statements/sql-statement-restore.md) 进行备份恢复。 + +> **注意:** +> +> - `BACKUP` 和 `RESTORE` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 +> - 在生产集群中,关闭 GC 机制和备份操作会一定程度上降低集群的读性能,建议在业务低峰期进行备份,并设置合适的 `RATE_LIMIT` 限制备份操作对线上业务的影响。 +> - 上下游集群版本不一致时,应检查 BR 工具的[兼容性](/br/backup-and-restore-overview.md#使用建议)。本文假设上下游集群版本相同。 + +1. 关闭 GC。 + + 为了保证增量迁移过程中新写入的数据不丢失,在开始备份之前,需要关闭上游集群的垃圾回收 (GC) 机制,以确保系统不再清理历史数据。 + + 执行如下命令关闭 GC: + + ```sql + MySQL [test]> SET GLOBAL tidb_gc_enable=FALSE; + ``` + + ``` + Query OK, 0 rows affected (0.01 sec) + ``` + + 查询 `tidb_gc_enable` 的取值,判断 GC 是否已关闭: + + ```sql + MySQL [test]> SELECT @@global.tidb_gc_enable; + ``` + + ``` + +-------------------------+ + | @@global.tidb_gc_enable | + +-------------------------+ + | 0 | + +-------------------------+ + 1 row in set (0.00 sec) + ``` + +2. 备份数据。 + + 在上游集群中执行 BACKUP 语句备份数据: + + ```sql + MySQL [(none)]> BACKUP DATABASE * TO '`s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true`' RATE_LIMIT = 120 MB/SECOND; + ``` + + ``` + +----------------------+----------+--------------------+---------------------+---------------------+ + | Destination | Size | BackupTS | Queue Time | Execution Time | + +----------------------+----------+--------------------+---------------------+---------------------+ + | local:///tmp/backup/ | 10315858 | 431434047157698561 | 2022-02-25 19:57:59 | 2022-02-25 19:57:59 | + +----------------------+----------+--------------------+---------------------+---------------------+ + 1 row in set (2.11 sec) + ``` + + 备份语句提交成功后,TiDB 会返回关于备份数据的元信息,这里需要重点关注 BackupTS,它意味着该时间点之前数据会被备份,后边的教程中,本文将使用 BackupTS 作为**数据校验截止时间**和 **TiCDC 增量扫描的开始时间**。 + +3. 恢复数据。 + + 在下游集群中执行 RESTORE 语句恢复数据: + + ```sql + mysql> RESTORE DATABASE * FROM '`s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true`'; + ``` + + ``` + +----------------------+----------+--------------------+---------------------+---------------------+ + | Destination | Size | BackupTS | Queue Time | Execution Time | + +----------------------+----------+--------------------+---------------------+---------------------+ + | local:///tmp/backup/ | 10315858 | 431434141450371074 | 2022-02-25 20:03:59 | 2022-02-25 20:03:59 | + +----------------------+----------+--------------------+---------------------+---------------------+ + 1 row in set (41.85 sec) + ``` + +4. (可选)校验数据。 + + 通过 [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) 工具,可以验证上下游数据在某个时间点的一致性。从上述备份和恢复命令的输出可以看到,上游集群备份的时间点为 431434047157698561,下游集群完成数据恢复的时间点为 431434141450371074。 + + ```shell + sync_diff_inspector -C ./config.yaml + ``` + + 关于 sync-diff-inspector 的配置方法,请参考[配置文件说明](/sync-diff-inspector/sync-diff-inspector-overview.md#配置文件说明)。在本文中,相应的配置如下: + + ```toml + # Diff Configuration. + ######################### Global config ######################### + check-thread-count = 4 + export-fix-sql = true + check-struct-only = false + + ######################### Datasource config ######################### + [data-sources] + [data-sources.upstream] + host = "172.16.6.123" # 替换为实际上游集群 ip + port = 4000 + user = "root" + password = "" + snapshot = "431434047157698561" # 配置为实际的备份时间点 + [data-sources.downstream] + host = "172.16.6.124" # 替换为实际下游集群 ip + port = 4000 + user = "root" + password = "" + snapshot = "431434141450371074" # 配置为实际的恢复时间点 + + ######################### Task config ######################### + [task] + output-dir = "./output" + source-instances = ["upstream"] + target-instance = "downstream" + target-check-tables = ["*.*"] + ``` + +## 第 3 步:迁移增量数据 + +1. 部署 TiCDC。 + + 完成全量数据迁移后,就可以部署并配置 TiCDC 集群同步增量数据,实际生产集群中请参考 [TiCDC 部署](/ticdc/deploy-ticdc.md)。本文在创建测试集群时,已经启动了一个 TiCDC 节点,因此可以直接进行 changefeed 的配置。 + +2. 创建同步任务。 + + 创建 changefeed 配置文件并保存为 `changefeed.toml`。 + + ```toml + [consistent] + # 一致性级别,配置成 eventual 表示开启一致性复制 + level = "eventual" + # 使用 S3 来存储 redo log, 其他可选为 local, nfs + storage = "s3://redo?access-key=minio&secret-access-key=miniostorage&endpoint=http://172.16.6.125:6060&force-path-style=true" + ``` + + 在上游集群中,执行以下命令创建从上游到下游集群的同步链路: + + ```shell + tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="primary-to-secondary" --start-ts="431434047157698561" + ``` + + 以上命令中: + + - `--server`:TiCDC 集群任意一节点的地址 + - `--sink-uri`:同步任务下游的地址 + - `--start-ts`:TiCDC 同步的起点,需要设置为实际的备份时间点(也就是[第 2 步:迁移全量数据](#第-2-步迁移全量数据)提到的 BackupTS) + + 更多关于 changefeed 的配置,请参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 + +3. 重新开启 GC。 + + TiCDC 可以保证未同步的历史数据不会被回收。因此,创建完从上游到下游集群的 changefeed 之后,就可以执行如下命令恢复集群的垃圾回收功能。详情请参考 [TiCDC GC safepoint 的完整行为](/ticdc/ticdc-faq.md#ticdc-gc-safepoint-的完整行为是什么)。 + + 执行如下命令打开 GC: + + ```sql + MySQL [test]> SET GLOBAL tidb_gc_enable=TRUE; + ``` + + ``` + Query OK, 0 rows affected (0.01 sec) + ``` + + 查询 `tidb_gc_enable` 的取值,判断 GC 是否已开启: + + ```sql + MySQL [test]> SELECT @@global.tidb_gc_enable; + ``` + + ``` + +-------------------------+ + | @@global.tidb_gc_enable | + +-------------------------+ + | 1 | + +-------------------------+ + 1 row in set (0.00 sec) + ``` + +## 第 4 步:模拟主集群故障 + +模拟在业务过程中上游 TiDB 发生灾难性故障无法再启动起来,这里可以直接使用 Ctrl + C 终止 tiup playground 进程。 + +## 第 5 步:使用 redo log 确保数据一致性 + +在正常同步过程中,为了提高 TiCDC 的吞吐能力,TiCDC 会将事务并行写入下游。因此,当 TiCDC 同步链路意外中断时,下游可能不会恰好停在与上游一致的状态。我们这里需要使用 TiCDC 的命令行工具来向下游重放 redo log,使下游达到最终一致性状态。 + +```shell +tiup cdc redo apply --storage "s3://redo?access-key=minio&secret-access-key=miniostorage&endpoint=http://172.16.6.123:6060&force-path-style=true" --tmp-dir /tmp/redo --sink-uri "mysql://root:@172.16.6.124:4000" +``` + +- `--storage`:指定 redo log 所在的 S3 位置以及 credential +- `--tmp-dir`:为从 S3 下载 redo log 的缓存目录 +- `--sink-uri`:指定下游集群的地址 + +## 第 6 步:恢复主集群及业务 + +现在从集群有了某一时刻全部的一致性数据,你需要重新搭建主从集群来保证数据可靠性。 + +1. 在 NodeA 重新搭建一个新的 TiDB 集群作为新的主集群。 + + ```shell + tiup --tag upstream playground v5.4.0 --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 + ``` + +2. 使用 BR 将从集群数据全量备份恢复到主集群。 + + ```shell + # 全量备份从集群的数据 + tiup br --pd http://172.16.6.124:2379 backup full --storage ./backup + # 全量恢复从集群的数据 + tiup br --pd http://172.16.6.123:2379 restore full --storage ./backup + ``` + +3. 创建一个 TiCDC 同步任务,备份主集群数据到从集群。 + + ```shell + # 创建 changefeed + tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="primary-to-secondary" + ``` diff --git a/sql-statements/sql-statement-backup.md b/sql-statements/sql-statement-backup.md index b463ab020c57..35dc318491df 100644 --- a/sql-statements/sql-statement-backup.md +++ b/sql-statements/sql-statement-backup.md @@ -5,6 +5,10 @@ summary: TiDB 数据库中 BACKUP 的使用概况。 # BACKUP +> **警告:** +> +> `BACKUP` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 + `BACKUP` 语句用于对 TiDB 集群执行分布式备份操作。 `BACKUP` 语句使用的引擎与 [BR](/br/backup-and-restore-use-cases.md) 相同,但备份过程是由 TiDB 本身驱动,而非单独的 BR 工具。BR 工具的优势和警告也适用于 `BACKUP` 语句。 diff --git a/sql-statements/sql-statement-restore.md b/sql-statements/sql-statement-restore.md index d7678b206856..f708b205308d 100644 --- a/sql-statements/sql-statement-restore.md +++ b/sql-statements/sql-statement-restore.md @@ -5,6 +5,10 @@ summary: TiDB 数据库中 RESTORE 的使用概况。 # RESTORE +> **警告:** +> +> `RESTORE` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 + `RESTORE` 语句用于执行分布式恢复,把 [`BACKUP` 语句](/sql-statements/sql-statement-backup.md)生成的备份文件恢复到 TiDB 集群中。 `RESTORE` 语句使用的引擎与 [BR](/br/backup-and-restore-use-cases.md) 相同,但恢复过程是由 TiDB 本身驱动,而非单独的 BR 工具。BR 工具的优势和警告也适用于 `RESTORE` 语句。需要注意的是,**`RESTORE` 语句目前不遵循 ACID 原则**。 From 17fd2800c3ffbf2d26cb8b7c1e184173531dd091 Mon Sep 17 00:00:00 2001 From: Aolin Date: Tue, 28 Nov 2023 20:25:18 +0800 Subject: [PATCH 2/3] Discard changes to migrate-from-tidb-to-tidb.md --- migrate-from-tidb-to-tidb.md | 303 ----------------------------------- 1 file changed, 303 deletions(-) delete mode 100644 migrate-from-tidb-to-tidb.md diff --git a/migrate-from-tidb-to-tidb.md b/migrate-from-tidb-to-tidb.md deleted file mode 100644 index 9a0c3cc7eaf0..000000000000 --- a/migrate-from-tidb-to-tidb.md +++ /dev/null @@ -1,303 +0,0 @@ ---- -title: 从 TiDB 集群迁移数据至另一 TiDB 集群 -summary: 了解如何将数据从一个 TiDB 集群迁移至另一 TiDB 集群。 -aliases: ['/zh/tidb/dev/incremental-replication-between-clusters/'] ---- - -# 从 TiDB 集群迁移数据至另一 TiDB 集群 - -本文档介绍如何将数据从一个 TiDB 集群迁移至另一 TiDB。在如下场景中,你可以将数据从一个 TiDB 集群迁移至另一个 TiDB 集群: - -- 拆库:原 TiDB 集群体量过大,或者为了避免原有的 TiDB 集群所承载的数个业务之间互相影响,将原 TiDB 集群中的部分表迁到另一个 TiDB 集群。 -- 迁库:是对数据库的物理位置进行迁移,比如更换数据中心。 -- 升级:在对数据正确性要求严苛的场景下,可以将数据迁移到一个更高版本的 TiDB 集群,确保数据安全。 - -本文将模拟整个迁移过程,具体包括以下四个步骤: - -1. 搭建环境 -2. 迁移全量数据 -3. 迁移增量数据 -4. 平滑切换业务 - -## 第 1 步:搭建环境 - -1. 部署集群。 - - 使用 TiUP Playground 快速部署上下游测试集群。更多部署信息,请参考 [TiUP 官方文档](/tiup/tiup-cluster.md)。 - - {{< copyable "shell-regular" >}} - - ```shell - # 创建上游集群 - tiup --tag upstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 - # 创建下游集群 - tiup --tag downstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 - # 查看集群状态 - tiup status - ``` - -2. 初始化数据。 - - 测试集群中默认创建了 test 数据库,因此可以使用 [sysbench](https://github.com/akopytov/sysbench#linux) 工具生成测试数据,用以模拟真实集群中的历史数据。 - - {{< copyable "shell-regular" >}} - - ```shell - sysbench oltp_write_only --config-file=./tidb-config --tables=10 --table-size=10000 prepare - ``` - - 这里通过 sysbench 运行 oltp_write_only 脚本,其将在测试数据库中生成 10 张表,每张表包含 10000 行初始数据。tidb-config 的配置如下: - - ```yaml - mysql-host=172.16.6.122 # 这里需要替换为实际上游集群 ip - mysql-port=4000 - mysql-user=root - mysql-password= - db-driver=mysql # 设置数据库驱动为 mysql - mysql-db=test # 设置测试数据库为 test - report-interval=10 # 设置定期统计的时间间隔为 10 秒 - threads=10 # 设置 worker 线程数量为 10 - time=0 # 设置脚本总执行时间,0 表示不限制 - rate=100 # 设置平均事务速率 tps = 100 - ``` - -3. 模拟业务负载。 - - 实际生产集群的数据迁移过程中,通常原集群还会写入新的业务数据,本文中可以通过 sysbench 工具模拟持续的写入负载,下面的命令会使用 10 个 worker 在数据库中的 sbtest1、sbtest2 和 sbtest3 三张表中持续写入数据,其总 tps 限制为 100。 - - {{< copyable "shell-regular" >}} - - ```shell - sysbench oltp_write_only --config-file=./tidb-config --tables=3 run - ``` - -4. 准备外部存储。 - - 在全量数据备份中,上下游集群均需访问备份文件,因此推荐使用[备份存储](/br/backup-and-restore-storages.md)存储备份文件,本文中通过 Minio 模拟兼容 S3 的存储服务: - - {{< copyable "shell-regular" >}} - - ```shell - wget https://dl.min.io/server/minio/release/linux-amd64/minio - chmod +x minio - # 配置访问 minio 的 access-key access-screct-id - export HOST_IP='172.16.6.122' # 替换为实际上游集群 ip - export MINIO_ROOT_USER='minio' - export MINIO_ROOT_PASSWORD='miniostorage' - # 创建数据目录, 其中 backup 为 bucket 的名称 - mkdir -p data/backup - # 启动 minio, 暴露端口在 6060 - ./minio server ./data --address :6060 & - ``` - - 上述命令行启动了一个单节点的 minio server 模拟 S3 服务,其相关参数为: - - - Endpoint: - - Access-key: minio - - Secret-access-key: miniostorage - - Bucket: backup - - 相应的访问链接为: - - {{< copyable "shell-regular" >}} - - ```shell - s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true - ``` - -## 第 2 步:迁移全量数据 - -搭建好测试环境后,可以使用 [BR](https://github.com/pingcap/tidb/tree/master/br) 工具的备份和恢复功能迁移全量数据。BR 工具有多种[使用方式](/br/br-use-overview.md#部署和使用-br),本文中使用 SQL 语句 [`BACKUP`](/sql-statements/sql-statement-backup.md) 和 [`RESTORE`](/sql-statements/sql-statement-restore.md) 进行备份恢复。 - -> **注意:** -> -> - `BACKUP` 和 `RESTORE` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 -> - 在生产集群中,关闭 GC 机制和备份操作会一定程度上降低集群的读性能,建议在业务低峰期进行备份,并设置合适的 `RATE_LIMIT` 限制备份操作对线上业务的影响。 -> - 上下游集群版本不一致时,应检查 BR 工具的[兼容性](/br/backup-and-restore-overview.md#使用须知)。本文假设上下游集群版本相同。 - -1. 关闭 GC。 - - 为了保证增量迁移过程中新写入的数据不丢失,在开始备份之前,需要关闭上游集群的垃圾回收 (GC) 机制,以确保系统不再清理历史数据。 - - 执行如下命令关闭 GC: - - ```sql - MySQL [test]> SET GLOBAL tidb_gc_enable=FALSE; - ``` - - ``` - Query OK, 0 rows affected (0.01 sec) - ``` - - 查询 `tidb_gc_enable` 的取值,判断 GC 是否已关闭: - - ```sql - MySQL [test]> SELECT @@global.tidb_gc_enable; - ``` - - ``` - +-------------------------+: - | @@global.tidb_gc_enable | - +-------------------------+ - | 0 | - +-------------------------+ - 1 row in set (0.00 sec) - ``` - -2. 备份数据。 - - 在上游集群中执行 BACKUP 语句备份数据: - - ```sql - MySQL [(none)]> BACKUP DATABASE * TO 's3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true' RATE_LIMIT = 120 MB/SECOND; - ``` - - ``` - +---------------+----------+--------------------+---------------------+---------------------+ - | Destination | Size | BackupTS | Queue Time | Execution Time | - +---------------+----------+--------------------+---------------------+---------------------+ - | s3://backup | 10315858 | 431434047157698561 | 2022-02-25 19:57:59 | 2022-02-25 19:57:59 | - +---------------+----------+--------------------+---------------------+---------------------+ - 1 row in set (2.11 sec) - ``` - - 备份语句提交成功后,TiDB 会返回关于备份数据的元信息,这里需要重点关注 BackupTS,它意味着该时间点之前数据会被备份,后边的教程中,本文将使用 BackupTS 作为**数据校验截止时间**和 **TiCDC 增量扫描的开始时间**。 - -3. 恢复数据。 - - 在下游集群中执行 RESTORE 语句恢复数据: - - ```sql - mysql> RESTORE DATABASE * FROM 's3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true'; - ``` - - ``` - +--------------+-----------+--------------------+---------------------+---------------------+ - | Destination | Size | BackupTS | Queue Time | Execution Time | - +--------------+-----------+--------------------+---------------------+---------------------+ - | s3://backup | 10315858 | 431434141450371074 | 2022-02-25 20:03:59 | 2022-02-25 20:03:59 | - +--------------+-----------+--------------------+---------------------+---------------------+ - 1 row in set (41.85 sec) - ``` - -4. (可选)校验数据。 - - 通过 [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) 工具,可以验证上下游数据在某个时间点的一致性。从上述备份和恢复命令的输出可以看到,上游集群备份的时间点为 431434047157698561,下游集群完成数据恢复的时间点为 431434141450371074。 - - ```shell - sync_diff_inspector -C ./config.yaml - ``` - - 关于 sync-diff-inspector 的配置方法,请参考[配置文件说明](/sync-diff-inspector/sync-diff-inspector-overview.md#配置文件说明),在本文中,相应的配置如下: - - ```toml - # Diff Configuration. - ######################### Datasource config ######################### - [data-sources] - [data-sources.upstream] - host = "172.16.6.122" # 需要替换为实际上游集群 ip - port = 4000 - user = "root" - password = "" - snapshot = "431434047157698561" # 配置为实际的备份时间点(参见「备份」小节的 BackupTS) - [data-sources.downstream] - host = "172.16.6.125" # 需要替换为实际下游集群 ip - port = 4000 - user = "root" - password = "" - - ######################### Task config ######################### - [task] - output-dir = "./output" - source-instances = ["upstream"] - target-instance = "downstream" - target-check-tables = ["*.*"] - ``` - -## 第 3 步:迁移增量数据 - -1. 部署 TiCDC。 - - 完成全量数据迁移后,就可以部署并配置 TiCDC 集群同步增量数据,实际生产集群中请参考 [TiCDC 部署](/ticdc/deploy-ticdc.md)。本文在创建测试集群时,已经启动了一个 TiCDC 节点,因此可以直接进行 changefeed 的配置。 - -2. 创建同步任务。 - - 在上游集群中,执行以下命令创建从上游到下游集群的同步链路: - - ```shell - tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="upstream-to-downstream" --start-ts="431434047157698561" - ``` - - 以上命令中: - - - `--server`:TiCDC 集群中任意一个节点的地址 - - `--sink-uri`:同步任务下游的地址 - - `--changefeed-id`:同步任务的 ID,格式需要符合正则表达式 ^[a-zA-Z0-9]+(\-[a-zA-Z0-9]+)*$ - - `--start-ts`:TiCDC 同步的起点,需要设置为实际的备份时间点,也就是[第 2 步:迁移全量数据](/migrate-from-tidb-to-mysql.md#第-2-步迁移全量数据)中 “备份数据” 提到的 BackupTS - - 更多关于 changefeed 的配置,请参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 - -3. 重新开启 GC。 - - TiCDC 可以保证 GC 只回收已经同步的历史数据。因此,创建完从上游到下游集群的 changefeed 之后,就可以执行如下命令恢复集群的垃圾回收功能。详情请参考 [TiCDC GC safepoint 的完整行为](/ticdc/ticdc-faq.md#ticdc-gc-safepoint-的完整行为是什么)。 - - 执行如下命令打开 GC: - - ```sql - MySQL [test]> SET GLOBAL tidb_gc_enable=TRUE; - ``` - - ``` - Query OK, 0 rows affected (0.01 sec) - ``` - - 查询 `tidb_gc_enable` 的取值,判断 GC 是否已开启: - - ```sql - MySQL [test]> SELECT @@global.tidb_gc_enable; - ``` - - ``` - +-------------------------+ - | @@global.tidb_gc_enable | - +-------------------------+ - | 1 | - +-------------------------+ - 1 row in set (0.00 sec) - ``` - -## 第 4 步:平滑切换业务 - -通过 TiCDC 创建上下游的同步链路后,原集群的写入数据会以非常低的延迟同步到新集群,此时可以逐步将读流量迁移到新集群了。观察一段时间,如果新集群表现稳定,就可以将写流量接入新集群,步骤如下: - -1. 停止上游集群的写业务。确认上游数据已全部同步到下游后,停止上游到下游集群的 changefeed。 - - ```shell - # 停止旧集群到新集群的 changefeed - tiup cdc cli changefeed pause -c "upstream-to-downstream" --server=http://172.16.6.122:8300 - - # 查看 changefeed 状态 - tiup cdc cli changefeed list - ``` - - ``` - [ - { - "id": "upstream-to-downstream", - "summary": { - "state": "stopped", # 需要确认这里的状态为 stopped - "tso": 431747241184329729, - "checkpoint": "2022-03-11 15:50:20.387", # 确认这里的时间晚于停写的时间 - "error": null - } - } - ] - ``` - -2. 创建下游到上游集群的 changefeed。由于此时上下游数据是一致的,且没有新数据写入,因此可以不指定 start-ts,默认为当前时间: - - ```shell - tiup cdc cli changefeed create --server=http://172.16.6.125:8300 --sink-uri="mysql://root:@172.16.6.122:4000" --changefeed-id="downstream -to-upstream" - ``` - -3. 将写业务迁移到下游集群,观察一段时间后,等新集群表现稳定,便可以弃用原集群。 From c61f004e57f0c6f9a7a7c2a1d13136489d11da2b Mon Sep 17 00:00:00 2001 From: Aolin Date: Tue, 28 Nov 2023 20:25:33 +0800 Subject: [PATCH 3/3] Discard changes to replicate-between-primary-and-secondary-clusters.md --- ...-between-primary-and-secondary-clusters.md | 318 ------------------ 1 file changed, 318 deletions(-) delete mode 100644 replicate-between-primary-and-secondary-clusters.md diff --git a/replicate-between-primary-and-secondary-clusters.md b/replicate-between-primary-and-secondary-clusters.md deleted file mode 100644 index b27355e9d385..000000000000 --- a/replicate-between-primary-and-secondary-clusters.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -title: 搭建双集群主从复制 -summary: 了解如何配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群,并将增量数据实时从主集群同步到从集群, ---- - -# 搭建双集群主从复制 - -本文档介绍如何配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群,并将增量数据实时从主集群同步到从集群,主要包含以下内容: - -1. 配置一个 TiDB 集群以及该集群的 TiDB 或 MySQL 从集群。 -2. 将增量数据实时从主集群同步到从集群。 -3. 在主集群发生灾难利用 Redo log 恢复一致性数据。 - -如果你需要配置一个运行中的 TiDB 集群和其从集群,以进行实时增量数据同步,可使用 [Backup & Restore (BR)](/br/backup-and-restore-overview.md) 和 [TiCDC](/ticdc/ticdc-overview.md)。 - -## 第 1 步:搭建环境 - -1. 部署集群。 - - 使用 tiup playground 快速部署 TiDB 上下游测试集群。生产环境可以参考 [tiup 官方文档](/tiup/tiup-cluster.md)根据业务需求来部署集群。 - - 为了方便展示和理解,我们简化部署结构,需要准备以下两台机器,分别来部署上游主集群和下游从集群。假设 IP 地址分别为: - - - NodeA: `172.16.6.123`,部署上游 TiDB - - - NodeB: `172.16.6.124`,部署下游 TiDB - - {{< copyable "shell-regular" >}} - - ```shell - - # 在 NodeA 上创建上游集群 - tiup --tag upstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 - # 在 NodeB 上创建下游集群 - tiup --tag downstream playground --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 0 - # 查看集群状态 - tiup status - ``` - -2. 初始化数据。 - - 测试集群中默认创建了 test 数据库,因此可以使用 [sysbench](https://github.com/akopytov/sysbench#linux) 工具生成测试数据,用以模拟真实集群中的历史数据。 - - ```shell - sysbench oltp_write_only --config-file=./tidb-config --tables=10 --table-size=10000 prepare - ``` - - 这里通过 sysbench 运行 oltp_write_only 脚本,其将在测试数据库中生成 10 张表,每张表包含 10000 行初始数据。tidb-config 的配置如下: - - ```yaml - mysql-host=172.16.6.122 # 这里需要替换为实际上游集群 ip - mysql-port=4000 - mysql-user=root - mysql-password= - db-driver=mysql # 设置数据库驱动为 mysql - mysql-db=test # 设置测试数据库为 test - report-interval=10 # 设置定期统计的时间间隔为 10 秒 - threads=10 # 设置 worker 线程数量为 10 - time=0 # 设置脚本总执行时间,0 表示不限制 - rate=100 # 设置平均事务速率 tps = 100 - ``` - -3. 模拟业务负载。 - - 实际生产集群的数据迁移过程中,通常原集群还会写入新的业务数据,本文中可以通过 sysbench 工具模拟持续的写入负载,下面的命令会使用 10 个 worker 在数据库中的 sbtest1、sbtest2 和 sbtest3 三张表中持续写入数据,其总 tps 限制为 100。 - - ```shell - sysbench oltp_write_only --config-file=./tidb-config --tables=3 run - ``` - -4. 准备外部存储。 - - 在全量数据备份中,上下游集群均需访问备份文件,因此推荐使用[外部存储](/br/backup-and-restore-storages.md)存储备份文件,本文中通过 Minio 模拟兼容 S3 的存储服务: - - ```shell - wget https://dl.min.io/server/minio/release/linux-amd64/minio - chmod +x minio - # 配置访问 minio 的 access-key access-secret-id - export `HOST_IP`='172.16.6.123' # 替换为实际部署 minio 的机器 ip - export** **MINIO_ROOT_USER**='**minio' - export MINIO_ROOT_PASSWORD='miniostorage' - # 创建 redo 和 backup 数据目录, 其中 redo, backup 为 bucket 名字 - mkdir -p data/redo - mkdir -p data/backup - # 启动 minio, 暴露端口在 6060 - nohup ./minio server ./data --address :6060 & - ``` - - 上述命令行启动了一个单节点的 minio server 模拟 S3 服务,其相关参数为: - - * Endpoint : `http://${HOST_IP}:6060/` - * Access-key : `minio` - * Secret-access-key: `miniostorage` - * Bucket: `redo` - - 其访问链接为如下: - - ```shell - s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true - ``` - -## 第 2 步:迁移全量数据 - -搭建好测试环境后,可以使用 [BR](https://github.com/pingcap/tidb/tree/master/br) 工具的备份和恢复功能迁移全量数据。BR 工具有多种[使用方式](/br/br-use-overview.md#部署和使用-br),本文中使用 SQL 语句 [`BACKUP`](/sql-statements/sql-statement-backup.md) 和 [`RESTORE`](/sql-statements/sql-statement-restore.md) 进行备份恢复。 - -> **注意:** -> -> - `BACKUP` 和 `RESTORE` 语句目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。 -> - 在生产集群中,关闭 GC 机制和备份操作会一定程度上降低集群的读性能,建议在业务低峰期进行备份,并设置合适的 `RATE_LIMIT` 限制备份操作对线上业务的影响。 -> - 上下游集群版本不一致时,应检查 BR 工具的[兼容性](/br/backup-and-restore-overview.md#使用建议)。本文假设上下游集群版本相同。 - -1. 关闭 GC。 - - 为了保证增量迁移过程中新写入的数据不丢失,在开始备份之前,需要关闭上游集群的垃圾回收 (GC) 机制,以确保系统不再清理历史数据。 - - 执行如下命令关闭 GC: - - ```sql - MySQL [test]> SET GLOBAL tidb_gc_enable=FALSE; - ``` - - ``` - Query OK, 0 rows affected (0.01 sec) - ``` - - 查询 `tidb_gc_enable` 的取值,判断 GC 是否已关闭: - - ```sql - MySQL [test]> SELECT @@global.tidb_gc_enable; - ``` - - ``` - +-------------------------+ - | @@global.tidb_gc_enable | - +-------------------------+ - | 0 | - +-------------------------+ - 1 row in set (0.00 sec) - ``` - -2. 备份数据。 - - 在上游集群中执行 BACKUP 语句备份数据: - - ```sql - MySQL [(none)]> BACKUP DATABASE * TO '`s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true`' RATE_LIMIT = 120 MB/SECOND; - ``` - - ``` - +----------------------+----------+--------------------+---------------------+---------------------+ - | Destination | Size | BackupTS | Queue Time | Execution Time | - +----------------------+----------+--------------------+---------------------+---------------------+ - | local:///tmp/backup/ | 10315858 | 431434047157698561 | 2022-02-25 19:57:59 | 2022-02-25 19:57:59 | - +----------------------+----------+--------------------+---------------------+---------------------+ - 1 row in set (2.11 sec) - ``` - - 备份语句提交成功后,TiDB 会返回关于备份数据的元信息,这里需要重点关注 BackupTS,它意味着该时间点之前数据会被备份,后边的教程中,本文将使用 BackupTS 作为**数据校验截止时间**和 **TiCDC 增量扫描的开始时间**。 - -3. 恢复数据。 - - 在下游集群中执行 RESTORE 语句恢复数据: - - ```sql - mysql> RESTORE DATABASE * FROM '`s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://${HOST_IP}:6060&force-path-style=true`'; - ``` - - ``` - +----------------------+----------+--------------------+---------------------+---------------------+ - | Destination | Size | BackupTS | Queue Time | Execution Time | - +----------------------+----------+--------------------+---------------------+---------------------+ - | local:///tmp/backup/ | 10315858 | 431434141450371074 | 2022-02-25 20:03:59 | 2022-02-25 20:03:59 | - +----------------------+----------+--------------------+---------------------+---------------------+ - 1 row in set (41.85 sec) - ``` - -4. (可选)校验数据。 - - 通过 [sync-diff-inspector](/sync-diff-inspector/sync-diff-inspector-overview.md) 工具,可以验证上下游数据在某个时间点的一致性。从上述备份和恢复命令的输出可以看到,上游集群备份的时间点为 431434047157698561,下游集群完成数据恢复的时间点为 431434141450371074。 - - ```shell - sync_diff_inspector -C ./config.yaml - ``` - - 关于 sync-diff-inspector 的配置方法,请参考[配置文件说明](/sync-diff-inspector/sync-diff-inspector-overview.md#配置文件说明)。在本文中,相应的配置如下: - - ```toml - # Diff Configuration. - ######################### Global config ######################### - check-thread-count = 4 - export-fix-sql = true - check-struct-only = false - - ######################### Datasource config ######################### - [data-sources] - [data-sources.upstream] - host = "172.16.6.123" # 替换为实际上游集群 ip - port = 4000 - user = "root" - password = "" - snapshot = "431434047157698561" # 配置为实际的备份时间点 - [data-sources.downstream] - host = "172.16.6.124" # 替换为实际下游集群 ip - port = 4000 - user = "root" - password = "" - snapshot = "431434141450371074" # 配置为实际的恢复时间点 - - ######################### Task config ######################### - [task] - output-dir = "./output" - source-instances = ["upstream"] - target-instance = "downstream" - target-check-tables = ["*.*"] - ``` - -## 第 3 步:迁移增量数据 - -1. 部署 TiCDC。 - - 完成全量数据迁移后,就可以部署并配置 TiCDC 集群同步增量数据,实际生产集群中请参考 [TiCDC 部署](/ticdc/deploy-ticdc.md)。本文在创建测试集群时,已经启动了一个 TiCDC 节点,因此可以直接进行 changefeed 的配置。 - -2. 创建同步任务。 - - 创建 changefeed 配置文件并保存为 `changefeed.toml`。 - - ```toml - [consistent] - # 一致性级别,配置成 eventual 表示开启一致性复制 - level = "eventual" - # 使用 S3 来存储 redo log, 其他可选为 local, nfs - storage = "s3://redo?access-key=minio&secret-access-key=miniostorage&endpoint=http://172.16.6.125:6060&force-path-style=true" - ``` - - 在上游集群中,执行以下命令创建从上游到下游集群的同步链路: - - ```shell - tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="primary-to-secondary" --start-ts="431434047157698561" - ``` - - 以上命令中: - - - `--server`:TiCDC 集群任意一节点的地址 - - `--sink-uri`:同步任务下游的地址 - - `--start-ts`:TiCDC 同步的起点,需要设置为实际的备份时间点(也就是[第 2 步:迁移全量数据](#第-2-步迁移全量数据)提到的 BackupTS) - - 更多关于 changefeed 的配置,请参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 - -3. 重新开启 GC。 - - TiCDC 可以保证未同步的历史数据不会被回收。因此,创建完从上游到下游集群的 changefeed 之后,就可以执行如下命令恢复集群的垃圾回收功能。详情请参考 [TiCDC GC safepoint 的完整行为](/ticdc/ticdc-faq.md#ticdc-gc-safepoint-的完整行为是什么)。 - - 执行如下命令打开 GC: - - ```sql - MySQL [test]> SET GLOBAL tidb_gc_enable=TRUE; - ``` - - ``` - Query OK, 0 rows affected (0.01 sec) - ``` - - 查询 `tidb_gc_enable` 的取值,判断 GC 是否已开启: - - ```sql - MySQL [test]> SELECT @@global.tidb_gc_enable; - ``` - - ``` - +-------------------------+ - | @@global.tidb_gc_enable | - +-------------------------+ - | 1 | - +-------------------------+ - 1 row in set (0.00 sec) - ``` - -## 第 4 步:模拟主集群故障 - -模拟在业务过程中上游 TiDB 发生灾难性故障无法再启动起来,这里可以直接使用 Ctrl + C 终止 tiup playground 进程。 - -## 第 5 步:使用 redo log 确保数据一致性 - -在正常同步过程中,为了提高 TiCDC 的吞吐能力,TiCDC 会将事务并行写入下游。因此,当 TiCDC 同步链路意外中断时,下游可能不会恰好停在与上游一致的状态。我们这里需要使用 TiCDC 的命令行工具来向下游重放 redo log,使下游达到最终一致性状态。 - -```shell -tiup cdc redo apply --storage "s3://redo?access-key=minio&secret-access-key=miniostorage&endpoint=http://172.16.6.123:6060&force-path-style=true" --tmp-dir /tmp/redo --sink-uri "mysql://root:@172.16.6.124:4000" -``` - -- `--storage`:指定 redo log 所在的 S3 位置以及 credential -- `--tmp-dir`:为从 S3 下载 redo log 的缓存目录 -- `--sink-uri`:指定下游集群的地址 - -## 第 6 步:恢复主集群及业务 - -现在从集群有了某一时刻全部的一致性数据,你需要重新搭建主从集群来保证数据可靠性。 - -1. 在 NodeA 重新搭建一个新的 TiDB 集群作为新的主集群。 - - ```shell - tiup --tag upstream playground v5.4.0 --host 0.0.0.0 --db 1 --pd 1 --kv 1 --tiflash 0 --ticdc 1 - ``` - -2. 使用 BR 将从集群数据全量备份恢复到主集群。 - - ```shell - # 全量备份从集群的数据 - tiup br --pd http://172.16.6.124:2379 backup full --storage ./backup - # 全量恢复从集群的数据 - tiup br --pd http://172.16.6.123:2379 restore full --storage ./backup - ``` - -3. 创建一个 TiCDC 同步任务,备份主集群数据到从集群。 - - ```shell - # 创建 changefeed - tiup cdc cli changefeed create --server=http://172.16.6.122:8300 --sink-uri="mysql://root:@172.16.6.125:4000" --changefeed-id="primary-to-secondary" - ```