From e673d5d26d55a6ae3aed779455368a610a366642 Mon Sep 17 00:00:00 2001 From: Dhruba Borthakur Date: Mon, 3 Jun 2013 12:57:23 -0700 Subject: [PATCH] Do not submit multiple simultaneous seek-compaction requests. Summary: The code was such that if multi-threaded-compactions as well as seek compaction are enabled then it submits multiple compaction request for the same range of keys. This causes extraneous sst-files to accumulate at various levels. Test Plan: I am not able to write a very good unit test for this one but can easily reproduce this bug with 'dbstress' with the following options. batch=1;maxk=100000000;ops=100000000;ro=0;fm=2;bpl=10485760;of=500000; wbn=3; mbc=20; mb=2097152; wbs=4194304; dds=1; sync=0; t=32; bs=16384; cs=1048576; of=500000; ./db_stress --disable_seek_compaction=0 --mmap_read=0 --threads=$t --block_size=$bs --cache_size=$cs --open_files=$of --verify_checksum=1 --db=/data/mysql/leveldb/dbstress.dir --sync=$sync --disable_wal=1 --disable_data_sync=$dds --write_buffer_size=$wbs --target_file_size_base=$mb --target_file_size_multiplier=$fm --max_write_buffer_number=$wbn --max_background_compactions=$mbc --max_bytes_for_level_base=$bpl --reopen=$ro --ops_per_thread=$ops --max_key=$maxk --test_batches_snapshots=$batch Reviewers: leveldb, emayanke Reviewed By: emayanke Differential Revision: https://reviews.facebook.net/D11055 --- db/version_set.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/db/version_set.cc b/db/version_set.cc index fb277e628..c1d81f48b 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -2061,14 +2061,23 @@ Compaction* VersionSet::PickCompaction() { } // Find compactions needed by seeks - if (c == nullptr && (current_->file_to_compact_ != nullptr)) { + FileMetaData* f = current_->file_to_compact_; + if (c == nullptr && f != nullptr && !f->being_compacted) { + level = current_->file_to_compact_level_; + int parent_index = -1; // Only allow one level 0 compaction at a time. + // Do not pick this file if its parents at level+1 are being compacted. if (level != 0 || compactions_in_progress_[0].empty()) { - c = new Compaction(level, MaxFileSizeForLevel(level), - MaxGrandParentOverlapBytes(level), NumberLevels(), true); - c->inputs_[0].push_back(current_->file_to_compact_); + if(!ParentRangeInCompaction(&f->smallest, &f->largest, level, + &parent_index)) { + c = new Compaction(level, MaxFileSizeForLevel(level), + MaxGrandParentOverlapBytes(level), NumberLevels(), true); + c->inputs_[0].push_back(f); + c->parent_index_ = parent_index; + current_->file_to_compact_ = nullptr; + } } }