From: Andrew Kryczka Date: Wed, 30 Aug 2017 06:02:34 +0000 (-0700) Subject: fix deleterange with memtable prefix bloom X-Git-Tag: rocksdb-5.7.3~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2b81d372eba5148d2e9dad8a3c9fdb92a358dde5;p=rocksdb.git fix deleterange with memtable prefix bloom Summary: the range delete tombstones in memtable should be added to the aggregator even when the memtable's prefix bloom filter tells us the lookup key's not there. This bug could cause data to temporarily reappear until the memtable containing range deletions is flushed. Reported in #2743. Closes https://github.com/facebook/rocksdb/pull/2745 Differential Revision: D5639007 Pulled By: ajkr fbshipit-source-id: 04fc6facb6f978340a3f639536f4ca7c0d73dfc9 --- diff --git a/HISTORY.md b/HISTORY.md index 7d740b512..ca9656862 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,8 @@ # Rocksdb Change Log +## 5.7.3 (08/29/2017) +### Bug Fixes +* Fix transient reappearance of keys covered by range deletions when memtable prefix bloom filter is enabled. + ## 5.7.2 (08/15/2017) ### Bug Fixes * Fix incorrect dropping of deletions issue with FIFO compaction. diff --git a/db/db_range_del_test.cc b/db/db_range_del_test.cc index 0288f80bd..d80c9d144 100644 --- a/db/db_range_del_test.cc +++ b/db/db_range_del_test.cc @@ -868,6 +868,32 @@ TEST_F(DBRangeDelTest, SubcompactionHasEmptyDedicatedRangeDelFile) { db_->ReleaseSnapshot(snapshot); } +TEST_F(DBRangeDelTest, MemtableBloomFilter) { + // regression test for #2743. the range delete tombstones in memtable should + // be added even when Get() skips searching due to its prefix bloom filter + const int kMemtableSize = 1 << 20; // 1MB + const int kMemtablePrefixFilterSize = 1 << 13; // 8KB + const int kNumKeys = 1000; + const int kPrefixLen = 8; + Options options = CurrentOptions(); + options.memtable_prefix_bloom_size_ratio = + static_cast(kMemtablePrefixFilterSize) / kMemtableSize; + options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(kPrefixLen)); + options.write_buffer_size = kMemtableSize; + Reopen(options); + + for (int i = 0; i < kNumKeys; ++i) { + ASSERT_OK(Put(Key(i), "val")); + } + Flush(); + ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(), Key(0), + Key(kNumKeys))); + for (int i = 0; i < kNumKeys; ++i) { + std::string value; + ASSERT_TRUE(db_->Get(ReadOptions(), Key(i), &value).IsNotFound()); + } +} + #endif // ROCKSDB_LITE } // namespace rocksdb diff --git a/db/memtable.cc b/db/memtable.cc index efea6199a..a24989123 100644 --- a/db/memtable.cc +++ b/db/memtable.cc @@ -643,6 +643,14 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s, } PERF_TIMER_GUARD(get_from_memtable_time); + std::unique_ptr range_del_iter( + NewRangeTombstoneIterator(read_opts)); + Status status = range_del_agg->AddTombstones(std::move(range_del_iter)); + if (!status.ok()) { + *s = status; + return false; + } + Slice user_key = key.user_key(); bool found_final_value = false; bool merge_in_progress = s->IsMergeInProgress(); @@ -658,13 +666,6 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s, if (prefix_bloom_) { PERF_COUNTER_ADD(bloom_memtable_hit_count, 1); } - std::unique_ptr range_del_iter( - NewRangeTombstoneIterator(read_opts)); - Status status = range_del_agg->AddTombstones(std::move(range_del_iter)); - if (!status.ok()) { - *s = status; - return false; - } Saver saver; saver.status = s; saver.found_final_value = &found_final_value;