原文来源:https://tidb.net/blog/4d55d6a3
一、先从最省事的开始,GC 时间内的恢复
简单解释下,tidb 有个参数,tidb_gc_life_time
,一般默认是 10 分钟。建议适当加大。
查询方式
select @@tidb_gc_life_time;
再不行就看 grafana 里,tikv-details> gc 有个 TiKV Auto GC SafePoint,只要是在这个时间之后的,都可以通过下面 3 个方式恢复。
1.1 表的数据量很小,通过工具导出
set @@tidb_snapshot="2023-11-12 10:53:26";
导出,这个就看你的工具了,一般的 *Navicat 就挺好用的 *。
导入一样用工具,记得建个新表。
1.2 表的数据量中等,百万级别,考虑一下使用 loaddata
loaddata 导出
set @@tidb_snapshot="2023-11-12 10:53:26";
SELECT * FROM t10 INTO OUTFILE '/tmp/t10.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
;
复制代码
loaddata 导入
set session tidb_batch_commit=50000;
LOAD DATA LOCAL INFILE
'/tmp/t10.csv'
INTO TABLE t10_bak
FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\r\n' (id, name, id2);
复制代码
留个疑问,仔细查下 tidb_batch_commit 参数,你会发现官方不推荐设置这个参数,这个会破坏事务一致性的,为什么我要在导入前加入这个参数呢?
加戏——指定列导入
LOAD DATA LOCAL INFILE '/tmp/t14.csv' INTO TABLE t14 FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n'
(@C1,@C2,@C3,@C4,@C5 )
set row_id=@C1,
name=@C2,
id=@C4,
c=@C5;
复制代码
非常规使用 tidb,就造就了一些场景需要指定列导入:
a. 表中存在虚拟列
b. 想在导入阶段对值做些处理
1.3 表数据很大,千万级以上,建议用 Dumpling + Lightning
dumpling 导出
官方参数就挺好用,搬运一下
./dumpling -u root -P 4900 -h 127.0.0.1 -o /tmp/test \
--snapshot "2023-12-05 15:12:45" \
--filetype csv -F 100MiB \
-T test.t4
复制代码
Lightning 导入
也是从官方参数就挺好用,搬运一下。
建议使用 tidb 模式,可以满足大部分场景的需求了。如果确实速度太慢,表太大,可以优先调整参数 region-concurrency。
[lightning]
# 日志
level = "info"
file = "/tmp/tidb-lightning.log"
check-requirements = true
[mydumper]
data-source-dir = "/tmp/test"
[tikv-importer]
backend = "tidb"
[tidb]
host = "127.0.0.1"
port = 4000
user = "root"
password = ""
log-level = "error"
复制代码
./tidb-lightning --config /tmp/lightning.toml
导出常见报错如下,请检查 gc 时间,数据被 gc 了,再次强调默认数据库的 tidb_gc_life_time 时间为 10m。
请使用异机恢复方式。
create dumper failed: fail to set snapshot for tidb, please set
--consistency=none/--consistency=lock or fix snapshot problem: Error 8055:
snapshot is older than GC safe point 2023-12-05 14:27:33.218 +0800 CST
复制代码
导入有同名表需要注意下,直接导入是不会报错的,会清理数据,建议手动改下导出的文件,换个表名。最好是空库导入
以下是一些的尝试,验证了一下骚操作的可行性
1. 尝试直接 insert,报错明显,语法不通。
MySQL [test]> insert into t5 select * from t4 as of timestamp '2023-12-06 08:45:26';
ERROR 8135 (HY000): can not set different time in the as of
复制代码
2. 设置了快照时间 insert,报错表不在,第一反应,不是刚建的新表,为啥不存在,仔细一想,报错没啥问题,历史时间点下,数据库是没有这个表的。
MySQL [test]> set @@tidb_snapshot='2023-12-06 08:45:26';
Query OK, 0 rows affected (0.00 sec)
MySQL [test]> insert into t5 select * from t4 ;
ERROR 1146 (42S02): Table 'test.t5' doesn't exist
复制代码
3. 假使我有预感,建一个空表一直放着,再搞呢。还是报错了,这个报错信息就比较直接了,不能在快照下对数据做修改。
MySQL [test]> set @@tidb_snapshot='2023-12-06 09:13:00';
Query OK, 0 rows affected (0.01 sec)
MySQL [test]> insert into t5 select * from t4 ;
ERROR 1105 (HY000): can not execute write statement when 'tidb_snapshot' is set
复制代码
已经踩过了,看到的人就不要再踩了。老老实实正规操作。
1.4 本地恢复 drop table、truncate table
a. 本地恢复 drop table、truncate table
Flashback table
truncate 需要把现有表换名
b. 6.5 以上版本又多了两个功能
整个集群闪退 Flashback cluster
单个 database 级别 drop 闪回
flashback database database_name to database_name;
有没有发现一个小技巧,tidb 在 6.5 是不支持直接 rename database,但是可以通过 flashback database 换名。
二、gc 时间外,异机恢复
没有全备和没有日志的就别妄想恢复了,该醒醒了,赶紧配吧,别等真的需要再搞。如果真的有方法,偷偷告诉我,我想学。
2.1 binlog 恢复
当集群配置有 pump 和 drainer 的时候,就可以使用全备(一般都是 dumpling)+ 增量的 binlog,配置有全备和全备时间点后的增量 binlog 日志。
全备恢复工具 lighting,不在赘述。
增量恢复工具 reparo 配置文件,注意 stop-tso 可以写时间的。
data-dir = "/tidb-data4/binlog"
log-level = "info"
start-tso = "2023-12-02 15:04:05"
stop-datetime = "2023-12-02 15:04:05"
dest-type = "mysql"
safe-mode = false
[[replicate-do-table]]
db-name ="test"
tbl-name = "t4"
[dest-db]
host = "127.0.0.1"
port = 4000
user = "root"
password = "xxxxxxxxxxx"
复制代码
./reparo -config reparo.toml
复制代码
再稍微说下 reparo,binlog 解析工具,不仅可以做增量恢复,还可以 dest-type = “print” 导出 sql 文本。比如只是误删一部分数据,就可以解析问题时间段日志就行了。
2.2 br full + br log
br 用于全备的库,要求还是比较多的,一般要挂 cos 或 nas,不然备到本地,恢复的时候还需要手动整合到一起。
br 相当于 binglog 组件虽然要求多,但是真的快,毕竟是相当于物理级别的 cp,记忆犹新一个大库 dump 一天搞不完,用 br 搞 2 个多小时,当然要 cos 或者 nas 也足够快。
br log 是 pitr,是直接从 kv 取的增量变化,这个也是需要挂 cos 或 nas 用于存储。
br 恢复的命令比较简单了,把全备恢复和增量恢复整合在了一起,很友好。
tiup br restore point \
--pd="10.3.72.75:2979" \
--full-backup-storage='/tidbbackup/brfull/' \
--storage "/tidbbackup/brlog/"
复制代码
简单看下效果
tiup is checking updates for component br ...
Starting component `br`: /home/db/tidb/.tiup/components/br/v6.5.3/br restore point --pd=10.3.72.75:2979 --full-backup-storage=/tidbbackup/brfull/ --storage /tidbbackup/brlog/
Detail BR log in /tmp/br.log.2023-12-05T10.29.16+0800
Full Restore <-------------------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00%
[2023/12/05 10:29:23.647 +08:00] [INFO] [collector.go:73] ["Full Restore success summary"] [total-ranges=29] [ranges-succeed=29] [ranges-failed=0] [split-region=655.559µs] [restore-ranges=12] [total-take=7.100235857s] [total-kv-size=504.4MB] [average-speed=71.04MB/s] [restore-data-size(after-compressed)=27.13MB] [Size=27131118] [BackupTS=446101705187131404] [RestoreTS=446101810752520193] [total-kv=254138]
Restore Meta Files <-------------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00%
Restore KV Files <---------------------------------------------------------------------------------------------------------------------------------------------------------------> 100.00%
[2023/12/05 10:29:24.702 +08:00] [INFO] [collector.go:73] ["restore log success summary"] [total-take=1.054945723s] [restore-from=446101705187131404] [restore-to=446101733590433793] [restore-from="2023-12-05 10:22:34.968 +0800"] [restore-to="2023-12-05 10:24:23.318 +0800"] [total-kv-count=12] [total-size=1.947kB] [average-speed=1.846kB/s]
复制代码
可以看到先做的是 Full Restore 全备,后面做的 restore log 增量恢复。
总结一下:
所有恢复前提,就是你要了解数据库的恢复的前提条件具不具备,比如说gc设置1天,一天做一次全备不做增备,能恢复什么时间点的数据。
为了确保今后在遇到误操作删数据问题时能够迅速、有效地解决,请重视备份。 本篇也是想总结下各个恢复手段,希望能帮助到大家!
如果有什么不对,还请多多指正!
复制代码
作者介绍:Soysauce520,来自神州数码钛合金战队,是一支致力于为企业提供分布式数据库 TiDB 整体解决方案的专业技术团队。团队成员拥有丰富的数据库从业背景,全部拥有 TiDB 高级资格证书,并活跃于 TiDB 开源社区,是官方认证合作伙伴。目前已为 10+ 客户提供了专业的 TiDB 交付服务,涵盖金融、证券、物流、电力、政府、零售等重点行业。
#
评论