This is an automated email from the ASF dual-hosted git repository.

gavinchou pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 64e8cf2c399 [improvement](be) Add queue time for delete bitmap tasks 
(#65248)
64e8cf2c399 is described below

commit 64e8cf2c3992f7377e8d5af567c95b863d169166
Author: bobhan1 <[email protected]>
AuthorDate: Mon Jul 13 10:46:25 2026 +0800

    [improvement](be) Add queue time for delete bitmap tasks (#65248)
    
    Problem Summary: MOW memtable flush calculates delete bitmap
    asynchronously, but its log did not show how long the async task waited
    in the executor queue. The load delete-bitmap executor also used the
    same thread-pool metric name as the normal delete-bitmap executor,
    making their metrics hard to distinguish. This change records queue time
    for flush, segment-level, between-segment, and cloud tablet-level async
    delete-bitmap tasks, and gives the load delete-bitmap executor a
    distinct thread-pool name.
---
 .../cloud/cloud_engine_calc_delete_bitmap_task.cpp |  25 ++--
 .../cloud/cloud_engine_calc_delete_bitmap_task.h   |   2 +-
 be/src/cloud/cloud_storage_engine.cpp              |   4 +-
 .../storage/delete/calc_delete_bitmap_executor.cpp |  12 +-
 .../storage/delete/calc_delete_bitmap_executor.h   |   3 +-
 be/src/storage/rowset/beta_rowset_writer.cpp       | 126 +++++++++++----------
 be/src/storage/storage_engine.cpp                  |   4 +-
 be/src/storage/tablet/base_tablet.cpp              |  20 ++--
 be/src/storage/tablet/base_tablet.h                |   5 +-
 9 files changed, 109 insertions(+), 92 deletions(-)

diff --git a/be/src/cloud/cloud_engine_calc_delete_bitmap_task.cpp 
b/be/src/cloud/cloud_engine_calc_delete_bitmap_task.cpp
index c310cd6a0b6..869edca0b49 100644
--- a/be/src/cloud/cloud_engine_calc_delete_bitmap_task.cpp
+++ b/be/src/cloud/cloud_engine_calc_delete_bitmap_task.cpp
@@ -93,15 +93,18 @@ Status CloudEngineCalcDeleteBitmapTask::execute() {
             if (has_tablet_states) {
                 
tablet_calc_delete_bitmap_ptr->set_tablet_state(partition.tablet_states[i]);
             }
-            auto submit_st = token->submit_func([tablet_id, 
tablet_calc_delete_bitmap_ptr, this]() {
-                auto st = tablet_calc_delete_bitmap_ptr->handle();
-                if (st.ok()) {
-                    add_succ_tablet_id(tablet_id);
-                } else {
-                    LOG(WARNING) << "handle calc delete bitmap fail, st=" << 
st.to_string();
-                    add_error_tablet_id(tablet_id, st);
-                }
-            });
+            const auto submit_time_us = MonotonicMicros();
+            auto submit_st = token->submit_func(
+                    [tablet_id, tablet_calc_delete_bitmap_ptr, this, 
submit_time_us]() {
+                        const auto queue_time_us = MonotonicMicros() - 
submit_time_us;
+                        auto st = 
tablet_calc_delete_bitmap_ptr->handle(queue_time_us);
+                        if (st.ok()) {
+                            add_succ_tablet_id(tablet_id);
+                        } else {
+                            LOG(WARNING) << "handle calc delete bitmap fail, 
st=" << st.to_string();
+                            add_error_tablet_id(tablet_id, st);
+                        }
+                    });
             VLOG_DEBUG << "submit TabletCalcDeleteBitmapTask for tablet=" << 
tablet_id;
             if (!submit_st.ok()) {
                 _res = submit_st;
@@ -143,7 +146,7 @@ void 
CloudTabletCalcDeleteBitmapTask::set_tablet_state(int64_t tablet_state) {
     _ms_tablet_state = tablet_state;
 }
 
-Status CloudTabletCalcDeleteBitmapTask::handle() const {
+Status CloudTabletCalcDeleteBitmapTask::handle(int64_t queue_time_us) const {
     VLOG_DEBUG << "start calculate delete bitmap on tablet " << _tablet_id
                << ", txn_id=" << _transaction_id;
     SCOPED_ATTACH_TASK(_mem_tracker);
@@ -284,7 +287,7 @@ Status CloudTabletCalcDeleteBitmapTask::handle() const {
     auto total_update_delete_bitmap_time_us = MonotonicMicros() - t3;
     LOG(INFO) << "finish calculate delete bitmap on tablet"
               << ", table_id=" << tablet->table_id() << ", transaction_id=" << 
_transaction_id
-              << ", tablet_id=" << tablet->tablet_id()
+              << ", tablet_id=" << tablet->tablet_id() << ", queue_time_us=" 
<< queue_time_us
               << ", get_tablet_time_us=" << get_tablet_time_us
               << ", sync_rowset_time_us=" << sync_rowset_time_us
               << ", total_update_delete_bitmap_time_us=" << 
total_update_delete_bitmap_time_us
diff --git a/be/src/cloud/cloud_engine_calc_delete_bitmap_task.h 
b/be/src/cloud/cloud_engine_calc_delete_bitmap_task.h
index 5ea11e8d4c3..04b085b5ff6 100644
--- a/be/src/cloud/cloud_engine_calc_delete_bitmap_task.h
+++ b/be/src/cloud/cloud_engine_calc_delete_bitmap_task.h
@@ -43,7 +43,7 @@ public:
                               int64_t ms_cumulative_point);
     void set_tablet_state(int64_t tablet_state);
 
-    Status handle() const;
+    Status handle(int64_t queue_time_us) const;
 
 private:
     Status _handle_rowset(std::shared_ptr<CloudTablet> tablet, int64_t version,
diff --git a/be/src/cloud/cloud_storage_engine.cpp 
b/be/src/cloud/cloud_storage_engine.cpp
index 803a738d6da..0dc8321c2c4 100644
--- a/be/src/cloud/cloud_storage_engine.cpp
+++ b/be/src/cloud/cloud_storage_engine.cpp
@@ -206,10 +206,12 @@ Status CloudStorageEngine::open() {
             
cast_set<int32_t>(io::FileCacheFactory::instance()->get_cache_instance_size()));
 
     _calc_delete_bitmap_executor = 
std::make_unique<CalcDeleteBitmapExecutor>();
-    _calc_delete_bitmap_executor->init(config::calc_delete_bitmap_max_thread);
+    _calc_delete_bitmap_executor->init("TabletCalcDeleteBitmapThreadPool",
+                                       config::calc_delete_bitmap_max_thread);
 
     _calc_delete_bitmap_executor_for_load = 
std::make_unique<CalcDeleteBitmapExecutor>();
     _calc_delete_bitmap_executor_for_load->init(
+            "LoadCalcDeleteBitmapThreadPool",
             config::calc_delete_bitmap_for_load_max_thread > 0
                     ? config::calc_delete_bitmap_for_load_max_thread
                     : std::max(1, CpuInfo::num_cores() / 2));
diff --git a/be/src/storage/delete/calc_delete_bitmap_executor.cpp 
b/be/src/storage/delete/calc_delete_bitmap_executor.cpp
index 1867dc54a9e..af1b4bfb23a 100644
--- a/be/src/storage/delete/calc_delete_bitmap_executor.cpp
+++ b/be/src/storage/delete/calc_delete_bitmap_executor.cpp
@@ -41,11 +41,13 @@ Status CalcDeleteBitmapToken::submit(BaseTabletSPtr tablet, 
RowsetSharedPtr cur_
         _resource_ctx = thread_context()->resource_ctx();
     }
 
+    const auto submit_time_us = MonotonicMicros();
     return _thread_token->submit_func([=, this]() {
+        const auto queue_time_us = MonotonicMicros() - submit_time_us;
         SCOPED_ATTACH_TASK(_resource_ctx);
         auto st = tablet->calc_segment_delete_bitmap(cur_rowset, cur_segment, 
target_rowsets,
                                                      delete_bitmap, 
end_version, rowset_writer,
-                                                     tablet_delete_bitmap);
+                                                     tablet_delete_bitmap, 
queue_time_us);
         if (!st.ok()) {
             LOG(WARNING) << "failed to calc segment delete bitmap, tablet_id: "
                          << tablet->tablet_id() << " rowset: " << 
cur_rowset->rowset_id()
@@ -68,10 +70,12 @@ Status CalcDeleteBitmapToken::submit(BaseTabletSPtr tablet, 
TabletSchemaSPtr sch
         RETURN_IF_ERROR(_status);
         _resource_ctx = thread_context()->resource_ctx();
     }
+    const auto submit_time_us = MonotonicMicros();
     return _thread_token->submit_func([=, this]() {
+        const auto queue_time_us = MonotonicMicros() - submit_time_us;
         SCOPED_ATTACH_TASK(_resource_ctx);
         auto st = tablet->calc_delete_bitmap_between_segments(schema, 
rowset_id, segments,
-                                                              delete_bitmap);
+                                                              delete_bitmap, 
queue_time_us);
         if (!st.ok()) {
             LOG(WARNING) << "failed to calc delete bitmap between segments, 
tablet_id: "
                          << tablet->tablet_id() << " rowset: " << rowset_id
@@ -90,8 +94,8 @@ Status CalcDeleteBitmapToken::wait() {
     return _status;
 }
 
-void CalcDeleteBitmapExecutor::init(int max_threads) {
-    static_cast<void>(ThreadPoolBuilder("TabletCalcDeleteBitmapThreadPool")
+void CalcDeleteBitmapExecutor::init(const std::string& name, int max_threads) {
+    static_cast<void>(ThreadPoolBuilder(name)
                               .set_min_threads(1)
                               .set_max_threads(max_threads)
                               .build(&_thread_pool));
diff --git a/be/src/storage/delete/calc_delete_bitmap_executor.h 
b/be/src/storage/delete/calc_delete_bitmap_executor.h
index be97505e038..4f0f0fd2c7f 100644
--- a/be/src/storage/delete/calc_delete_bitmap_executor.h
+++ b/be/src/storage/delete/calc_delete_bitmap_executor.h
@@ -23,6 +23,7 @@
 #include <iosfwd>
 #include <memory>
 #include <shared_mutex>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -105,7 +106,7 @@ public:
     ~CalcDeleteBitmapExecutor() { _thread_pool->shutdown(); }
 
     // init should be called after storage engine is opened,
-    void init(int max_threads);
+    void init(const std::string& name, int max_threads);
 
     std::unique_ptr<CalcDeleteBitmapToken> create_token();
 
diff --git a/be/src/storage/rowset/beta_rowset_writer.cpp 
b/be/src/storage/rowset/beta_rowset_writer.cpp
index cf54ea07e1d..40aef241fcf 100644
--- a/be/src/storage/rowset/beta_rowset_writer.cpp
+++ b/be/src/storage/rowset/beta_rowset_writer.cpp
@@ -418,72 +418,74 @@ Status 
BaseBetaRowsetWriter::_generate_delete_bitmap(int32_t segment_id) {
     // Submit the entire delete bitmap calculation process to thread pool for 
async execution
     // This avoids blocking memtable flush thread while waiting for file 
upload to complete
     // The process includes: file_writer->close(), _build_tmp, load_segments, 
and calc_delete_bitmap
-    return _calc_delete_bitmap_token->submit_func(
-            [this, segment_id, specified_rowsets = 
std::move(specified_rowsets)]() -> Status {
-                Status st = Status::OK();
-                // Step 1: Close file_writer (must be done before 
load_segments)
-                auto* file_writer = _seg_files.get(segment_id);
-                if (file_writer && file_writer->state() != 
io::FileWriter::State::CLOSED) {
-                    MonotonicStopWatch close_timer;
-                    close_timer.start();
-                    st = file_writer->close();
-                    close_timer.stop();
-
-                    auto close_time_ms = 
close_timer.elapsed_time_milliseconds();
-                    if (close_time_ms > 1000) {
-                        LOG(INFO) << "file_writer->close() took " << 
close_time_ms
-                                  << "ms for segment_id=" << segment_id
-                                  << ", tablet_id=" << _context.tablet_id
-                                  << ", rowset_id=" << _context.rowset_id;
-                    }
-                    if (!st.ok()) {
-                        return st;
-                    }
-                }
+    const auto submit_time_us = MonotonicMicros();
+    return _calc_delete_bitmap_token->submit_func([this, segment_id,
+                                                   specified_rowsets = 
std::move(specified_rowsets),
+                                                   submit_time_us]() -> Status 
{
+        const auto queue_time_us = MonotonicMicros() - submit_time_us;
+        Status st = Status::OK();
+        // Step 1: Close file_writer (must be done before load_segments)
+        auto* file_writer = _seg_files.get(segment_id);
+        if (file_writer && file_writer->state() != 
io::FileWriter::State::CLOSED) {
+            MonotonicStopWatch close_timer;
+            close_timer.start();
+            st = file_writer->close();
+            close_timer.stop();
+
+            auto close_time_ms = close_timer.elapsed_time_milliseconds();
+            if (close_time_ms > 1000) {
+                LOG(INFO) << "file_writer->close() took " << close_time_ms
+                          << "ms for segment_id=" << segment_id
+                          << ", tablet_id=" << _context.tablet_id
+                          << ", rowset_id=" << _context.rowset_id;
+            }
+            if (!st.ok()) {
+                return st;
+            }
+        }
 
-                OlapStopWatch watch;
-                // Step 2: Build tmp rowset (needs file_writer to be closed)
-                RowsetSharedPtr rowset_ptr;
-                st = _build_tmp(rowset_ptr);
-                if (!st.ok()) {
-                    return st;
-                }
+        OlapStopWatch watch;
+        // Step 2: Build tmp rowset (needs file_writer to be closed)
+        RowsetSharedPtr rowset_ptr;
+        st = _build_tmp(rowset_ptr);
+        if (!st.ok()) {
+            return st;
+        }
 
-                // Step 3: Load segments (needs file_writer to be closed and 
rowset to be built)
-                auto* beta_rowset = 
reinterpret_cast<BetaRowset*>(rowset_ptr.get());
-                std::vector<segment_v2::SegmentSharedPtr> segments;
-                st = beta_rowset->load_segments(segment_id, segment_id + 1, 
&segments);
-                if (!st.ok()) {
-                    return st;
-                }
+        // Step 3: Load segments (needs file_writer to be closed and rowset to 
be built)
+        auto* beta_rowset = reinterpret_cast<BetaRowset*>(rowset_ptr.get());
+        std::vector<segment_v2::SegmentSharedPtr> segments;
+        st = beta_rowset->load_segments(segment_id, segment_id + 1, &segments);
+        if (!st.ok()) {
+            return st;
+        }
 
-                // Step 4: Calculate delete bitmap
-                st = BaseTablet::calc_delete_bitmap(
-                        _context.tablet, rowset_ptr, segments, 
specified_rowsets,
-                        _context.mow_context->delete_bitmap, 
_context.mow_context->max_version,
-                        nullptr, nullptr, nullptr);
-                if (!st.ok()) {
-                    return st;
-                }
+        // Step 4: Calculate delete bitmap
+        st = BaseTablet::calc_delete_bitmap(_context.tablet, rowset_ptr, 
segments,
+                                            specified_rowsets, 
_context.mow_context->delete_bitmap,
+                                            _context.mow_context->max_version, 
nullptr, nullptr,
+                                            nullptr);
+        if (!st.ok()) {
+            return st;
+        }
 
-                size_t total_rows =
-                        std::accumulate(segments.begin(), segments.end(), 0,
-                                        [](size_t sum, const 
segment_v2::SegmentSharedPtr& s) {
-                                            return sum += s->num_rows();
-                                        });
-                LOG(INFO) << "[Memtable Flush] construct delete bitmap tablet: 
"
-                          << _context.tablet->tablet_id()
-                          << ", rowset_ids: " << 
_context.mow_context->rowset_ids->size()
-                          << ", cur max_version: " << 
_context.mow_context->max_version
-                          << ", transaction_id: " << 
_context.mow_context->txn_id
-                          << ", delete_bitmap_count: "
-                          << 
_context.mow_context->delete_bitmap->get_delete_bitmap_count()
-                          << ", delete_bitmap_cardinality: "
-                          << _context.mow_context->delete_bitmap->cardinality()
-                          << ", cost: " << watch.get_elapse_time_us()
-                          << "(us), total rows: " << total_rows;
-                return Status::OK();
-            });
+        size_t total_rows = std::accumulate(segments.begin(), segments.end(), 
0,
+                                            [](size_t sum, const 
segment_v2::SegmentSharedPtr& s) {
+                                                return sum += s->num_rows();
+                                            });
+        LOG(INFO) << "[Memtable Flush] construct delete bitmap tablet: "
+                  << _context.tablet->tablet_id()
+                  << ", rowset_ids: " << 
_context.mow_context->rowset_ids->size()
+                  << ", cur max_version: " << _context.mow_context->max_version
+                  << ", transaction_id: " << _context.mow_context->txn_id
+                  << ", delete_bitmap_count: "
+                  << 
_context.mow_context->delete_bitmap->get_delete_bitmap_count()
+                  << ", delete_bitmap_cardinality: "
+                  << _context.mow_context->delete_bitmap->cardinality()
+                  << ", queue_time_us: " << queue_time_us
+                  << ", cost: " << watch.get_elapse_time_us() << "(us), total 
rows: " << total_rows;
+        return Status::OK();
+    });
 }
 
 Status BetaRowsetWriter::init(const RowsetWriterContext& 
rowset_writer_context) {
diff --git a/be/src/storage/storage_engine.cpp 
b/be/src/storage/storage_engine.cpp
index 2616742465a..2bc9e46b101 100644
--- a/be/src/storage/storage_engine.cpp
+++ b/be/src/storage/storage_engine.cpp
@@ -325,10 +325,12 @@ Status StorageEngine::_open() {
     _memtable_flush_executor->init(_disk_num);
 
     _calc_delete_bitmap_executor = 
std::make_unique<CalcDeleteBitmapExecutor>();
-    _calc_delete_bitmap_executor->init(config::calc_delete_bitmap_max_thread);
+    _calc_delete_bitmap_executor->init("TabletCalcDeleteBitmapThreadPool",
+                                       config::calc_delete_bitmap_max_thread);
 
     _calc_delete_bitmap_executor_for_load = 
std::make_unique<CalcDeleteBitmapExecutor>();
     _calc_delete_bitmap_executor_for_load->init(
+            "LoadCalcDeleteBitmapThreadPool",
             config::calc_delete_bitmap_for_load_max_thread > 0
                     ? config::calc_delete_bitmap_for_load_max_thread
                     : std::max(1, CpuInfo::num_cores() / 2));
diff --git a/be/src/storage/tablet/base_tablet.cpp 
b/be/src/storage/tablet/base_tablet.cpp
index 3cd8747ee79..92161a3476f 100644
--- a/be/src/storage/tablet/base_tablet.cpp
+++ b/be/src/storage/tablet/base_tablet.cpp
@@ -381,7 +381,8 @@ void 
BaseTablet::generate_tablet_meta_copy_unlocked(TabletMeta& new_tablet_meta,
 
 Status BaseTablet::calc_delete_bitmap_between_segments(
         TabletSchemaSPtr schema, RowsetId rowset_id,
-        const std::vector<segment_v2::SegmentSharedPtr>& segments, 
DeleteBitmapPtr delete_bitmap) {
+        const std::vector<segment_v2::SegmentSharedPtr>& segments, 
DeleteBitmapPtr delete_bitmap,
+        int64_t queue_time_us) {
     size_t const num_segments = segments.size();
     if (num_segments < 2) {
         return Status::OK();
@@ -409,9 +410,9 @@ Status BaseTablet::calc_delete_bitmap_between_segments(
     LOG(INFO) << fmt::format(
             "construct delete bitmap between segments, "
             "tablet: {}, rowset: {}, number of segments: {}, bitmap count: {}, 
bitmap cardinality: "
-            "{}, cost {} (us)",
+            "{}, queue_time_us: {}, cost {} (us)",
             tablet_id(), rowset_id.to_string(), num_segments,
-            delete_bitmap->get_delete_bitmap_count(), 
delete_bitmap->cardinality(),
+            delete_bitmap->get_delete_bitmap_count(), 
delete_bitmap->cardinality(), queue_time_us,
             watch.get_elapse_time_us());
     return Status::OK();
 }
@@ -600,7 +601,8 @@ Status 
BaseTablet::calc_segment_delete_bitmap(RowsetSharedPtr rowset,
                                               const 
std::vector<RowsetSharedPtr>& specified_rowsets,
                                               DeleteBitmapPtr delete_bitmap, 
int64_t end_version,
                                               RowsetWriter* rowset_writer,
-                                              DeleteBitmapPtr 
tablet_delete_bitmap) {
+                                              DeleteBitmapPtr 
tablet_delete_bitmap,
+                                              int64_t queue_time_us) {
     OlapStopWatch watch;
     auto rowset_id = rowset->rowset_id();
     Version dummy_version(end_version + 1, end_version + 1);
@@ -869,7 +871,7 @@ Status 
BaseTablet::calc_segment_delete_bitmap(RowsetSharedPtr rowset,
         }
         RETURN_IF_ERROR(rowset_writer->flush_single_block(&ordered_block));
         auto cost_us = watch.get_elapse_time_us();
-        if (config::enable_mow_verbose_log || cost_us > 10 * 1000) {
+        if (config::enable_mow_verbose_log || cost_us > 10 * 1000 || 
queue_time_us > 10 * 1000) {
             LOG(INFO) << "calc segment delete bitmap for "
                       << partial_update_info->partial_update_mode_str()
                       << ", tablet: " << tablet_id() << " rowset: " << 
rowset_id
@@ -878,19 +880,19 @@ Status 
BaseTablet::calc_segment_delete_bitmap(RowsetSharedPtr rowset,
                       << " new generated rows: " << new_generated_rows
                       << " bitmap num: " << 
delete_bitmap->get_delete_bitmap_count()
                       << " bitmap cardinality: " << 
delete_bitmap->cardinality()
-                      << " cost: " << cost_us << "(us)";
+                      << " queue_time_us: " << queue_time_us << ", cost: " << 
cost_us << "(us)";
         }
         return Status::OK();
     }
     auto cost_us = watch.get_elapse_time_us();
-    if (config::enable_mow_verbose_log || cost_us > 10 * 1000) {
+    if (config::enable_mow_verbose_log || cost_us > 10 * 1000 || queue_time_us 
> 10 * 1000) {
         LOG(INFO) << "calc segment delete bitmap, tablet: " << tablet_id()
                   << " rowset: " << rowset_id << " seg_id: " << seg->id()
                   << " dummy_version: " << end_version + 1 << " rows: " << 
seg->num_rows()
                   << " conflict rows: " << conflict_rows
                   << " bitmap num: " << 
delete_bitmap->get_delete_bitmap_count()
-                  << " bitmap cardinality: " << delete_bitmap->cardinality() 
<< " cost: " << cost_us
-                  << "(us)";
+                  << " bitmap cardinality: " << delete_bitmap->cardinality()
+                  << " queue_time_us: " << queue_time_us << ", cost: " << 
cost_us << "(us)";
     }
     return Status::OK();
 }
diff --git a/be/src/storage/tablet/base_tablet.h 
b/be/src/storage/tablet/base_tablet.h
index c26e944b01c..510e994e36c 100644
--- a/be/src/storage/tablet/base_tablet.h
+++ b/be/src/storage/tablet/base_tablet.h
@@ -202,12 +202,13 @@ public:
                                       const std::vector<RowsetSharedPtr>& 
specified_rowsets,
                                       DeleteBitmapPtr delete_bitmap, int64_t 
end_version,
                                       RowsetWriter* rowset_writer,
-                                      DeleteBitmapPtr tablet_delete_bitmap = 
nullptr);
+                                      DeleteBitmapPtr tablet_delete_bitmap = 
nullptr,
+                                      int64_t queue_time_us = 0);
 
     Status calc_delete_bitmap_between_segments(
             TabletSchemaSPtr schema, RowsetId rowset_id,
             const std::vector<segment_v2::SegmentSharedPtr>& segments,
-            DeleteBitmapPtr delete_bitmap);
+            DeleteBitmapPtr delete_bitmap, int64_t queue_time_us = 0);
 
     static Status commit_phase_update_delete_bitmap(
             const BaseTabletSPtr& tablet, const RowsetSharedPtr& rowset,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to