Reputation: 3993
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
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