openGauss数据库闪回功能验证
目录
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
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表的恢复。
现在开始操作。
- 建表、插入测试数据。
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;
目前为止都很正常,返回数据也是对的。
r_reason_sk | r_reason_id | r_reason_desc
-------------+------------------+------------------------------------------------------------------------------------------------------
1 | AA | reason1
2 | AB | reason2
3 | AC | reason3
(3 rows)
然后,关键点来了。删除数据然后看能不能闪回。
TRUNCATE TABLE tpcds.reason_t2;
select * from tpcds.reason_t2;
--现在查询表是空的,没错。
--执行闪回
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模式。
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;
--清空数据
TRUNCATE TABLE tpcds.reason_t2;
--确认清空成功了
select * from tpcds.reason_t2;
--闪回到清空前
TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE TRUNCATE;
再查询一下,数据回来了。测试成功
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功能。
DROP TABLE tpcds.reason_t2;
select * from tpcds.reason_t2;
--因为表已经drop了,所以理所当然的报错。然后继续闪回
TIMECAPSULE TABLE tpcds.reason_t2 to BEFORE DROP;
--重新查询,表又恢复了。
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”。想测试该特性的小伙伴还是小心这个点。)
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();
--出去接杯水再回来
INSERT INTO tpcds.time_table select 3, now(),int8in(xidout(next_csn)), 'time3' from gs_get_next_xid_csn();
--去拿了包薯片
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,现在重新查询
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的闪回能力。
SELECT * FROM tpcds.time_table TIMECAPSULE CSN 351356;
最后清空回收站。
openGauss=# purge recyclebin;
PURGE RECYCLEBIN
5.总结&反思
功能测试基本完成,特性还是很不错的,操作下来也比较简单。现在反思下我遇到的两个问题,都是因为表的存储方式为astore,而闪回特性不支持该种类型导致的,建表时指定为ustore就可以解决。so,有没有办法默认建表时就是ustore存储呢?继续翻看产品文档,是有参数可以设置的。
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版本闪回特性的一些基本验证,希望能帮到正在看的你~
相关文章
- 西安一码通的崩溃这个锅多半要由数据库来背
- PostgreSQL系统字段详解数据库
- 文档数据库 OrientDB v2.2.18 发布详解大数据
- Redis 3.2.8:新的数据库功能提升(redis3.2.8)
- MFC编程实现MySQL数据库操作(mfc对mysql的操作)
- Mysql数据库实现上一篇下一篇功能(mysql上一篇下一篇)
- MySQL分段功能:解析数据库的精彩之处(mysql分段)
- 深入浅出Oracle数据库触发器类型(oracle触发器类型)
- Oracle数据库触发器类型及功能简介(oracle触发器类型)
- Oracle 数据库:强大功能带给您无穷可能(oracle数据库功能)
- 求职者福利:Oracle数据库开放招聘!(oracle数据库招聘)
- MySQL 数据库的特性介绍——从功能完备到高度安全化(mysql的特性)
- MySQL数据库集群:强大功能和持久性.(mysql的数据库集群)
- MySQL实现跨数据库查询功能(mysql跨数据库查询)
- 福州:成为 Oracle 数据库之都!(福州oracle)
- 学习MySQL数据库:第四版详解(mysql第4版)
- 如何进行MySQL数据库的物理备份?(mysql物理备份)
- 云端MSSQL数据库安全备份技术研究(云mssql数据库备份)
- 2020年SQL Server革新:优化功能助力数据库业务发展(sqlserver年版)
- Oracle数据库功能强大而多样:一窥间(oracle功能介绍)
- c语言软件应用oracle数据库实现强大功能(c 软件用oracle)
- Oracle 12162 解锁更强大的数据库功能(oracle-12162)
- Cmd下安装Oracle数据库补丁记录(Cmd下oracle补丁)
- 云环境中Redis实现量变的效率提升(云数据库redis的优势)
- 探究Oracle数据库中游标的功能(oracle中的游标作用)
- MySQL下载获取高效数据库管理软件(mysql下载 软件)
- python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
- JAVA简单链接Oracle数据库注册和登陆功能的实现代码