rocksdb-doc-cn

概述

Rocksdb对文件系统以及存储介质保持不可预知的态度。文件系统操作不是原子的,并且在系统错误的时候容易出现不一致。即使打开了日志系统,文件系统还是不能在一个不合法的重启中保持一致。POSIX文件系统不支持原子化的批量操作。因此,无法依赖RocksDB的数据存储文件中的元数据文件来构建RocksDB重启前的最后的状态。

RocksDB有一个内建的机制来处理这些POSIX文件系统的限制,这个机制就是保存一个名为MANIFEST的ROCKSDB状态变化的事务日志文件。MANIFEST文件用于在重启的时候,恢复rocksdb到最后一个一致的一致性状态。

术语

如何工作?

MANIFEST是一个RocksDB状态变更的事务日志。MANIFEST由manifest日志文件以及最后的manifest文件指针组成。Manifest日志是滚动日志文件,命名方式为MANIFEST-(seq number)。seq number总是递增。CURRENT是一个特殊的文件,用于声明最新的manifest日志文件。

在系统(重新)启动的时候,最新的manifest日志文件会包含一个一致的ROCKSDB的状态。任何对RocksDB状态修改的子序列都会被记录到manifest日志文件中。当一个manifest日志超过特定的大小,一个新的manifest日志文件会更新,且保证刷盘到文件系统。成功更新CURRENT文件之后,就的manifest文件就会被删掉。

MANIFEST={CURRENT, MANIFEST-<seq-no>*}
CURRENT = 指向当前manifest日志的文件指针
MANIFEST-<seq-no> = 包含RocksDB状态的快照以及后续的修改

版本(version)编辑

一个任何时刻的RocksDB的特定状态都指向一个版本(version)(换句话说,快照)。任何针对这个版本的修改,都被认为是一个版本编辑。一个版本(或者说一个rocksDB的状态快照)由一系列的版本编辑合并构成。本质上来说,一个manifest日志文件是一个版本编辑的序列。

版本编辑 = 任何RocksDB状态变更
版本 = {版本编辑*}
manifest日志文件 = {版本,版本编辑*} = {版本编辑*}

版本编辑布局

Manifest日志是一个版本编辑记录的序列。版本编辑记录类型是通过编辑标示号码区分的。

我们使用下列数据类型来进行编码/解码。

数据类型

简单数据类型

复杂数据类型

string - 带长度前缀的字符串数据:

+-----------+--------------------+
| size (n)  | content of string  |
+-----------+--------------------+
|<- Var32 ->|<-- n            -->|

版本编辑记录格式

版本编辑记录使用下面的格式。解码器通过记录标示号码区分不同类别的记录

+-------------+------ ......... ----------+
| Record ID   | Variable size record data |
+-------------+------ .......... ---------+
<-- Var32 --->|<-- varies by type       -->

版本编辑记录类型以及布局

针对RocksDB不同的状态变更,有非常多样的编辑记录。

比较器编辑记录:

记录比较器的名字

+-------------+----------------+
| kComparator | data           |
+-------------+----------------+
<-- Var32 --->|<-- String   -->|

日志数量编辑记录: 最新的WAL日志文件数量

+-------------+----------------+
| kLogNumber  | log number     |
+-------------+----------------+
<-- Var32 --->|<-- Var64    -->|

上一个文件号编辑记录: 上一个manifest文件号

+------------------+----------------+
| kPrevFileNumber  | log number     |
+------------------+----------------+
<-- Var32      --->|<-- Var64    -->|

下一个文件号编辑记录: 下一个manifest文件号:

+------------------+----------------+
| kNextFileNumber  | log number     |
+------------------+----------------+
<-- Var32      --->|<-- Var64    -->|

最新的seq number编辑记录:

rocksdb最新的seq number

+------------------+----------------+
| kLastSequence    | log number     |
+------------------+----------------+
<-- Var32      --->|<-- Var64    -->|

最大的列族编辑记录:

调整允许使用的最大列族数

+---------------------+----------------+
| kMaxColumnFamily    | log number     |
+---------------------+----------------+
<-- Var32         --->|<-- Var32    -->|

删除文件编辑记录: 把一个文件标记为从数据库中删除

+-----------------+-------------+--------------+
| kDeletedFile    | level       | file number  |
+-----------------+-------------+--------------+
<-- Var32     --->|<-- Var32 -->|<-- Var64  -->|

新文件编辑记录: 把一个文件标记为新加入数据库,并且提供必要的元数据给ROCKSDB

+--------------+-------------+--------------+------------+----------------+--------------+----------------+----------------+
| kNewFile4    | level       | file number  | file size  | smallest_key   | largest_key  | smallest_seqno | largest_seq_no |
+--------------+-------------+--------------+------------+----------------+--------------+----------------+----------------+
|<-- var32  -->|<-- var32 -->|<-- var64  -->|<-  var64 ->|<-- String   -->|<-- String -->|<-- var64    -->|<-- var64    -->|

+-----------+---------------+-------+------------------+-------+--------------+
|kPathID ---| Path size(n)  | path  | kNeedCompaction  | 1     | value (0/1)  |
+-----------+---------------+-------+------------------+-------+--------------+
<- var32  ->|<-- var32   -->|<- n ->|<-- var32      -->|<- 1 ->|<-- 1      -->|
+--------------+-------------+--------------+------------+----------------+--------------+----------------+----------------+
| kNewFile2    | level       | file number  | file size  | smallest_key   | largest_key  | smallest_seqno | largest_seq_no |
+--------------+-------------+--------------+------------+----------------+--------------+----------------+----------------+
<-- var32   -->|<-- var32 -->|<-- var64  -->|<-  var64 ->|<-- String   -->|<-- String -->|<-- var64    -->|<-- var64    -->|
+--------------+-------------+--------------+-------------+-------------+----------------+--------------+
| kNewFile3    | level       | file number  | Path ID     | file size   | smallest_key   | largest_key  |
+--------------+-------------+--------------+-------------+-------------+----------------+--------------+
|<-- var32  -->|<-- var32 -->|<-- var64  -->|<-- var32 -->|<-- var64 -->|<-- String   -->|<-- String -->|
+----------------+----------------+
| smallest_seqno | largest_seq_no |
+----------------+----------------+
<-- var64     -->|<-- var64    -->|

列族信息编辑记录:

标记列族功能的状态(打开/关闭)

+------------------+----------------+
| kColumnFamily    | 0/1            |
+------------------+----------------+
<-- Var32      --->|<-- Var32    -->|

列族增加编辑记录:

增加一个列族

+---------------------+----------------+
| kColumnFamilyAdd    | cf name        |
+---------------------+----------------+
<-- Var32         --->|<-- String   -->|

列族删除编辑记录: 删除所有列族

+---------------------+
| kColumnFamilyDrop   |
+---------------------+
<-- Var32         --->|
看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账