leveldb WriteBatch 隔离
leveldb WriteBatch isolation
如果我通过 WriteBatch 写入大量更改,是否可以保证另一个线程不会在写入磁盘的过程中读取并最终得到一些新值和一些旧值(即将被修改) ?
文档说 WriteBatch 是原子的(全有或全无)但是隔离呢?
保证隔离。
看看下面的代码:
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);
这是write batch的程序,它申请[last_sequence + 1, last_sequence + Count(updates)]
,在所有update操作完成后申请sequence。这意味着读取操作可以在批处理完成之前获取序列 <= last_sequence
,或者在批处理完成后获取序列 >= last_sequence + Count(updates)
都提交到 wal 和 memtable。
如果我通过 WriteBatch 写入大量更改,是否可以保证另一个线程不会在写入磁盘的过程中读取并最终得到一些新值和一些旧值(即将被修改) ?
文档说 WriteBatch 是原子的(全有或全无)但是隔离呢?
保证隔离。
看看下面的代码:
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);
这是write batch的程序,它申请[last_sequence + 1, last_sequence + Count(updates)]
,在所有update操作完成后申请sequence。这意味着读取操作可以在批处理完成之前获取序列 <= last_sequence
,或者在批处理完成后获取序列 >= last_sequence + Count(updates)
都提交到 wal 和 memtable。