随着运行时间的增加,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的更多相关文章

  1. leveldb 学习记录(三) MemTable 与 Immutable Memtable

    前文: leveldb 学习记录(一) skiplist leveldb 学习记录(二) Slice 存储格式: leveldb数据在内存中以 Memtable存储(核心结构是skiplist 已介绍 ...

  2. leveldb 学习记录(四) skiplist补与变长数字

    在leveldb 学习记录(一) skiplist 已经将skiplist的插入 查找等操作流程用图示说明 这里在介绍 下skiplist的代码 里面有几个模块 template<typenam ...

  3. leveldb 学习记录(四)Log文件

    前文记录 leveldb 学习记录(一) skiplistleveldb 学习记录(二) Sliceleveldb 学习记录(三) MemTable 与 Immutable Memtablelevel ...

  4. leveldb 学习记录(五)SSTable格式介绍

    本节主要记录SSTable的结构 为下一步代码阅读打好基础,考虑到已经有大量优秀博客解析透彻 就不再编写了 这里推荐 https://blog.csdn.net/tankles/article/det ...

  5. leveldb 学习记录(七) SSTable构造

    使用TableBuilder构造一个Table struct TableBuilder::Rep { // TableBuilder内部使用的结构,记录当前的一些状态等 Options options ...

  6. zeromq学习记录(八)负载均衡 附ZMQ_ROUTER的流程分析

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  7. leveldb 学习记录(一) skiplist

    leveldb LevelDb是一个持久化存储的KV系统,并非完全将数据放置于内存中,部分数据也会存储到磁盘上. 想了解这个由谷歌大神编写的经典项目. 可以从数据结构以及数据结构的处理下手,也可以从示 ...

  8. leveldb 学习记录(二) Slice

    基本每个KV库都有一个简洁的字符串管理类 比如redis的sds  比如leveldb的slice 管理一个字符串指针和数据长度 通过对字符串指针 长度的管理实现一般的创建 判断是否为空 获取第N个位 ...

  9. leveldb 学习记录(六)SSTable:Block操作

    block结构示意图 sstable中Block 头文件如下: class Block { public: // Initialize the block with the specified con ...

随机推荐

  1. 黄聪:用 CSS 实现元素垂直居中,有哪些好的方案?

    1.不知道自己高度和父容器高度的情况下, 利用绝对定位只需要以下三行: parentElement{ position:relative; } childElement{ position: abso ...

  2. kafka partition(分区)与 group(转)

    原文  https://www.cnblogs.com/liuwei6/p/6900686.html 一. 1.原理图 2.原理描述 一个topic 可以配置几个partition,produce发送 ...

  3. java中随机二维数组中寻找最大值并输出坐标

    public static void main(String[] args) { int x=0; int y=0; int a[][]=new int[5][5]; int max=-Integer ...

  4. react购物车

    import React, { Component } from 'react';   import {Tabs} from './Tabs'   import 'whatwg-fetch'   im ...

  5. Python 内置os模块的简单实用

    获取路径&目录添加文件 在自动化测试的过程,考虑到工程文件的移动或者在其他人的工作环境中运行,所以我们的路径要灵活,不能把路径写死. 推荐使用Python的内置模块OS 参照图 import ...

  6. 使用httpClient发送post请求连接restful接口

    public static String httpPost(String url,String arg){ InputStream is; BufferedReader br; StringBuild ...

  7. 《面向对象程序设计(Java)》第四周学习总结

    第一部分 第四章部分理论知识 1.面向对象程序设计概述:java是完全面向对象的,必须熟悉OOP才能编写java程序. 类:由类构造对象的过程称为创建类的实例. 封装:封装是将数据和行为组合在一个包中 ...

  8. 阿里云服务器 CentOS 安装Mysql 5.6

    下载:https://dev.mysql.com/downloads/file/?id=471181   第一步: 安装mysql5姿势是要先安装带有可用的mysql5系列社区版资源的rpm包 [ro ...

  9. codeforces 1041A Heist

    electronic a.电子的 heist v.抢劫 in ascending order 升序 indice n.标记 device n.装置设备 staff n.职员 in arbitrary ...

  10. source tree使用经验

    FeatureXXX具体功能开发分支,从develop分支拉,功能开发自测完后合并到develop分支.来不及上线的feature分支不要合并到develop. develop开发分支,上面代码都是已 ...