[leveldb] 2-Open()操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/simonyucsdy/article/details/81587790

Open函数(db/db_impl.cc,1500-1504)

//定义在db/db_impl.cc中
Status DB::Open(const Options& options, const std::string& dbname,
                DB** dbptr)  {
  *dbptr = nullptr;

  DBImpl* impl = new DBImpl(options, dbname);
  //

1504行用到了桥接模式,DB的桥接类DBImpl构造函数():

DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
    : env_(raw_options.env),
      internal_comparator_(raw_options.comparator),
      internal_filter_policy_(raw_options.filter_policy),
      options_(SanitizeOptions(dbname, &internal_comparator_,
                               &internal_filter_policy_, raw_options)),
      owns_info_log_(options_.info_log != raw_options.info_log),
      owns_cache_(options_.block_cache != raw_options.block_cache),
      dbname_(dbname),
      table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
      db_lock_(nullptr),
      shutting_down_(nullptr),
      background_work_finished_signal_(&mutex_),
      mem_(nullptr),
      imm_(nullptr),
      logfile_(nullptr),
      logfile_number_(0),
      log_(nullptr),
      seed_(0),
      tmp_batch_(new WriteBatch),
      background_compaction_scheduled_(false),
      manual_compaction_(nullptr),
      versions_(new VersionSet(dbname_, &options_, table_cache_, &internal_comparator_)) 
{
  has_imm_.Release_Store(nullptr);
}
  • env_, 负责所有IO操作
  • internal_comparator_, 比较器,比较不同key的大小
  • internal_filter_policy_, 自定义文件过滤
  • options_,  动作选择
  • db_lock_, 文件锁
  • shutting_down_, 基于memory barrier的原子指针
  • mem_ , memtable
  • imm_, immemtable
  • tmp_batch_, 所有Put都是以batch写入, 这里建立个临时的
  • manual_compaction_, 
  • has_imm_,是否有正在等待的immemtable
  • table_cache_,SSTable查询缓存
  • versions_,MVCC
Status DB::Open(const Options& options, const std::string& dbname,
                DB** dbptr) {
  *dbptr = nullptr;

  DBImpl* impl = new DBImpl(options, dbname);
  impl->mutex_.Lock(); //上锁
  VersionEdit edit;
  // Recover handles create_if_missing, error_if_exists
  bool save_manifest = false;
  Status s = impl->Recover(&edit, &save_manifest); //恢复操作
  if (s.ok() && impl->mem_ == nullptr) {
    // 恢复成功且没有memtable,则创建log和相应的memtable
    // Create new log and a corresponding memtable.
    uint64_t new_log_number = impl->versions_->NewFileNumber(); 
    WritableFile* lfile;
    // 新建可写文件lfile
    s = options.env->NewWritableFile(LogFileName(dbname, new_log_number), &lfile); 
    if (s.ok()) {
      edit.SetLogNumber(new_log_number); //
      impl->logfile_ = lfile; //DB的log文件
      impl->logfile_number_ = new_log_number; //log文件数目
      impl->log_ = new log::Writer(lfile); //写文件
      impl->mem_ = new MemTable(impl->internal_comparator_); //新建memtable
      impl->mem_->Ref(); //
    }
  }

  if (s.ok() && save_manifest) {
    edit.SetPrevLogNumber(0);  // No older logs needed after recovery.
    edit.SetLogNumber(impl->logfile_number_);
    s = impl->versions_->LogAndApply(&edit, &impl->mutex_);
  }

  if (s.ok()) {
    impl->DeleteObsoleteFiles(); //清理无用文件
    impl->MaybeScheduleCompaction(); //检查是否需要compaction
  }
  impl->mutex_.Unlock(); //解锁
  if (s.ok()) {
    assert(impl->mem_ != nullptr);
    *dbptr = impl;
  } else {
    delete impl;
  }
  return s;
}

这就是整个的Open操作流程,需要着重说一下VersionEdit的概念,由于LSM Tree机制没有任何主索引体系(不使用哈希表), 只要保证Log+SSTable正确, 就一定能得到正确的结果,所以不同version之间的差别就是SSTable的差别, A版本到B版本, A版本对SSTable执行了删除e, d, f的操作, B版本对其执行了增加o, p, q的操作,两者合并就是最终的SSTable,这就使SSTable具有了性能稳定性。

VersionEdit_t0 + VersionEdit_t1 = Data_t1

猜你喜欢

转载自blog.csdn.net/simonyucsdy/article/details/81587790