1. 下载对应 ansible 版本,本次采用。
    2. 执行 pip install -r ./requirements.txt 安装依赖。
    3. 设置部署结构:
      1. 本次部署一共使用6台机器,IP 从 101-106。
      2. 101-106 为 TiKV 节点,101-103 为 PD 节点,104-106 为 TiDB 节点。

    关于备份恢复中需要用到的br工具,已经附带在官方 tidb-toolkit-v4.0.0-beta.1.tar.gz 包中,如果是使用 ansible 安装,可以直接在 tidb-ansible 目录下的 downloads 中找到。

    2. 构建测试数据

    在 TiDB 中创建对应库表

    使用任意方式构造数据,比如使用 python 脚本:

    1. import time
    2. mydb = mysql.connector.connect(
    3. host="xxxx.104", # 这里需要替换成 tidb-server 的 ip
    4. user='root',
    5. port=4000,
    6. database='br_test'
    7. )
    8. mycursor = mydb.cursor()
    9. for i in range (100000):
    10. mycursor.execute('insert into br_table values(%s,%s,now())',(i,str(i)+'xxxx'))
    11. if i%1000==0:
    12. mycursor.execute('commit')
    13. mycursor.close()
    14. mydb.close()

    接下来在 TiDB 中查看数据已经生成

    1. MySQL [br_test]> select count(1) from br_table;
    2. +----------+
    3. +----------+
    4. | 100000 |
    5. +----------+
    6. 1 row in set (0.04 sec)

    最后总共生成的数据文件分布在 6 个 TiKV 节点上。

    3. 备份准备

    在进行备份前,有一些需要调整的配置项

    1. tikv_gc_life_time 参数
    1. # 设置 gc 时间,避免备份时间过长导致数据被回收,需要注意的是,备份完成后,需要改回来参数。
    2. #默认值
    3. SELECT VARIABLE_VALUE FROM mysql.tidb WHERE VARIABLE_NAME = 'tikv_gc_life_time';
    4. 10m0s
    5. # 设置为720h
    6. UPDATE mysql.tidb SET VARIABLE_VALUE = '720h' WHERE VARIABLE_NAME = 'tikv_gc_life_time';
    7. # 验证修改确实成功
    8. SELECT * FROM mysql.tidb WHERE VARIABLE_NAME = 'tikv_gc_life_time';
    9. 720h
    1. 备份存储位置

    当前备份是备份到文件系统,也就是可以通过SMB/NFS之类的挂载,备份到远程备份中心。

    需要注意的是,下文中执行挂载操作的,是所有的 TiKV, BR 节点,而非 TiDB,PD 所在节点。

    挂载 NFS:

    而在这些操作之前,其他共用参数单独讨论。

    另外需要注意的一点是,因为备份通过 gRPC 发送相关到 TiKV,因此 BR 执行的位置,最好是 PD 节点,避免额外的麻烦。

    5. 通用参数

    —ca,—cert,—key 如果设置了TLS类连接安全认证,这些参数指定相关安全证书等。

    —concurrency 每个节点执行任务的并行度,默认4。

    —log-file,—log-level设置日志输出位置以及级别。

    -u, —pd 链接 PD 地址,默认127.0.0.1:2379

    —ratelimit 限制每个节点的速度,单位是MB

    -s, —storage 指定存储位置,比方”local:///data_nfs1”

    6. 全库备份与恢复

    参考命令:

    1. bin/br backup full --pd "192.168.122.101:2379" --storage "local:///data_nfs1/backup"

    这个命令会备份全库到各个 TiKV 节点下的 /data_nfs1/backup 目录。

    简单从日志看一下整个备份流程:

    1. * PD 连接获取到所有 TiKV 节点。
    2. * 查询 infoSchema 获取元数据。
    3. * 发送备份请求:{"cluster_id":6801677637806839235,"start_key":"dIAAAAAAAAAvX3IAAAAAAAAAAA==","end_key":"dIAAAAAAAAAvX3L//////////wA=","end_version":415142848617512967,"concurrency":4,"storage_backend":{Backend":{"Local":{"path":"/data_nfs1/backup"}}}}"
    4. * 各个 TiKV 节点开始执行备份,执行命令完成后,返回到 BR 进行统计。
    5. * 执行表的checksum [table=`br_test`.`br_table`] [Crc64Xor=12896770389982935753] [TotalKvs=100000] [TotalBytes=4788890]
    6. * 保存备份的元数据。
    7. * 完成备份。

    备份完成后,在指定的备份目录,会最终出现命名类似5_2_23_80992061af3e5194c3f28a5b79d486c5e9db2feda1afb3f84b4ca229ddce9932_write.sst的备份集合,也就是最终的备份文件。

    为了简化操作,这里在原有集群上进行恢复,往往实际中是要恢复到一个全新的集群上。

    首先执行以下语句删除数据:

    1. MySQL [br_test]> drop table br_table;

    从日志看:

    1. 寻找并确认 PD 节点。
    2. 执行DDL语句:CREATE DATABASE /!32312 IF NOT EXISTS/ 以及 CREATE TABLE IF NOT EXISTS。
    3. 执行必要的alter auto incrementID 语句, 防止恢复后从之前的 id 分配,导致数据覆盖。
    4. 切割 sst 为 Region 负责的小数据集合,分别进行数据写入。
    5. 完成操作后,输出统计信息 [“Full restore summary: total restore tables: 1, total success: 1, total failed: 0, total take(s): 0.25, total size(MB): 2.28, avg speed(MB/s): 9.08, total kv: 50001”] [“restore files”=1] [“restore ranges”=1] [“split region”=6.373065871s] [“restore checksum”=45.843202ms]

    执行完成后,可以看到数据已经恢复完成:

    1. MySQL [br_test]> select count(1) from br_table;
    2. +----------+
    3. | count(1) |
    4. +----------+
    5. | 100000|
    6. +----------+
    7. 1 row in set (0.12 sec)

    8. 单库备份与恢复

    单库的备份恢复参考命令如下:

    备份:

    1. bin/br backup db --db "br_test" --pd "192.168.122.101:2379" --storage "local:///data_nfs1/backup"

    恢复:

    9. 单表备份与恢复

    单库的备份恢复参考命令如下:

    备份:

    1. bin/br restore table --db "br_test" --table "br_table" --pd "192.168.122.101:2379" --storage "local:///data_nfs1/backup"

    通过上述实践,我们了解了 BR 基本用法,想要了解具体代码实现可以登陆 BR 项目主页(https://github.com/pingcap/br), 欢迎提供更多的使用建议,帮助我们改进。