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

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 972d0c8b0ae branch-4.1: [fix](spill) Record the spill read deserialize 
timer #67041 (#67059)
972d0c8b0ae is described below

commit 972d0c8b0aee52779394d2cb25fe6980d8b387ce
Author: Xiangyi Zhu <[email protected]>
AuthorDate: Tue Aug 25 10:40:29 2026 +0800

    branch-4.1: [fix](spill) Record the spill read deserialize timer #67041 
(#67059)
    
    ### What problem does this PR solve?
    
    Issue Number: close #67040
    
    Related PR: #67041
    
    Problem Summary:
    
    Cherry-picked from #67041. The automatic pick failed with conflicts in
    the three test files, so this is a manual backport.
    
    `SpillReadDeserializeBlockTime` is always `0` in query profiles on
    branch-4.1 — the time spent deserializing spilled blocks is never
    recorded.
    
    `PipelineXSpillLocalState` registers the counter as
    `"SpillReadDeserializeBlockTime"` (`be/src/exec/operator/operator.h`),
    but `SpillFileReader` looked it up with a literal that is missing an
    `s`:
    
    ```cpp
    // be/src/exec/spill/spill_file_reader.cpp
    _deserialize_timer = 
custom_profile->get_counter("SpillReadDerializeBlockTime");
    //                                                        ^^^ Derialize
    ```
    
    `get_counter()` returns `nullptr` for the unknown name and `ScopedTimer`
    returns early on a null counter, so `SCOPED_TIMER(_deserialize_timer)`
    in `SpillFileReader::read()` silently measures nothing.
    
    **Difference from the master PR:** #67041 resolves every spill read
    counter through the shared `profile::` name constants, but
    `be/src/runtime/runtime_profile_counter_names.h` does not exist on
    branch-4.1. This backport therefore keeps the minimal spelling fix
    rather than porting the constant refactor — that is also what caused the
    automatic cherry-pick conflict.
    
    Changes:
    
    1. `SpillFileReader` looks the counter up under the name the operator
    actually registers.
    2. `spill_file_test.cpp` and `spill_repartitioner_test.cpp` registered
    the same misspelling by hand, which is why the gap went unnoticed: the
    reader's lookup matched in tests while returning null in a real query.
    They now register the canonical name.
    3. `spillable_operator_test_helper` registered `SpillReadFileTime` and
    `SpillReadDeserializeBlockTime` as `TUnit::UNIT`. That stayed harmless
    only while the deserialize lookup resolved to null; once it resolves,
    `SCOPED_TIMER`'s `DCHECK_EQ(counter->type(), TUnit::TIME_NS)` would
    fire, so both are registered as timers.
    
    ### Release note
    
    Fix `SpillReadDeserializeBlockTime` always being 0 in query profiles.
    
    ### Check List (For Author)
    
    - Test
        - [x] Unit Test
    
    Ported `SpillFileTest.ReadDeserializeTimerIsRecorded` from #67041. It
    fails before
    this change: with the test registering the canonical name, the reader's
    misspelled
    lookup yields a null counter and the timer stays at 0 after a real read.
    The test
    also asserts the misspelled name is absent, so it cannot be
    reintroduced.
    
    - Behavior changed:
        - [x] No.
    
    Profile-only fix. The counter already existed and was already reported;
    it was
          simply never updated. No counter is added, removed, or renamed.
    
    - Does this need documentation?
        - [x] No.
---
 be/src/exec/spill/spill_file_reader.cpp            |  2 +-
 .../operator/spillable_operator_test_helper.cpp    |  7 ++-
 be/test/vec/spill/spill_file_test.cpp              | 52 +++++++++++++++++++++-
 be/test/vec/spill/spill_repartitioner_test.cpp     |  2 +-
 4 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/be/src/exec/spill/spill_file_reader.cpp 
b/be/src/exec/spill/spill_file_reader.cpp
index 50609d93f42..a0c00266e52 100644
--- a/be/src/exec/spill/spill_file_reader.cpp
+++ b/be/src/exec/spill/spill_file_reader.cpp
@@ -48,7 +48,7 @@ SpillFileReader::SpillFileReader(RuntimeState* state, 
RuntimeProfile* profile,
     RuntimeProfile* custom_profile = profile->get_child("CustomCounters");
     DCHECK(custom_profile != nullptr);
     _read_file_timer = custom_profile->get_counter("SpillReadFileTime");
-    _deserialize_timer = 
custom_profile->get_counter("SpillReadDerializeBlockTime");
+    _deserialize_timer = 
custom_profile->get_counter("SpillReadDeserializeBlockTime");
     _read_block_count = custom_profile->get_counter("SpillReadBlockCount");
     _read_block_data_size = custom_profile->get_counter("SpillReadBlockBytes");
     _read_file_size = custom_profile->get_counter("SpillReadFileBytes");
diff --git a/be/test/exec/operator/spillable_operator_test_helper.cpp 
b/be/test/exec/operator/spillable_operator_test_helper.cpp
index fb87b156545..57d7eaa438c 100644
--- a/be/test/exec/operator/spillable_operator_test_helper.cpp
+++ b/be/test/exec/operator/spillable_operator_test_helper.cpp
@@ -52,8 +52,11 @@ void SpillableOperatorTestHelper::SetUp() {
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillWriteBlockBytes", 
TUnit::BYTES, 1);
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillWriteFileBytes", 
TUnit::BYTES, 1);
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillWriteRows", 
TUnit::UNIT, 1);
-    ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillReadFileTime", 
TUnit::UNIT, 1);
-    ADD_COUNTER_WITH_LEVEL(custom_profile.get(), 
"SpillReadDeserializeBlockTime", TUnit::UNIT, 1);
+    // Both are consumed through SCOPED_TIMER in SpillFileReader, which 
DCHECKs the counter
+    // is TUnit::TIME_NS. Registering them as plain UNIT counters only stayed 
harmless while
+    // the deserialize lookup was misspelled and resolved to null.
+    ADD_TIMER_WITH_LEVEL(custom_profile.get(), "SpillReadFileTime", 1);
+    ADD_TIMER_WITH_LEVEL(custom_profile.get(), 
"SpillReadDeserializeBlockTime", 1);
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillReadBlockCount", 
TUnit::UNIT, 1);
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillReadBlockBytes", 
TUnit::UNIT, 1);
     ADD_COUNTER_WITH_LEVEL(custom_profile.get(), "SpillReadFileBytes", 
TUnit::UNIT, 1);
diff --git a/be/test/vec/spill/spill_file_test.cpp 
b/be/test/vec/spill/spill_file_test.cpp
index 11b16df1712..286a056c3cf 100644
--- a/be/test/vec/spill/spill_file_test.cpp
+++ b/be/test/vec/spill/spill_file_test.cpp
@@ -73,7 +73,7 @@ protected:
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillWriteFileBytes", 
TUnit::BYTES, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillWriteRows", 
TUnit::UNIT, 1);
         ADD_TIMER_WITH_LEVEL(_custom_profile.get(), "SpillReadFileTime", 1);
-        ADD_TIMER_WITH_LEVEL(_custom_profile.get(), 
"SpillReadDerializeBlockTime", 1);
+        ADD_TIMER_WITH_LEVEL(_custom_profile.get(), 
"SpillReadDeserializeBlockTime", 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadBlockCount", 
TUnit::UNIT, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadBlockBytes", 
TUnit::UNIT, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadFileBytes", 
TUnit::UNIT, 1);
@@ -1451,6 +1451,56 @@ TEST_F(SpillFileTest, ReadCounters) {
     ASSERT_GT(read_file_size->value(), 0);
 }
 
+// Regression test: SpillFileReader used to look up the deserialize timer 
under a
+// misspelled name ("SpillReadDerializeBlockTime"), so get_counter() returned 
null and
+// SCOPED_TIMER silently recorded nothing. The counter stayed at 0 in every 
profile.
+TEST_F(SpillFileTest, ReadDeserializeTimerIsRecorded) {
+    SpillFileSPtr spill_file;
+    auto st = ExecEnv::GetInstance()->spill_file_mgr()->create_spill_file(
+            "test_query/read_deserialize_timer", spill_file);
+    ASSERT_TRUE(st.ok());
+
+    {
+        SpillFileWriterSPtr writer;
+        st = spill_file->create_writer(_runtime_state.get(), _profile.get(), 
writer);
+        ASSERT_TRUE(st.ok());
+
+        auto block = _create_int_block({1, 2, 3, 4, 5});
+        st = writer->write_block(_runtime_state.get(), block);
+        ASSERT_TRUE(st.ok());
+
+        st = writer->close();
+        ASSERT_TRUE(st.ok());
+    }
+
+    // The timer is registered under the canonical name and must still be 
untouched
+    // before any read happens.
+    auto* deserialize_timer = 
_custom_profile->get_counter("SpillReadDeserializeBlockTime");
+    ASSERT_TRUE(deserialize_timer != nullptr);
+    ASSERT_EQ(deserialize_timer->value(), 0);
+
+    auto reader = spill_file->create_reader(_runtime_state.get(), 
_profile.get());
+    st = reader->open();
+    ASSERT_TRUE(st.ok());
+
+    Block block;
+    bool eos = false;
+    st = reader->read(&block, &eos);
+    ASSERT_TRUE(st.ok());
+    ASSERT_EQ(block.rows(), 5);
+
+    st = reader->close();
+    ASSERT_TRUE(st.ok());
+
+    // Deserializing a real block must land on the canonical counter. This is 
0 whenever
+    // the reader's lookup name does not match what the operator registered.
+    ASSERT_GT(deserialize_timer->value(), 0);
+
+    // The misspelled name must not exist: if it reappears, some caller 
registered it and
+    // the two spellings will drift apart again.
+    ASSERT_TRUE(_custom_profile->get_counter("SpillReadDerializeBlockTime") == 
nullptr);
+}
+
 // ═══════════════════════════════════════════════════════════════════════
 // SpillDataDir tests
 // ═══════════════════════════════════════════════════════════════════════
diff --git a/be/test/vec/spill/spill_repartitioner_test.cpp 
b/be/test/vec/spill/spill_repartitioner_test.cpp
index 53ffcf9f0ac..b630c0d8920 100644
--- a/be/test/vec/spill/spill_repartitioner_test.cpp
+++ b/be/test/vec/spill/spill_repartitioner_test.cpp
@@ -67,7 +67,7 @@ protected:
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillWriteFileBytes", 
TUnit::BYTES, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillWriteRows", 
TUnit::UNIT, 1);
         ADD_TIMER_WITH_LEVEL(_custom_profile.get(), "SpillReadFileTime", 1);
-        ADD_TIMER_WITH_LEVEL(_custom_profile.get(), 
"SpillReadDerializeBlockTime", 1);
+        ADD_TIMER_WITH_LEVEL(_custom_profile.get(), 
"SpillReadDeserializeBlockTime", 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadBlockCount", 
TUnit::UNIT, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadBlockBytes", 
TUnit::UNIT, 1);
         ADD_COUNTER_WITH_LEVEL(_custom_profile.get(), "SpillReadFileBytes", 
TUnit::UNIT, 1);


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

Reply via email to