mirror of
https://github.com/facebook/rocksdb.git
synced 2026-11-07 11:32:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acef93ed65 | ||
|
|
cf38a47a64 | ||
|
|
b722a18f67 | ||
|
|
2b81d372eb |
No files matched your search
@@ -1,4 +1,9 @@
|
||||
# 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.
|
||||
* Fix potentially wrong file smallest key when range deletions separated by snapshot are written together.
|
||||
|
||||
## 5.7.2 (08/15/2017)
|
||||
### Bug Fixes
|
||||
* Fix incorrect dropping of deletions issue with FIFO compaction.
|
||||
|
||||
@@ -868,6 +868,66 @@ 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());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DBRangeDelTest, UnorderedTombstones) {
|
||||
// Regression test for #2752. Range delete tombstones between
|
||||
// different snapshot stripes are not stored in order, so the first
|
||||
// tombstone of each snapshot stripe should be checked as a smallest
|
||||
// candidate.
|
||||
Options options = CurrentOptions();
|
||||
DestroyAndReopen(options);
|
||||
|
||||
auto cf = db_->DefaultColumnFamily();
|
||||
|
||||
ASSERT_OK(db_->Put(WriteOptions(), cf, "a", "a"));
|
||||
ASSERT_OK(db_->Flush(FlushOptions(), cf));
|
||||
ASSERT_EQ(1, NumTableFilesAtLevel(0));
|
||||
ASSERT_OK(dbfull()->TEST_CompactRange(0, nullptr, nullptr));
|
||||
ASSERT_EQ(1, NumTableFilesAtLevel(1));
|
||||
|
||||
ASSERT_OK(db_->DeleteRange(WriteOptions(), cf, "b", "c"));
|
||||
// Hold a snapshot to separate these two delete ranges.
|
||||
auto snapshot = db_->GetSnapshot();
|
||||
ASSERT_OK(db_->DeleteRange(WriteOptions(), cf, "a", "b"));
|
||||
ASSERT_OK(db_->Flush(FlushOptions(), cf));
|
||||
db_->ReleaseSnapshot(snapshot);
|
||||
|
||||
std::vector<std::vector<FileMetaData>> files;
|
||||
dbfull()->TEST_GetFilesMetaData(cf, &files);
|
||||
ASSERT_EQ(1, files[0].size());
|
||||
ASSERT_EQ("a", files[0][0].smallest.user_key());
|
||||
ASSERT_EQ("c", files[0][0].largest.user_key());
|
||||
|
||||
std::string v;
|
||||
auto s = db_->Get(ReadOptions(), "a", &v);
|
||||
ASSERT_TRUE(s.IsNotFound());
|
||||
}
|
||||
|
||||
#endif // ROCKSDB_LITE
|
||||
|
||||
} // namespace rocksdb
|
||||
|
||||
+8
-7
@@ -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;
|
||||
|
||||
@@ -412,8 +412,8 @@ void RangeDelAggregator::AddToBuilder(
|
||||
|
||||
// Note the order in which tombstones are stored is insignificant since we
|
||||
// insert them into a std::map on the read path.
|
||||
bool first_added = false;
|
||||
while (stripe_map_iter != rep_->stripe_map_.end()) {
|
||||
bool first_added = false;
|
||||
for (auto tombstone_map_iter = stripe_map_iter->second.raw_map.begin();
|
||||
tombstone_map_iter != stripe_map_iter->second.raw_map.end();
|
||||
++tombstone_map_iter) {
|
||||
@@ -452,7 +452,7 @@ void RangeDelAggregator::AddToBuilder(
|
||||
builder->Add(ikey_and_end_key.first.Encode(), ikey_and_end_key.second);
|
||||
if (!first_added) {
|
||||
first_added = true;
|
||||
InternalKey smallest_candidate = std::move(ikey_and_end_key.first);;
|
||||
InternalKey smallest_candidate = std::move(ikey_and_end_key.first);
|
||||
if (lower_bound != nullptr &&
|
||||
icmp_.user_comparator()->Compare(smallest_candidate.user_key(),
|
||||
*lower_bound) <= 0) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define ROCKSDB_MAJOR 5
|
||||
#define ROCKSDB_MINOR 7
|
||||
#define ROCKSDB_PATCH 2
|
||||
#define ROCKSDB_PATCH 3
|
||||
|
||||
// Do not use these. We made the mistake of declaring macros starting with
|
||||
// double underscore. Now we have to live with our choice. We'll deprecate these
|
||||
|
||||
Reference in new issue
Block a user