OceanBase 源码解读(八):事务日志的提交和回放

批处理
• 阅读 1390

此前,带你读源码第七篇:《一文读懂数据库索引实现原理》尝试从代码导读的角度,简要介绍了 OceanBase 的索引构建流程,带领大家读懂索引构建的相关代码。

本期“源码解读”由 OceanBase 开发工程师刻晴为大家带来“事务日志的提交和回放”。OceanBase 的日志( clog )类似于传统数据库的 REDO 日志,这个模块负责在事务提交时持久化事务数据,并实现了基于 Multi_Paxos 的分布式一致性协议。

日志模块的设计理念

与传统关系型数据库的日志模块相比,OceanBase 的日志服务主要有如下几点挑战:

  • 通过 Multi_Paxos 替换传统的主备同步机制,进而实现系统的高可用和数据的高可靠。
  • 需要支持全球部署,多个副本之间的网络时延达到几十甚至数百 ms。
  • 作为分布式数据库,OceanBase 以 Partition 作为数据同步的基本单位。单机要求支持十万量级的 Partition,在此基础上,需要支持日志数据的高效写入和读取。
  • 同时,任何功能本身均需要考虑操作的批量化,以加速执行速度。日志服务维护副本的成员列表、Leader 等状态信息,需要为分布式系统的丰富功能提供高效的支持。

日志的一生

OceanBase 的日志模块实现了一套标准的 Multi_Paxos,保证在未发生多数派永久性故障的前提下,所有提交成功的数据均可恢复。

同时实现了乱序日志提交,保证事务之间无依赖。在下面关于 OceanBase 对 Multi_Paxos 的工程实现介绍前,我们默认读者已经了解 Multi_Paxos 的核心思想,如果你还想了解更多,欢迎在社区问答区对 Multi_Paxos 进行了解。

以一个分区的一条事务日志为例,正常的流程大致如下:

OceanBase 源码解读(八):事务日志的提交和回放

1、事务层调用 log_service->submit_log() 接口提交日志(其中携带 on_succ_cb 回调指针)。

2、clog 首先为它分配 log_id和submit_timestamp,然后提交到滑动窗口中,生成一个新的 log_task,本地提交写盘,通过 RPC 将日志同步给 follower。

3、本地写盘完成时调用 log_service->flush_cb(),更新 log_task 状态,标记本地持久化成功,follower 写盘成功后给 leader 回 ack。

4、leader 收到 ack 更新 log_task 的 ack_list。

5、leader 在 4、5 两步中会统计多数派,一旦达成 majority,按顺序调用 log_task->on_success 回调事务,同时发送 confirmed_info 消息给 follower ,并将此日志从滑动窗口中滑出。

6、follower 收到 confirmed_info 消息后尝试将此日志从滑动窗口中滑出,在滑出动作中将日志提交回放。

在 follower 上,会对已提交的日志实时进行回放。回放流程大致如下:

OceanBase 源码解读(八):事务日志的提交和回放

follower 在滑出日志时会推大每个分区内记录回放位点的 submit_log_task 的对应值,这个任务会被异步的提交到一个全局线程池中等待消费。

当全局线程池消费某分区的 submit_log_task 时,会将其中记录的所有待回放日志以此读盘并分配到所在分区的对应的 4 个回放任务队列中,分配的方式主要是按照 trans_id 进行哈希,确保同一事务的日志被分配到一个队列中,被分配到新任务的队列将队列 task_queue 作为一个任务再次异步提交到 1 中提到的全局线程池中等待消费。

当全局线程池消费 task_queue 时,会依次遍历队列中所有子任务,并根据日志类型执行相应的应用逻辑。至此,一个日志就真正同步到了 follower 中,在 follower 上也可读了。

学完本篇源码解读,希望你对“事务日志的提交与回放”有了相应了解,下期我们将为大家带来 OceanBase 存储层代码解读的相关内容,敬请期待!

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这