RocksDB——Flush

RocksDB——Flush

Flush触发流程

image

MemtableList::FlushRequested()

将memtable中请求flush的flagflush_requested_标记为true

DBImpl::SchedulePendingFlush()

db/db_impl_compaction_flush.cc

将当前cfd加入PendingFlushQueue

DBImpl::MaybeScheduleFlushOrCompaction()

db/db_impl_compaction_flush.cc

触发flush或者compaction

首先判断是否处于特殊阶段,这些阶段直接返回:

  • 打开数据库(opened_successfully_ == true):避免compaction与open的数据竞争
  • 暂停后台任务(bg_work_paused_ > 0)
  • 关闭数据库的时候(shutting_down_ == true)

通过Env::GetBackgroudThreads获取HIGH pri线程池中线程数

如果满足:

  1. HIGH pri线程池中还有线程资源;
  2. 未处理的flush请求(unscheduled_flushes_) > 0 ;
  3. 正在处理的flush请求数(bg_flush_scheduled_)小于限制的最大同时处理flush数(bg_job_limits.max_flushes)

则触发HIGH pri的flush,直到上面的条件之一不满足为止

此时后台线程执行函数BGWorkFlush,使用HIGH pri线程池

如果HIGH pri线程池已经没有线程了,则尝试使用LOW pri线程池

如果满足:

  1. 未处理flush请求(unscheduled_flushes_) > 0
  2. 后台flush总数(bg_flush_scheduled_)以及后台compaction总数(bg_compaction_scheduled_)之和小于最大的flush限制个数(bg_job_limits.max_flushes)

则触发LOW pri的flush,直到上面的条件之一不满足为止

此时后台线程执行函数BGWorkFlush,使用LOW pri线程池

如果当前没有flush待处理,则处理compaction,如果满足:

  1. 当前正在处理的compaction总数(bg_compaction_scheduled_)小于最大可运行compaction总数(bg_job_limits.max_compactions)
  2. 待处理compaction总数大于0(unscheduled_compactions_)

则触发compaction,直到上述条件不满足为止

此时后台线程执行函数BGWorkCompaction,使用LOW pri线程池

Flush的执行过程

BGWorkFlush

db/db_impl_compaction_flush.cc

这个函数交给子线程执行,然后子线程可以调用BackgroundCallFlush执行真正的Flush操作

BackgroundCallFlush

db/db_impl_compaction_flush.cc

首先记录插入到pending_outputs_中的number(这个number是新生成table的number,处理完之后再释放)

增加正在处理的flush计数:num_running_flushes++

调用BackgroundFlush进行flush操作,传入参数:made_progress(默认false)、job_contextlog_buffer

当发生错误返回的状态不是ok的时候处理错误

ReleaseFieNumberFromPendingOutputs(pending_outputs_inserted_elem)从pending_outputs_中删除掉前面记录的elem,也就是当前memtable已经成功处理

FindAbsoleteFiles:处理flush失败时候的临时文件问题

num_running_flushes--;

bg_flushe_scheduled--;

至此处理完一个flush操作(无论失败还是成功),则将正在运行的flush任务计数减1,同时被安排的flush任务数减1

最后调用MaybeScheduleFlushOrCompaction,尝试触发下一次flush或者compaction

BackgroundFlush

db/db_impl_compaction_flush.cc

在排除所有的非正常情况下开始执行flush的准备工作,首先就是通过while循环获取一个cfd,获取cfd的函数为DBImpl::PopFirstFromFlushQueue,该函数从flush_queue_中pop出一个cfd。在确保当前cfd不是被drop或者是没有达到flush状态的cfd,则选择该cfd进行flush

通过GetLastMutableCFOptions获取当前cfd的设置信息,然后调用FlushMemtableToOutputFile,对当前cfd进行flush操作,传入参数:

cfd
mutable_cf_options
made_progress
job_context
log_buffer

Flush函数实现

FlushMemtableToOutputFile

【sequence number & snapshot 】

earlist_write_conflict_snapshot

通过snapshot_checker获取所有的snapshot

snapshot_checker

【构造FlushJob】

传入参数:

dbname_
cfd
immutable_db_options_
mutable_cf_options
env_options_for_compaction_
versions_.get()
&mutex_
&shutting_down_
snapshot_seqs
earlist_write_conflict_snapshot
snapshot_checker
job_context
log_buffer

// 获取文件路径相关
directories.GetDir()
GetDataDir(cfd, 0U)
    
GetCompressionFlush(*cfd->ioptions(), mutable_cf_options)
stats_
&event_logger_
mutable_cf_options.report_bg_io_stats

FlushJob是进行Flush操作的主体结构,包含了进行Flush操作的主要的操作的封装

【flushjob.PickMemtable】从传入的cfd中选择待flush的immutable memtable,详见后文的FlushJob解析

【NotifyOnFlushBegins】:通知listener flush开始

【flushjob.run】传入空的file_meta(FileMetaData)

【InstallSuperVersionAndScheduleWork】:构建新的SuperVersion结构并触发新的flush以及compaction

【NotifyOnFlushCompleted】:通知listener flush完成

【sst_file_manager.addfile】:更新sfm中的磁盘空间使用情况

FlushJob(有test)

(db/flush_job.h, db/flush_job.cc)

API
  • PickMemtable

该函数主要作用是获取需要进行flush的memtable,此处与leveldb不同的是,一个cf里可能包含多个待flush的memtable,所以这里选出来的也可能有多个memtable

获取memtbale的过程是调用cfd->imm()->PickMemtableToFlush,获取一个memtable的list

从memtable列表中获取第一个memtable,使用其edit结构来保存本次flush的元信息(lognumber、cf_id)

调用version_set的NewFileNumber接口为新的文件生成一个filenumber(同时可以指定对应level的路径)

  • Run

WriteLevel0Table:写数据的过程

WriteLevel0Table

该函数为真正进行读写数据的函数,在该函数内将FlushJob中挑选出来的所有Memtable进行Merge然后构造成sstable并写到L0

首先构造一个write_hint,调用的函数接口是cfd_->CaculateSSTWriteHint,传入参数0

然后遍历所有的memtable,并获取每个memtable的iterator。在遍历的过程中同时还构造memtable的RangeTombstoneIterator,如果不为空表示有range delete操作,则将这个iterator添加到另一个vector中

使用所有的memtable的iterator构造MergingIterator,以及所有的range_del_iterator构造MergingIterator

调用BuildTable函数构造SSTable

处理完成 之后如果output_file_directory不为空则同步该目录(output_file_directory_->Fsync())

调用edit_->AddFile,将生成的文件添加到L0

记录本次Flush的状态

WriteHint

WriteHint是用来提示RocksDB中写数据位置的一项优化措施

首先看定义:

 enum WriteLifeTimeHint {
    WLTH_NOT_SET = 0, // No hint information set
    WLTH_NONE,        // No hints about write life time
    WLTH_SHORT,       // Data written has a short life time
    WLTH_MEDIUM,      // Data written has a medium life time
    WLTH_LONG,        // Data written has a long life time
    WLTH_EXTREME,     // Data written has an extremely long life time
  };

write hint以enum的形式定义,每个选项表示对应数据的生命周期的长度

在计算SST的write hint的时候是根据sst写入的目标level实现的,该模式只适用于leveled compaction,对于L0、L1是WLTH_MEDIUM,L2是WLTH,LONG而L3及以上是WLTH_EXTREME

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容