1、写在前面
闪回相对于备份恢复而言更轻量级,针对于某一个表因为错误的事务提交而导致的数据错误,闪回主要是针对于事务而言的,数据库必须在正常的运行状态下执行;如果介质损坏等还是需要使用传统的备份恢复。
闪回功能针对于不同的存储引擎会有相应的限制,因此在测试闪回之前先了解一下open Gauss的存储引擎。
2、存储引擎概述
用一张图描述一下存储引擎的划分:
openGauss的存储引擎主要分为磁盘存储引擎和内存存储引擎:
磁盘存储引擎:顾名思义就是数据保存在磁盘上,通过特定的接口从磁盘中读取数据,存储结构以page为单位,为了方便与服务器进行交互,需要与操作系统中的block大小对齐,服务器的block大小一般是4k,因此数据库在实际页大小的时候都是4k的整数倍,比如:4k、8k、16k、32k。MogDB默认的页大小就是8K。
内存存储引擎(Mstore):顾名思义就是数据存储在内存中,sql引擎指直接与内存交互,但为了保证数据的持久性,会有特殊的技术把内存引擎中的数据合并到磁盘当中,比如当下比较流行的LSM Tree。MogDB中的MOT表就属于内存存储引擎。
磁盘存储引擎需要通过接口从磁盘中读取到数据库的缓冲区,而内存引擎则避免的与磁盘的io,所以在追求高并发、高性能的OLTP类系统中可以考虑使用内存存储引擎。
磁盘存储引擎又分为行存储引擎和列存储引擎。行存储引擎,顾名思义数据是以行的形式存放在page中,主要应用于事务类交易系统;列存储引擎是以列的形式存放在page中,主要应用于OLAP类统计查询系统,并且可以使用更多的压缩方式,存储空间会更好的利用。
行存储引擎又根据不同的优化方式分为Astore(优化追加写)存储引擎和Ustore(优化更新)存储引擎。
Ustore是原地更新(in-place update)设计,支持 MVCC(Multi- Version Concurrency Control,多版本并发控制),类似于Oracle的设计,最新的数据(已提交)与前版本数据(undo)分开存储。
Astroe也支持多版本查询,只是前版本数据与数据都是在一起存储,会更占用空间,一个page中可能存放4条Astroe的数据,但是在Ustore中可能会存储8条。因为Astro历史版本数据和最新的数据存放到有一起。
3、基于内存存储引擎的MOT
MOT是通过内存存储引擎管理的内存表,支持事务的ACID特性,由于内存是易丢失的,所以如果想保证数据的持久性,需要把MOT的数据同步到磁盘中,MOT是通过WAL重做日志和MOT检查点实现了数据的持久性,详细请参考官方文档MOT的使用,当前只是测试功能。
1)编辑mot.conf配置文件
Mot.conf在data目录下,把以下注释内容取消掉
enable_checkpoint = true checkpoint_dir = /opt/mogdb/data/checkpoint checkpoint_segsize = 16 MB checkpoint_workers = 3 checkpoint_recovery_workers = 3 |
在postgresql.conf中增加一行指定mot配置文件路径,另外需要修改enable_incremental_checkpoint 为off
mot_config_file = '/opt/mogdb/data/data/mot.conf' enable_incremental_checkpoint = off |
重启数据库
gs_om -t restart
2)给用户赋权,可以创建和访问MOT
db_mogdb=> grant USAGE ON FOREIGN SERVER mot_server TO zkh; |
3)使用FOREIGN关键字创建MOT
create FOREIGN TABLE mot_tables_mysql ( schemaname character varying(150), tablename character varying(150), tableowner character varying(150), tablespace character varying(150), hasindexes character varying(150), hasrules character varying(150), hastriggers character varying(150), tablecreator character varying(150), created character varying(150), last_ddl_time character varying(150) ); |
4)测试主库中创建的MOT表没有同步到从库
5)转换磁盘表到内存表
#导出数据 gs_dump -Fc db_mogdb -a --table dump_tables_mysql -f dump_tables_mysql.dump -U zkh -W Zkh12345678 #原表修改名称 alter table dump_tables_mysql rename to dump_tables_mysql_bak; #创建一模一样的MOT表 create FOREIGN TABLE dump_tables_mysql ( schemaname character varying(150), tablename character varying(150), tableowner character varying(150), tablespace character varying(150), hasindexes character varying(150), hasrules character varying(150), hastriggers character varying(150), tablecreator character varying(150), created character varying(150), last_ddl_time character varying(150) ); #导入数据 gs_restore -C -d db_mogdb dump_tables_mysql.dump -U zkh -W Zkh12345678 |
4、数据闪回
闪回限制
官方中档中针对于Ustore和Astore存储引擎支持的闪回功能存在区别,Ustroe存储引擎支持DML类的事务闪回,比如delete、update、insert;Astore只支持drop、truncate的闪回,其实主要是应用了回收站的功能,实际测试结果只有Ustore支持truncate和drop的闪回恢复,MVCC多版本查询没有测试通过;Astroe不支持闪回功能。
在Mogdb中默认创建的Astore的表,通过设置enable_default_ustore_table参数为on可以修改为默认创建Ustore的表,当然在创建表的时候可以指定storage_parameter参数选择存储引擎。
与闪回相关的参数
参数 | 含义 | 默认值 |
undo_zone_count | Undozone的数量,保证undo的并发性,文档中描述是预留参数,当前版本未支持,仅Ustore使用 | 0 |
version_retention_age | 旧版本保留的事务数,文档中描述是预留参数,当前版本未支持,仅Ustore使用 | 0 |
enable_recyclebin | 回收站 | Off |
recyclebin_retention_time | 回收站保留时间 | 900s |
undo_space_limit_size | Undo空间总大小 | 33554432*8k |
undo_limit_size_per_transaction | 单个事务使用的最大undo大小 | 4194304*8k |
打开回收站
gs_guc reload -N all -I all -c "enable_recyclebin=on"; |
测试闪回功能
1)Astore的drop闪回
#验证是否开启了回收站功能 db_mogdb=> show enable_recyclebin; enable_recyclebin ------------------- on (1 row) #误删除表 db_mogdb=> drop table test_flashback; #尝试闪回 db_mogdb=> TIMECAPSULE table zkh.test_flashback to before drop ; ERROR: recycle object "test_flashback" desired does not exist #查看pg_catalog.gs_recyclebin 仍然没记录。 |
又一次踩坑,试一下Ustore的表
#创建Ustroe的表 CREATE TABLE ustore_flasback ( id character varying(2) NOT NULL, name character varying(50), saler numeric(10,2), dept_no character varying(2) ) WITH (STORAGE_TYPE=USTORE); ALTER TABLE ustore_flasback ADD CONSTRAINT ustore_flasback_pkey PRIMARY KEY (id); #删除表 db_mogdb=> drop table ustore_flasback; DROP TABLE #闪回表 db_mogdb=> TIMECAPSULE table ustore_flasback to before drop ; TimeCapsule Table db_mogdb=> select * from ustore_flasback; id | name | saler | dept_no ----+------+-----------+--------- 2 | zs | 6000.00 | 10 3 | ls | 7000.00 | 10 4 | wemz | 8000.00 | 10 5 | lucy | 9000.00 | 10 6 | lili | 10000.00 | 10 7 | ww | 50000.00 | 10 8 | tq | 10000.00 | 10 1 | zkh | 100000.00 | 10 (8 rows) |
可见Ustore的成功闪回了。那就是Astore不支持闪回,难道文档中标记有误?
2)Ustore的truncate闪回
db_mogdb=> truncate table ustore_flasback; TRUNCATE TABLE db_mogdb=> TIMECAPSULE table ustore_flasback to before truncate; TimeCapsule Table db_mogdb=> select * from ustore_flasback; id | name | saler | dept_no ----+------+-----------+--------- 2 | zs | 6000.00 | 10 3 | ls | 7000.00 | 10 4 | wemz | 8000.00 | 10 5 | lucy | 9000.00 | 10 6 | lili | 10000.00 | 10 7 | ww | 50000.00 | 10 8 | tq | 10000.00 | 10 1 | zkh | 100000.00 | 10 (8 rows) |
闪回成功。
3)Ustore的误操作多版本查询
db_mogdb=> select sysdate; sysdate --------------------- 2022-08-17 15:25:07 (1 row) db_mogdb=> update ustore_flasback set saler=100000; UPDATE 8 db_mogdb=> select * from ustore_flasback; id | name | saler | dept_no ----+------+-----------+--------- 2 | zs | 100000.00 | 10 3 | ls | 100000.00 | 10 4 | wemz | 100000.00 | 10 5 | lucy | 100000.00 | 10 6 | lili | 100000.00 | 10 7 | ww | 100000.00 | 10 8 | tq | 100000.00 | 10 1 | zkh | 100000.00 | 10 (8 rows) db_mogdb=> SELECT * FROM ustore_flasback AS t TIMECAPSULE TIMESTAMP to_timestamp ('2022-08-17 15:25:07', 'YYYY-MM-DD HH24:MI:SS'); ERROR: cannot find the restore point |
竟然闪回失败了。。。头大,按理说没有问题
因为好多与undo有关的参数都是预留参数,当前版本不支持,难道多版本查询当前版本也不支持?
5、写在最后
这次测试首先了解了MogDB的存储引擎,目前MogDB中enable_default_ustore_table默认是off,这样创建的表是都是基于Astore存储引擎,个人理解按照功能而言其实Ustroe会更好一些,不知道后续版本是否会默认开启enable_default_ustore_table这个参数,其次测试了MOT表,MOT表不支持主从环境,这样从库无法同步,如果主库本地介质损坏,MOT数据虽然有检查点,但是如果检查点路径在本地磁盘,数据也可能无法恢复。最后测试了闪回功能,当前版本基于mvcc的闪回没有支持,期待后续能开放更多的功能,也可能是我的测试方法不对,还请大佬指正。