当应用要插入一条记录时,leveldb首先是将其写入到log中,若成功,则继续将其插入到memtable中。因此,当系统故障而memtable又没有来得及将数据存放到内存中,那么就可以通过log文件来恢复数据,保证数据不会丢失。
由于log的读比较复杂,因此将主要介绍log的写操作。
在class DBImpl中主要有两个与log相关的成员变量:log::Writer* log_; 和 WritableFile* logfile_;
其中log_用于向logfile_中增加一条记录 ,logfile_主要用于对log文件进行同步、刷新等操作
1、Writer类
class Writer {
public:
explicit Writer(WritableFile* dest);
~Writer();
Status AddRecord(const Slice& slice);
private:
WritableFile* dest_; //以一个WritableFile对象作为Writer的成员,Writer则是将要插入的记录插入到dest_中
int block_offset_; // 当前位置在Block中的偏移
uint32_t type_crc_[kMaxRecordType + 1];//CRC
Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length);//调用Append写入数据
};
Writer类对外只提供了一个方法AddRecord()用于加入一条记录,同时其中还有一个WritableFile成员变量,记录最终是插入到WritableFile创建的文件中的。
根据leveldb源码可知,log文件每次都是以32K的物理Block为单位进行操作的,因此log文件可看作是由很多个连续的32K的Block组成的。插入一条数据时,首先确定数据在Block中的起始位置,然后不断写入到log文件中。
Status Writer::AddRecord(const Slice& slice) {
const char* ptr = slice.data();
size
版权声明:本文为u012658346原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。