〇、前置知识
写数据时分两步:1、将数据追加到日志中;2、将数据插入到内存数据库
sequenceNumber:leveldb数据存放形式是LSM,以追加的形式存储,相同key时以seqnumber来确定先后关系
write操作要记录到log文件中的格式为:
几种类型的key:
- user_key:用户输入的数据key(slice格式)
- paredInternalkey:是对Internalkey的解析(user_key、sequenceNumber、Type)
- Internalkey:内部key,常用来比如key比较的场景
- memtable key:存储在memtable中的key,这个key包含value
- lookup key:用于DBImpl::Get中
一、Memtable.h分析
作用:往内存中添加、查找数据。内部用跳跃表实现,还可以内存估计
每个插入的key-value都会有一个序列号(升序),值类型(0删、1插)
部分函数功能:
- Add():要把key-value编码后插入到内部的跳跃表中,插入的格式为:
- Get():查找key,调用迭代器SEEK(),自己也实现了一个MemTableIterator的类(迭代器)。流程如下:
- 先查询当前在用的memtable,查到返回
- 查询正在转换为SST的memtable中寻找,查到返回,否则在磁盘中寻找。在较低的leve中找到数据后就不需要去更高的level中查找了
二、write_batch.h分析
功能:批量写操作,对外提供的接口需要调用这个函数
rep_:所有更新记录都会编码后写入到这里,编码格式为:
每个recode格式为:
内部调用:
- WriteBatchInternal 辅助类,功能:
- 对rep_的一些操作,获取seq、count;
- InsertInto:把当前batch更新记录到memtable
-
MemTableInserter 辅助类:提供操作的put和del接口(把记录插入到memtable)
- handle类:put()把这个记录放到memtable中(调用add方法)
方法:
- put():操作rep_,增加一个record
- delete()
- Append():合并writeBatch对象
- iterate:将rep_存储的键值对放到hander上执行
三、db_impl.cc/writerBatch合并
- 根据第一个writeBatch调整max_size
- 遍历writer,看能否达到合并的条件,如果有合并就返回tmp_batch_,合并结果放到tmo_batch里