暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

KaiwuDB 时序引擎 WAL 技术详解

原创 KaiwuDB 2024-03-15
489

一、背景介绍

为了满足KaiwuDB对操作原子性及数据―致性的要求,并支持时序引擎分布式事务,KaiwuDB引入了Write-Ahead Logging (WAL)功能。其设计目标主要有:
1.支持时序数据库的数据灾难恢复;
2.保证时序数据库多个操作的原子性;
3.支持时序存储引擎分布式事务。

KaiwuDB提供两种级别的WAL日志:实例级别和时序表级别。其中,KaiwuDB实例级别的WAL日志用于记录每个时序表Schema的变更,包括列数据类型变更、加减列、加减TAG等;时序表级别的WAL日志用来记录与本时序表相关的所有的数据变更,包括数据的INSERT、UPDATE 和DELETE以及事务信息等。

传统关系数据库的WAL日志通常是针对具体数据页的物理日志。KaiwuDB的WAL有所不同,使用逻辑日志的方式记录时序表变更,并且在数据记录上面添加日志LSN信息,用来确定日志条目与数据记录之间的对应关系。

二、WAL功能详解

KaiwuDB的节点启动时(无论宕机与否),在启动时序引擎的过程中,需要遍历本节点存储目录中的所有时序表,并调用时序表每个EntityGroup中WALMgr的recovery方法进进行系统恢复。KaiwuDB的WAL引擎主要包括三个模块,用于操作文件的FileMgr,用于存储和管理数据的最小单元LogBlock,用于在KaiwuDB内部进行读取和写入WALLog的BuffMgr模块组成。

LogBlock

为加快数据读取解析,加快写入速度,设定每次读取和写入的最小单位是4KB。LogBlock包括两种形式,一种是位于每个文件首部的HeaderBlock,另一种是用于存储数据的EntryBlock。

  • HeaderBlock用于存储当前日志文件的管理信息;
  • EntryBlock用于存储所有的WALLog,包括对应的BlockNo(4bytes),已写入的数据长度DataLen(2bytes),首条日志的起始地址FirstRecGrp(2bytes),检查点CheckpointNo(4bytes),存储的日志数据以及对整个Block数据完整性的校验码Checksum(4bytes)。

LogBlock是用于对WALLog操作的最小单位,也是在文件中读取和写入的最小单位。由于日志文件组中的文件会被循环利用,因此引入write pos和checkpoint两个时序表级别内部属性。

write pos 记录当前位置,根据日志写入情况实时后移。checkpoint 是指系统发起的最后一次checkpoint的LSN,即数据落盘操作。每次同步WAL记录到日志文件组中,write pos位置就会后移更新。write pos和checkpoint 之间的空间为FREE SPACE,可以用来写入新的WALLog记录。

image.png

KaiwuDB 的checkpoint采用定时轮询机制,checkpoint后移更新有两种情况:

  • 由后台线程定期同步数据文件到磁盘(见ts.wal.checkpoint.interval),同步成功后更新checkpoint;
  • 加载日志文件组恢复数据时,加载过的记录应该被清空,这时可以后移更新 checkpoint。

FileMgr

WAL File Manager用于管理WAL日志文件。时序表WALLog文件由多个文件组成,称为日志文件组,默认为10个,每个文件默认大小为128MB,用户可以通过系统参数进行调整。Log文件按照固定大小的Block组织,称为Log Block,每个Log Block的大小为4k。

FileMgr每次写入日志文件都是以LogBlock为单位,对于操作系统来说,频繁地写入几十字节与几百字节并无区别,LogBlock的写入都是顺序的,以尽可能提升写入性能。LogBlock分为两种:

  • HeaderBlock,用于存储一些元数据信息,每个日志文件都会有一个HeaderBlock,位于文件起始位置;
  • EntryBlock,用于存储具体的WAL。

LogFile文件默认为64MiB,起始第一个为HeaderBlock,存储元数据信息,其余均为EntryBlock,存储WAL数据。

image.png

BufferMgr

单一的文件写入涉及到大量的IO以及文件的偏移量更新操作,对于每条WALLog都需要落盘的情形,该操作会大幅度影响性能。在不需要每条WALLog实时落盘的情况下,提供了WALBuffer Manager以减少过多的落盘请求。

BufferManager结构包括底层的FileManager以提供对文件的写入,包含一个EntryBlock的双向链表用于写入WALLog,提供了firstBlock指针指向链表的头节点,提供了current_block指向当前正在写入的block节点。BufferManager提供对外的读写WALLog的接口。所有的读写都是通过BufferManager调用对应的EntryBlock去完成的,写入的结果保存在BufferManager中,而非直接刷盘。BufferMananger通过flush接口进行数据的落盘,此时BufferManager将需要落盘的Blocks提供给FileManager写入文件,并更新BufferManager的Block链表。
image.png

如上图所示,默认使用第三种模式,TS Engine将数据写入BufferManager,当达到flush interval或写入Log Buffer到一定数量时出发flush,将BufferManager中的所有数据刷盘到本地文件。

三、应用场景

LogBlock,FileMgr,BufferMgr是相互独立的,所有的Log写入都是通过BufferMgr完成的,而LogBlock, FileMgr对KaiwuDB其他组件不可见。FileMgr负责Block到文件的写入工作。WAL日志条目包括以下类型,除此之外可根据具体需求进行添加:
• INSERT
• UPDATE
• DELETE
• CHECKPOTNT
• BEGIN
• COMMIT
• ROLLBACK
• TSBEGIN
• TSCOMMIT
• TSROLLBACK
• DDL_CREATE
• DDL_DROP
• DDL_ALTER_COLUMN

四、总结

通过为KaiwuDB引入Write-Ahead Logging (WAL)及事务管理功能,可以实现以下目标:
1.支持时序数据库的数据灾难恢复(Crash Recovery) ;
2.保证时序数据库多个操作的原子性;
KaiwuDB提供实例级别和时序表级别两种级别的WAL日志。其中实例级别的WAL日志用来记录每个时序表Schema的变更,包括列数据类型变更、加减列、加减TAG等。时序表级别的WAL日志用来记录与本时序表相关的所有的数据变更,包括数据的(INSERT、UPDATE、DELETE以及事务信息等。

传统关系数据库的WAL日志通常是针对具体数据页的物理日志。KaiwuDB的WAL有所不同,使用逻辑日志的方式记录时序表变更,并且在数据记录上面添加日志LSN信息,用来确定日志条目与数据记录之间的对应关系。

最后修改时间:2025-04-09 20:49:39
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论