diff --git a/db/db_impl/db_impl_write.cc b/db/db_impl/db_impl_write.cc index fc7495cf0..635f16f01 100644 --- a/db/db_impl/db_impl_write.cc +++ b/db/db_impl/db_impl_write.cc @@ -1796,7 +1796,8 @@ Status DBImpl::DelayWrite(uint64_t num_bytes, // might wait here indefinitely as the background compaction may never // finish successfully, resulting in the stall condition lasting // indefinitely - while (error_handler_.GetBGError().ok() && write_controller_.IsStopped()) { + while (error_handler_.GetBGError().ok() && write_controller_.IsStopped() && + !shutting_down_.load(std::memory_order_relaxed)) { if (write_options.no_slowdown) { return Status::Incomplete("Write stall"); } @@ -1822,9 +1823,13 @@ Status DBImpl::DelayWrite(uint64_t num_bytes, // proceed Status s; if (write_controller_.IsStopped()) { - // If writes are still stopped, it means we bailed due to a background - // error - s = Status::Incomplete(error_handler_.GetBGError().ToString()); + if (!shutting_down_.load(std::memory_order_relaxed)) { + // If writes are still stopped and db not shutdown, it means we bailed + // due to a background error + s = Status::Incomplete(error_handler_.GetBGError().ToString()); + } else { + s = Status::ShutdownInProgress("stalled writes"); + } } if (error_handler_.IsDBStopped()) { s = error_handler_.GetBGError(); diff --git a/db/db_test.cc b/db/db_test.cc index 7de55a82b..a22a42b3c 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -7211,6 +7211,46 @@ TEST_F(DBTest, MemoryUsageWithMaxWriteBufferSizeToMaintain) { } } +TEST_F(DBTest, ShuttingDownNotBlockStalledWrites) { + Options options = CurrentOptions(); + options.disable_auto_compactions = true; + Reopen(options); + Random rnd(403); + + ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( + "BackgroundCallCompaction:1", + [&](void* /* arg */) { env_->SleepForMicroseconds(2 * 1000 * 1000); }); + + ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency( + {{"DBImpl::DelayWrite:Wait", + "DBTest::ShuttingDownNotBlockStalledWrites"}}); + + ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing(); + + for (int i = 0; i < 20; i++) { + for (int j = 0; j < 100; j++) { + std::string value = rnd.RandomString(1000); + ASSERT_OK(Put("key_" + std::to_string(j), value)); + } + Flush(); + } + ASSERT_EQ(GetSstFileCount(dbname_), 20); + + options.level0_stop_writes_trigger = 20; + options.disable_auto_compactions = false; + Reopen(options); + + std::thread thd([&]() { + Status s = Put("key_" + std::to_string(101), "101"); + ASSERT_EQ(s.code(), Status::kShutdownInProgress); + }); + + TEST_SYNC_POINT("DBTest::ShuttingDownNotBlockStalledWrites"); + CancelAllBackgroundWork(db_, true); + LogFlush(options.info_log); + + thd.join(); +} #endif } // namespace ROCKSDB_NAMESPACE