1、leveldb的文件命名
当运行一次leveldb来写入数据时,leveldb可能会生成很多个log文件和SSTable文件,而这些文件的命名都是类似的,都是固定前缀+文件编号+固定后缀的。这些文件的名称是调用函数MakeFileName()来生成的。
static std::string MakeFileName(const std::string& name, uint64_t number,
const char* suffix) {
char buf[100];
snprintf(buf, sizeof(buf), "/%06llu.%s",static_cast<unsigned long long>(number),suffix);
return name + buf;
}
由上可知,文件编号都是按6位数字进行输出的。以log文件为例
std::string LogFileName(const std::string& name, uint64_t number) {
return MakeFileName(name, number, "log");
}
name是数据库的名称,假设为testdb,number为文件编号,假设为3,则生成的文件名为testdb/000003.log。
如果是.sst文件,则文件名是testdb/000003.sst。
因此当我们要获取某个文件时,我们只需要知道文件的编号和文件类型即可。
2、文件编号使用
leveldb中生成的文件都可以通过文件编号和文件类型获得,所有的文件共用一套编号系统,即所有文件的编号都不相同,且是逐渐递增的。
在类leveldb::DBImpl中保存了VersionSet 变量,用于管理所有版本。而leveldb所有文件的文件编号都是通过类VersionSet中的变量next_file_number_来获取的,该变量在VersionSet构造函数中完成初始化,且初始值为2(next_file_number_(2))。
通过代码发现,leveldb把编号1留给了Recover()过程中的Manifest清单文件。
const std::string manifest = DescriptorFileName(dbname_, 1);
Manifest文件记录了leveldb的元信息,包括数据库使用的Comparator名,以及各SSTable文件的管理信息:如Level层数、文件名、最小key和最大key等等。
leveldb中文件编号都是逐渐递增的,通过VersionSet中的函数NewFileNumber()获得:
uint64_t NewFileNumber() { return next_file_number_++; }
3、VersionSet中的编号
VersionSet中保存了多个编号:
uint64_t next_file_number_;//用于生成系统下一个文件的编号
uint64_t manifest_file_number_;//Manifest文件的编号,主要在Recover()时用到
uint64_t last_sequence_;
uint64_t log_number_;
uint64_t prev_log_number_; // 0 or backing store for memtable being compacted
last_sequence_则记录了向leveldb中写入的记录总数,写数据时被使用:
Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
/* ...... */
uint64_t last_sequence = versions_->LastSequence();//首先获得已经写入的记录总数
Writer* last_writer = &w;
if (status.ok() && my_batch != NULL) {
WriteBatch* updates = BuildBatchGroup(&last_writer);
WriteBatchInternal::SetSequence(updates, last_sequence + 1);//对WriteBatch的序号+1
last_sequence += WriteBatchInternal::Count(updates);//加上此次写入的记录数,即为此时已经写入的记录总数
/* ...... */
versions_->SetLastSequence(last_sequence);//将其保存在VersionSet中
}
/* ...... */
}
4、leveldb中的文件
leveldb在运行过程中会产生多种文件,除了之前介绍过的log文件和.sst文件外,还有:
Manifest文件:记录leveldb的信息,包括SSTable文件的管理信息
Current:其中保存的是当前使用的Manifest文件名
<dbname>/log:系统的运行日志,记录系统的运行信息或者错误日志。(注意,不是前面提到的以编号+.log后缀的log文件)