@@ -147,11 +147,13 @@ DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
147147 background_compaction_scheduled_(false ),
148148 manual_compaction_(nullptr ),
149149 versions_(new VersionSet(dbname_, &options_, table_cache_,
150- &internal_comparator_)) {}
150+ &internal_comparator_)),
151+ suspending_compaction_(false ) {}
151152
152153DBImpl::~DBImpl () {
153154 // Wait for background work to finish.
154155 mutex_.Lock ();
156+ suspending_compaction_.store (false , std::memory_order_release); // make sure that the suspend flag is clear
155157 shutting_down_.store (true , std::memory_order_release);
156158 while (background_compaction_scheduled_) {
157159 background_work_finished_signal_.Wait ();
@@ -670,6 +672,8 @@ void DBImpl::MaybeScheduleCompaction() {
670672 // Already scheduled
671673 } else if (shutting_down_.load (std::memory_order_acquire)) {
672674 // DB is being deleted; no more background compactions
675+ } else if (imm_ == nullptr && suspending_compaction_.load (std::memory_order_acquire)) {
676+ // DB is being suspended; no more background compactions
673677 } else if (!bg_error_.ok ()) {
674678 // Already got an error; no more changes
675679 } else if (imm_ == nullptr && manual_compaction_ == nullptr &&
@@ -681,6 +685,23 @@ void DBImpl::MaybeScheduleCompaction() {
681685 }
682686}
683687
688+ void DBImpl::SuspendCompaction () {
689+ // set suspend flag and wait for any currently executing bg tasks to complete
690+ Log (options_.info_log , " BG suspend compaction\n " );
691+ mutex_.Lock ();
692+ suspending_compaction_.store (true , std::memory_order_release);
693+ mutex_.Unlock ();
694+ Log (options_.info_log , " BG suspended\n " );
695+ }
696+
697+ void DBImpl::ResumeCompaction () {
698+ Log (options_.info_log , " BG resume compaction\n " );
699+ mutex_.Lock ();
700+ suspending_compaction_.store (false , std::memory_order_release);
701+ mutex_.Unlock ();
702+ Log (options_.info_log , " db BG resumed\n " );
703+ }
704+
684705void DBImpl::BGWork (void * db) {
685706 reinterpret_cast <DBImpl*>(db)->BackgroundCall ();
686707}
@@ -700,7 +721,9 @@ void DBImpl::BackgroundCall() {
700721
701722 // Previous compaction may have produced too many files in a level,
702723 // so reschedule another compaction if needed.
703- MaybeScheduleCompaction ();
724+ if (!suspending_compaction_.load (std::memory_order_acquire)) {
725+ MaybeScheduleCompaction ();
726+ }
704727 background_work_finished_signal_.SignalAll ();
705728}
706729
@@ -766,6 +789,8 @@ void DBImpl::BackgroundCompaction() {
766789 // Done
767790 } else if (shutting_down_.load (std::memory_order_acquire)) {
768791 // Ignore compaction errors found during shutting down
792+ } else if (suspending_compaction_.load (std::memory_order_acquire)) {
793+ // Ignore compaction errors found during suspend
769794 } else {
770795 Log (options_.info_log , " Compaction error: %s" , status.ToString ().c_str ());
771796 }
@@ -1353,6 +1378,9 @@ Status DBImpl::MakeRoomForWrite(bool force) {
13531378 (mem_->ApproximateMemoryUsage () <= options_.write_buffer_size )) {
13541379 // There is room in current memtable
13551380 break ;
1381+ } else if (suspending_compaction_.load (std::memory_order_acquire)) {
1382+ // suspending, don't do this now
1383+ break ;
13561384 } else if (imm_ != nullptr ) {
13571385 // We have filled up the current memtable, but the previous
13581386 // one is still being compacted, so we wait.
@@ -1397,7 +1425,9 @@ Status DBImpl::MakeRoomForWrite(bool force) {
13971425 mem_ = new MemTable (internal_comparator_);
13981426 mem_->Ref ();
13991427 force = false ; // Do not force another compaction if have room
1400- MaybeScheduleCompaction ();
1428+ if (!suspending_compaction_.load (std::memory_order_acquire)) {
1429+ MaybeScheduleCompaction ();
1430+ }
14011431 }
14021432 }
14031433 return s;
0 commit comments