当前位置: 首页 > 工具软件 > py-leveldb > 使用案例 >

10-leveldb repair流程及优化方法

弓晔
2023-12-01

leveldb做为一个单机存储引擎,难免遇到数据损坏的情况:比如意外断电、磁盘坏块等。轻者文件损坏无法读取,严重者则导致数据库无法启动。这个时候就需要进行数据修复了。
leveldb提供的修复流程如下:
(1) wal日志文件转化为sstable文件
(2) 扫描所有的sstable文件

  • (a) smallest/largest for the table
  • (b) largest sequence number in the table

(3) 生成MANIFEST文件:

  • log number设置为0
  • next-file-number设置为1 + largest file number
  • last-sequence-number设置为largest sequence
  • compaction指针清除
  • 所有的sstable文件添加到level 0

由上述流程可知,leveldb修复后会将所有的文件添加到level 0,根据level 0层的规则,由于文件之间key有重叠,读取时会在每个文件都读取一次,速度是很慢的;同时,我们知道Leveldb有一个参数L0_stop_trigger,即当0层文件数据达到该值时,写操作是被阻塞的。所以如果数据量很大,修复后0层数据文件很多,此时leveldb是无法正常提供读写服务的。
此时,我们需要等待0层大量的文件经过compaction,0层文件个数恢复到L0_compact_trigger个数以下时数据库完全恢复,才能正常提供服务。
在实际的环境中,100G大小的数据修复后,恢复时间长达一星期之久!这对于现场生产环境来说,是完全无法接受的。因此,我们需要对repair的流程进行优化。
在实际的环境中,当部分数据文件损坏时,其实我们需要做的就是修复指定的文件即可。而无需重构所有文件的层级关系。只有当MANIFEST文件损坏或丢失时,我们才需要采取上述方法进行修复。在大多数情况下MANIFEST文件并没有丢失,或者我们为了避免损坏修复的代价,可以定期对MANIFEST文件进行备份。
下面就来说说在MANIFEST文件并未损坏的情况下的修复方法:
1、解析MANIFEST文件,并生成最终的version(用一个VersinEdit表示,VersionEdit中记录了每个level下的文件)
2、根据VersionEdit中记录的文件逐个扫描table

  • 如果table丢失,则从VersionEdit中移除该表
  • 如果table部分损坏,则解析可读部分重新生成table,并更新VersionEdit中该表的属性

3、如果待恢复目录下仍有一些文件并不在VersionEdit中记录的任一level中,则将该部分文件添加到level 0
4、将VersionEdit生成MANIFEST文件

通过上述步骤,leveldb的修复就完成了。重新启动leveldb后,基本上就可以恢复工作了。整个修复过程可能就在几分钟,与之前的一星期之久,效率大大提升!

因此,当遇到数据损坏的情况时,我们首先应该检查MANIFEST文件是否存在,如果存在,则对我们修复效率的提升帮助巨大。如果该文件丢失,那只能按官方给的方法进行修复了。

 类似资料: