由之前对Compaction的介绍:LevelDb之Compaction 可知,Compaction操作主要是用来合并文件的。同时Compaction可以分为两种:
1)将Memtable中的数据导出到SSTable文件中
2)合并不同level的SSTable文件
在写数据时,可能会导致Memtable写满,此时会需要将Memtable转化为SSTable。
由之前对FileMetaData数据结构的分析可知,当一个.sst文件的查找次数超过最大允许值时,也需要将其合并。
因此在读数据时,也可能会触发合并。
在DBImpl::Write()中首先会调用到DBImpl::MakeRoomForWrite(bool force)来确保有空间可以写入。
Status status = MakeRoomForWrite(my_batch == NULL);
1、DBImpl::MakeRoomForWrite() 和 DBImpl::Get()
1)当有数据要写入时,my_batch != NULL,则force为false。force==true,则没有数据需要写入,表示只是为了进行合并。DBImpl::MakeRoomForWrite()的实现如下(暂时考虑有数据写入,即force = false的情况):Status DBImpl::MakeRoomForWrite(bool force) { //false
mutex_.AssertHeld();
bool allow_delay = !force; //true
Status s;
while (true) {
if (!bg_error_.ok()) {
s = bg_error_;
break;
} else if (
allow_delay && //true
versions_->NumLevelFiles(0) >= config::kL0_SlowdownWritesTrigger) {//当L0的文件数到达8个时,则会减慢写入速度,表现的是延迟一段时间再写入
mutex_.Unlock(); //释放锁,则在休眠时可以进行其他操作
env_->SleepForMicroseconds(1000);//休眠1ms
allow_delay = false; //变为false,则下次循环不会进入这里,保证不会