Don't let other compactions run when manual compaction runs

Summary:
Based on discussions from t4982833. This is just a short-term fix, I plan to revamp manual compaction process as part of t4982812.

Also, I think we should schedule automatic compactions at the very end of manual compactions, not when we're done with one level. I made that change as part of this diff. Let me know if you disagree.

Test Plan: make check for now

Reviewers: sdong, tnovak, yhchiang, ljin

Reviewed By: yhchiang

Subscribers: leveldb

Differential Revision: https://reviews.facebook.net/D22401
main
Igor Canadi 10 years ago
parent d5bd6c772b
commit d977e55596
  1. 30
      db/db_impl.cc

@ -1677,6 +1677,13 @@ Status DBImpl::CompactRange(ColumnFamilyHandle* column_family,
} }
LogFlush(options_.info_log); LogFlush(options_.info_log);
{
MutexLock l(&mutex_);
// an automatic compaction that has been scheduled might have been
// preempted by the manual compactions. Need to schedule it back.
MaybeScheduleFlushOrCompaction();
}
return s; return s;
} }
@ -1864,18 +1871,15 @@ Status DBImpl::RunManualCompaction(ColumnFamilyData* cfd, int input_level,
bg_cv_.Wait(); bg_cv_.Wait();
} else { } else {
manual_compaction_ = &manual; manual_compaction_ = &manual;
MaybeScheduleFlushOrCompaction(); assert(bg_compaction_scheduled_ == 0);
bg_compaction_scheduled_++;
env_->Schedule(&DBImpl::BGWorkCompaction, this, Env::Priority::LOW);
} }
} }
assert(!manual.in_progress); assert(!manual.in_progress);
assert(bg_manual_only_ > 0); assert(bg_manual_only_ > 0);
--bg_manual_only_; --bg_manual_only_;
if (bg_manual_only_ == 0) {
// an automatic compaction should have been scheduled might have be
// preempted by the manual compactions. Need to schedule it back.
MaybeScheduleFlushOrCompaction();
}
return manual.status; return manual.status;
} }
@ -1963,11 +1967,11 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
// Schedule BGWorkCompaction if there's a compaction pending (or a memtable // Schedule BGWorkCompaction if there's a compaction pending (or a memtable
// flush, but the HIGH pool is not enabled) // flush, but the HIGH pool is not enabled)
// Do it only if max_background_compactions hasn't been reached and, in case // Do it only if max_background_compactions hasn't been reached and
// bg_manual_only_ > 0, if it's a manual compaction. // bg_manual_only_ == 0
if ((manual_compaction_ || is_compaction_needed || if (!bg_manual_only_ &&
(is_flush_pending && options_.max_background_flushes == 0)) && (is_compaction_needed ||
(!bg_manual_only_ || manual_compaction_)) { (is_flush_pending && options_.max_background_flushes == 0))) {
if (bg_compaction_scheduled_ < options_.max_background_compactions) { if (bg_compaction_scheduled_ < options_.max_background_compactions) {
bg_compaction_scheduled_++; bg_compaction_scheduled_++;
env_->Schedule(&DBImpl::BGWorkCompaction, this, Env::Priority::LOW); env_->Schedule(&DBImpl::BGWorkCompaction, this, Env::Priority::LOW);
@ -2194,6 +2198,10 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
if (is_manual) { if (is_manual) {
// another thread cannot pick up the same work // another thread cannot pick up the same work
manual_compaction_->in_progress = true; manual_compaction_->in_progress = true;
} else if (manual_compaction_ != nullptr) {
// there should be no automatic compactions running when manual compaction
// is running
return Status::OK();
} }
// FLUSH preempts compaction // FLUSH preempts compaction

Loading…
Cancel
Save