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

openGauss中的事务原子性

openGauss小助手 2021-10-30
233

如图10-5所示,openGauss通过WAL日志、事务提交日志以及更新记录的多版本来保证写事务的原子性。

图10-5 openGauss事务的原子性示意图

(1)对于插入事务,例如以下插入事务:

START TRANSACTION;

INSERT INTO t(a) VALUES (v1);

INSERT INTO t(a) VALUES (v2);

COMMIT;

通常,我们将一条记录在数据库内部的物理组织方式称为元组,其在形式上类似一个结构体。在上述插入事务的执行过程中,对于每一条新插入的记录,在它们元组结构体头部的xmin成员处都附加了插入事务的唯一标识,即一个全局递增的事务号(Transaction ID,简称XID)。如10.2.1节中所述,这两条插入的记录(元组)连同它们的头部会被顺序写入WAL日志中。

在该事务的提交阶段,在WAL日志中,会插入一条事务提交日志,以持久化该事务的提交结果,并会在专门的事务提交信息日志(Commit LOG,CLOG)中记录该事务号对应的事务提交结果(提交还是回滚)。此后,如果有查询事务读到这两条记录,会首先去CLOG中查询记录头部事务号对应的提交信息,如果为提交,并且通过可见性判断,那么这两条记录会在查询结果中返回;如果CLOG中事务号为回滚状态,或者CLOG中事务号为提交状态但是该事务号对该查询不可见,那么这两条记录不会在查询结果中返回。如上,在没有故障发生的情况下,上述插入两行记录的事务是原子的,不会发生只看到插入一条的“中间状态”。

下面考虑故障场景。

如果在事务写下提交日志之前,数据库发生宕机,那么数据库恢复过程中虽然会把这两条记录插入到数据页面中,但是并不会在CLOG中将该插入事务号标识为提交状态,后续查询也不会返回这两条记录。

如果在事务写下提交日志之后,数据库发生宕机,那么数据库恢复过程中,不仅会把这两条记录插入到数据页面中。同时,还会在CLOG中将该插入事务号标识为提交状态,后续查询可以同时看见这两条插入的记录。如上,在故障场景下,上述插入两行记录的事务操作亦是原子的。

(2)对于删除事务,例如:

START TRANSACTION;

DELETE FROM t WHERE a = v1;

DELETE FROM t WHERE a = v2;

COMMIT;

在该删除事务的执行过程中,对于上面每一条被删除的记录,在它们元组头部的xmax成员处都附加了删除事务的事务号。同时,与插入操作相同,该删除事务的提交状态通过事务提交日志物化,并记录到CLOG中。从而,无论在正常场景还是故障场景下,如果后续查询涉及上述被删除的那些记录,它们的可见性均取决于统一的、在CLOG中记录的删除事务的状态,不会发生部分记录能查询到、部分记录不能查询到的“中间状态”。

(3)对于更新事务,例如:

START TRANSACTION;

UPDATE t set a = v1’ WHERE a = v1;

UPDATE t set a = v2’ WHERE a = v2;

COMMIT;

在openGauss中,上述更新事务等同于先删除v1和v2这两行老版本记录,再插入v1和v2这两行新版本记录,删除和插入事务的原子性已经在(1)和(2)中说明,因此更新事务亦是原子的。

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

评论