cmu15-445 Project #4 - LOGGING & RECOVERY

Project 4的主要工作是实现bustub中的Logging,Recovery和Checkpoints的功能

Task #1 - LOG MANAGER

为了实现bustub中原子性和持久性的目标,bustub中通过日志记录存储过程中的修改信息,日志保证已经commit的事务中所做的修改的有效性 ,同时保证发生系统崩溃时尚未提交的事务中所做的修改不生效。最常用的日志结构是WAL,WAL是一连串的记录,记录着数据库中所有的修改动作,在文件include/recovery/log_record.h中对WAL的结构进行声明。
在实现中,有一个全局的对象LogManager,在TablePage中会创建一个log record并调用Log Manager中的AppendLogRecord函数将log record写入到log buffer中(当enable_logging为true时)。

Task 1中需要实现以下部分:
1.对于LogManager中的RunFlushThread函数,需启动一个线程去执行该函数,从而将log flush到磁盘中,当系统调用shutdown/StopFlushThread时该线程停止运行。当间隔了log_timeout秒或者log buffer满了的时候调用RunFlushTread函数,LogManager需要使用异步I/O操作,需要使用两个log buffer,一个用于flushing(flush_buffer),另一个用于写入log records(log buffer),当发生以下情况时需要交换这两个buffer:
(1)当log buffer满了的时候
(2)当过了log_timeout秒的时候
(3)当buffer pool需要从LRU replacer中淘汰一个脏页的时候
2. StopFlushThread用于停止logging以及等待flush thread结束
3. LogManager中需要实现group commit的功能,group commit用于减少调用fsync的开销,从而提升commit-per-second的吞吐量。在TransationManager中,当调用Commit或者Abort函数时,在释放锁之前需要保证log records已经永久性地存储在磁盘中,此时不能强行flush,而是需要等待够log_timeout秒或者其他操作隐式触发flush。
4. 在BufferPoolManager中,当创建一个新的page时,如果page_table_中已经存在对应的page_id的记录,需要修改对应的frame_id为新创建的page的frame id,否则无法通过测试。
5. 当buffer pool manager从clock replacer中淘汰一个脏页并将脏页写回到磁盘时,需要通过比较pageLSN和persistent_lsn_(Log Manager中的一个成员)并flush pageLSN以下的log。和group commit不一样的是,buffer pool可以强行将log manager flush到log buffer中。
6. TablePage中的一些部分需要处理WAL:
(1)创建一个log record
(2)调用LogManger的AppendLogRecord将log record写入到log buffer中(当enable_logging为true时)
(3)更新prevLSN为当前的事务
(4)更新LSN为当前的page
Project中所需要完成的部分是实现LogManager中的AppendLogRecord函数,使得log record可以正确地持久化到log buffer中

TASK #2 - SYSTEM RECOVERY

Task2的工作是根据log恢复数据库
由于在bustub中不支持fuzzy checkpoint,所以不需要进行分析阶段。在这个task中只需要修改LogRecovery类(recovery/log_recovery.cpp和include/recovery/log_recovery.h),具体需要实现以下函数:

  1. DeserializeLogRecord:从log buffer中反序列化和重建log record,当反序列化成功时该函数返回true,否则说明log buffer中可能存在不完整的log record。
  2. Redo:读取log文件到buffer中(减少不必要的I/O操作),并且重做log record对应的操作,在redo的过程中维护一个active_txn_表以及lsn_mapping_表。
  3. Undo:遍历active_txn_表,undo表中的事务对应的操作,在这个project不需要关注recovery过程出现crash的情况,这意味着不需要complementary logging。

TASK #3 - CHECKPOINTS

在Task3中将要实现一个完整的一致性checkpoint,bustub中的CheckpoinManager处理相关问题,从而去阻塞新的事务,flush WAL到磁盘中,flush buffer pool中所有的脏页到磁盘中,最后允许开始一个新的事务。
CheckpointManager中主要包括两个函数:

  1. BeginCheckpoint:使用TransationManager去阻塞新的事务的启动,然后使用LogManager去保证内存中的WAL写入到磁盘中,最后使用BufferPoolManager去flush所有的脏页到磁盘中,注意bustub中必须在此函数返回前阻塞所有的事务。
  2. EndCheckpoint:使用TransationManager允许新的事务启动。

你可能感兴趣的:(数据库,database)