Skip to content

Commit 9d2e474

Browse files
committed
[#25600] DocDB: Implement variable bloom filtering for RocksDB iterator
Summary: Currently we check bloom filter when RocksDB iterator is being created. So it could be used only when we plan to use this iterator for particular row lookup. Implemented variable bloom filters check and used it during conflict resolution. TServer insert time for PgSingleTServerTest.Scan test improved from 12.46s to 11.99s. When bloom filter is used in variable mode, we defer checking whether iterator should be created for the particular sst file. I.e. iterators are always created, but user could change bloom filter key on the fly. `MergingIteratorBase` is responsible for managing bloom filter key updates. When key is updated it checks whether particular iterator matches the provided key and could add/remove entries to iterators heap. Jira: DB-14846 Test Plan: Jenkins Reviewers: timur Reviewed By: timur Subscribers: kannan, ybase, yql Tags: #jenkins-ready Differential Revision: https://phorge.dev.yugabyte.com/D41176
1 parent 1bdc9a8 commit 9d2e474

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+709
-262
lines changed

src/yb/client/ql-tablet-test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2031,7 +2031,7 @@ Status CalcKeysDistributionAcrossWorkers(
20312031

20322032
auto iter = CreateRocksDBIterator(
20332033
tablet->doc_db().regular, tablet->doc_db().key_bounds,
2034-
docdb::BloomFilterMode::DONT_USE_BLOOM_FILTER, boost::none, rocksdb::kDefaultQueryId,
2034+
docdb::BloomFilterOptions::Inactive(), rocksdb::kDefaultQueryId,
20352035
/* file_filter = */ nullptr, /* iterate_upper_bound = */ nullptr,
20362036
rocksdb::CacheRestartBlockKeys { direction == tablet::Direction::kBackward });
20372037
if (direction == tablet::Direction::kForward) {

src/yb/docdb/bounded_rocksdb_iterator.cc

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,29 @@ const rocksdb::KeyValueEntry& BoundedRocksDbIterator::SeekToLast() {
5555
}
5656

5757
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::Seek(Slice target) {
58+
return DoSeek(target, nullptr);
59+
}
60+
61+
template <class Filter>
62+
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::DoSeek(Slice target, Filter filter_user_key) {
5863
if (!key_bounds_->lower.empty() && target.compare(key_bounds_->lower) < 0) {
59-
return FilterEntry(iterator_->Seek(key_bounds_->lower));
64+
return FilterEntry(DoSeekImpl(key_bounds_->lower, filter_user_key));
6065
}
6166

6267
if (!key_bounds_->upper.empty() && target.compare(key_bounds_->upper) > 0) {
63-
return FilterEntry(iterator_->Seek(key_bounds_->upper));
68+
return FilterEntry(DoSeekImpl(key_bounds_->upper, filter_user_key));
6469
}
6570

66-
return FilterEntry(iterator_->Seek(target));
71+
return FilterEntry(DoSeekImpl(target, filter_user_key));
72+
}
73+
74+
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::DoSeekImpl(Slice target, std::nullptr_t) {
75+
return iterator_->Seek(target);
76+
}
77+
78+
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::DoSeekImpl(
79+
Slice target, Slice filter_user_key) {
80+
return iterator_->SeekWithNewFilter(target, filter_user_key);
6781
}
6882

6983
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::Next() {
@@ -97,5 +111,10 @@ void BoundedRocksDbIterator::UseFastNext(bool value) {
97111
iterator_->UseFastNext(value);
98112
}
99113

114+
const rocksdb::KeyValueEntry& BoundedRocksDbIterator::DoSeekWithNewFilter(
115+
Slice target, Slice filter_user_key) {
116+
return DoSeek(target, filter_user_key);
117+
}
118+
100119
} // namespace docdb
101120
} // namespace yb

src/yb/docdb/bounded_rocksdb_iterator.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ class BoundedRocksDbIterator final : public rocksdb::Iterator {
7575

7676
private:
7777
const rocksdb::KeyValueEntry& FilterEntry(const rocksdb::KeyValueEntry& entry) const;
78+
template <class Filter>
79+
const rocksdb::KeyValueEntry& DoSeek(Slice target, Filter filter_user_key);
80+
const rocksdb::KeyValueEntry& DoSeekImpl(Slice target, std::nullptr_t);
81+
const rocksdb::KeyValueEntry& DoSeekImpl(Slice target, Slice filter_user_key);
82+
const rocksdb::KeyValueEntry& DoSeekWithNewFilter(Slice target, Slice filter_user_key) override;
7883

7984
std::unique_ptr<rocksdb::Iterator> iterator_;
8085
const KeyBounds* key_bounds_;

src/yb/docdb/conflict_resolution.cc

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -896,23 +896,20 @@ class StrongConflictChecker {
896896

897897
Status Check(
898898
Slice intent_key, bool strong, ConflictManagementPolicy conflict_management_policy) {
899-
const auto bloom_filter_prefix = VERIFY_RESULT(ExtractFilterPrefixFromKey(intent_key));
900-
if (!value_iter_.Initialized() || bloom_filter_prefix != value_iter_bloom_filter_prefix_) {
899+
if (!value_iter_.Initialized()) {
901900
auto hybrid_time_file_filter =
902901
FLAGS_docdb_ht_filter_conflict_with_committed ? CreateHybridTimeFileFilter(read_time_)
903902
: nullptr;
904903
value_iter_ = CreateRocksDBIterator(
905904
resolver_.doc_db().regular,
906905
resolver_.doc_db().key_bounds,
907-
BloomFilterMode::USE_BLOOM_FILTER,
908-
intent_key,
906+
BloomFilterOptions::Variable(),
909907
rocksdb::kDefaultQueryId,
910908
hybrid_time_file_filter,
911909
/* iterate_upper_bound = */ nullptr,
912910
rocksdb::CacheRestartBlockKeys::kFalse);
913-
value_iter_bloom_filter_prefix_ = bloom_filter_prefix;
914911
}
915-
value_iter_.Seek(intent_key);
912+
value_iter_.SeekWithNewFilter(intent_key);
916913

917914
VLOG_WITH_PREFIX_AND_FUNC(4)
918915
<< "Overwrite; Seek: " << intent_key.ToDebugString() << " ("
@@ -994,7 +991,6 @@ class StrongConflictChecker {
994991

995992
// RocksDb iterator with bloom filter can be reused in case keys has same hash component.
996993
BoundedRocksDbIterator value_iter_;
997-
Slice value_iter_bloom_filter_prefix_;
998994
};
999995

1000996
class ConflictResolverContextBase : public ConflictResolverContext {

src/yb/docdb/cql_operation.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,7 @@ Result<bool> QLWriteOperation::HasDuplicateUniqueIndexValueBackward(
637637

638638
auto iter = CreateIntentAwareIterator(
639639
data.doc_write_batch->doc_db(),
640-
BloomFilterMode::USE_BLOOM_FILTER,
641-
pk_doc_key_->Encode().AsSlice(),
640+
BloomFilterOptions::Fixed(pk_doc_key_->Encode().AsSlice()),
642641
request_.query_id(),
643642
txn_op_context_,
644643
data.read_operation_data);

src/yb/docdb/doc_reader.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ Result<DocHybridTime> GetTableTombstoneTime(
220220
table_id = table_id_buf.AsSlice();
221221

222222
auto iter = CreateIntentAwareIterator(
223-
doc_db, BloomFilterMode::USE_BLOOM_FILTER, table_id, rocksdb::kDefaultQueryId, txn_op_context,
223+
doc_db, BloomFilterOptions::Fixed(table_id), rocksdb::kDefaultQueryId, txn_op_context,
224224
read_operation_data.WithStatistics(nullptr));
225225
iter->Seek(table_id, SeekFilter::kAll);
226226
const auto& entry_data = VERIFY_RESULT_REF(iter->Fetch());
@@ -250,7 +250,7 @@ Result<std::optional<SubDocument>> TEST_GetSubDocument(
250250
const ReadOperationData& read_operation_data,
251251
const dockv::ReaderProjection* projection) {
252252
auto iter = CreateIntentAwareIterator(
253-
doc_db, BloomFilterMode::USE_BLOOM_FILTER, sub_doc_key, query_id,
253+
doc_db, BloomFilterOptions::Fixed(sub_doc_key), query_id,
254254
txn_op_context, read_operation_data);
255255
DOCDB_DEBUG_LOG("GetSubDocument for key $0 @ $1", sub_doc_key.ToDebugHexString(),
256256
iter->read_time().ToString());

src/yb/docdb/doc_reader_redis.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ Status GetRedisSubDocument(
386386
const TransactionOperationContext& txn_op_context,
387387
const ReadOperationData& read_operation_data) {
388388
auto iter = CreateIntentAwareIterator(
389-
doc_db, BloomFilterMode::USE_BLOOM_FILTER, data.subdocument_key, query_id, txn_op_context,
389+
doc_db, BloomFilterOptions::Fixed(data.subdocument_key), query_id, txn_op_context,
390390
read_operation_data);
391391
return GetRedisSubDocument(iter.get(), data, nullptr /* projection */, SeekFwdSuffices::kFalse);
392392
}

src/yb/docdb/doc_rowwise_iterator.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ DocRowwiseIterator::DocRowwiseIterator(
8383
DocRowwiseIterator::~DocRowwiseIterator() = default;
8484

8585
void DocRowwiseIterator::InitIterator(
86-
BloomFilterMode bloom_filter_mode,
87-
const boost::optional<const Slice>& user_key_for_filter,
86+
const BloomFilterOptions& bloom_filter,
8887
const rocksdb::QueryId query_id,
8988
std::shared_ptr<rocksdb::ReadFileFilter> file_filter) {
9089
if (table_type_ == TableType::PGSQL_TABLE_TYPE) {
@@ -103,8 +102,7 @@ void DocRowwiseIterator::InitIterator(
103102

104103
db_iter_ = CreateIntentAwareIterator(
105104
doc_db_,
106-
bloom_filter_mode,
107-
user_key_for_filter,
105+
bloom_filter,
108106
query_id,
109107
txn_op_context_,
110108
read_operation_data_,

src/yb/docdb/doc_rowwise_iterator.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ class DocRowwiseIterator final : public DocRowwiseIteratorBase {
108108

109109
private:
110110
void InitIterator(
111-
BloomFilterMode bloom_filter_mode = BloomFilterMode::DONT_USE_BLOOM_FILTER,
112-
const boost::optional<const Slice>& user_key_for_filter = boost::none,
111+
const BloomFilterOptions& bloom_filter = BloomFilterOptions::Inactive(),
113112
const rocksdb::QueryId query_id = rocksdb::kDefaultQueryId,
114113
std::shared_ptr<rocksdb::ReadFileFilter> file_filter = nullptr) override;
115114

src/yb/docdb/doc_rowwise_iterator_base.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ Status DocRowwiseIteratorBase::Init(const qlexpr::YQLScanSpec& doc_spec, SkipSee
172172
const bool is_fixed_point_get =
173173
!bounds.lower.empty() &&
174174
VERIFY_RESULT(HashedOrFirstRangeComponentsEqual(bounds.lower, bounds.upper));
175-
const auto mode = is_fixed_point_get ? BloomFilterMode::USE_BLOOM_FILTER
176-
: BloomFilterMode::DONT_USE_BLOOM_FILTER;
175+
const auto bloom_filter = is_fixed_point_get ? BloomFilterOptions::Fixed(bounds.lower.AsSlice())
176+
: BloomFilterOptions::Inactive();
177177

178178
if (is_forward_scan_) {
179179
has_bound_key_ = !bounds.upper.empty();
@@ -194,7 +194,7 @@ Status DocRowwiseIteratorBase::Init(const qlexpr::YQLScanSpec& doc_spec, SkipSee
194194
}
195195
}
196196

197-
InitIterator(mode, bounds.lower.AsSlice(), doc_spec.QueryId(), CreateFileFilter(doc_spec));
197+
InitIterator(bloom_filter, doc_spec.QueryId(), CreateFileFilter(doc_spec));
198198

199199
if (has_bound_key_) {
200200
if (is_forward_scan_) {

0 commit comments

Comments
 (0)