openGauss源码解析(61)

openGauss源码解析:存储引擎源码解析(29)

4.3.5 事务

事务部分覆盖了从openGauss映射到MOT的所有支持的DDL/DML操作。

事务与并发控制机制紧密耦合,每个操作都必须通过并发控制管理,并完成相应的行为。

MOT基于乐观并发机制,几乎不使用锁,因此每个客户端都有自己的事务视图,并且不会阻塞DML,与磁盘表对每个非SELECT操作都加锁的使用方式有显著区别。

每个局部行都有一个初始状态,状态由txn_state_machine管理。txn_state_machine扩展了Silo,支持新操作写后读和读后写,类似于MESI缓存一致性协议。如图4-56所示,MOT将新操作(RD/WR)视为本地缓存中的缓存不命中,并将状态从无效提升为新状态。

图4‑56 DML事务状态机

图注:状态说明:

INV:错误状态(INVALID STATE);RD:查询状态(SELECT STATE);WR:更新状态(UPDATE STATE);DEL:删除状态(DELETE STATE);INS:插入状态(INSERT STATE)。

操作说明:

INV:无效操作(INVALID);RD:读操作(READ);WR:写操作(WRITE);DEL:删除操作(DEL);INS:插入操作(INSERT)。

详细流程

SELECT具体流程如图4-57所示。

图4-57 SELECT时序图

(1) 当SELECT操作被发送到FDW,FDW就会打开一个游标并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效则在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估隔离级别和来自缓存的结果:如果TxnAccess返回了一行,直接将其返回给openGauss;否则以下下两种情况。

① 隔离级别为READ_COMMITED时生成行的副本并返回给FDW。

② 隔离级别为REPEATABLE_READ时映射缓存中的行,并将缓存的行返回给FDW。

UPDATE具体流程如图4 58所示。

图4‑58 UPDATE时序图

(1) 当UPDATE操作被发送到FDW,FDW就会打开一个游标,并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效就在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估来自缓存的结果。

① 如果TxnAccess返回了一行,直接将其返回openGauss。

② 如果没有找到该行,则映射哨兵并返回缓存的行。

(5) openGauss计算返回的行,如果该行与筛选器匹配则openGauss向FDW发送带有更新数据的更新操作。
(6) TxnManager将行的状态提升为WR,并用从openGauss接收的新数据更新本地行。

DELETE具体流程如图4‑59所示。

图4‑59 DELETE时序图

(1) 当DELETE操作被发送到FDW,FDW就会打开一个游标并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效就在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估来自缓存的结果。

① 如果TxnAccess返回了一行,直接将其返回openGauss。

② 如果没有找到该行,则映射哨兵并返回缓存的行。

(5) openGauss计算返回的行,如果该行与筛选器匹配,则openGauss向FDW发送带有更新数据的删除操作。
(6) TxnManager将行的状态提升为DEL,并将本地行标记为已删除。

INSERT具体流程如图4‑60所示。

图4‑60 INSERT序列图

(1) 操作发送到FDW后,FDW使用表API准备插入的行,并将该行发送到事务管理器。
(2) 事务管理器执行以下算法。
  1. 对于表中的每个索引执行以下操作。

① 将哨兵插入索引。

② 如果已提交行–中止事务。

③ 如果成功插入行–映射并完成插入。

④ 如果行不存在,如下。

  • 如果已映射-自己插入,则中止。
  • 否则将它映射到本地缓存。
(3) TxnManager对于重复的key返回RC_OK或RC_ABORT。TxnDDLAccess用于缓存和访问事务性DDL更改。事务中执行的所有DDL都存储在TxnDDLAccess中,并在事务提交/回滚时应用回滚。假设openGauss负责DDL并发,并确保并发的DDL更改不会并行执行。TxnAccess类用于缓存和访问事务性DML更改的。在事务中执行的所有DML都存储在TxnAccess中,并在事务提交/回滚中应用回滚。Access类用于保存单行访问的数据。AccessParams用于保存当前访问的参数,为CC管理提供额外的信息。InsItem用于保存行插入请求的数据。
posted @ 2024-04-29 16:52  openGauss-bot  阅读(9)  评论(0编辑  收藏  举报