GBase 8a本身没有回收站功能,被删除的数据是不能通过SQL命令直接恢复的。本文介绍一种非正常手段,用来【尝试】恢复最后一次删除的数据。
警告
本操作属于非正常手段:
如果你有备份,请用备份恢复
如果你能重新录入数据,请重新录入
另外本操作如果手工操作失误,可能导致当前数据主副本不一致,或者数据状态不对,从而影响后续使用,所以只有在丢失的数据极其重要时,考虑的一个【尝试性】方案。
前提
该表做完delete后,没有其它的DML,DDL等操作。否则数据已经改动了,你恢复的最后一次,可能不再是你认为的【最后一次】。
集群
2节点集群
[root@rh6-1 ~]# gcadmin CLUSTER STATE: ACTIVE CLUSTER MODE: NORMAL ================================================================= | GBASE COORDINATOR CLUSTER INFORMATION | ================================================================= | NodeName | IpAddress |gcware |gcluster |DataState | ----------------------------------------------------------------- | coordinator1 | 10.0.2.201 | OPEN | OPEN | 0 | ----------------------------------------------------------------- ============================================================= | GBASE DATA CLUSTER INFORMATION | ============================================================= |NodeName | IpAddress |gnode |syncserver |DataState | ------------------------------------------------------------- | node1 | 10.0.2.201 | OPEN | OPEN | 0 | ------------------------------------------------------------- | node2 | 10.0.2.202 | OPEN | OPEN | 0 | -------------------------------------------------------------
复制
测试表
一张单列的表
gbase> create table tt(id int); Query OK, 0 rows affected (Elapsed: 00:00:00.28)
复制
测试数据
插入3行数据。
gbase> select * from tt; Empty set (Elapsed: 00:00:00.01) gbase> insert into tt values(1),(2),(3); Query OK, 3 rows affected (Elapsed: 00:00:00.16) Records: 3 Duplicates: 0 Warnings: 0 gbase> select * from tt; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (Elapsed: 00:00:00.01)
复制
删除数据
通过delete删除一行数据。
gbase> delete tt where id=1; Query OK, 1 row affected (Elapsed: 00:00:00.23) gbase> select * from tt; +------+ | id | +------+ | 2 | | 3 | +------+ 2 rows in set (Elapsed: 00:00:00.01)
复制
建议备份
在尝试恢复前,建议对表的当前可用数据做备份。如果手工恢复出问题了,最多就是真的丢失了被删除的数据。
create table tt_bak like tt; insert into tt_bak select * from tt;
复制
如果恢复失败,可以通过如下步骤恢复备份
rename table tt to tt_BAD; rename table tt_bak to tt;
复制
尝试恢复被删除的数据
如下操作【有可能】要在每个节点执行,这涉及到你删除的数据,到底影响了哪些分片。只有有数据被本次删除的分片,才需要恢复。如果不涉及到本次删除的分片被操作了,那么可能回退到了一个你无法确认的状态了。
获得数据节点的分片号
其中的IP是主节点,后面的segment ID就是分片号。比如针对tt表,在10.0.2.202上,分片号是1,其分片表的名字就是 tt_n1。在10.0.2.210上,分片表的名字就是tt_n2。
后面的duplicate是备份表所在IP,分片名字和主分片是一样的。
[root@rh6-1 ~]# gcadmin showdistribution Distribution ID: 2 | State: new | Total segment num: 2 Primary Segment Node IP Segment ID Duplicate Segment node IP ======================================================================================================================== | 10.0.2.202 | 1 | 10.0.2.201 | ------------------------------------------------------------------------------------------------------------------------ | 10.0.2.201 | 2 | 10.0.2.202 | ======================================================================================================================== [root@rh6-1 ~]#
复制
查看数据节点的每个分片信息
通过information_schema.tables表,拿到该节点的分片的SCN号和最后更新信息。 需要根据update_time,判断最后删除操作,是否涉及了这个分片。
如下的输出,tt_n1的更新时间是14:20:33,而tt_n2是14:20:11,可以看出上次的delete操作,只影响了n1分片,而没有影响n2分片。对于多个数据节点的集群,每个分片都要检查一次,找到上次delete影响的分片号。
注意,各个节点的【时钟】如果不同,且表的DML操作很频繁,则【非常容易】出现【误判】,导致恢复失败。
[gbase@rh6-1 ~]$ gncli testdb GBase client 8.6.2.43-R28 .125499. Copyright (c) 2004-2021, GBase. All Rights Reserved. gbase> select scn,UPDATE_TIME from information_schema.tables where table_name='tt_n1'; +---------+---------------------+ | scn | UPDATE_TIME | +---------+---------------------+ | 5242933 | 2021-06-17 14:20:33 | +---------+---------------------+ 1 row in set (Elapsed: 00:00:00.00) gbase> select now(); +---------------------+ | now() | +---------------------+ | 2021-06-17 14:21:11 | +---------------------+ 1 row in set (Elapsed: 00:00:00.00) gbase> select scn,UPDATE_TIME from information_schema.tables where table_name='tt_n2'; +---------+---------------------+ | scn | UPDATE_TIME | +---------+---------------------+ | 5242931 | 2021-06-17 14:20:11 | +---------+---------------------+ 1 row in set (Elapsed: 00:00:00.00) gbase>
复制
尝试回退该分片
再次声明:该操作如果评估错误,将导致数据内容处于一个不可知的状态。
根据测试的2节点集群,n1分片需要恢复,通过如下的revert语句,尝试恢复。
可以看到,tt_n1表,被删除的id=1的数据回来了。查看tables表,可以看到scn从 5242933 减少到了5242932。
GBase client 8.6.2.43-R28 .125499. Copyright (c) 2004-2021, GBase. All Rights Reserved. gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 2 | | 3 | +------+ 2 rows in set (Elapsed: 00:00:00.00) gbase> revert table testdb.tt_n1 scn_number 5242933; Query OK, 0 rows affected (Elapsed: 00:00:00.04) gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (Elapsed: 00:00:00.00) gbase> select scn,UPDATE_TIME from information_schema.tables where table_name='tt_n1'; +---------+---------------------+ | scn | UPDATE_TIME | +---------+---------------------+ | 5242932 | 2021-06-17 14:20:21 | +---------+---------------------+ 1 row in set (Elapsed: 00:00:00.00)
复制
针对副本,也要做相同的操作
GBase client 8.6.2.43-R28 .125499. Copyright (c) 2004-2021, GBase. All Rights Reserved. gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 2 | | 3 | +------+ 2 rows in set (Elapsed: 00:00:00.01) gbase> revert table testdb.tt_n1 scn_number 5242933; Query OK, 0 rows affected (Elapsed: 00:00:00.04) gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (Elapsed: 00:00:00.00) gbase>
复制
回到集群查询验证
可以看到被我们删除的id=1的数据已经恢复了。
[gbase@rh6-1 ~]$ gccli testdb GBase client 8.6.2.43-R28 .125499. Copyright (c) 2004-2021, GBase. All Rights Reserved. gbase> select * from testdb.tt; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (Elapsed: 00:00:00.02)
复制
意外处理
如果前面的revert弄错了,你可以通过revert再回退到最新的版本,这个revert你可以理解成【切换】的意思。但如果多个分片,切换错了,那么数据就会处于一种未知的状态了。
[gbase@rh6-1 ~]$ gncli -h10.0.2.202 testdb GBase client 8.6.2.43-R28 .125499. Copyright (c) 2004-2021, GBase. All Rights Reserved. gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (Elapsed: 00:00:00.00) gbase> select scn,UPDATE_TIME from information_schema.tables where table_name='tt_n1'; +---------+---------------------+ | scn | UPDATE_TIME | +---------+---------------------+ | 5242932 | 2021-06-17 14:20:21 | +---------+---------------------+ 1 row in set (Elapsed: 00:00:00.00) gbase> revert table testdb.tt_n1 scn_number 5242932; Query OK, 0 rows affected (Elapsed: 00:00:00.03) gbase> select scn,UPDATE_TIME from information_schema.tables where table_name='tt_n1'; +---------+---------------------+ | scn | UPDATE_TIME | +---------+---------------------+ | 5242933 | 2021-06-17 14:20:33 | +---------+---------------------+ 1 row in set (Elapsed: 00:00:00.01) gbase> select * from testdb.tt_n1; +------+ | id | +------+ | 2 | | 3 | +------+ 2 rows in set (Elapsed: 00:00:00.00)
复制