合 TiDB恢复被误删除的数据或表
Tags: TiDB误操作恢复闪回truncate恢复drop恢复
概述
FLASHBACK TABLE
参考:https://docs.pingcap.com/zh/tidb/stable/sql-statement-flashback-table/
在 TiDB 4.0 中,引入了 FLASHBACK TABLE
语法,其功能是在 Garbage Collection (GC) life time 时间内,可以用 FLASHBACK TABLE
语句来恢复被 DROP
或 TRUNCATE
删除的表以及数据。
可以使用系统变量 tidb_gc_life_time
配置数据的历史版本的保留时间(默认值是 10m0s
)。可以使用以下 SQL 语句查询当前的 safePoint
,即 GC 已经清理到的时间点:
1 | SELECT * FROM mysql.tidb WHERE variable_name = 'tikv_gc_safe_point'; |
只要被 DROP
或 TRUNCATE
删除的表是在 tikv_gc_safe_point
时间之后,都能用 FLASHBACK TABLE
语法来恢复。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | MySQL [mysql]> select * from GLOBAL_VARIABLES where variable_name='tidb_gc_life_time'; +-------------------+----------------+ | VARIABLE_NAME | VARIABLE_VALUE | +-------------------+----------------+ | tidb_gc_life_time | 10m0s | +-------------------+----------------+ 1 row in set (0.05 sec) MySQL [mysql]> show variables like 'tidb_gc_life_time'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | tidb_gc_life_time | 10m0s | +-------------------+-------+ 1 row in set (0.07 sec) MySQL [(none)]> SELECT * FROM mysql.tidb; +--------------------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------+ | VARIABLE_NAME | VARIABLE_VALUE | COMMENT | +--------------------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------+ | bootstrapped | True | Bootstrap flag. Do not delete. | | tidb_server_version | 78 | Bootstrap version. Do not delete. | | system_tz | Asia/Shanghai | TiDB Global System Timezone. | | new_collation_enabled | False | If the new collations are enabled. Do not edit it. | | tikv_gc_leader_uuid | 5f8534338180001 | Current GC worker leader UUID. (DO NOT EDIT) | | tikv_gc_leader_desc | host:lhrtidb, pid:1711, start at 2022-01-01 16:45:35.655634965 +0800 CST m=+54.854095389 | Host name and pid of current GC leader. (DO NOT EDIT) | | tikv_gc_leader_lease | 20220103-09:44:38 +0800 | Current GC worker leader lease. (DO NOT EDIT) | | tikv_gc_enable | true | Current GC enable status | | tikv_gc_run_interval | 10m0s | GC run interval, at least 10m, in Go format. | | tikv_gc_life_time | 10m0s | All versions within life time will not be collected by GC, at least 10m, in Go format. | | tikv_gc_last_run_time | 20220103-09:35:38 +0800 | The time when last GC starts. (DO NOT EDIT) | | tikv_gc_safe_point | 20220103-09:25:38 +0800 | All versions after safe point can be accessed. (DO NOT EDIT) | | tikv_gc_auto_concurrency | true | Let TiDB pick the concurrency automatically. If set false, tikv_gc_concurrency will be used | | tikv_gc_scan_lock_mode | legacy | Mode of scanning locks, "physical" or "legacy" | | tikv_gc_mode | distributed | Mode of GC, "central" or "distributed" | +--------------------------+------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------+ 15 rows in set (0.05 sec) |
注意事项
如果删除了一张表并过了 GC lifetime,就不能再用 FLASHBACK TABLE
语句来恢复被删除的数据了,否则会返回错误,错误类似于 Can't find dropped/truncated table 't' in GC safe point 2020-03-16 16:34:52 +0800 CST
。
在开启 TiDB Binlog 时使用 FLASHBACK TABLE
需要注意以下情况:
- 下游从集群也支持
FLASHBACK TABLE
- 从集群的 GC lifetime 一定要长于主集群的 GC lifetime。上下游同步存在的延迟可能也会造成下游恢复数据失败。
如果 Binlog 同步出错,则需要在 Binlog 过滤掉该表,同时手动全量重新导入该表的数据。
工作原理
TiDB 在删除表时,实际上只删除了表的元信息,并将需要删除的表数据(行数据和索引数据)写一条数据到 mysql.gc_delete_range
表。TiDB 后台的 GC Worker 会定期从 mysql.gc_delete_range
表中取出超过 GC lifetime 相关范围的 key 进行删除。
所以,FLASHBACK TABLE
只需要在 GC Worker 还没删除表数据前,恢复表的元信息并删除 mysql.gc_delete_range
表中相应的行记录即可。恢复表的元信息可以用 TiDB 的快照读实现。具体的快照读内容可以参考读取历史数据文档。下面是 FLASHBACK TABLE t TO t1
的工作流程:
- 从 DDL History job 中查找
drop table
或者truncate table
类型的操作,且操作的表名是t
的第一个 DDL job,若没找到,则返回错误。 - 检查 DDL job 的开始时间,是否在
tikv_gc_safe_point
之前。如果是tikv_gc_safe_point
之前,说明被DROP
或TRUNCATE
删除的表已经被 GC 清理掉,返回错误。 - 用 DDL job 的开始时间作为 snapshot 读取历史数据,读取表的元信息。
- 删除
mysql.gc_delete_range
中和表t
相关的 GC 任务。 - 将表的元信息中的
name
修改成t1
,并用该元信息新建一个表。注意:这里只是修改了表名,但是 table ID 不变,依旧是之前被删除的表t
的 table ID。
可以发现,从表 t
被删除,到表 t
被 FLASHBACK
恢复到 t1
,一直都是对表的元信息进行操作,而表的用户数据一直未被修改过。被恢复的表 t1
和之前被删除的表 t
的 table ID 相同,所以表 t1
才能读取表t
的用户数据。
注意:
不能用
FLASHBACK
多次恢复同一个被删除的表,因为FLASHBACK
所恢复表的 table ID 还是被删除表的 table ID,而 TiDB 要求所有还存在的表 table ID 必须全局唯一。
FLASHBACK TABLE
是通过快照读获取表的元信息后,再走一次类似于 CREATE TABLE
的建表流程,所以 FLASHBACK TABLE
实际上也是一种 DDL 操作。
RECOVER TABLE
参考:https://docs.pingcap.com/zh/tidb/stable/sql-statement-recover-table/#recover-table
RECOVER TABLE
的功能是恢复被删除的表及其数据。在 DROP TABLE
后,在 GC life time 时间内,可以用 RECOVER TABLE
语句恢复被删除的表以及其数据。
语法:
1 2 | RECOVER TABLE table_name RECOVER TABLE BY JOB ddl_job_id |
注意事项
如果删除表后并过了 GC lifetime,就不能再用 RECOVER TABLE
来恢复被删除的表了,执行 RECOVER TABLE
语句会返回类似错误:snapshot is older than GC safe point 2019-07-10 13:45:57 +0800 CST
。
对于 3.0.0 及之后的 TiDB 版本,不推荐在使用 TiDB Binlog 的情况下使用 RECOVER TABLE
功能。
TiDB Binlog 在 3.0.1 支持 RECOVER TABLE
后,可在下面的情况下使用 RECOVER TABLE
:
- 3.0.1+ 版本的 TiDB Binlog
- 主从集群都使用 TiDB 3.0
- 从集群 GC lifetime 一定要长于主集群(不过由于上下游同步的延迟,可能也会造成下游 recover 失败)
TiDB Binlog 同步错误处理
当使用 TiDB Binlog 同步工具时,上游 TiDB 使用 RECOVER TABLE
后,TiDB Binlog 可能会因为下面几个原因造成同步中断:
- 下游数据库不支持
RECOVER TABLE
语句。类似错误:check the manual that corresponds to your MySQL server version for the right syntax to use near 'RECOVER TABLE table_name'
。 - 上下游数据库的 GC lifetime 不一样。类似错误:
snapshot is older than GC safe point 2019-07-10 13:45:57 +0800 CST
。 - 上下游数据库的同步延迟。类似错误:
snapshot is older than GC safe point 2019-07-10 13:45:57 +0800 CST
。
只能通过重新全量导入被删除的表来恢复 TiDB Binlog 的数据同步。
示例
根据表名恢复被删除的表。
1DROP TABLE t;1RECOVER TABLE t;根据表名恢复被删除的表需满足以下条件:
- 最近 DDL JOB 历史中找到的第一个
DROP TABLE
操作,且 DROP TABLE
所删除的表的名称与RECOVER TABLE
语句指定表名相同
- 最近 DDL JOB 历史中找到的第一个
根据删除表时的 DDL JOB ID 恢复被删除的表。
如果第一次删除表 t 后,又新建了一个表 t,然后又把新建的表 t 删除了,此时如果想恢复最开始删除的表 t, 就需要用到指定 DDL JOB ID 的语法了。
本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信dbaup66,谢谢!