暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

MogDB/openGauss3.0 UNDO相关参数

原创 何放 2022-08-22
1652

本次测试数据库版本为MogDB/openGauss3.0,测试undo相关的参数会怎样影响undo目录中旧版本数据自动回收的能力,强制回收会不会丢数据。

undo目录结构图

image.png
数据目录中的undo目录下有三个目录和一个undometa文件,undometa是undo的元数据文件,permanent是存储undo的持久化数据的,这部分数据丢失,会导致ustore表数据的不一致。因此$PGDATA/undo目录不能随便删除。

测试undo参数

  • undo_retention_time
    参数说明: 设置undo旧版本保留时间,默认不保留旧版本。

  • undo_space_limit_size
    参数说明: 用于控制undo强制回收阈值,达到阈值的80%启动强制回收。

  • undo_limit_size_per_transaction
    参数说明: 用于控制单事务undo分配空间阈值,达到阈值时事务报错回滚。

undo_retention_time的测试

  1. undo_retention_time值为0,undo最大空间800MB,对ustore表做增删改操作,同时undo统计信息

image.png

select gs_stat_undo();

通过undo系统函数 gs_stat_undo() 可以看到在ustore表数据修改时undo目录就一直在增大,事务提交,执行成功就不再增大。大概过了5秒 undo目录里的旧数据就被清理,又回到原先值。

查看undo目录大小
image.png

查看这时间段表的CSN是不存在的

SELECT * FROM gs_txn_snapshot where snptime between '2022-08-16 09:00:00' and '2022-08-16 10:00:00'; snptime | snpxmin | snpcsn | snpsnapshot ---------+---------+--------+------------- (0 rows)

undo_retention_time参数起到了及时清理旧版本数据的作用,设置为0s undo目录清理旧版本数据的特别快,约等于不存储旧版本数据,空间上节省了不少。但是旧版本数据删除了,基于MVCC的闪回表和闪回查询就无法做到,所以这样设置不利于基于MVCC的闪回恢复。

  1. undo_retention_time值为60s,undo最大空间800MB,对ustore表做DML
MogDB=# create table t1 (id int , name text); CREATE TABLE MogDB=# insert into t1 values (generate_series(1,1000000),md5(random()::text)); INSERT 0 1000000 MogDB=# select gs_stat_undo(); gs_stat_undo ------------------------------------------------------------- (4,"1 : 40, 0 : 0, 0 : 0",45,640,42576,42618,0,0,3053,3004) (1 row) -- 隔半分钟再执行 MogDB=# insert into t1 values (generate_series(1,1000000),md5(random()::text)); INSERT 0 1000000 MogDB=# select gs_stat_undo(); gs_stat_undo ------------------------------------------------------------- (4,"1 : 80, 0 : 0, 0 : 0",85,640,42594,42638,0,0,3093,3004) (1 row) -- 第一次插入后的一分钟空间被回收了 MogDB=# select gs_stat_undo(); gs_stat_undo ------------------------------------------------------------- (4,"1 : 40, 0 : 0, 0 : 0",44,640,42621,42662,0,0,3093,3045) (1 row) -- 再过半分钟第二次insert的空间又被回收 MogDB=# select gs_stat_undo(); gs_stat_undo ----------------------------------------------------------- (4,"0 : 0, 0 : 0, 0 : 0",4,640,42652,42690,0,0,3093,3085) (1 row)

上面测试可以看出,多久提交是按照事务提交的时间计算,待够了60s的事务就会释放它的旧版本数据。时间短也不利于做基于MVCC的闪回表闪回查询。

  1. undo_retention_time值为30000s,undo最大空间800MB,对ustore表做DML
MogDB=# insert into t1 values (generate_series(1,2000000),md5(random()::text)); INSERT 0 2000000 MogDB=# insert into t1 values (generate_series(1,2000000),md5(random()::text)); INSERT 0 2000000 MogDB=# insert into t1 values (generate_series(1,2000000),md5(random()::text)); INSERT 0 2000000 MogDB=# delete t1 where id < 1000000; DELETE 2999997
MogDB=# select gs_stat_undo(); gs_stat_undo ----------------------------------------------------------- (4,"0 : 0, 0 : 0, 0 : 0",4,640,42920,44007,0,0,3093,3085) (1 row) MogDB=# select gs_stat_undo(); gs_stat_undo --------------------------------------------------------------- (4,"1 : 224, 0 : 0, 0 : 0",228,640,42920,44365,0,0,3317,3085) (1 row) MogDB=# select gs_stat_undo(); gs_stat_undo --------------------------------------------------------------- (4,"1 : 454, 0 : 0, 0 : 0",458,640,42920,44397,0,0,3547,3085) (1 row) MogDB=# select gs_stat_undo(); gs_stat_undo --------------------------------------------------------------- (4,"1 : 592, 0 : 0, 0 : 0",596,640,42920,44397,0,0,3685,3085) (1 row) MogDB=# select gs_stat_undo(); gs_stat_undo --------------------------------------------------------------- (4,"1 : 397, 0 : 0, 0 : 0",401,640,42920,44397,0,0,3691,3286) (1 row)

因为回收时间还比较久,undo目录为了保证旧版本的还能写入,设置了最大目录的80%作为阈值,可以看到在接近640MB的时候undo空间有自动清理机制,保证事务还能写入undo目录。

undo_limit_size_per_transaction测试1

  1. 设置undo_limit_size_per_transaction为30M,事务大于这个值会是什么结果。
MogDB=# select COUNT(*) from t1 ; count --------- 3800001 (1 row) MogDB=# insert into t1 values (generate_series(1,2000000),md5(random()::text)); ERROR: [RollbackIfUndoExceeds:71]xid 47550, the undo size 31457286 of the transaction exceeds the threshold 31457280. MogDB=# select COUNT(*) from t1 ; count --------- 3800001 (1 row) MogDB=# update t1 set id = 10; ERROR: [RollbackIfUndoExceeds:71]xid 47620, the undo size 31457316 of the transaction exceeds the threshold 31457280. MogDB=# select COUNT(*) from t1 where id = 10; count ------- 4 (1 row) MogDB=# delete t1 ; ERROR: [RollbackIfUndoExceeds:71]xid 47677, the undo size 31457376 of the transaction exceeds the threshold 31457280. MogDB=# select COUNT(*) from t1; count --------- 3800001 (1 row)

单事务最大阈值的设置,可以让超过值的事务回滚,不影响到原来的数据。

undo_limit_size_per_transaction测试2

undo_space_limit_size是undo目录可使用的最大值,我们把undo_limit_size_per_transaction设置比undo最大可用空间都大进行测试。那么undo_limit_size_per_transaction=800MB,undo_limit_size_per_transaction=2G,执行一条超过800MB的事务。
image.png

有的时候undo目录会写到640MB开始清零,然后继续进行写入,事务没有被中断,也没有影响表更新的数据,有的时候会如下,到最大undo目录大小值还是没有清理。
image.png

虽然undo空间满了,但不影响其他事务的进行,其他事务会触发undo目录全部清理。
image.png

报错表进行查询报如下错,数据已经丢失。

openGauss=# select count(*) from t1; ERROR: snapshot too old! the undo record has been force discard

undo_limit_size_per_transaction的值一定比undo_space_limit_size要小,在openGauss官方的默认配置里undo_limit_size_per_transaction比undo_space_limit_size更小。

最后修改时间:2022-08-23 09:14:22
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论