Fix assert failure when DBImpl::SyncWAL() conflicts with log rolling
Summary: DBImpl::SyncWAL() releases db mutex before calling DBImpl::MarkLogsSynced(), while inside DBImpl::MarkLogsSynced() we assert there is none or one outstanding log file. However, a memtable switch can happen in between and causing two or outstanding logs there, failing the assert. The diff adds a unit test that repros the issue and fix the assert so that the unit test passes. Test Plan: Run the new tests. Reviewers: anthony, kolmike, yhchiang, IslamAbdelRahman, kradhakrishnan, andrewkr Reviewed By: andrewkr Subscribers: leveldb, dhruba Differential Revision: https://reviews.facebook.net/D54621
This commit is contained in:
parent
2568985ab3
commit
38201b3599
@ -2542,6 +2542,36 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
|
||||
cfd->RecalculateWriteStallConditions(mutable_cf_options);
|
||||
ASSERT_EQ(2, dbfull()->BGCompactionsAllowed());
|
||||
}
|
||||
|
||||
TEST_F(ColumnFamilyTest, LogSyncConflictFlush) {
|
||||
Open();
|
||||
CreateColumnFamiliesAndReopen({"one", "two"});
|
||||
|
||||
Put(0, "", "");
|
||||
Put(1, "foo", "bar");
|
||||
|
||||
rocksdb::SyncPoint::GetInstance()->LoadDependency(
|
||||
{{"DBImpl::SyncWAL:BeforeMarkLogsSynced:1",
|
||||
"ColumnFamilyTest::LogSyncConflictFlush:1"},
|
||||
{"ColumnFamilyTest::LogSyncConflictFlush:2",
|
||||
"DBImpl::SyncWAL:BeforeMarkLogsSynced:2"}});
|
||||
|
||||
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
|
||||
|
||||
std::thread thread([&] { db_->SyncWAL(); });
|
||||
|
||||
TEST_SYNC_POINT("ColumnFamilyTest::LogSyncConflictFlush:1");
|
||||
Flush(1);
|
||||
Put(1, "foo", "bar");
|
||||
Flush(1);
|
||||
|
||||
TEST_SYNC_POINT("ColumnFamilyTest::LogSyncConflictFlush:2");
|
||||
|
||||
thread.join();
|
||||
|
||||
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
|
||||
Close();
|
||||
}
|
||||
} // namespace rocksdb
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
@ -2202,6 +2202,9 @@ Status DBImpl::SyncWAL() {
|
||||
status = directories_.GetWalDir()->Fsync();
|
||||
}
|
||||
|
||||
TEST_SYNC_POINT("DBImpl::SyncWAL:BeforeMarkLogsSynced:1");
|
||||
TEST_SYNC_POINT("DBImpl::SyncWAL:BeforeMarkLogsSynced:2");
|
||||
|
||||
{
|
||||
InstrumentedMutexLock l(&mutex_);
|
||||
MarkLogsSynced(current_log_number, need_log_dir_sync, status);
|
||||
@ -2229,7 +2232,8 @@ void DBImpl::MarkLogsSynced(
|
||||
++it;
|
||||
}
|
||||
}
|
||||
assert(logs_.empty() || (logs_.size() == 1 && !logs_[0].getting_synced));
|
||||
assert(logs_.empty() || logs_[0].number > up_to ||
|
||||
(logs_.size() == 1 && !logs_[0].getting_synced));
|
||||
log_sync_cv_.SignalAll();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user