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)视为本地缓存中的缓存不命中,并将状态从无效提升为新状态。
图注:状态说明:
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所示。
(1) 当SELECT操作被发送到FDW,FDW就会打开一个游标并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效则在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估隔离级别和来自缓存的结果:如果TxnAccess返回了一行,直接将其返回给openGauss;否则以下下两种情况。
① 隔离级别为READ_COMMITED时生成行的副本并返回给FDW。
② 隔离级别为REPEATABLE_READ时映射缓存中的行,并将缓存的行返回给FDW。
UPDATE具体流程如图4 58所示。
(1) 当UPDATE操作被发送到FDW,FDW就会打开一个游标,并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效就在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估来自缓存的结果。
① 如果TxnAccess返回了一行,直接将其返回openGauss。
② 如果没有找到该行,则映射哨兵并返回缓存的行。
(5) openGauss计算返回的行,如果该行与筛选器匹配则openGauss向FDW发送带有更新数据的更新操作。
(6) TxnManager将行的状态提升为WR,并用从openGauss接收的新数据更新本地行。
DELETE具体流程如图4‑59所示。
(1) 当DELETE操作被发送到FDW,FDW就会打开一个游标并将正确的哨兵发送到事务管理器。
(2) 事务管理器检查哨兵,如果哨兵有效就在缓存中搜索,否则返回未找到该行。
(3) TxnAccess在内部查找哨兵,如果在高速缓存中找到该行则返回该行,并认为是高速缓存命中。
(4) TxnManager评估来自缓存的结果。
① 如果TxnAccess返回了一行,直接将其返回openGauss。
② 如果没有找到该行,则映射哨兵并返回缓存的行。
(5) openGauss计算返回的行,如果该行与筛选器匹配,则openGauss向FDW发送带有更新数据的删除操作。
(6) TxnManager将行的状态提升为DEL,并将本地行标记为已删除。
INSERT具体流程如图4‑60所示。
(1) 操作发送到FDW后,FDW使用表API准备插入的行,并将该行发送到事务管理器。
(2) 事务管理器执行以下算法。
- 对于表中的每个索引执行以下操作。
① 将哨兵插入索引。
② 如果已提交行–中止事务。
③ 如果成功插入行–映射并完成插入。
④ 如果行不存在,如下。
- 如果已映射-自己插入,则中止。
- 否则将它映射到本地缓存。