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
This commit is contained in:
parent
1c8dbe2aa2
commit
af012c0f83
@ -8,6 +8,7 @@
|
||||
### Bug Fixes
|
||||
* Fix wrong latencies in `rocksdb.db.get.micros`, `rocksdb.db.write.micros`, and `rocksdb.sst.read.micros`.
|
||||
* Fix incorrect dropping of deletions during intra-L0 compaction.
|
||||
* Fix transient reappearance of keys covered by range deletions when memtable prefix bloom filter is enabled.
|
||||
|
||||
## 5.7.0 (07/13/2017)
|
||||
### Public API Change
|
||||
|
@ -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<double>(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
|
||||
|
@ -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<InternalIterator> 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<InternalIterator> 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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user