leveldb 学习记录(四)Log文件 leveldb 学习记录(四) skiplist

前文记录

leveldb 学习记录(一) skiplist
leveldb 学习记录(二) Slice
leveldb 学习记录(三) MemTable 与 Immutable Memtable
leveldb 学习记录(四) skiplist补完

KV数据库中 大部分是采用内存存储,如果中途发生意外情况,没有dump到磁盘的记录就可能会丢失,但是如果采用log记录操作便可以按照log记录进行这部分的数据恢复

所以,我们在每次操作kv记录的时候都需要将操作记录到log文件中。

每个日志文件都会切分为32KB的BLOCK,BLOCK来记录那些操作RECORD,但是不保证RECORD长度固定。所以有了以下设计

record :=      checksum: uint32          // crc32c of type and data[]
                  length: uint16
                  type: uint8                           // One of FULL, FIRST, MIDDLE, LAST
                  data: uint8[length]      

同时也不保证RECORD不跨BLOCK记录

所以RECORD的类型有 FULL, FIRST, MIDDLE, LAST四种类型

当一个RECORD在一个BLOCK内 那么它的类型是FULL

否则跨BLOCK记录RECORD的时候 记录可以分为FIRST, MIDDLE, LAST

如图

上图可以看到LOG文件由三个BLOCK组成BLOCK1 BLOCK2 BLOCK3

不同的RECORD 分配如下 

BLOCK1  RECORDA整个数据都在BLOCK1中,所以他的类型是FULL 。接着是 RECORDB的部分数据 类型为FIRST

BLOCK2  RECORDB的数据, 由于部分数据在BLOCK1和BLOCK3中,所以这部分RECORDB的类型是MIDDLE

BLOCK3  首先是RECORDB的数据,类型是LAST。 紧接着是RECORDC,这部分数据类型为FULL

record分为校验和,长度,类型和数据。

对应的相关LOG 数据结构如下

 1 enum RecordType {
 2   // Zero is reserved for preallocated files
 3   kZeroType = 0,
 4 
 5   kFullType = 1,
 6 
 7   // For fragments
 8   kFirstType = 2,
 9   kMiddleType = 3,
10   kLastType = 4
11 };
12 static const int kMaxRecordType = kLastType;
13 
14 static const int kBlockSize = 32768;
15 
16 // Header is checksum (4 bytes), type (1 byte), length (2 bytes).
17 static const int kHeaderSize = 4 + 1 + 2;
18 
19 }
20 }

写日志类Writer:

头文件

 1 class Writer {
 2  public:
 3   // Create a writer that will append data to "*dest".
 4   // "*dest" must be initially empty.
 5   // "*dest" must remain live while this Writer is in use.
 6   explicit Writer(WritableFile* dest);
 7   ~Writer();
 8 
 9   Status AddRecord(const Slice& slice);
10 
11  private:
12   WritableFile* dest_;
13   int block_offset_;       // Current offset in block
14 
15   // crc32c values for all supported record types.  These are
16   // pre-computed to reduce the overhead of computing the crc of the
17   // record type stored in the header.
18   uint32_t type_crc_[kMaxRecordType + 1];
19 
20   Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length);
21 
22   // No copying allowed
23   Writer(const Writer&);
24   void operator=(const Writer&);
25 };

除开构造函数,主要来看看AddRecord和EmitPhysicalRecord函数

参考:

https://blog.csdn.net/tankles/article/details/7663873

猜你喜欢

转载自www.cnblogs.com/itdef/p/9789241.html