openGauss 6.0.0 闪回功能实践
一、 闪回功能简介
闪回恢复功能是数据库恢复技术的一环,可以有选择性的撤销一个已提交事务的影响,将数据从人为不正确的操作中进行恢复。在采用闪回技术之前,只能通过备份恢复、PITR等手段找回已提交的数据库修改,恢复时长需要数分钟甚至数小时。采用闪回技术后,恢复已提交的数据库修改前的数据,只需要秒级,而且恢复时间和数据库大小无关。
OpenGauss 6.0.0 LTS版本支持Ustore内核存储引擎的闪回查询、闪回表和DROP/TRUNCATE操作,分别适用于用户的误更新、删除、插入、DROP和TRUNCATE操作。用户通过配置回收站开关,回收站数据保留时间和UNDO记录保留时间来实现历史时间点数据的恢复和查询。
说明: ASTORE引擎暂不支持闪回。
二、闪回参数介绍
undo_retention_time
参数说明:设置undo旧版本保留时间。
取值范围:整型,单位为s,最小值为0,最大值为259200。
默认值:0
enable_recyclebin
参数说明:用来控制回收站的实时打开和关闭。
取值范围:布尔型
默认值:off
recyclebin_retention_time
参数说明:设置回收站对象保留时间,超过该时间的回收站对象将被自动清理。在执行purge recyclebin或者后台回收站清理线程时,将会删除超过该时间的回收站对象。
取值范围:整型,单位为s,最小值为1,最大值为2147483647。
默认值:15min(即900s)
参数设置:上述参数皆为SIGHUP级别,设置后立即生效(实际等待线程重新加载参数略有延迟)。
openGauss=# ALTER SYSTEM SET paraname TO value;
三、闪回操作介绍
闪回查询
闪回查询可以查询过去某个时间点表的某个snapshot数据,这一特性可用于查看和逻辑重建意外删除或更改的受损数据。闪回查询基于MVCC多版本机制,通过检索查询旧版本,获取指定老版本数据。
前提条件:配置undo_retention_time参数,用于设置undo旧版本保留时间(闪回查询操作可查询的最大时间)。使用USTORE存储引擎进行创表。
闪回查询语句
- 闪回快照查询, 查询结果为闪回线程每3秒记录一次的数据库快照,可根据snptime(时间戳)或CSN号进行闪回查询。
openGauss=# select * from gs_txn_snapshot;
snptime | snpxmin | snpcsn | snpsnapshot
-------------------------------+---------+--------+------------------
2024-11-07 10:46:47.86958+08 | 14963 | 2406 | xmin:14963 +
| | | xmax:14963 +
| | | snapshotcsn:2406+
| | | timeline:0 +
| | | rec:0 +k
| | |
2024-11-07 10:46:50.901461+08 | 14964 | 2407 | xmin:14964 +
| | | xmax:14964 +
| | | snapshotcsn:2407+
| | | timeline:0 +
| | | rec:0 +
| | |
- 根据时间戳查询
openGauss=# SELECT * FROM t1 TIMECAPSULE TIMESTAMP to_timestamp ('2024-11-07 15:08:06.398681', 'YYYY-MM-DD HH24:MI:SS.FF');
c1 | c2
----+----
1 | 1
2 | 5
3 | 3
3 | 3
4 | 4
6 | 6
(6 rows)
- 根据CSN号查询
openGauss=# SELECT * FROM t1 TIMECAPSULE CSN 7308;
c1 | c2
----+----
1 | 1
2 | 5
3 | 3
3 | 3
4 | 4
6 | 6
(6 rows)
上述两种方法可以查询到表过去某个时间点或csn号表的状态。
闪回表
闪回表可以将表恢复至特定时间点,当逻辑损坏仅限于一个或一组表,而不是整个数据库时,此特性可以快速恢复表的数据。闪回表基于MVCC多版本机制,通过删除指定时间点和该时间点之后的增量数据,并找回指定时间点和当前时间点删除的数据,实现表级数据还原。
前提条件:配置undo_retention_time参数,用于设置undo旧版本保留时间(闪回表操作可恢复的最大时间)。使用USTORE存储引擎进行创表。
闪回表语句
---t1表当前状态
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
3 | 10
3 | 10
4 | 4
6 | 6
(6 rows)
---对t1进行更新操作
openGauss=# update t1 set c2 = 3 where c1 = 3;
UPDATE 2
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
3 | 3
3 | 3
4 | 4
6 | 6
(6 rows)
- 根据时间戳闪回恢复表,表恢复到更新操作之前(该时间戳为更新操作之前)。
openGauss=# TIMECAPSULE TABLE t1 TO TIMESTAMP to_timestamp ('2024-11-07 16:08:19.061248', 'YYYY-MM-DD HH24:MI:SS.FF');
TimeCapsule Table
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
- 根据CSN号闪回恢复表
---重新对表进行更新操作
openGauss=# update t1 set c2 = 3 where c1 = 3;
UPDATE 2
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 3
3 | 3
(6 rows)
---将表恢复到更新操作之前的状态
openGauss=# TIMECAPSULE TABLE t1 TO CSN 8505;
TimeCapsule Table
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
闪回DROP
可以恢复意外删除的表,从回收站(recycle bin)中恢复被删除的表及其附属结构如索引、表约束等。闪回drop是基于回收站机制,通过还原回收站中记录的表的物理文件,实现已drop表的恢复。
前提条件:开启enable_recyclebin参数,启用回收站(DROP和TRUNCATE操作会将原表信息存入回收站中用于闪回恢复)。recyclebin_retention_time参数用于设置回收站对象保留时间,超过该时间的回收站对象将被自动清理。
闪回DROP语句
- 查询回收站信息
openGauss=# select * from gs_recyclebin;
rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------
(0 rows)
- DROP表,开启闪回,drop数据可恢复
openGauss=# drop table t1;
- 物理DROP表(不会将表信息存入回收站中),DROP数据不可恢复
openGauss=# drop table t1 purge;
- 闪回恢复表FROM DROP操作
--- DROP表t1
openGauss=# drop table t1;
DROP TABLE
--- 查看回收站,发现表t1数据已存入回收站
openGauss=# select * from gs_recyclebin;
rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+-----------------------------+---------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------
16387 | 15833 | 16384 | BIN$3DD94EB4000$2C87058==$0 | t1 | d | 0 | 9085 | 2024-11-07 16:37:06.905692+08 | 3565 | 3565 | 2200 | 10 | 0 | 16384 | t | t | 16122 | 16122
(1 row)
--- 再次查询表t1,发现表不存在
openGauss=# select * from t1;
ERROR: relation "t1" does not exist on node3
LINE 1: select * from t1;
^
--- 对表t1进行闪回DROP恢复操作
openGauss=# timecapsule table t1 to before drop;
TimeCapsule Table
--- 再次查询表t1,表已恢复
openGauss=# select * from t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
- 闪回恢复表FROM DROP操作并对表进行重命名(因为表在被DROP后可能创建同名的新表,导致表名冲突,无法恢复)
--- DROP表t1
openGauss=# drop table t1;
DROP TABLE
--- 查看表列表,表t1已被DROP
openGauss=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+-----------------------------+-------+-----------+------------------------------------------------------
public | BIN$3DD94EB4000$2C8CA38==$0 | table | sundechao | {orientation=row,storage_type=ustore,compression=no}
(1 row)
--- 对表t1进行闪回DROP恢复操作并重命名为new_t1
openGauss=# timecapsule table t1 to before drop rename to new_t1;
TimeCapsule Table
--- 再次查询表列表,new_t1表存在
openGauss=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+--------+-------+-----------+------------------------------------------------------
public | new_t1 | table | sundechao | {orientation=row,storage_type=ustore,compression=no}
(1 row)
--- 查询原始t1表已不存在
openGauss=# select * from t1;
ERROR: relation "t1" does not exist on node3
LINE 1: select * from t1;
^
--- new_t1表数据和原始t1表数据相同
openGauss=# select * from new_t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
- 清除recyclebin中表信息,清除后表无法再被恢复(BINxxxx为原表被DROP或TRUNCATE后,重命名的表名)
openGauss=# purge table t1;
openGauss=# purge table "BIN$3DD94EB4000$2C8CA38==$0";
- 清除recyclebin中索引信息,清除后索引无法再被恢复(BINxxxx为原索引被DROP后,重命名的索引名)
openGauss=# purge index idx1;
openGauss=# purge index "BIN$5AC94CA3215$5D3FE46==$0";
- 清除recyclebin中所有信息(该操作只允许数据库super user进行)。
openGauss=# purge recyclebin;
闪回TRUNCATE
可以恢复误操作或意外被进行truncate的表,从回收站中恢复被truncate的表及索引的物理数据。闪回truncate基于回收站机制,通过还原回收站中记录的表的物理文件,实现已truncate表的恢复。
前提条件:开启enable_recyclebin参数,启用回收站(DROP和TRUNCATE操作会将原表信息存入回收站中用于闪回恢复)。recyclebin_retention_time参数用于设置回收站对象保留时间,超过该时间的回收站对象将被自动清理。
闪回TRUNCATE语句
- TRUNCATE表,开启闪回,TRUNCATE数据可恢复
openGauss=# truncate table new_t1;
- 物理TRUNCATE表(不会将表信息存入回收站中),TRUNCATE数据不可恢复
openGauss=# truncate table new_t1 purge;
- 闪回恢复表FROM TRUNCATE操作
--- 查询new_t1表当前状态
openGauss=# select * from new_t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
openGauss=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+--------+-------+-----------+------------------------------------------------------
public | new_t1 | table | sundechao | {orientation=row,storage_type=ustore,compression=no}
(1 row)
openGauss=# select * from gs_recyclebin;
rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------
(0 rows)
--- TRUNCATE表new_t1后,基本信息状态
truncate table new_t1;
TRUNCATE TABLE
openGauss=# select * from gs_recyclebin;
rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+-----------------------------+---------------+--------------+---------+---------------+-------------------------------+--------------+--------------+--------------+----------+---------------+----------------+---------------+-------------+--------------+----------------
16389 | 15833 | 16384 | BIN$3DD94EB4000$2D02BA8==$0 | new_t1 | t | 0 | 9721 | 2024-11-07 17:09:26.626052+08 | 3565 | 9113 | 2200 | 10 | 0 | 16384 | t | t | 16122 | 16122
(1 row)
openGauss=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+--------+-------+-----------+------------------------------------------------------
public | new_t1 | table | sundechao | {orientation=row,storage_type=ustore,compression=no}
(1 row)
--- 查询表new_t1已没有数据
openGauss=# select * from new_t1;
c1 | c2
----+----
(0 rows)
--- 对表new_t1进行闪回TRUNCATE恢复操作
timecapsule table new_t1 to before truncate;
TimeCapsule Table
--- 再次查询表new_t1,表中数据已恢复
openGauss=# select * from new_t1;
c1 | c2
----+----
1 | 1
2 | 5
4 | 4
6 | 6
3 | 10
3 | 10
(6 rows)
总结
闪回恢复可以有选择性的撤销数据库在一段时间内提交的事务,将数据库恢复到一定时间节点的状态。该技术可以有效降低用户误操作对数据库数据带来的影响,而且闪回技术对于数据的恢复只需要秒级,极大的降低了对正常业务的影响。