leveldb文件类型
上面的log文件,sst文件,临时文件,清单文件末尾都带着序列号,序号是单调递增的(随着next_file_number从1开始递增),以保证不会和之前的文件名重复。另外,注意区分db log与info log:前者是为了防止保障数据安全而实现的二进制Log,后者是打印引擎中间运行状态及警告等信息的文本log。
随着更新与Compaction的进行,LevelDB会不断生成新文件,有时还会删除老文件,所以需要一个文件来记录文件列表,这个列表就是清单文件(manifest文件)的作用,清单会不断变化,DB需要知道最新的清单文件,必须将清单准备好后原子切换,这就是CURRENT文件的作用,LevelDB的清单过程更新如下:
1. 递增清单序号,生成一个新的清单文件。
2. 将此清单文件的名称写入到一个临时文件中。
3. 将临时文件rename为CURRENT。
DB::Open
LevelDB无论是创建数据库,还是打开现有的数据库,都是使用Open方法。代码如下:
Status DB::Open(const Options& options, const std::string& dbname,
DB** dbptr) {
*dbptr = NULL;
DBImpl* impl = new DBImpl(options, dbname);
impl->mutex_.Lock();
VersionEdit edit;
bool save_manifest = false;
// Recover逻辑,如果存在数据库,则Load数据库数据,并对日志进行恢复,否则,创建新的数据库
Status s = impl->Recover(&edit, &save_manifest); //具体可看recover那篇博文
if (s.ok() && impl->mem_ == NULL) {
//impl->mem_ == NULL说明没有继续使用旧日志需创建新的日志
// 从version_set获取一个新的文件序号用于日志文件,所以如果是新建的数据库,则第一个LOG的
//序号为2(1已经被MANIFEST占用,NewDB代码里可以看出)
uint64_t new_log_number = impl->versions_->NewFileNumber();
// 记录日志文件号,创建新的log文件及Writer对象
WritableFile* lfile;
s