暂无图片
暂无图片
7
暂无图片
暂无图片
暂无图片

MogDB/openGauss 闪回特性

概述

在MogDB 和 openGauss 数据库的2.1.0版本增加了闪回特性,可以通过回收站功能恢复误删除(非purge)的表,也可以利用MVCC机制将表恢复指定时间点或者CSN(commit sequence number),但在生产中不建议直接对DML误操作表直接闪回恢复,而是通过“闪回查询”将历史快照保存到另一张表中,人工干预恢复。

在2.1版本中,回收站功能只能用在astore(Append Update)存储方式误删除的表,而对于查看DML误操作数据只能用在ustore(In-place Update)存储方式的表,数据库表默认的存储方式是astore,但在3.0版本中,回收站功能取消了对astore表的支持。

ustore存储方式也是2.1.0版本新增的特性,像oracle一样,Ustore存储引擎将最新版本的“有效数据”和历史版本的“垃圾数据”分离存储。将最新版本的“有效数据”存储在数据页面上,并单独开辟一段UNDO空间,用于统一管理历史版本的“垃圾数据”,因此数据空间不会由于频繁更新而膨胀,“垃圾数据”集中回收效率更高。而我们所说的闪回,也就是在undo表空间中将历史数据重新检索出来。

当我们在truncate(非purge)或drop(非purge)表的同时,会在回收站创建一个以BIN开头的表,我们也可以在系统表gs_recyclebin中查看到对应关系,回收站详细信息如下:
image.png

使用闪回特性,我们还需要依赖几个数据库参数:

undo_zone_count=16384           --内存中可分配的undo zone数量,0代表禁用undo和Ustore表,建议取值为max_connections*4,修改此参数需要重启数据库
enable_default_ustore_table=on  --开启默认支持Ustore存储引擎
version_retention_age=10000     --旧版本保留的事务数,超过该事务数的旧版本将被回收清理(3.0版本弃用)
enable_recyclebin=on            --打开回收站
recyclebin_retention_time=15min --设置回收站对象保留时间,超过该时间的回收站对象将被自动清理

闪回语法

闪回查询

image.png

闪回表

--恢复到指定时间点或者CSN(只支持ustore)
TIMECAPSULE TABLE table_name TO { TIMESTAMP | CSN } expression

--恢复到drop前(2.1版本只支持astore,3.0版本只支持ustore)
TIMECAPSULE TABLE { table_name } TO BEFORE DROP [RENAME TO new_tablename]

--恢复到truncate前(2.1版本只支持astore,3.0版本只支持ustore)
TIMECAPSULE TABLE { table_name } TO BEFORE TRUNCATE

环境准备

# create table t_astore(id int,col1 varchar(8)) with (storage_type=astore);
CREATE TABLE
# create table t_ustore(id int,col1 varchar(8));
CREATE TABLE
# \dt+
                                                List of relations
 Schema |   Name   | Type  | Owner |  Size   |                       Storage                        | Description
--------+----------+-------+-------+---------+------------------------------------------------------+-------------
 public | t_astore | table | o3m   | 0 bytes | {orientation=row,storage_type=astore,compression=no} |
 public | t_ustore | table | o3m   | 0 bytes | {orientation=row,compression=no,storage_type=USTORE} |
(2 rows)

ustore表

openGauss=# insert into t_ustore values(1,'u1'),(2,'u2');
INSERT 0 2
openGauss=# select now();
              now
-------------------------------
 2022-03-20 23:33:41.442001+08
(1 row)

openGauss=# update t_ustore set col1='uu' where id=2;
UPDATE 1
openGauss=# select now();
              now
-------------------------------
 2022-03-20 23:34:04.102349+08
(1 row)

openGauss=# delete from t_ustore;
DELETE 2
openGauss=# select now();
              now
-------------------------------
 2022-03-20 23:34:12.450033+08
(1 row)

openGauss=# select * from t_ustore ;
 id | col1
----+------
(0 rows)

openGauss=#

astore表

openGauss=# insert into t_astore values(1,'a1'),(2,'a2');
INSERT 0 2
openGauss=# select now();
              now
-------------------------------
 2022-03-20 23:34:23.785888+08
(1 row)

openGauss=# update t_astore set col1='au' where id=2;
UPDATE 1
openGauss=# select now();
             now
-----------------------------
 2022-03-20 23:34:34.8255+08
(1 row)

openGauss=# select * from t_astore;
 id | col1
----+------
  1 | a1
  2 | au
(2 rows)

闪回查询

DML误操作操作有两种方式查看历史数据,一个是基于时间的,一个是基于CSN的。准确的时间点如果没有记住的话,可以通过gs_xlogdump工具去xlog日志中查询,而CSN可以去gs_txn_snapshot表中查询,但查询CSN也要基于时间,暂时还不明白这个CSN的作用。

基于时间

openGauss=# select * from t_ustore timecapsule timestamp to_timestamp('2022-03-20 23:33:41','YYYY-MM-DD HH24:MI:SS.FF');
 id | col1
----+------
  1 | u1
  2 | u2
(2 rows)

openGauss=# select * from t_ustore timecapsule timestamp to_timestamp('2022-03-20 23:34:04','YYYY-MM-DD HH24:MI:SS.FF');
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)

PS: astore表不支持DML的历史数据查看,所以即使astore表数据变更的时间比ustore表晚,依然会提示Restore point too old

openGauss=# select * from t_astore timecapsule timestamp to_timestamp('2022-03-20 23:34:23','YYYY-MM-DD HH24:MI:SS.FF');
ERROR:  Restore point too old
openGauss=# select * from t_astore timecapsule timestamp to_timestamp('2022-03-20 23:34:34','YYYY-MM-DD HH24:MI:SS.FF');
ERROR:  Restore point too old

基于CSN

需要通过时间区间来查看CSN,通过select now() 获取的时间与表中记录的不一定完全准确

--查看CSN
openGauss=# select snptime,snpcsn from gs_txn_snapshot where snptime>='2022-03-20 23:33:40' and snptime<='2022-03-20 23:34:34';
            snptime            | snpcsn
-------------------------------+--------
 2022-03-20 23:33:40.349962+08 |   3698
 2022-03-20 23:33:43.373007+08 |   3700
 2022-03-20 23:33:46.396391+08 |   3702
 2022-03-20 23:33:49.419893+08 |   3704
 2022-03-20 23:33:52.442851+08 |   3706
 2022-03-20 23:33:55.466295+08 |   3708
 2022-03-20 23:33:58.489744+08 |   3710
 2022-03-20 23:34:01.512586+08 |   3713
 2022-03-20 23:34:04.536088+08 |   3715
 2022-03-20 23:34:07.559386+08 |   3717
 2022-03-20 23:34:10.582615+08 |   3719
 2022-03-20 23:34:13.603701+08 |   3722
 2022-03-20 23:34:16.626773+08 |   3724
 2022-03-20 23:34:19.648223+08 |   3726
 2022-03-20 23:34:22.669206+08 |   3729
 2022-03-20 23:34:25.692428+08 |   3731
 2022-03-20 23:34:28.71559+08  |   3733
 2022-03-20 23:34:31.739034+08 |   3735

openGauss=# select * from t_ustore timecapsule csn 3700;
 id | col1
----+------
  1 | u1
  2 | u2
(2 rows)

openGauss=# select * from t_ustore timecapsule csn 3715;
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)


PS: t_ustore表中的数据是在2022-03-20 23:34:12之前删除的,在CSN 3719 和 3722之间,我们来看一下:
openGauss=# select * from t_ustore timecapsule csn 3719;
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)

openGauss=# select * from t_ustore timecapsule csn 3722;
 id | col1
----+------
(0 rows)

PS: astore表依然不支持通过CSN查看历史数据
openGauss=# select * from t_astore timecapsule csn 3735;
ERROR:  Restore point too old

闪回查询数据保存

为了防止undo空间中的旧事务版本被清除,当我们找到我们需要的数据,可以直接通过查询建表的方式将历史数据保留下来,然后需要人工介入,将错误数据恢复到原表。

openGauss=# select * into t from t_ustore timecapsule timestamp to_timestamp('2022-03-20 23:34:04','YYYY-MM-DD HH24:MI:SS.FF');
INSERT 0 2
openGauss=# select * from t;
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)

闪回表

闪回表分两种,一种是dml误操作闪回,另一种是drop/truncate闪回。

DML闪回

openGauss=# select * from t_ustore;
 id | col1
----+------
(0 rows)

openGauss=# select * from t_ustore as t timecapsule timestamp to_timestamp('2022-03-20 23:34:04','YYYY-MM-DD HH24:MI:SS.FF');
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)

openGauss=# TIMECAPSULE TABLE t_ustore to timestamp to_timestamp('2022-03-20 23:34:04','YYYY-MM-DD HH24:MI:SS.FF');
TimeCapsule Table
openGauss=#
openGauss=# select * from t_ustore;
 id | col1
----+------
  1 | u1
  2 | uu
(2 rows)

drop/truncate闪回

2.1版本
image.png

3.0版本
image.pngimage.png

我们开启回收站的功能后,对astore和ustore表做了相同操作,发现2.1版本中astore的表还存在,3.0版本中ustore的表还存在,虽然名字已经变了,但我们可以通过系统表gs_recyclebin来查看对应关系。

openGauss=# SELECT rcyname,rcyoriginname,rcytablespace FROM GS_RECYCLEBIN;
           rcyname           | rcyoriginname | rcytablespace
-----------------------------+---------------+---------------
 BIN$3C534EB400E$9E1A118==$0 | t_astore      |             0
(1 rows)

如果我们先做了truncate然后做了drop操作,这时如果想直接恢复到truncate之前,会有报错提示,需要我们先恢复drop操作,然后再找回truncate之前的数据,以2.1版本为例:

openGauss=# timecapsule table t_astore to before truncate;
ERROR:  relation "t_astore" does not exist
openGauss=# timecapsule table t_astore to before drop rename to astorebak;
TimeCapsule Table
openGauss=# select * from astorebak;
 id | col1
----+------
(0 rows)
openGauss=# timecapsule table t_astore to before truncate;
TimeCapsule Table
openGauss=# \dt+
                                                  List of relations
 Schema |   Name    | Type  | Owner |    Size    |                       Storage                        | Description
--------+-----------+-------+-------+------------+------------------------------------------------------+-------------
 public | astorebak | table | o3m   | 8192 bytes | {orientation=row,storage_type=astore,compression=no} |
(1 row)

openGauss=# select * from astorebak;
 id | col1
----+------
  1 | a1
  2 | au
(2 rows)

对于带purge的drop 或 truncate 操作的表是不可恢复的,如
drop table t purge;
truncate t purge;

清空回收站

openGauss=# select * from gs_recyclebin;
 rcybaseid | rcydbid | rcyrelid |           rcyname           | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn |        rcyrecycletime         | rcycreatecsn | rcychangecsn |
rcynamespace | rcyowner | rcytablespace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+-----------------------------+---------------+--------------+---------+---------------+-------------------------------+--------------+--------------+-
-------------+----------+---------------+----------------+---------------+-------------+--------------+----------------
     16404 |   15443 |    16398 | BIN$3C534EB400E$9E612D8==$0 | astorebak     | t            |       0 |          4838 | 2022-03-21 00:02:00.923583+08 |         3678 |         3678 |
        2200 |       10 |             0 |          16405 | t             | t           | 0            | 27487790694400
(1 row)

openGauss=# purge recyclebin;
PURGE RECYCLEBIN
openGauss=# select * from gs_recyclebin;
 rcybaseid | rcydbid | rcyrelid | rcyname | rcyoriginname | rcyoperation | rcytype | rcyrecyclecsn | rcyrecycletime | rcycreatecsn | rcychangecsn | rcynamespace | rcyowner | rcytables
pace | rcyrelfilenode | rcycanrestore | rcycanpurge | rcyfrozenxid | rcyfrozenxid64
-----------+---------+----------+---------+---------------+--------------+---------+---------------+----------------+--------------+--------------+--------------+----------+----------
-----+----------------+---------------+-------------+--------------+----------------
(0 rows)
最后修改时间:2022-06-03 11:40:57
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论