LevelDB log files are composed of a sequence of 32KB blocks. The final block in a file may be a partial block. Each block contains a sequence of records and an optional trailer.
Block Structure
A block consists of zero or more records followed by an optional trailer. A record cannot start within the last six bytes of a block. Any remaining bytes (up to 6) form the trailer, which must consist entirely of zero bytes and should be skipped by readers.
Record Structure
Each record is defined by the following fields (all little-endian):
checksum: uint32 (CRC32C of the type and data[])length: uint16 (The length of the data field)type: uint8 (The record type)data: uint8[length] (The actual payload)
Record Types
LevelDB uses four record types to handle both single-block records and records that span multiple blocks:
FULL (1): The record contains the entire user data in a single fragment.FIRST (2): The first fragment of a user record that has been split across blocks.MIDDLE (3): An interior fragment of a split user record.LAST (4): The final fragment of a split user record.
Fragmented Record Example
When a user record is larger than a block or spans a block boundary, it is split:
- A
FIRST record contains the initial fragment. - One or more
MIDDLE records contain the intermediate fragments. - A
LAST record contains the final fragment.
If exactly seven bytes remain in a block and a new non-zero length record is added, the writer must emit a FIRST record with zero bytes of user data to fill the remaining seven bytes, then continue the user data in subsequent blocks.
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]