From ccf869cf5fe6a58f569831b9b558b57b8d00a9a2 Mon Sep 17 00:00:00 2001 From: zhannngchen <48427519+zhannngchen@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:15:39 +0800 Subject: [PATCH] pick [opt](merge-on-write) avoid to check delete bitmap while lookup rowkey in some situation to reduce CPU cost (#41480) (#41439) Issue Number: close #xxx cherry-pick #41480 --- .../olap/rowset/segment_v2/segment_writer.cpp | 4 +-- .../segment_v2/vertical_segment_writer.cpp | 4 +-- be/src/olap/tablet.cpp | 27 ++++++++++++------- be/src/olap/tablet.h | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/be/src/olap/rowset/segment_v2/segment_writer.cpp b/be/src/olap/rowset/segment_v2/segment_writer.cpp index 8edd7c8cf15080..369d09a717cf6b 100644 --- a/be/src/olap/rowset/segment_v2/segment_writer.cpp +++ b/be/src/olap/rowset/segment_v2/segment_writer.cpp @@ -363,7 +363,7 @@ Status SegmentWriter::probe_key_for_mow( RowsetSharedPtr rowset; auto st = tablet->lookup_row_key(key, _tablet_schema.get(), have_input_seq_column, specified_rowsets, &loc, _mow_context->max_version, - segment_caches, &rowset); + segment_caches, &rowset, true, true); if (st.is()) { if (_opts.rowset_ctx->partial_update_info->is_strict_mode) { ++stats.num_rows_filtered; @@ -867,7 +867,7 @@ Status SegmentWriter::merge_rows_for_sequence_column( st = tablet->lookup_row_key(key, _tablet_schema.get(), false, specified_rowsets, &loc, _mow_context->max_version, segment_caches, &rowset, true, - &previous_encoded_seq_value); + true, &previous_encoded_seq_value); DCHECK(st.is() || st.ok()); Slice previous_seq_slice {}; diff --git a/be/src/olap/rowset/segment_v2/vertical_segment_writer.cpp b/be/src/olap/rowset/segment_v2/vertical_segment_writer.cpp index 2dfd4c6919608a..e29c29220f961c 100644 --- a/be/src/olap/rowset/segment_v2/vertical_segment_writer.cpp +++ b/be/src/olap/rowset/segment_v2/vertical_segment_writer.cpp @@ -316,7 +316,7 @@ Status VerticalSegmentWriter::_probe_key_for_mow( RowsetSharedPtr rowset; auto st = tablet->lookup_row_key(key, _tablet_schema.get(), have_input_seq_column, specified_rowsets, &loc, _mow_context->max_version, - segment_caches, &rowset); + segment_caches, &rowset, true, true); if (st.is()) { if (_opts.rowset_ctx->partial_update_info->is_strict_mode) { ++stats.num_rows_filtered; @@ -860,7 +860,7 @@ Status VerticalSegmentWriter::_merge_rows_for_sequence_column( std::string previous_encoded_seq_value {}; st = tablet->lookup_row_key(key, _tablet_schema.get(), false, specified_rowsets, &loc, _mow_context->max_version, segment_caches, &rowset, true, - &previous_encoded_seq_value); + true, &previous_encoded_seq_value); DCHECK(st.is() || st.ok()); Slice previous_seq_slice {}; diff --git a/be/src/olap/tablet.cpp b/be/src/olap/tablet.cpp index 5f9fdad2df23e0..b9fc4aa1fbafe0 100644 --- a/be/src/olap/tablet.cpp +++ b/be/src/olap/tablet.cpp @@ -2856,7 +2856,7 @@ Status Tablet::lookup_row_key(const Slice& encoded_key, TabletSchema* latest_sch const std::vector& specified_rowsets, RowLocation* row_location, uint32_t version, std::vector>& segment_caches, - RowsetSharedPtr* rowset, bool with_rowid, + RowsetSharedPtr* rowset, bool with_rowid, bool is_partial_update, std::string* encoded_seq_value) { SCOPED_BVAR_LATENCY(g_tablet_lookup_rowkey_latency); size_t seq_col_length = 0; @@ -2874,6 +2874,8 @@ Status Tablet::lookup_row_key(const Slice& encoded_key, TabletSchema* latest_sch Slice(encoded_key.get_data(), encoded_key.get_size() - seq_col_length - rowid_length); RowLocation loc; + bool need_to_check_delete_bitmap = is_partial_update || with_seq_col; + for (size_t i = 0; i < specified_rowsets.size(); i++) { auto& rs = specified_rowsets[i]; auto& segments_key_bounds = rs->rowset_meta()->get_segments_key_bounds(); @@ -2912,15 +2914,19 @@ Status Tablet::lookup_row_key(const Slice& encoded_key, TabletSchema* latest_sch if (!s.ok() && !s.is()) { return s; } - if (s.ok() && _tablet_meta->delete_bitmap().contains_agg_without_cache( - {loc.rowset_id, loc.segment_id, version}, loc.row_id)) { - // if has sequence col, we continue to compare the sequence_id of - // all rowsets, util we find an existing key. - if (schema->has_sequence_col()) { - continue; + if (s.ok() && need_to_check_delete_bitmap) { + // check if the key is already mark deleted + if (_tablet_meta->delete_bitmap().contains_agg_without_cache( + {loc.rowset_id, loc.segment_id, version}, loc.row_id)) { + // if has sequence col, we continue to compare the sequence_id of + // all rowsets, util we find an existing key. + if (with_seq_col) { + continue; + } + // The key is deleted, we need to break the loop and return + // KEY_NOT_FOUND. + break; } - // The key is deleted, we don't need to search for it any more. - break; } // `st` is either OK or KEY_ALREADY_EXISTS now. // for partial update, even if the key is already exists, we still need to @@ -3097,7 +3103,8 @@ Status Tablet::calc_segment_delete_bitmap(RowsetSharedPtr rowset, RowsetSharedPtr rowset_find; auto st = lookup_row_key(key, rowset_schema.get(), true, specified_rowsets, &loc, - dummy_version.first - 1, segment_caches, &rowset_find); + dummy_version.first - 1, segment_caches, &rowset_find, false, + is_partial_update); bool expected_st = st.ok() || st.is() || st.is(); // It's a defensive DCHECK, we need to exclude some common errors to avoid core-dump // while stress test diff --git a/be/src/olap/tablet.h b/be/src/olap/tablet.h index 1d5dee6686fff9..af1373fa7c14d9 100644 --- a/be/src/olap/tablet.h +++ b/be/src/olap/tablet.h @@ -439,7 +439,7 @@ class Tablet final : public BaseTablet { RowLocation* row_location, uint32_t version, std::vector>& segment_caches, RowsetSharedPtr* rowset = nullptr, bool with_rowid = true, - std::string* encoded_seq_value = nullptr); + bool is_partial_update = false, std::string* encoded_seq_value = nullptr); // Lookup a row with TupleDescriptor and fill Block Status lookup_row_data(const Slice& encoded_key, const RowLocation& row_location,