漫谈OceanBase的多版本并发控制

OceanBase的MemTable包含两个部分:索引结构及行操作链。其中,索引结构存储行头信息,采用内存B树实现;行操作链表中存储了不同版本的修改操作,从而支持多版本并发控制。

OceanBase支持多线程并发修改,写操作拆分为两个阶段:

  • 预提交(多线程执行):事务执行线程首先锁住待更新数据行,接着,将事务中针对数据行的操作追加到该行的未提交行操作链表中,最后,往提交任务队列中加入一个提交任务。
  • 提交(单线程执行):提交线程不断地扫描并取出提交任务队列中的提交任务,将这些任务的操作日志追加到日志缓冲区中。如果日志缓冲区到达一定大小,将日志缓冲区中的数据同步到备机,同时写入主机的磁盘日志文件。操作日志写成功后,将未提交行操作链表中的cell操作追加到已提交行操作链表的末尾,释放锁并回复客户端写操作成功。

如下图所示,MemTable行操作链表包含两个部分:已提交部分和未提交部分。另外,每个事务管理结构记录了当前事务正在操作的数据行的行头,每个数据行的行头包含已提交和未提交行操作链表的头部指针。在预提交阶段,每个事务会将cell操作递加到未提交行操作链表中,并在行头保存未提交行操作链表的头部指针以及锁信息,同时,将行头信息记录到事务管理结构中;在提交阶段,根据事务管理结构中记录的行头信息找到未提交行操作链表,链接到已提交行操作链表的末尾,并释放行头记录的锁。

class ObTransExecutor
{
public:
    //处理预提交任务
    void handle_trans(void* ptask, void* pdata);
    //处理提交任务
    void handle_commit(void* ptask, void* pdata);
};

_1

obTransExecutor是UpdateServer读写事务处理的入口类,它主要包含两个方法:handle_trans以及handle_commit。其中,handle_trans处理预提交任务,handle_commit处理提交任务。handle_trans首先将写事务预提交到MemTable中,接着将写事务加入提交任务队列。提交线程不断地从提交任务队列中取出提交任务,并调用handle_commit进行处理。每个写事务会根据提交时的系统时间生成一个事务版本,读事务只会读取在它之前提交的写事务的修改操作。

如下图所示,对主键为1的商品有2个写事务,事务T1(提交版本号为
2)将商品购买人数修改为100,事务T2(提交版本号为4)将商品购买人数修改为50。那么,事务T2预提交时,T1已经提交,该商品的已提交行操作链包含一个cell:(update,购买人数,100),未提交操作链包含一个cell:(update,购买人数,50)。事务T2成功提交后,该商品的已提交行操作链将包含两个cell:(update,购买人数,100)以及(update,购买人数,50),未提交行操作链为空。对于只读事务:

  • T3:事务版本号为1,T1和T2均未提交,该行数据为空。
  • T4:事务版本号为3,T1已提交,T2未提交,读取到(update,购买人数,100)。尽管T2在T4执行过程中将购买人数修改为50,T4第二次读取时会过滤掉T2的修改操作,因而两次读取将得到相同的结果。
  • T5:事务版本号为5,T1和T2均已提交,读取到(update,购买人数,10)以及(update,购买人数,50),购买人数最终值为50。

_

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值