openGauss
开源数据库
openGauss社区官网
开源社区
openGauss社区入门(opengauss-事务管理和MVVC学习总结)
2022-08-01openGauss社区开发入门
一.事务
1.事务的定义
1 事务的属性
- 原子性(Atomicity):同一个事务下,事务是不可被分割的
- 一致性(Consistency):一致性,事务的的前后数据的完整性需一致
- 隔离性(Isolation):不同事务之间相互隔离,互不影响
- 持久性(Durability):事务一旦执行,数据库的变化就是永久性的
2 事务的隔离级别

二.Mvvc
1.openGauss 中 MVCC 的实现思路
- 定义多版本的数据——使用元组头部信息的字段来标示元组的版本号
- 定义数据的有效性、可见性、可更新性——通过当前的事务快照和对应元组的版本号判断
- 实现不同的数据库隔离级别——通过在不同时机获取快照实现
2.基本概念
1.事务号
当事务开始(执行 begin 第一条命令时),事务管理器会为该事务分配一个 txid(transaction id)作为唯一标识符。txid 是一个 32 位无符号整数,取值空间大小约 42 亿(2^32-1)。 txid 可通过 txid_current()函数获取
3 其中与 MVCC 相关的重要信息
t_xmin:保存插入该元组的事务 txid(该元组由哪个事务插入) t_xmax:保存更新或删除该元组的事务 txid。若该元组尚未被删除或更新,则 t_xmax=0,即 invalid t_cid:保存命令标识(command id,cid),指在该事务中,执行当前命令之前还执行过几条 sql 命令(从 0 开始计算) t_ctid:一个指针,保存指向自身或新元组的元组的标识符(tid)
4 事务实现
每行上有 xmin 和 xmax 两个系统字段 当插入一行数据时,将这行上的 xmin 设置为当前的事务 id,而 xmax 设置为 0 当更新一行时,实际上是插入新行,把旧行上的 xmax 设置为当前事务 id,新插入行的 xmin 设置为当前事务 id,新行的 xmax 设置为 0 当删除一行时,把当前行的 xmax 设置为当前事务 id 当读到一行时,查询 xmin 和 xmax 对应的事务状态是否是已提交还是回滚了, 就能判断出此行对当前行是否是可见。 查看指定表对应的 page header 内容

4.事务 ID 的增长
- 事务 ID 不能无限增长
- txid 到最大值,又会从最小值
- 开始 0: 无效事务 ID 1: 表示系统表初使化时的事务 ID,比任务普通的事务 ID 都旧。 2: 冻结的事务 ID,比任务普通的事务 ID 都旧。 同一个数据库中,存在的最旧和最新两个事务之间的年龄允许的最多是 2^31,即 20 亿。
可用的有效最小事务 ID 为 3。VACUUM 时将所有已提交的事务 ID 均设置为 2,即 frozon。之后所有的事务都比 frozon 事务新,因此 VACUUM 之前的所有已提交的数据都对之后的事务可见。通过这种方式实现了事务 ID 的循环利用。