RocksDB代码分析——Flush流程
这里从DBImpl::MaybeScheduleFlushOrCompaction
开始讲起。
DBImpl::MaybeScheduleFlushOrCompaction
可能会scheduleDBImpl::BGWorkFlush
和DBImpl::BGWorkCompaction
。这里主要看Flush。Compaction部分见:{% post_link Storage/'RocksDB代码分析——Compaction流程' %}
DBImpl::BGWorkFlush
中调用了DBImpl::BackgroundCallFlush
。
DBImpl::BackgroundCallFlush
中先上DB锁,然后调用DBImpl::BackgroundFlush
,最后再调用DBImpl::MaybeScheduleFlushOrCompaction
。
DBImpl::BackgroundFlush
中先调用DBImpl::PopFirstFromFlushQueue
从DBImpl::flush_queue_
中取出FlushRequest flush_req
(唯一的取出者),从中再取出ColumnFamilyData
。再把这些ColumnFamilyData
放进bg_flush_args
,作为DBImpl::FlushMemTablesToOutputFiles
的参数。DBImpl::flush_queue_
里的FlushRequest
的来源见:{% post_link Storage/"RocksDB代码分析——写入流程" %}。最后再将这些ColumnFamilyData
给UnrefAndTryDelete
。
DBImpl::FlushMemTablesToOutputFiles
中,如果不是atomic_flush(默认),那么一定只有一个要flush的MemTable。把ColumnFamilyData
拿出来,作为参数传给DBImpl::FlushMemTableToOutputFile
。
构造
FlushJob flush_job
flush_job.PickMemTable()
,把MemTable的VersionEdit
存在FlushJob::edit_
里。
flush_job.Run
,也就是调用FlushJob::Run
调用
FlushJob::WriteLevel0Table
db_mutex_->Unlock();
BuildTable
db_mutex_->Lock();
edit_->AddFile
。这个edit_
实际上是MemTable的VersionEdit调用
MemTableList::TryInstallMemtableFlushResults
将被flush的memory table的
flush_completed_
标记为true
。
从老到新把所有flush_completed_
的immutable memory table的VersionEdit
存进edit_list
,然后通过VersionSet::LogAndApply
commit这些edit,里面调用VersionSet::ProcessManifestWrites
。调用
VersionBuilder::Apply
,里面调用VersionBuilder::Rep::Apply
,里面调用VersionBuilder::Rep::ApplyFileAddition
,最终将file_number存到VersionBuilder::Rep::levels_[level].added_files
里。
调用VersionBuilder::SaveTo
,里面调用VersionBuilder::Rep::SaveTo
,里面调用VersionBuilder::Rep::SaveSSTFilesTo
,先对VersionBuilder::Rep::levels_[level].added_files
排序,L0的SSTable用NewestFirstBySeqNo
排序,其他的用BySmallestKey
排序,然后跟老version里已有的SSTable merge到一个新的version。把
ColumnFamilyData
作为参数调用DBImpl::InstallSuperVersionAndScheduleWork
。因为把MemTable写入到L0层之后总是会想要把这些SSTable给compact到L1层,所以接下来准备schedule compaction。
把ColumnFamilyData
作为参数调用DBImpl::SchedulePendingCompaction
将
ColumnFamilyData
传给DBImpl::AddToCompactionQueue
,从而将其加入到DBImpl::compaction_queue_
中。调用
DBImpl::MaybeScheduleFlushOrCompaction
接下来的compaction流程看这里: