于是我把这个问题放到RocksDB群里,了解到在一些新版本的内核的XFS文件系统上,fallocate函数有一个bug。这会导致使用fallocate分配的SST文件大小与实际manifest不一致。虽然是内核bug,但是RocksDB也需要绕过它,修复在这个https://github.com/facebook/rocksdb/pull/2038。
不过,出现上述不一致错误的SST文件并没有损坏,只是文件末尾出现了一些漏洞。我们只要从MANIFEST文件中获取SST的实际大小并手动截断就可以正常使用了。为了修复这些文件,我决定查看清单文件。
MANIFEST
MANIFEST记录了RocksDB的一些状态变化信息,用于重启时将RocksDB恢复到最近的一致状态。
为什么需要清单? RocksDB是一个key-value存储,但它的实际数据文件仍然存储在操作系统的文件系统中。有时,文件系统操作不是原子的,可能会因为某些系统问题而出现数据不一致的情况。即使文件系统有日志日志,也不是绝对安全的。因此,RocksDB 并没有将一些元信息存储在自己的key-value 系统中,而是使用单独的MANIFEST 文件。
MANIFEST 包括一系列清单文件和标识最新清单文件的CURRENT 文件。清单文件名的格式与MANIFEST-类似,序列号会一直增加,最新的清单文件必须具有最大的序列号。
我们可以将MANIFEST 视为事务日志。只要RocksDB的状态发生变化,就会被记录下来。当清单文件超过配置的最大值时,将创建一个包含当前RocksDB 状态信息的新清单文件,CURRENT 文件将记录最新的清单文件信息。所有更改同步到文件系统后,旧的清单文件将被清除。
清单={ 当前,清单-* }
CURRENT=标识最新的清单文件
MANIFEST-=此处需要备注某个快照的RocksDB状态以及后续的更新操作。 max_manifest_file_size必须设置,否则RocksDB恢复时间会很长。
Version Edit
RocksDB使用版本来表示任意时刻的特定状态(实际上是快照)。对版本的任何更改都将被视为版本编辑。版本是通过组合一系列版本编辑而构建的。也就是说,一个manifest文件实际上包含了一系列的版本编辑记录。每条记录都将由唯一的编辑编号来标识。
Record Format
版本编辑中的类型均使用特定的编码方法。对于整数来说,通常有两种类型:Var和Fixed。例如,Var32 是int32 整数的可变长度编码。
对于字符串类型,使用size(n) + content。 Size 是整个字符串的实际长度,以Var32 编码。
对于版本编辑记录,它由记录ID 加上可变长度字节组成。记录ID采用Var32编码,实际记录数据需要根据不同类型进行解析。
Record Type
记录有多种类型,包括Comparator、Log Number、Previous Manifest File Number等。例如Comparator,格式为
+-------------+----------------+
| k比较器|数据|
+-------------+----------------+-- Var32 ---|-- String --|不同Type具体分析,可以参考RocksDB源码VersionEdit:DecodeFrom函数。因为比较简单,这里就不解释了。
这里我们重点关注New File的记录类型,因为它会记录实际的SST信息。例如,新文件格式4的格式为:
+-------------+-------------+-------------+----- -- ------+----------------+--------------+---------- -- ----+----------------+
| kNewFile4 |水平|文件编号|文件大小|最小的键|最大的键|最小的序列号|最大序列号|
+-------------+-------------+-------------+----- -- ------+----------------+--------------+---------- -- ----+----------------+
|-- var32 --|-- var32 --|-- var64 --|- var64 -|-- 字符串--|-- 字符串--|-- var64 --|-- var64 --|
+------------+----------------+--------+---------------- ----+--------+-------------+
|kPathID ---|路径大小(n) |路径| k需要压缩| 1 |值(0/1) |
+------------+----------------+--------+---------------- ---+--------+--------------+- var32 -|-- var32 --|- n -|-- var32 --|- 1 -|-- 1 --|具体到我们之前遇到的问题,如果要修复SST,需要读取manifest文件中的New File记录,然后解析出它的实际路径和对应的文件大小,然后它已完成截断。
【深入解析RocksDB:高效键值存储解决方案】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
我一直觉得RocksDB 的存储性能很棒!
有9位网友表示赞同!
刚在项目里用到RocksDB,感觉很轻量化。
有13位网友表示赞同!
学过很多数据库,RocksDB 的架构还是很有特色的。
有18位网友表示赞同!
对于大数据处理来说,RocksDB 效率还是很高的。
有5位网友表示赞同!
我在博客上看到一篇关于 RocksDB 优化文章,现在正在试试看。
有10位网友表示赞同!
想用 RocksDB 来替换下现有的数据库系统,不知道难度怎么样?
有15位网友表示赞同!
听说 RocksDB 的社区很活跃,有许多资料可以参考。
有19位网友表示赞同!
学习RocksDB的API文档还挺有意思!
有13位网友表示赞同!
需要在项目里用到高性能存储,RocksDB 应该是个不错的选择吧。
有9位网友表示赞同!
最近的版本增加了哪些新功能?
有9位网友表示赞同!
对 RocksDB 的移植支持怎么样?
有18位网友表示赞同!
RocksDB 在并发操作方面能提升多少效率?
有20位网友表示赞同!
有没有关于 RocksDB 测试和调优的文章推荐?
有5位网友表示赞同!
使用 RocksDB 需要考虑哪些安全方面的因素?
有9位网友表示赞同!
想了解 RocksDB 的故障恢复机制。
有9位网友表示赞同!
RocksDB 对不同硬件平台的支持怎么样?
有5位网友表示赞同!
ROCKSDB 用来做缓存还是用来持久存储比较合适?
有8位网友表示赞同!
在多进程环境下使用 RocksDB 有什么注意事项?
有9位网友表示赞同!
请问 RocksDB 能支持多种数据类型吗?
有13位网友表示赞同!
想了解关于 RocksDB 的开源许可证信息。
有19位网友表示赞同!