leveldb 学习记录(八) compact
随着运行时间的增加,memtable会慢慢 转化成 sstable。
sstable会越来越多 我们就需要进行整合 compact
代码会在写入查询key值 db写入时等多出位置调用MaybeScheduleCompaction ()
检测是否需要进行compact
void DBImpl::MaybeScheduleCompaction() {
mutex_.AssertHeld();
if (bg_compaction_scheduled_) {
// Already scheduled
} else if (shutting_down_.Acquire_Load()) {
// DB is being deleted; no more background compactions
} else if (imm_ == NULL &&
manual_compaction_ == NULL &&
!versions_->NeedsCompaction()) {
// No work to be done
} else {
bg_compaction_scheduled_ = true;
env_->Schedule(&DBImpl::BGWork, this);
}
}
void DBImpl::BGWork(void* db) {
reinterpret_cast<DBImpl*>(db)->BackgroundCall();
}
void DBImpl::BackgroundCall() {
MutexLock l(&mutex_);
assert(bg_compaction_scheduled_);
if (!shutting_down_.Acquire_Load()) {
BackgroundCompaction();
}
bg_compaction_scheduled_ = false;
// Previous compaction may have produced too many files in a level,
// so reschedule another compaction if needed.
MaybeScheduleCompaction();
bg_cv_.SignalAll();
}
实际进行compact的函数是 void DBImpl::BackgroundCompaction()

1 手动触发情况下 会填写class DBImpl下的一个变量 ManualCompaction manual_compaction_
struct ManualCompaction {
int level;
bool done;
const InternalKey* begin; // NULL means beginning of key range
const InternalKey* end; // NULL means end of key range
InternalKey tmp_storage; // Used to keep track of compaction progress
};
为了避免外部指定的 key-range 过大,一次 compact 过多的 sstable 文件, manual_compaction 可能不会一次做完,所以有 done 来标
识是否已经全部完成, tmp_storage 保存上一次 compact 到的 end-key,即下一次的 startkey。
指定的beg end KEY会赋值到 versions_中,以便后面进行compact。 versions_->CompactRange(m->level, m->begin, m->end);
2 通过 versions_->PickCompaction() 选择需要compact的level 和 key range
Compaction* VersionSet::PickCompaction() {
Compaction* c;
int level;
// We prefer compactions triggered by too much data in a level over
// the compactions triggered by seeks.
const bool size_compaction = (current_->compaction_score_ >= );
const bool seek_compaction = (current_->file_to_compact_ != NULL);
if (size_compaction) {
level = current_->compaction_level_;
assert(level >= );
assert(level+ < config::kNumLevels);
c = new Compaction(level);
// Pick the first file that comes after compact_pointer_[level]
for (size_t i = ; i < current_->files_[level].size(); i++) {
FileMetaData* f = current_->files_[level][i];
if (compact_pointer_[level].empty() ||
icmp_.Compare(f->largest.Encode(), compact_pointer_[level]) > ) {
c->inputs_[].push_back(f);
break;
}
}
if (c->inputs_[].empty()) {
// Wrap-around to the beginning of the key space
c->inputs_[].push_back(current_->files_[level][]);
}
} else if (seek_compaction) {
level = current_->file_to_compact_level_;
c = new Compaction(level);
c->inputs_[].push_back(current_->file_to_compact_);
} else {
return NULL;
}
c->input_version_ = current_;
c->input_version_->Ref();
// Files in level 0 may overlap each other, so pick up all overlapping ones
if (level == ) {
InternalKey smallest, largest;
GetRange(c->inputs_[], &smallest, &largest);
// Note that the next call will discard the file we placed in
// c->inputs_[0] earlier and replace it with an overlapping set
// which will include the picked file.
current_->GetOverlappingInputs(, &smallest, &largest, &c->inputs_[]);
assert(!c->inputs_[].empty());
}
SetupOtherInputs(c);
return c;
}
PickCompaction函数中 根据 文件尺寸和被seek多次 来确认compact的文件
使用 c = new Compaction(level) 记录要compact的level和文件指针
todo 实际的compact操作 CompactMemTable() DoCompactionWork()
参考
《leveldb实现解析》 淘宝 那岩
leveldb 学习记录(八) compact的更多相关文章
- leveldb 学习记录(三) MemTable 与 Immutable Memtable
前文: leveldb 学习记录(一) skiplist leveldb 学习记录(二) Slice 存储格式: leveldb数据在内存中以 Memtable存储(核心结构是skiplist 已介绍 ...
- leveldb 学习记录(四) skiplist补与变长数字
在leveldb 学习记录(一) skiplist 已经将skiplist的插入 查找等操作流程用图示说明 这里在介绍 下skiplist的代码 里面有几个模块 template<typenam ...
- leveldb 学习记录(四)Log文件
前文记录 leveldb 学习记录(一) skiplistleveldb 学习记录(二) Sliceleveldb 学习记录(三) MemTable 与 Immutable Memtablelevel ...
- leveldb 学习记录(五)SSTable格式介绍
本节主要记录SSTable的结构 为下一步代码阅读打好基础,考虑到已经有大量优秀博客解析透彻 就不再编写了 这里推荐 https://blog.csdn.net/tankles/article/det ...
- leveldb 学习记录(七) SSTable构造
使用TableBuilder构造一个Table struct TableBuilder::Rep { // TableBuilder内部使用的结构,记录当前的一些状态等 Options options ...
- zeromq学习记录(八)负载均衡 附ZMQ_ROUTER的流程分析
/************************************************************** 技术博客 http://www.cnblogs.com/itdef/ ...
- leveldb 学习记录(一) skiplist
leveldb LevelDb是一个持久化存储的KV系统,并非完全将数据放置于内存中,部分数据也会存储到磁盘上. 想了解这个由谷歌大神编写的经典项目. 可以从数据结构以及数据结构的处理下手,也可以从示 ...
- leveldb 学习记录(二) Slice
基本每个KV库都有一个简洁的字符串管理类 比如redis的sds 比如leveldb的slice 管理一个字符串指针和数据长度 通过对字符串指针 长度的管理实现一般的创建 判断是否为空 获取第N个位 ...
- leveldb 学习记录(六)SSTable:Block操作
block结构示意图 sstable中Block 头文件如下: class Block { public: // Initialize the block with the specified con ...
随机推荐
- git tag 常用操作
1.获取最新tag(获取不到就多获取几次) git fetch origin 或者 git fetch origin <tagname> 2. checkout tag到本地分支(如果看 ...
- xcopy命令总结
xcopy命令总结1.拷贝多个文件和目录用xcopy /yhie或者xcopy /yhis命令,注意目标路径要以\结尾,例如:xcopy /yhie *.* e:\xxx\2.拷贝多个固定名字的文件用 ...
- ADB server didn't ACK failed to start daemon 5037
错误信息: C:\Users\lizy>adb devices adb devicesadb server is out of date. killing... ADB server didn ...
- Web项目中得到访问者的真实ip
Web项目中得到访问者的真实ip 描述:最近要实现个功能是要记录管理员登录的真实ip,但在项目中如果直接使用request.getRemoteAddr()获得ip的话,获得的可能不是真实ip,是因为使 ...
- [C#]WinForm 中 comboBox控件之数据绑定
[C#]WinForm 中 comboBox控件之数据绑定 一.IList 现在我们直接创建一个List集合,然后绑定 IList<string> list = new List<s ...
- oracle之分析函数解析及其应用场景
ORACLE 分析函数FIRST_VALUE,LAST_VALUE用法sum overavg over first_value overlast_value over...聚合函数结合over就是分析 ...
- gradle-4.1-all.zip离线包下载 极速 android studio2.3 3.0编译必备
http://download.csdn.net/download/yongheng289/10039982 gradle-4.1-all.zip离线包下载 极速 android studio2.3 ...
- 工具函数(获取url , 时间格式化,随机数)
(function(window,$){ function Tools() { } // url Tools.prototype.readUrlToParams = function() { var ...
- python:爬虫获取淘宝/天猫的商品信息
[需求]输入关键字,如书包,可以搜索出对应商品的信息,包括:商品标题.商品链接.价格范围:且最终的商品信息需要符合:包邮.价格差不会超过某数值 #coding=utf-8 ""&q ...
- 代码: !AJAX
http://www.cnblogs.com/cwp-bg/p/7668840.html ajax和jsonp使用总结 2017-10-17 var requestUrl="http://l ...