Skip to content

Commit 8986577

Browse files
committed
Revert "Merging iterator to avoid child iterator reseek for some cases (facebook#5286)" (facebook#5871)
Summary: This reverts commit 9fad3e2. Iterator verification in stress tests sometimes fail for assertion table/block_based/block_based_table_reader.cc:2973: void rocksdb::BlockBasedTableIterator<TBlockIter, TValue>::FindBlockForward() [with TBlockIter = rocksdb::DataBlockIter; TValue = rocksdb::Slice]: Assertion `!next_block_is_out_of_bound || user_comparator_.Compare(*read_options_.iterate_upper_bound, index_iter_->user_key()) <= 0' failed. It is likely to be linked to facebook#5286 together with facebook#5468 as the former PR makes some child iterator's seek being avoided, so that upper bound condition fails to be updated there. Strictly speaking, the former PR was merged before the latter one, but the latter one feels a more important improvement so I choose to revert the former one for now. Pull Request resolved: facebook#5871 Differential Revision: D17689196 fbshipit-source-id: 4ded5be68f67bee2782d31a29cb72ea68f59dd8c
1 parent 749b35d commit 8986577

File tree

7 files changed

+9
-98
lines changed

7 files changed

+9
-98
lines changed

HISTORY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Rocksdb Change Log
22
## Unreleased
3+
### Bug Fixes
4+
* Revert the feature "Merging iterator to avoid child iterator reseek for some cases (#5286)" since it might cause strong results when reseek happens with a different iterator upper bound.
35

46
## 6.5.0 (9/13/2019)
57
### Bug Fixes
@@ -104,7 +106,6 @@
104106
* Fix a bug caused by secondary not skipping the beginning of new MANIFEST.
105107
* On DB open, delete WAL trash files left behind in wal_dir
106108

107-
108109
## 6.2.0 (4/30/2019)
109110
### New Features
110111
* Add an option `strict_bytes_per_sync` that causes a file-writing thread to block rather than exceed the limit on bytes pending writeback specified by `bytes_per_sync` or `wal_bytes_per_sync`.

db/db_iterator_test.cc

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,75 +2690,6 @@ TEST_P(DBIteratorTest, AvoidReseekLevelIterator) {
26902690
SyncPoint::GetInstance()->DisableProcessing();
26912691
}
26922692

2693-
TEST_P(DBIteratorTest, AvoidReseekChildIterator) {
2694-
Options options = CurrentOptions();
2695-
options.compression = CompressionType::kNoCompression;
2696-
BlockBasedTableOptions table_options;
2697-
table_options.block_size = 800;
2698-
options.table_factory.reset(NewBlockBasedTableFactory(table_options));
2699-
Reopen(options);
2700-
2701-
Random rnd(301);
2702-
std::string random_str = RandomString(&rnd, 180);
2703-
2704-
ASSERT_OK(Put("1", random_str));
2705-
ASSERT_OK(Put("2", random_str));
2706-
ASSERT_OK(Put("3", random_str));
2707-
ASSERT_OK(Put("4", random_str));
2708-
ASSERT_OK(Put("8", random_str));
2709-
ASSERT_OK(Put("9", random_str));
2710-
ASSERT_OK(Flush());
2711-
ASSERT_OK(Put("5", random_str));
2712-
ASSERT_OK(Put("6", random_str));
2713-
ASSERT_OK(Put("7", random_str));
2714-
ASSERT_OK(Flush());
2715-
2716-
// These two keys will be kept in memtable.
2717-
ASSERT_OK(Put("0", random_str));
2718-
ASSERT_OK(Put("8", random_str));
2719-
2720-
int num_iter_wrapper_seek = 0;
2721-
SyncPoint::GetInstance()->SetCallBack(
2722-
"IteratorWrapper::Seek:0",
2723-
[&](void* /*arg*/) { num_iter_wrapper_seek++; });
2724-
SyncPoint::GetInstance()->EnableProcessing();
2725-
{
2726-
std::unique_ptr<Iterator> iter(NewIterator(ReadOptions()));
2727-
iter->Seek("1");
2728-
ASSERT_TRUE(iter->Valid());
2729-
// DBIter always wraps internal iterator with IteratorWrapper,
2730-
// and in merging iterator each child iterator will be wrapped
2731-
// with IteratorWrapper.
2732-
ASSERT_EQ(4, num_iter_wrapper_seek);
2733-
2734-
// child position: 1 and 5
2735-
num_iter_wrapper_seek = 0;
2736-
iter->Seek("2");
2737-
ASSERT_TRUE(iter->Valid());
2738-
ASSERT_EQ(3, num_iter_wrapper_seek);
2739-
2740-
// child position: 2 and 5
2741-
num_iter_wrapper_seek = 0;
2742-
iter->Seek("6");
2743-
ASSERT_TRUE(iter->Valid());
2744-
ASSERT_EQ(4, num_iter_wrapper_seek);
2745-
2746-
// child position: 8 and 6
2747-
num_iter_wrapper_seek = 0;
2748-
iter->Seek("7");
2749-
ASSERT_TRUE(iter->Valid());
2750-
ASSERT_EQ(3, num_iter_wrapper_seek);
2751-
2752-
// child position: 8 and 7
2753-
num_iter_wrapper_seek = 0;
2754-
iter->Seek("5");
2755-
ASSERT_TRUE(iter->Valid());
2756-
ASSERT_EQ(4, num_iter_wrapper_seek);
2757-
}
2758-
2759-
SyncPoint::GetInstance()->DisableProcessing();
2760-
}
2761-
27622693
// MyRocks may change iterate bounds before seek. Simply test to make sure such
27632694
// usage doesn't break iterator.
27642695
TEST_P(DBIteratorTest, IterateBoundChangedBeforeSeek) {

db/version_set.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,8 +859,7 @@ class LevelIterator final : public InternalIterator {
859859
bool skip_filters, int level, RangeDelAggregator* range_del_agg,
860860
const std::vector<AtomicCompactionUnitBoundary>*
861861
compaction_boundaries = nullptr)
862-
: InternalIterator(false),
863-
table_cache_(table_cache),
862+
: table_cache_(table_cache),
864863
read_options_(read_options),
865864
env_options_(env_options),
866865
icomparator_(icomparator),

table/block_based/block_based_table_reader.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,7 @@ class BlockBasedTableIterator : public InternalIteratorBase<TValue> {
615615
const SliceTransform* prefix_extractor,
616616
BlockType block_type, TableReaderCaller caller,
617617
size_t compaction_readahead_size = 0)
618-
: InternalIteratorBase<TValue>(false),
619-
table_(table),
618+
: table_(table),
620619
read_options_(read_options),
621620
icomp_(icomp),
622621
user_comparator_(icomp.user_comparator()),

table/internal_iterator.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ struct IterateResult {
2525
template <class TValue>
2626
class InternalIteratorBase : public Cleanable {
2727
public:
28-
InternalIteratorBase() : is_mutable_(true) {}
29-
InternalIteratorBase(bool _is_mutable) : is_mutable_(_is_mutable) {}
28+
InternalIteratorBase() {}
29+
3030
// No copying allowed
3131
InternalIteratorBase(const InternalIteratorBase&) = delete;
3232
InternalIteratorBase& operator=(const InternalIteratorBase&) = delete;
@@ -148,7 +148,6 @@ class InternalIteratorBase : public Cleanable {
148148
virtual Status GetProperty(std::string /*prop_name*/, std::string* /*prop*/) {
149149
return Status::NotSupported("");
150150
}
151-
bool is_mutable() const { return is_mutable_; }
152151

153152
protected:
154153
void SeekForPrevImpl(const Slice& target, const Comparator* cmp) {

table/iterator_wrapper.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class IteratorWrapperBase {
7373
}
7474
void Prev() { assert(iter_); iter_->Prev(); Update(); }
7575
void Seek(const Slice& k) {
76-
TEST_SYNC_POINT("IteratorWrapper::Seek:0");
7776
assert(iter_);
7877
iter_->Seek(k);
7978
Update();

table/merging_iterator.cc

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -127,29 +127,12 @@ class MergingIterator : public InternalIterator {
127127
}
128128

129129
void Seek(const Slice& target) override {
130-
bool is_increasing_reseek = false;
131-
if (current_ != nullptr && direction_ == kForward && status_.ok() &&
132-
comparator_->Compare(target, key()) >= 0) {
133-
is_increasing_reseek = true;
134-
}
135130
ClearHeaps();
136131
status_ = Status::OK();
137132
for (auto& child : children_) {
138-
// If upper bound never changes, we can skip Seek() for
139-
// the !Valid() case too, but people do hack the code to change
140-
// upper bound between Seek(), so it's not a good idea to break
141-
// the API.
142-
// If DBIter is used on top of merging iterator, we probably
143-
// can skip mutable child iterators if they are invalid too,
144-
// but it's a less clean API. We can optimize for it later if
145-
// needed.
146-
if (!is_increasing_reseek || !child.Valid() ||
147-
comparator_->Compare(target, child.key()) > 0 ||
148-
child.iter()->is_mutable()) {
149-
PERF_TIMER_GUARD(seek_child_seek_time);
150-
child.Seek(target);
151-
PERF_COUNTER_ADD(seek_child_seek_count, 1);
152-
}
133+
PERF_TIMER_GUARD(seek_child_seek_time);
134+
child.Seek(target);
135+
PERF_COUNTER_ADD(seek_child_seek_count, 1);
153136

154137
if (child.Valid()) {
155138
assert(child.status().ok());

0 commit comments

Comments
 (0)