leveldb的WAL及MANIFEST文件均是以log形式存储的。
Log文件包含了一系列的32K大小的块。每个块包含了一系列的记录(record):
block := record* trailer?
record :=
checksum: uint32 // crc32c of type and data[] ; little-endian
length: uint16 // little-endian
type: uint8 // One of FULL, FIRST, MIDDLE, LAST
data: uint8[length]
如果一个块的最后剩余小于等于6个字节,那么这部分会以0填充,而不会从该部分开始一条新的记录(因为6个字节无法记录一个完整的record)。在读取的时候也会直接跳过这些填充的0字节。
但是,如果一个块的最后刚好剩余7个字节,可以添加一个新的记录进来,并且这个记录被标注为FIRST,其数据长度为0(checksum+length+type,刚好7字节)。用户剩余数据会写入下一个块中。
记录和类型定义如下:
FULL == 1
FIRST == 2
MIDDLE == 3
LAST == 4
FULL标记的record包含了用户记录的全部内容。
FIRST,MIDDLE,LAST用于将用户记录拆分成多条record的情况(由于块大小限制的原因)。FIRST表示用户记录的第一片,LAST是用户记录的最后一片,所有中间片都被标记为MIDDLE。
这样在读取一条完整的用户记录时,要么读取一个FULL record,否则必须读取到FIRST、MIDDLE、LAST record,才能组合出一条完整的用户数据。
Example: 考虑以下长度的用户记录:
A: length 1000
B: length 97270
C: length 8000
A 将会以一条FULL记录存储在第一个块中.
B 将会被分成三片:第一片占用第一个块的剩余部分,第二片占用第二个块,第三片占用第三个块的前面部分,并且第三个块刚好剩余6个字节,这6个字节将不会记录新的数据,而是用0填充。
C 将会以一条FULL记录存储在第四个块中。
Some benefits over the recordio format:
对于大型记录,我们不需要额外的缓冲。

最低0.47元/天 解锁文章
905

被折叠的 条评论
为什么被折叠?



