前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >openGauss数据库闪回功能验证

openGauss数据库闪回功能验证

作者头像
叶秋学长
发布2023-02-01 10:56:54
8660
发布2023-02-01 10:56:54
举报
文章被收录于专栏:全栈学习专栏全栈学习专栏

目录

1. 背景

2.测试环境准备

3.基于类似windows系统回收站的恢复

4.基于MVCC多版本的数据恢复

5.总结&反思

1. 背景

openGauss闪回功能能够有选择性的高效撤销一个已提交事务的影响,从人为错误中恢复。在采用闪回技术之前,只能通过备份恢复、PITR等手段找回已提交的数据库修改,恢复时长需要数分钟甚至数小时。采用闪回技术后,恢复已提交的数据库修改前的数据,只需要秒级,而且恢复时间和数据库大小无关。适用于:

1)误删除表的场景;

2)需要将表中的数据恢复到指定时间点或者CSN。

闪回支持两种恢复模式:

基于MVCC多版本的数据恢复:适用于误删除、误更新、误插入数据的查询和恢复,用户通过配置旧版本保留时间,并执行相应的查询或恢复命令,查询或恢复到指定的时间点或CSN点。

基于类似windows系统回收站的恢复:适用于误DROP、误TRUNCATE的表的恢复。用户通过配置回收站开关,并执行相应的恢复命令,可以将误DROP、误TRUNCATE的表找回。

看起来不错,谁还没有个手滑误操作的时候。搓搓小手,试一试。

2.测试环境准备

软硬件环境:

  • 华为云服务器+openGauss企业版3.0.0 + openEuler20.03
  • Data Studio (这个为了方便执行SQL的,非必须)

参数设置:

  • 启用回收站参数enable_recyclebin。
  • 设置回收站对象保留时间recyclebin_retention_time,超过该时间的回收站对象将被自动清理。单位为s,最小值为0,最大值为259200。
  • 设置内存中可分配的undo zone数量undo_zone_count,0代表禁用undo和Ustore表,建议取值为max_connections*4
代码语言:javascript
复制
gs_guc set -N all -I all -c "undo_zone_count=16384"            
gs_guc set -N all -I all -c "enable_recyclebin=on"           
gs_guc set -N all -I all -c "recyclebin_retention_time=30min"  
gs_om -t restart

3.基于类似windows系统回收站的恢复

回收站的方式有两种:

  • 闪回TRUNCATE:可以恢复误操作或意外被进行truncate的表,从回收站中恢复被truncate的表及索引的物理数据。闪回truncate基于回收站机制,通过还原回收站中记录的表的物理文件,实现已truncate表的恢复。
  • 闪回DROP:可以恢复意外删除的表,从回收站(recyclebin)中恢复被删除的表及其附属结构如索引、表约束等。闪回drop是基于回收站机制,通过还原回收站中记录的表的物理文件,实现已drop表的恢复。

现在开始操作。

  • 建表、插入测试数据。
代码语言:javascript
复制
create SCHEMA tpcds; 
DROP TABLE IF EXISTS tpcds.reason_t2; 
 CREATE TABLE tpcds.reason_t2 
 ( 
  r_reason_sk    integer, 
  r_reason_id    character(16), 
  r_reason_desc  character(100) 
  ) with(STORAGE_TYPE=USTORE); 
INSERT INTO tpcds.reason_t2 VALUES (1, 'AA', 'reason1'),(2, 'AB', 'reason2'),(3, 'AC', 'reason3'); 
select * from tpcds.reason_t2;

目前为止都很正常,返回数据也是对的。

代码语言:javascript
复制
r_reason_sk |   r_reason_id    |                                            r_reason_desc 
-------------+------------------+------------------------------------------------------------------------------------------------------ 
           1 | AA               | reason1 
           2 | AB               | reason2 
           3 | AC               | reason3 
(3 rows)

然后,关键点来了。删除数据然后看能不能闪回。

代码语言:javascript
复制
TRUNCATE TABLE tpcds.reason_t2; 
select * from tpcds.reason_t2;

--现在查询表是空的,没错。

--执行闪回

代码语言:javascript
复制
TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE TRUNCATE;

oh ,翻车鱼来了,我得到了一个error :“ERROR: timecapsule does not support astore yet”

不支持astore??嗯,看了下注意事项,没有说到这个。后来查看管理员指南,在特性描述倒是说了“ASTORE引擎暂不支持闪回功能。备机不支持闪回操作。”在开发者指南 CREATE TABLE部分找到这么一句话。

STORAGE_TYPE:指定存储引擎类型,该参数设置成功后就不再支持修改。不拉不拉 ,不指定表时,默认是Append-Only存储。因此,由于openGauss建表默认为astore模式,是不支持闪回的。所以,现在需要修改建表脚本为ustore模式。

代码语言:javascript
复制
DROP TABLE IF EXISTS tpcds.reason_t2; 
 CREATE TABLE tpcds.reason_t2 
 ( 
  r_reason_sk    integer, 
  r_reason_id    character(16), 
  r_reason_desc  character(100) 
  ) with(STORAGE_TYPE=USTORE); 
INSERT INTO tpcds.reason_t2 VALUES (1, 'AA', 'reason1'),(2, 'AB', 'reason2'),(3, 'AC', 'reason3'); 
select * from tpcds.reason_t2;

--清空数据

代码语言:javascript
复制
TRUNCATE TABLE tpcds.reason_t2;

--确认清空成功了

代码语言:javascript
复制
select * from tpcds.reason_t2;

--闪回到清空前

代码语言:javascript
复制
TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE TRUNCATE;

再查询一下,数据回来了。测试成功

代码语言:javascript
复制
openGauss=# select * from tpcds.reason_t2; 
 r_reason_sk |   r_reason_id    |                                            r_reason_desc 
-------------+------------------+------------------------------------------------------------------------------------------------------ 
           1 | AA               | reason1 
           2 | AB               | reason2 
           3 | AC               | reason3 
(3 rows)

再测试下DROP功能。

代码语言:javascript
复制
DROP TABLE tpcds.reason_t2; 
select * from tpcds.reason_t2;

--因为表已经drop了,所以理所当然的报错。然后继续闪回

代码语言:javascript
复制
TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE DROP;

--重新查询,表又恢复了。

代码语言:javascript
复制
openGauss=# select * from tpcds.reason_t2; 
 r_reason_sk |   r_reason_id    |                                            r_reason_desc 
-------------+------------------+------------------------------------------------------------------------------------------------------ 
           1 | AA               | reason1 
           2 | AB               | reason2 
           3 | AC               | reason3 
(3 rows)

drop掉的表和数据也都回来了。奈斯

4.基于MVCC多版本的数据恢复

  • 依旧是建表插数据。(PS:其实我在这里又翻车了一次,开始建表时又没有指定STORAGE_TYPE=USTORE,得到了一个error “ERROR: timecapsule feature does not support heap table”。想测试该特性的小伙伴还是小心这个点。)
代码语言:javascript
复制
drop table if EXISTS tpcds.time_table; 
create table tpcds.time_table(idx integer, snaptime timestamp, snapcsn bigint, timeDesc character(100)) with(STORAGE_TYPE=USTORE); 
 
INSERT INTO tpcds.time_table select 1, now(),int8in(xidout(next_csn)), 'time1' from gs_get_next_xid_csn(); 
INSERT INTO tpcds.time_table select 2, now(),int8in(xidout(next_csn)), 'time2' from gs_get_next_xid_csn();

--出去接杯水再回来

代码语言:javascript
复制
INSERT INTO tpcds.time_table select 3, now(),int8in(xidout(next_csn)), 'time3' from gs_get_next_xid_csn();

--去拿了包薯片

代码语言:javascript
复制
INSERT INTO tpcds.time_table select 4, now(),int8in(xidout(next_csn)), 'time4' from gs_get_next_xid_csn(); 
 select * from tpcds.time_table;
  • OK,现在重新查询
代码语言:javascript
复制
delete tpcds.time_table; 
SELECT * FROM tpcds.time_table TIMECAPSULE TIMESTAMP to_timestamp('2022-05-17 16:17:20.311176','YYYY-MM-DD HH24:MI:SS.FF');

结果正确,已经可以重新查询到指定时间之前的数据了。3 和 4 因为是16:17:20之后才插入的,所以不能查到。

  • 再测试下根据CSN的闪回能力。
代码语言:javascript
复制
SELECT * FROM tpcds.time_table TIMECAPSULE CSN 351356;

最后清空回收站。

代码语言:javascript
复制
openGauss=# purge recyclebin; 
PURGE RECYCLEBIN

5.总结&反思

功能测试基本完成,特性还是很不错的,操作下来也比较简单。现在反思下我遇到的两个问题,都是因为表的存储方式为astore,而闪回特性不支持该种类型导致的,建表时指定为ustore就可以解决。so,有没有办法默认建表时就是ustore存储呢?继续翻看产品文档,是有参数可以设置的。

代码语言:javascript
复制
gs_guc set -N all -I all -c "enable_default_ustore_table=on"  

这样在实验开始前设置好就无需再建表时手动指定存储格式了。但是,为什么数据库的默认值给的是astore呢?补课学习下ustore和astore的差异。

astore:

openGauss内核当前使用的行引擎采用的是Append Update(追加更新)模式,该模式在INSERT、DELETE、HOT UPDATE(页面内更新)的场景下有较好的表现。主要面向通用的在线交易处理类业务应用场景,适合高并发、小数据量的单点或小范围数据读、写操作。astore为行存储格式,向上提供元组形式的读、写;向下以页面为单位通过可扩展的介质管理器对存储介质进行读、写操作;并通过页面粒度的共享缓冲区来优化读、写操作的效率。

astore存储格式为追加写优化设计,其多版本元组产生和存储方式下图所示。

当一个更新操作将v0版本元组更新为v1版本元组之后,如果v0版本元组所在页面仍然有空闲空间,则直接在该页面内插入更新后的v1版本元组,并将v0版本的元组指针指向v1版本的元组指针。在这个过程中,新版本元组以追加写的方式和被更新的老版本元组混合存放,这样可以减少更新操作的I/O开销。然而,需要指出的是,由于新、老版本元组是混合存放的,因此在清理老版本元组时需要的清理开销会比较大。因此,astore存储格式比较适合频繁插入、少量更新的业务场景。详细内容参考:

openGauss数据库源码解析系列文章——存储引擎源码解析(一)

ustore:

ustore属于In-place Update更新模式,中文意思为:原地更新,是openGauss内核新增的一种存储模式。astore对于非HOT UPDATE场景,垃圾回收不够高效。ustore存储模式提供“原地更新”能力,主要思路是将最新版本的“有效数据”和历史版本的“垃圾数据”分离存储。将最新版本的“有效数据”存储在数据页面上,而单独开辟一段undo(回滚)空间,用于统一管理历史版本的“垃圾数据”,因此数据空间不会由于频繁更新而膨胀,垃圾回收效率更高。通过NUMA-aware的undo子系统设计,使得undo子系统在多核平台上高效扩展。同时通过对元组和数据页面结构的重新设计,减少存储空间的占用。采用多版本索引技术,解决索引膨胀问题,彻底去除autovacuum(垃圾清理线程)机制,提升存储空间的回收复用效率。当前USTORE存储引擎不支持极致RTO回放模式。对于主机,在recovery_parse_workers参数设置大于1的情况下,创建USTORE存储引擎的表将返回报错;对于备机,如果数据库中已经包含USTORE表,那么后续如果再打开极致RTO功能,可能会导致回放失败和报错,严重情况下甚至可能导致备机数据损坏(这种情况下需要执行备机重建进行修复)。详细内容参考

openGauss数据库源码解析系列文章——存储引擎源码解析(四)

以上就是我对openGauss 3.0.0版本闪回特性的一些基本验证,希望能帮到正在看的你~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 叶秋学长 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档