RocksDB写入数据过程DBImpl::Write()源代码分析

Status DBImpl::Write(const WriteOptions& write_options, WriteBatch* my_batch) {
  if (my_batch == nullptr) {
    return Status::Corruption("Batch is nullptr!");
  }
  PERF_TIMER_GUARD(write_pre_and_post_process_time);
  // WriteThread::Writer是一个写任务的抽象结构,代表了用户的一次写操作。其中的batch字段存有
  // 实际需要写入的数据,sync字段指明这个写操作需不需要对事务日志执行fsync/fdatasync操作,而
  // disableWAL指明是否需要写事务日志,done字段在该写操作完成时设置,timeout_hint_us指明了
  // 这个写操作完成时间期限。
  // 最后,in_batch_group的比较有意思。在RocksDB内部,对写入操作做了优化,尽可能地将用户的写入
  // 批量处理。这其中使用了一个队列,即write_thread_内部的WriteThread::Writer*队列。在准备写队列头
  // 的任务时,会试着用BuildBatchGroup()构建一个批量任务组,将紧跟着队头的其他写操作任务加入
  // 到一个BatchGroup,一次性地写入数据库。
  WriteThread::Writer w(&mutex_);
  w.batch = my_batch;
  w.sync = write_options.sync;
  w.disableWAL = write_options.disableWAL;
  w.in_batch_group = false;
  w.done = false;
  w.timeout_hint_us = write_options.timeout_hint_us;

  uint64_t expiration_time = 0;
  bool has_timeout = false;
  if (w.timeout_hint_us == 0) {
    w.timeout_hint_us = WriteThread::kNoTimeOut;
  } else {
    expiration_time = env_->NowMicros() + w.timeout_hint_us;
    has_timeout = true;
  }

  if (!write_options.disableWAL) {
    RecordTick(stats_, WRITE_WITH_WAL);
  }

  // ???
  WriteContext context;
  mutex_.Lock();

  if (!write_options.disableWAL) {
    default_cf_internal_stats_->AddDBStats(InternalStats::WRITE_WITH_WAL, 1);
  }

  // 将当前写入任务@w挂入写队列,并在mutex_上睡眠等待。等待直到:
  // 1) 写操作设置了超时时间,等待超时。或,
  // 2) @w之前的任务都已完成,@w已处于队列头部。或,
  // 3) @w这个写任务被别的写线程完成了。
  // 第3个条件,任务被别的写线程完成,实际上是被之前的写任务合并进一个
  // WriteBatchGroup中去了。此时的@w会被标记成in_batch_group。有意思的是,在EnterWriteThread()
  // 里面,如果因为超时唤醒了,发现当前任务in_batch_group为true,则会继续等待,
  // 因为它已经被别的线程加入BatchGroup准备写入数据库了。
  Status status = write_thread_.EnterWriteThread(&w, expiration_time);
  assert(status.ok() || status.IsTimedOut());
  if (status.IsTimedOut()) {
    mutex_.Unlock();
    RecordTick(stats_, WRITE_TIMEDOUT);
    return Status::T
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值