log的类图如下:
图 1 Log 类图
> BasicLogRecord
最基础的日志读写的类。提供方法读取一条日志记录。但是,这各类紧限于按次序,在Page内顺序读取一个int值或一个string值。BasicLogRecord类操作的粒度是字段,即在一个LogRecord内,读字段的值。因此,本类对象之外,需要有组件了解一条LogRecord中值的类型及个数,管理本类的操作。
成员参数是Page型的pg(在哪里读数据)和int型的pos(读数据时用到的指针)。初始的pos指向本条LogRecord存储的位置。
nextInt()和nextString()返回当前指针pos指向的LogRecord的字段值。
> LogMgr
底层的日志管理器,主要负责向日志文件中写记录。不管日志记录的语义信息,只将日志记录当做一个整数、字符串的混合序列,持久化到文件中。日志的语义信息由事务管理模块的恢复管理器负责。
在日志文件中,以日志记录为元素,维护着一个环形链表。粗粒度地说,链表的数据结构如下图所示:
图2 日志记录环形链表的数据结构
根据代码:
图3 关键代码
从一个空的日志文件开始,添加第一条、第二条记录,举例如下:
图4 日志记录写入情况举例
以上是写入记录是的情况。
> LogIterator
日志迭代器,提供了在日志文件中,倒序读取日志记录的机制。主要负责读。
基于前面的倒序链表的数据结构,从日志文件中一次读取日志记录。由于特殊的数据结构,顺序读的过程中,实现了日志语义上的从最近时间向前倒序地读取。
以下举例说明读取记录时的情况。
先看代码
a. 构造函数中先调用的Reset()
b. 操作指针移动的MoveNext()
c. 读取记录的Current
图5 读取日志记录关键代码
读取记录举例:
图6 读取日志记录示例
底层的日志存储结构的实现,大致如上文所述。日志的语义信息,将放在恢复管理中一并介绍。