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

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


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 013b980b2bb branch-4.0: [fix](cloud) Preserve resource IDs when 
recycling empty rowsets #65862 (#65922)
013b980b2bb is described below

commit 013b980b2bb448cf946ee93e156c3cb0dad442ee
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Jul 27 17:36:44 2026 +0800

    branch-4.0: [fix](cloud) Preserve resource IDs when recycling empty rowsets 
#65862 (#65922)
    
    Cherry-picked from #65862
    
    Co-authored-by: Yixuan Wang <[email protected]>
---
 cloud/src/recycler/recycler.cpp | 17 ++++++++---------
 cloud/test/recycler_test.cpp    | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/cloud/src/recycler/recycler.cpp b/cloud/src/recycler/recycler.cpp
index aee8559bd11..eab850036f4 100644
--- a/cloud/src/recycler/recycler.cpp
+++ b/cloud/src/recycler/recycler.cpp
@@ -4314,16 +4314,15 @@ int InstanceRecycler::recycle_tablet(int64_t tablet_id, 
RecyclerMetricsContext&
     
TEST_SYNC_POINT_CALLBACK("InstanceRecycler::recycle_tablet.create_rowset_meta", 
&resp);
 
     for (const auto& rs_meta : resp.rowset_meta()) {
-        // Empty rowsets have no segment objects to delete, so they do not 
need a resource id.
-        if (rs_meta.num_segments() <= 0) {
-            LOG_INFO("rowset meta has no segments, skip this rowset")
-                    .tag("rs_meta", rs_meta.ShortDebugString())
-                    .tag("instance_id", instance_id_)
-                    .tag("tablet_id", tablet_id);
-            recycle_rowsets_number += 1;
-            continue;
-        }
         if (!rs_meta.has_resource_id() || rs_meta.resource_id().empty()) {
+            if (rs_meta.num_segments() <= 0) {
+                LOG_INFO("rowset meta has no segments and no resource id, skip 
this rowset")
+                        .tag("rs_meta", rs_meta.ShortDebugString())
+                        .tag("instance_id", instance_id_)
+                        .tag("tablet_id", tablet_id);
+                recycle_rowsets_number += 1;
+                continue;
+            }
             LOG_WARNING("rowset meta has a missing or empty resource id, 
impossible!")
                     .tag("rs_meta", rs_meta.ShortDebugString())
                     .tag("instance_id", instance_id_)
diff --git a/cloud/test/recycler_test.cpp b/cloud/test/recycler_test.cpp
index 218f7fa57f6..aa1aebba388 100644
--- a/cloud/test/recycler_test.cpp
+++ b/cloud/test/recycler_test.cpp
@@ -6782,6 +6782,44 @@ TEST(RecyclerTest, 
recycle_tablet_with_empty_resource_id_and_no_segments) {
     EXPECT_EQ(recycler.recycle_tablet(0, ctx), 0);
 }
 
+TEST(RecyclerTest, recycle_tablet_with_resource_id_and_no_segments) {
+    auto* sp = SyncPoint::get_instance();
+    DORIS_CLOUD_DEFER {
+        sp->clear_all_call_backs();
+        sp->clear_trace();
+        sp->disable_processing();
+    };
+
+    auto txn_kv = std::make_shared<MemTxnKv>();
+    EXPECT_EQ(txn_kv->init(), 0);
+    InstanceInfoPB instance;
+    instance.set_instance_id("test_instance");
+
+    auto accessor = std::make_shared<MockAccessor>();
+    constexpr int64_t tablet_id = 1234;
+    EXPECT_EQ(accessor->put_file("data/1234/orphan.dat", ""), 0);
+
+    sp->set_call_back("InstanceRecycler::recycle_tablet.create_rowset_meta", 
[](auto&& args) {
+        auto* resp = try_any_cast<GetRowsetResponse*>(args[0]);
+        auto* rs = resp->add_rowset_meta();
+        rs->set_num_segments(0);
+        rs->set_resource_id("resource_id");
+        rs = resp->add_rowset_meta();
+        rs->set_num_segments(0);
+    });
+    sp->enable_processing();
+
+    InstanceRecycler recycler(txn_kv, instance, thread_group,
+                              std::make_shared<TxnLazyCommitter>(txn_kv));
+    EXPECT_EQ(recycler.init(), 0);
+    recycler.TEST_add_accessor("resource_id", accessor);
+
+    EXPECT_EQ(accessor->exists("data/1234/orphan.dat"), 0);
+    RecyclerMetricsContext ctx;
+    EXPECT_EQ(recycler.recycle_tablet(tablet_id, ctx), 0);
+    EXPECT_EQ(accessor->exists("data/1234/orphan.dat"), 1);
+}
+
 TEST(RecyclerTest, recycle_tablet_with_wrong_resource_id) {
     auto* sp = SyncPoint::get_instance();
     DORIS_CLOUD_DEFER {


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

Reply via email to