RocksDB代码分析——读取流程

阅读量: searchstar 2023-12-07 21:38:51
Categories: Tags:

分析均基于v6.27.3。以下流程为了方便理解均经过了简化。

首先,我们通过调用DB::Open来创建数据库,它返回了一个DB*DB::Open内部调用了DBImpl::Open,在里面构造了一个DBImpl*并转换成DB*返回。所以我们拿到的DB*其实是DBImpl*

然后我们调用DB::Get来读取数据。DB::Get是个virtual函数,它被DBImpl::Get给override了。

DBImpl::Get里调用了DBImpl::GetImpl

DBImpl::GetImpl中,先调用DBImpl::GetAndRefSuperVersion拿到thread local的super version,然后调用MemTable::Get读取memory table和immutable memory table,如果找到了就返回,否则调用Version::Get继续在sv->current里查找。

Version::Get中,首先将key装进GetContext,然后遍历每个key range包含这个key的SSTable,把GetContext作为参数调用TableCache::Get来查找这个SSTable。如果都没找到就返回not found。

TableCache::Get中,调用TableReader::Get

Table默认是BlockBasedTable,所以这里的TableReader应该是BlockBasedTable的reader:

class BlockBasedTable : public TableReader {

BlockBasedTable::Get中,调用BlockBasedTable::NewIndexIterator获得block index的iterator,然后遍历key range包含目标key的data block。对每个遍历到的data block,调用BlockBasedTable::NewDataBlockIterator构造DataBlockIter biter,然后seek next在里面查找key。

BlockBasedTable::NewDataBlockIterator中,调用BlockBasedTable::RetrieveBlock,将块存入CachableEntry<Block> block

BlockBasedTable::RetrieveBlock中,参数use_cache=true,所以调用BlockBasedTable::MaybeReadBlockAndLoadToCache

BlockBasedTable::MaybeReadBlockAndLoadToCache中,参数contents=nullptr,所以调用BlockBasedTable::GetDataBlockFromCache,如果miss的话就调用BlockFetcher::ReadBlockContents

BlockFetcher::ReadBlockContents中,先尝试从persistent cache和prefetch buffer中读取。如果不成功的话,就调用RandomAccessFileReader::Read从文件中读取。