0
0
0
0
博客/.../

基于PITR的备份恢复示例

 YangChao  发表于  2026-02-09
原创

PITR使用限制:

  • PITR 仅支持恢复到全新的空集群。
  • PITR 仅支持集群粒度的恢复,不支持对单个 database 或 table 的恢复。
  • PITR 不支持恢复系统表中用户表和权限表的数据。
  • PITR 数据恢复任务运行期间,不支持同时运行日志备份任务,也不支持通过 TiCDC 同步数据到下游集群。

环境说明:

192.168.68.100  中控机,MinIO、TiDB
192.168.68.101-103:集群1(备份源端数据库)
192.168.68.201-203:集群2(恢复目标端数据库)

一、部署MinIO

安装minio(二进制):192.168.68.100

#官网:https://www.minio.org.cn/
wget -O /usr/local/bin/minio https://dl.minio.org.cn/server/minio/release/linux-amd64/minio # 服务端
wget -O /usr/local/bin/mc https://dl.minio.org.cn/client/mc/release/linux-amd64/mc # 客户端

[root@localhost ~]# chmod 755 /usr/local/bin/{minio,mc}n
[root@server100 ~]# mc --version
[root@server100 ~]# minio --version

创建数据目录、日志目录,添加用户;

mkdir -p /data/minio/{data,logs}
useradd minio && echo minio | passwd --stdin minio # 可选,创建普通用户来运行进程
chown minio.minio -R /data/minio/

创建启动脚本

su - minio
vi /data/minio/minio.sh

#!/bin/bash

MINIO_DATA_DIR=/data/minio/data
MINIO_LOGS_DIR=/data/minio/logs

export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=Admin@123

MINIO_ADDR=0.0.0.0 # 监听端口和地址
MINIO_API=9000 # 数据服务端口,用于处理用户的上传、下载等数据操作请求
MINIO_UI=9001  # 控制台服务端口,用于提供Web管理界面

case "$1" in
  start)
      nohup minio server ${MINIO_DATA_DIR} \
            --console-address ${MINIO_ADDR}:${MINIO_UI} \
            --address ${MINIO_ADDR}:${MINIO_API} >> ${MINIO_LOGS_DIR}/minio-$(date +%Y%m%d).log 2>&1 &
      ;;
  stop)
      pid=$(ps -ef |egrep "minio[/]" |awk '{print $2}')
      [ ! -z ${pid} ] && kill -9 ${pid} || echo "minio not running..."
      ;;    
  *)
      echo "Usage: $0 {start|stop}"
      exit 1
esac

启动服务

bash minio.sh start

访问Web页面:

http://192.168.68.100:9001/login (admin/Admin@123)

image.png

创建bucket:

在管理页面点击:Create Bucket 之后,输入名称创建。

image.png

二、部署TiDB集群

创建用户及相关目录

#创建tidb用户
useradd tidb
echo "tidb:TiDb@123" | chpasswd

#配置tidb用户sudo权限
visudo
tidb            ALL=(ALL)       NOPASSWD: ALL

#中控机到各目标机的ssh免密登录
su - tidb
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub tidb@192.168.68.100
for i in {1..3};do ssh-copy-id -i ~/.ssh/id_rsa.pub tidb@192.168.68.10$i;done
for i in {1..3};do ssh-copy-id -i ~/.ssh/id_rsa.pub tidb@192.168.68.20$i;done
#ssh-copy-id -p <端口号> <用户名>@<主机名或IP地址>

#验证免密登录
ssh tidb@192.168.68.100 -i ~/.ssh/id_rsa hostname
for i in {1..3};do ssh tidb@192.168.68.10$i -i ~/.ssh/id_rsa hostname;done
for i in {1..3};do ssh tidb@192.168.68.20$i -i ~/.ssh/id_rsa hostname;done

创建相关目录并修改属主

# 创建`deploy_dir`和`data_dir`存放目录
mkdir -p /opt/tidb-deploy
mkdir -p /data/tidb-data
chown -R tidb.tidb /opt/tidb-deploy
chown -R tidb.tidb /data/tidb-data

部署离线环境tiup组件

cd /mytmp
#解压安装包
tar -xvf tidb-server-v7.1.8-5.3-linux-amd64.tar.gz -C /opt/
tar -xvf tidb-toolkit-v7.1.8-5.3-linux-amd64.tar.gz -C /opt/

#部署离线环境 TiUP 组件
chown -R tidb.tidb /opt/tidb*
su - tidb
cd /opt/tidb-server-v7.1.8-5.3-linux-amd64/
sh local_install.sh

#根据提示执行
source /home/tidb/.bash_profile
tiup --version

验证tiup组件部署:

which tiup
tiup --version
tiup cluster
tiup --binary cluster
tiup list tidb   #查看可用版本

查看此时的镜像路径:

cat ~/.tiup/tiup.toml
tiup mirror show
#镜像路径记录于: ~/.tiup/tiup.toml 文件中

合并离线包

cp -rp keys ~/.tiup/
tiup mirror merge ../tidb-toolkit-v7.1.8-5.3-linux-amd64
tiup mirror show

tidb-test1.yaml 内容如下:

global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/opt/tidb-deploy"
  data_dir: "/data/tidb-data"
  listen_host: 0.0.0.0
  arch: "x86_64"

monitored:
  node_exporter_port: 9200
  blackbox_exporter_port: 9215
  deploy_dir: "/opt/tidb-deploy/monitored-9200"
  data_dir: "/data/tidb-data/monitored-9200"
  log_dir: "/opt/tidb-deploy/monitored-9200/log"

server_configs:
  tidb:
    log.file.max-days: 7
    log.slow-threshold: 500
  tikv:
    log.file.max-days: 7
  pd:
    log.file.max-days: 7
    replication.enable-placement-rules: true
    replication.location-labels: ["zone","rack","host"]
    replication.isolation-level: "host"

tidb_servers:
  - host: 192.168.68.100
    port: 4100
    status_port: 10081
    deploy_dir: "/opt/tidb-deploy/tidb-4100"
    log_dir: "/opt/tidb-deploy/tidb-4100/log"

pd_servers:
  - host: 192.168.68.101
    name: "pd-1"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"
  - host: 192.168.68.102
    name: "pd-2"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"
  - host: 192.168.68.103
    name: "pd-3"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"

tikv_servers:
  - host: 192.168.68.101
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone1", rack: "rack1", host: "host101" }
  - host: 192.168.68.102
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone1", rack: "rack1", host: "host102" }
  - host: 192.168.68.103
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone1", rack: "rack1", host: "host103" }

tidb-test2.yaml 内容如下:

global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/opt/tidb-deploy"
  data_dir: "/data/tidb-data"
  listen_host: 0.0.0.0
  arch: "x86_64"

server_configs:
  tidb:
    log.file.max-days: 7
    log.slow-threshold: 500
  tikv:
    log.file.max-days: 7
  pd:
    log.file.max-days: 7
    replication.enable-placement-rules: true
    replication.location-labels: ["zone","rack","host"]
    replication.isolation-level: "host"

tidb_servers:
  - host: 192.168.68.100
    port: 4200
    status_port: 10082
    deploy_dir: "/opt/tidb-deploy/tidb-4200"
    log_dir: "/opt/tidb-deploy/tidb-4200/log"

pd_servers:
  - host: 192.168.68.201
    name: "pd-1"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"
  - host: 192.168.68.202
    name: "pd-2"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"
  - host: 192.168.68.203
    name: "pd-3"
    client_port: 2379
    peer_port: 2380
    deploy_dir: "/opt/tidb-deploy/pd-2379"
    data_dir: "/data/tidb-data/pd-2379"
    log_dir: "/opt/tidb-deploy/pd-2379/log"

tikv_servers:
  - host: 192.168.68.201
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone2", rack: "rack2", host: "host201" }
  - host: 192.168.68.202
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone2", rack: "rack2", host: "host202" }
  - host: 192.168.68.203
    port: 20160
    status_port: 20180
    deploy_dir: "/opt/tidb-deploy/tikv-20160"
    data_dir: "/data/tidb-data/tikv-20160"
    log_dir: "/opt/tidb-deploy/tikv-20160/log"
    config:
      server.labels: { zone: "zone2", rack: "rack2", host: "host203" }

检查环境

#执行如下命令,检查环境
su - tidb
tiup cluster check tidb-test1.yaml --user root -p
tiup cluster check tidb-test2.yaml --user root -p

#发现有很多Fail,执行自修复命令
tiup cluster check tidb-test1.yaml --apply --user root -p
tiup cluster check tidb-test2.yaml --apply --user root -p

#执行完后再次检查
tiup cluster check tidb-test1.yaml --user root -p
tiup cluster check tidb-test2.yaml --user root -p
#可忽略Warn,没有Fail即可执行下一步

执行部署

su - tidb
cd /opt//opt/tidb-server-v7.1.8-5.3-linux-amd64
tiup cluster deploy tidb-test1 v7.1.8-5.3 tidb-test1.yaml --user tidb -p
tiup cluster deploy tidb-test2 v7.1.8-5.3 tidb-test2.yaml --user tidb -p

查看TiDB管理的集群

tiup cluster list

TiUP 支持管理多个 TiDB 集群,该命令会输出当前通过 TiUP cluster 管理的所有集群信息,包括集群名称、部署用户、版本、密钥信息等。

检查部署的TiDB集群情况

tiup cluster display tidb-test1
tiup cluster display tidb-test2

#部署完成后建议备份目录: /home/tidb/.tiup

初始化安全启动集群

安全启动后,TiUP 会自动生成 TiDB root 用户的密码,并在命令行界面返回密码。

使用安全启动方式后,不能通过无密码的 root 用户登录数据库,你需要记录命令行返回的密码进行后续操作。

tiup cluster start tidb-test1 --init
tiup cluster start tidb-test2 --init

验证集群运行状态

tiup cluster display tidb-test1
tiup cluster display tidb-test2

预期结果输出:各节点 Status 状态信息为 Up 说明集群状态正常。

三、配置启动备份

启动日志备份任务

tiup br log start  --task-name="pitr" --pd="192.168.68.101:2379" \
--storage="s3://tidb-test1/binlogs?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true"

tiup br log status --task-name="pitr" --pd="192.168.68.101:2379"

执行数据库操作:

MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
+----------------+
1 row in set (0.00 sec)
MySQL [test]> select * from t1;
+----+-------+
| id | info  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
+----+-------+
3 rows in set (0.00 sec)

注:如上是所示,在执行全量备份前,源端数据test中有一张测试表t1,有3条记录。

执行全量备份

tiup br backup full --pd "192.168.68.101:2379" \
--storage "s3://tidb-test1/full_backup?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true"

image.png

再次执行数据库操作:

MySQL [test]> create table t2(id int primary key, demo varchar(50));
Query OK, 0 rows affected (0.10 sec)

MySQL [test]> insert into t2 values(1,'test1'),(2,'test2'),(3,'test3');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MySQL [test]> select * from t2;
+----+-------+
| id | demo  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
+----+-------+
3 rows in set (0.00 sec)

MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+
2 rows in set (0.00 sec)

MySQL [test]> select now();
+---------------------+
| now()               |
+---------------------+
| 2026-01-12 12:34:32 |
+---------------------+
1 row in set (0.00 sec)

注:如上是所示,在执行全量备份后,又在源端数据test中新建了测试表t2,增加了3条记录。这样,在源端数据库test中共有两张表,分别有3条记录,此时时间戳时间:2026-01-12 12:34:32。

继续在源端数据库新增测试数据:

MySQL [test]> insert into t2 values(4,'test4'),(5,'test5'),(6,'test6');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MySQL [test]> select * from t2;
+----+-------+
| id | demo  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
|  4 | test4 |
|  5 | test5 |
|  6 | test6 |
+----+-------+
6 rows in set (0.01 sec)

MySQL [test]> select now();
+---------------------+
| now()               |
+---------------------+
| 2026-01-12 12:38:25 |
+---------------------+
1 row in set (0.00 sec)

注:如上是所示,继续在t2中,又增加了3条记录。这样t2表此时记录数量为6,此时时间戳时间:2026-01-12 12:38:25。

四、恢复备份验证

在执行PITR恢复前,先查询下源端数据库的在线日志备份情况,以确认能恢复到的最新时间点:

[tidb@server100 ~]$ tiup br log status --task-name="pitr" --pd="192.168.68.101:2379"
Starting component br: /home/tidb/.tiup/components/br/v7.1.8-5.3/br log status --task-name=pitr --pd=192.168.68.101:2379
Detail BR log in /tmp/br.log.2026-01-12T12.41.29+0800 
● Total 1 Tasks.
> #1 <
              name: pitr
            status: ● NORMAL
             start: 2026-01-12 12:26:02.662 +0800
               end: 2090-11-18 22:07:45.624 +0800
           storage: s3://tidb-test1/binlogs
       speed(est.): 0.00 ops/s
checkpoint[global]: 2026-01-12 12:40:36.062 +0800; gap=55s

如上所示,在线日志备份状态正常,最后 checkpoint[global]: 2026-01-12 12:40:36.062 +0800,即当前能恢复到的最新时间点。

基于时间点1恢复:(恢复到tidb-test2集群)

tiup br restore point --pd="192.168.68.201:2379" \
--storage="s3://tidb-test1/binlogs?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true" \
--full-backup-storage="s3://tidb-test1/full_backup?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true" \
--restored-ts="2026-01-12 12:34:32+0800"

查看恢复数据:

MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+
2 rows in set (0.00 sec)

MySQL [test]> select * from t1;
+----+-------+
| id | info  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
+----+-------+
3 rows in set (0.00 sec)

MySQL [test]> select * from t2;
+----+-------+
| id | demo  |
+----+-------+
|  1 | test1 |
|  2 | test2 |
|  3 | test3 |
+----+-------+
3 rows in set (0.00 sec)

注:如上所示,正常恢复到指定时间点。

基于时间点2恢复:(恢复到tidb-test2集群)​

# 恢复验证前需要先删除目标集群的数据库
tiup br restore point --pd="192.168.68.201:2379" \
--storage="s3://tidb-test1/binlogs?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true" \
--full-backup-storage="s3://tidb-test1/full_backup?access-key=admin&secret-access-key=Admin@123&endpoint=http://192.168.68.100:9000&force-path-style=true" \
--restored-ts="2026-01-12 12:38:25+0800"

查看恢复数据:

MySQL [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+
2 rows in set (0.00 sec)

MySQL [test]> select count(1) from t1;
+----------+
| count(1) |
+----------+
|        3 |
+----------+
1 row in set (0.00 sec)

MySQL [test]> select count(1) from t2;
+----------+
| count(1) |
+----------+
|        6 |
+----------+
1 row in set (0.00 sec)

注:如上所示,正常恢复到指定时间点。

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论