存储引擎源码解析 | 磁盘引擎(23)

2023年 12月 13日 51.2k 0

4.3.7 重做日志

MOT重做日志(Redo Log)使用预写式日志(write-ahead logging,WAL)技术来确保数据完整性。WAL的核心概念是,内存中的数据和索引的更改只有在记录下这些更改之后才会发生。因此写入重做日志是MOT提交协议的一部分。

如图4-63所示,MOT存储引擎的重做日志模块同样使用openGauss磁盘引擎的日志接口进行持久化和恢复。这意味着MOT重做数据被写入相同的XLOG文件,并使用相同的XLOG逻辑。使用与openGauss磁盘引擎相同的日志记录接口可确保跨引擎事务的一致性,并减少复制、日志恢复等模块的冗余实现。


图463 使用相同的XLOG (WAL)基础架构的openGauss磁盘库和MOT

1. 事务日志记录

与openGauss其他存储引擎不同,MOT内存引擎仅在事务实际提交时才会写入重做日志。因此,在事务期间或事务中止时,数据不会写入重做日志。这样可以减少写入的数据量,从而减少不必要的磁盘IO调用,因为这种磁盘IO调用很慢。例如,如果在事务期间多次更新同一行,则只将表示已提交行的最终状态写入日志。

由于设计MOT内存引擎时考虑了对接不同的数据库的可能性,因此如图4-64所示,MOT通过抽象的ILogger接口对接重做日志。


图464 ILogger接口

2. 日志类型
设计MOT内存引擎时同样考虑了支持不同的日志记录方式。如图4-65所示,MOT当前已实现同步日志(synchronous redo Log)和同步组日志(group synchronous redo log)。这是通过RedoLogHandler类实现的。RedoLogHandler封装了日志逻辑,在数据库启动时初始化。RedoLogHandler可以根据需要扩展实现新的日志记录方式。


图465 RedoLogHandler接口

每个事务管理器对象(TxnManager)都包含一个Redolog类,该类负责在提交时将事务数据序列化到缓冲区中。如图4-66所示,该缓冲区被传输到RedologHandler以进行日志记录。


图466 使用RedoLogHandler的事务日志记录

1) 同步日志记录
同步日志使用SynchronousRedoLogHandler。如图4-67所示,这是一个简单的RedoLogHandler实现,它只将序列化缓冲区委托给ILogger(XLOGLogger),以便将其写入XLOG。因为在写缓冲区时,事务被阻塞,所以称为同步。只有当所有事务数据被序列化并写入日志时,提交协议才会继续。


图467 SynchronousRedoLogHandler

2) 同步组提交日志记录
同步组提交日志由SegmentedGroupSyncRedoLogHandler类实现。它通过将几个事务分组到一个写块(write block)中并一起写入的方式优化日志记录。这种方法在一次调用中收集更多数据,可以最大限度地减少磁盘IO次数。除此之外, SegmentedGroupSyncRedoLogHandler将每个NUMA处理器(socket)的事务分组,以减少跨NUMA处理器的数据传输,因为跨NUMA处理器的数据访问比同一NUMA处理器本地内存访问慢。
当事务提交时,它将数据序列化到缓冲区中,这个缓冲区被传输到SegmentedGroupSyncRedoLogHandler,并放入一个提交组中。提交组(Commit Group)是一组序列化事务缓冲区的集合,这些事务缓冲区将被提交并写入磁盘。根据不同的配置参数,当一个组被填满或超过预先配置的时间时,MOT将关闭该组,并将该组内所有缓冲区一起写入日志。
图4-68描述了将多个事务分组一起写入的组提交逻辑。


图4-68 同步组提交对每个NUMA处理器的事务进行分组

3) 异步日志
MOT暂未开发专用的异步日志机制,异步日志是通过在conf配置文件中将synchronization_commit参数设置为“off”来实现的。

3. 关键类和数据结构
重做日志的关键类和数据结构如表4-39所示。

图4-69所示代码为XLOGLogger::AddToLog接口的实际实现。

图469 XLOGger对openGauss XLOG的委托

RedoLogHandler是重做日志逻辑的抽象。RedoLogHandler的派生类可实现不同的日志方法。RedoLogHandler是一个单例模式,由MOT管理,为RedoLog所用。
RedoLogHandlerFactory用于创建RedoLogHandler。MOT根据配置项中配置的RedoLogHandlerType创建RedoLogHandler。

SynchronousRedoLogHandler简单地将RedoLogBuffers委托给ILogger,以便写入重做日志。请参阅前述的同步日志记录小节。

GroupSyncRedoLogHandler是最先进的无锁组提交RedoLogHandler。GroupSyncRedoLogHandler将几个事务的redo log缓冲区分组到一个组,并把他们写在一起,以便优化和最小化磁盘IO。请参阅前述同步组提交小节。CommitGroup表示将一组RedoLogBuffer一起记录。一个提交组有一个主线程,由该主线程创建该提交组,它负责将组内的所有RedoLogBuffer写入日志。主线程写日志时,所有其他线程都在等待。主线程完成写入后将发送信号来唤醒组内其他所有线程,一旦唤醒,事务就可以继续。

SegmentedGroupSyncRedoLogHandler是配置了GroupCommit日志方法时的RedoLogHandler。它是RedoLogHandler的一个实现,每个socket都有GroupSyncRedoLogHandler。SegmentedGroupSyncRedoLogHandler的优点在于可以通过维护多个组提交处理程序实现更高的并发。SegmentedGroupSyncRedoLogHandler维护一个GroupSyncRedoLogHandler数组,并将线程绑定到Socket以将线程委托给正确的处理程序。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论