Skip to content

Commit 299f5c7

Browse files
committed
Create new log file outside the dbmutex.
Summary: All filesystem Io should be done outside the dbmutex. There was one place when we have to roll the transaction log that we were creating the new log file while holding the dbmutex. I rearranged this code so that the act of creating the new transaction log file is done without holding the dbmutex. I also allocate the new memtable outside the dbmutex, this is important because creating the memtable could be heavyweight. Test Plan: make check and dbstress Reviewers: haobo, igor Reviewed By: haobo CC: leveldb, reconnect.grayhat Differential Revision: https://reviews.facebook.net/D14283
1 parent 5b825d6 commit 299f5c7

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

db/db_impl.cc

+23-11
Original file line numberDiff line numberDiff line change
@@ -3077,36 +3077,48 @@ Status DBImpl::MakeRoomForWrite(bool force) {
30773077
}
30783078
allow_soft_rate_limit_delay = false;
30793079
mutex_.Lock();
3080+
30803081
} else {
3081-
// Attempt to switch to a new memtable and trigger compaction of old
3082-
DelayLoggingAndReset();
3082+
unique_ptr<WritableFile> lfile;
3083+
MemTable* memtmp = nullptr;
3084+
3085+
// Attempt to switch to a new memtable and trigger compaction of old.
3086+
// Do this without holding the dbmutex lock.
30833087
assert(versions_->PrevLogNumber() == 0);
30843088
uint64_t new_log_number = versions_->NewFileNumber();
3085-
unique_ptr<WritableFile> lfile;
3086-
EnvOptions soptions(storage_options_);
3087-
soptions.use_mmap_writes = false;
3088-
s = env_->NewWritableFile(
3089+
mutex_.Unlock();
3090+
{
3091+
EnvOptions soptions(storage_options_);
3092+
soptions.use_mmap_writes = false;
3093+
DelayLoggingAndReset();
3094+
s = env_->NewWritableFile(
30893095
LogFileName(options_.wal_dir, new_log_number),
30903096
&lfile,
30913097
soptions
30923098
);
3099+
if (s.ok()) {
3100+
// Our final size should be less than write_buffer_size
3101+
// (compression, etc) but err on the side of caution.
3102+
lfile->SetPreallocationBlockSize(1.1 * options_.write_buffer_size);
3103+
memtmp = new MemTable(
3104+
internal_comparator_, mem_rep_factory_, NumberLevels(), options_);
3105+
}
3106+
}
3107+
mutex_.Lock();
30933108
if (!s.ok()) {
30943109
// Avoid chewing through file number space in a tight loop.
30953110
versions_->ReuseFileNumber(new_log_number);
3111+
assert (!memtmp);
30963112
break;
30973113
}
3098-
// Our final size should be less than write_buffer_size
3099-
// (compression, etc) but err on the side of caution.
3100-
lfile->SetPreallocationBlockSize(1.1 * options_.write_buffer_size);
31013114
logfile_number_ = new_log_number;
31023115
log_.reset(new log::Writer(std::move(lfile)));
31033116
mem_->SetNextLogNumber(logfile_number_);
31043117
imm_.Add(mem_);
31053118
if (force) {
31063119
imm_.FlushRequested();
31073120
}
3108-
mem_ = new MemTable(
3109-
internal_comparator_, mem_rep_factory_, NumberLevels(), options_);
3121+
mem_ = memtmp;
31103122
mem_->Ref();
31113123
Log(options_.info_log,
31123124
"New memtable created with log file: #%lu\n",

0 commit comments

Comments
 (0)