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 ...
随机推荐
- 实战 ant design pro 中的坑
1.替换mock数据: 1.将:.roadhogrc.mock.js 中的代理模式替换 当不使用代理的时候就会将所有 /api/的链接换成 http://localhost:8080/ export ...
- sequelize的mssql配置
配置文件 development: { username: process.env.LOCAL_USERNAME, password: process.env.LOCAL_PASSWORD, data ...
- dependency walker检查dll依赖关系目录设置的问题
废话少说,直接上图 图中来看,似乎IESHIMS.DLL文件不存在报错,实际是因为没有加载IESHIMS.DLL所在的路径. 在我的电脑里面搜索有两个同名的dll,一个是32位的,一个是64位的. C ...
- springboot+mockito 异常解决方案
系统启动的异常日志如下 javax.net.ssl.* java.lang.IllegalStateException: Failed to load ApplicationContext at or ...
- 树莓派apt-get The value '\stable' is invalid for APT 错误
对apt-get进行任何操作都会报错: pi@raspberrypi:~ $ sudo apt-get upgrade Reading package lists... Done E: The val ...
- [SQL]查询整个数据库中某个特定值所在的表和字段的方法
查询整个数据库中某个特定值所在的表和字段的方法 当数据库做的太庞大的时候,难免会出现忘记哪个值会存入哪个表的情况,于是在网上找到的如下解决办法. 通过做一个存储过程,只需要传入一个想要查找的值,即可查 ...
- Action Form的过程
1.读取配置(初始化ModuleConfig对象) Struts框架总控制器(ActionServlet)是一个Servlet, 在web.xml中配置成自动启动的Servlet. 读取配置文件(st ...
- 发布者订阅者模式之JAVA实现
1.发布者接口 package com.shoshana.publishsubscribe; public interface IPublisher<M> { public voi ...
- Android开发 assets目录
Android资源文件分类: Android资源文件大致可以分为两种: 第一种是res目录下存放的可编译的资源文件: 这种资源文件系统会在R.Java里面自动生成该资源文件的ID,所以访问这种资源文件 ...
- 代码: 两列图片瀑布流(一次后台取数据,图片懒加载。下拉后分批显示图片。图片高度未知,当图片onload后才显示容器)
代码: 两列图片瀑布流(一次后台取数据,无ajax,图片懒加载.下拉后分批显示图片.图片高度未知,当图片onload后才显示容器) [思路]: 图片瀑布流,网上代码有多种实现方式,也有各类插件.没找到 ...