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)
创建bucket:
在管理页面点击:Create Bucket 之后,输入名称创建。
二、部署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"
再次执行数据库操作:
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)
注:如上所示,正常恢复到指定时间点。