levelDB 浅谈6--imm_ 落盘

316 阅读1分钟

levelDB 数据库的内存中有两块结构 mem_ 和 imm_(两个成员变量都是指针)。用户数据先插入到 mem_ 中,当 mem_ 所指向的 MemTable 达到容量上线时,复制给 imm_,然后 levelDB 利用背景线程将 imm_ 指向的 MemTable 构建成SSTable,落盘到第 0 层。

void DBImpl::CompactMemTable() {
  mutex_.AssertHeld();
  assert(imm_ != nullptr);

  // Save the contents of the memtable as a new Table
  VersionEdit edit;
  Version* base = versions_->current();
  base->Ref();
  Status s = WriteLevel0Table(imm_, &edit, base);
  base->Unref();

  if (s.ok() && shutting_down_.load(std::memory_order_acquire)) {
    s = Status::IOError("Deleting DB during memtable compaction");
  }

  // Replace immutable memtable with the generated Table
  if (s.ok()) {
    edit.SetPrevLogNumber(0);
    edit.SetLogNumber(logfile_number_);  // Earlier logs no longer needed
    // 基于edit构造新的version,并将新version添加到versions_中
    s = versions_->LogAndApply(&edit, &mutex_);
  }

  if (s.ok()) {
    // Commit to the new state
    imm_->Unref();
    imm_ = nullptr;
    has_imm_.store(false, std::memory_order_release);
    RemoveObsoleteFiles();
  } else {
    RecordBackgroundError(s);
  }
}