ren
ren

Reputation: 3993

leveldb WriteBatch isolation

If I get to write a lot of changes through a WriteBatch is there a guarantee that another thread won't read in the middle of writing to disk and end up with some new values and some old (which are about to be modified) ?

Documentation says WriteBatch is atomic (all or nothing) but what about isolation?

Upvotes: 1

Views: 1086

Answers (1)

sel-fish
sel-fish

Reputation: 4476

Isolation is guaranteed.

Take a look at the code below:

WriteBatch* updates = BuildBatchGroup(&last_writer);
WriteBatchInternal::SetSequence(updates, last_sequence + 1);
last_sequence += WriteBatchInternal::Count(updates);

// Add to log and apply to memtable.  We can release the lock
// during this phase since &w is currently responsible for logging
// and protects against concurrent loggers and concurrent writes
// into mem_.
{
  mutex_.Unlock();
  status = log_->AddRecord(WriteBatchInternal::Contents(updates));
  bool sync_error = false;
  if (status.ok() && options.sync) {
    status = logfile_->Sync();
    if (!status.ok()) {
      sync_error = true;
    }
  }
  if (status.ok()) {
    status = WriteBatchInternal::InsertInto(updates, mem_);
  }
  mutex_.Lock();
  if (sync_error) {
    // The state of the log file is indeterminate: the log record we
    // just added may or may not show up when the DB is re-opened.
    // So we force the DB into a mode where all future writes fail.
    RecordBackgroundError(status);
  }
}
if (updates == tmp_batch_) tmp_batch_->Clear();

versions_->SetLastSequence(last_sequence);

That's procedure of write batch, it apply for [last_sequence + 1, last_sequence + Count(updates)], and will apply the sequence after all the update operation done. Which means that read operation can get sequence <= last_sequence before the batch finished, or get sequence >= last_sequence + Count(updates) after the batch both committed to wal and memtable.

Upvotes: 3

Related Questions