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

yiguolei 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 648fce07e8f branch-4.0: [Enhancement](Compaction) Add compaction 
metadata size guard to prevent FDB transaction limit exceeded #58567 (#60273)
648fce07e8f is described below

commit 648fce07e8f6363377238aee3f5651adf4a9f784
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Jan 30 16:25:31 2026 +0800

    branch-4.0: [Enhancement](Compaction) Add compaction metadata size guard to 
prevent FDB transaction limit exceeded #58567 (#60273)
    
    Cherry-picked from #58567
    
    Co-authored-by: abmdocrt <[email protected]>
---
 be/src/cloud/cloud_base_compaction.cpp         |   3 +
 be/src/cloud/cloud_cumulative_compaction.cpp   |   2 +
 be/src/cloud/cloud_index_change_compaction.cpp |   7 +-
 be/src/cloud/config.cpp                        |   1 +
 be/src/cloud/config.h                          |   1 +
 be/src/olap/compaction.cpp                     |  92 ++++++++
 be/src/olap/compaction.h                       |  14 ++
 be/test/cloud/cloud_compaction_test.cpp        | 277 +++++++++++++++++++++++++
 8 files changed, 396 insertions(+), 1 deletion(-)

diff --git a/be/src/cloud/cloud_base_compaction.cpp 
b/be/src/cloud/cloud_base_compaction.cpp
index e3f7ae2f730..e0d424c413c 100644
--- a/be/src/cloud/cloud_base_compaction.cpp
+++ b/be/src/cloud/cloud_base_compaction.cpp
@@ -226,6 +226,7 @@ Status CloudBaseCompaction::pick_rowsets_to_compact() {
                     << ", num_cumulative_rowsets=" << _input_rowsets.size() - 1
                     << ", base_compaction_num_cumulative_rowsets="
                     << config::base_compaction_min_rowset_num;
+        apply_txn_size_truncation_and_log("CloudBaseCompaction");
         return Status::OK();
     }
 
@@ -251,6 +252,7 @@ Status CloudBaseCompaction::pick_rowsets_to_compact() {
                     << ", base_size=" << base_size
                     << ", cumulative_base_ratio=" << cumulative_base_ratio
                     << ", policy_ratio=" << base_cumulative_delta_ratio;
+        apply_txn_size_truncation_and_log("CloudBaseCompaction");
         return Status::OK();
     }
 
@@ -263,6 +265,7 @@ Status CloudBaseCompaction::pick_rowsets_to_compact() {
                     << ", interval_since_last_base_compaction="
                     << interval_since_last_base_compaction
                     << ", interval_threshold=" << interval_threshold;
+        apply_txn_size_truncation_and_log("CloudBaseCompaction");
         return Status::OK();
     }
 
diff --git a/be/src/cloud/cloud_cumulative_compaction.cpp 
b/be/src/cloud/cloud_cumulative_compaction.cpp
index 0398f24a5ad..bd2106741d6 100644
--- a/be/src/cloud/cloud_cumulative_compaction.cpp
+++ b/be/src/cloud/cloud_cumulative_compaction.cpp
@@ -532,6 +532,8 @@ Status CloudCumulativeCompaction::pick_rowsets_to_compact() 
{
         return Status::Error<CUMULATIVE_NO_SUITABLE_VERSION>(
                 "no suitable versions: only one rowset and not overlapping");
     }
+
+    apply_txn_size_truncation_and_log("CloudCumulativeCompaction");
     return Status::OK();
 }
 
diff --git a/be/src/cloud/cloud_index_change_compaction.cpp 
b/be/src/cloud/cloud_index_change_compaction.cpp
index b670a48c44a..001b9d64f4b 100644
--- a/be/src/cloud/cloud_index_change_compaction.cpp
+++ b/be/src/cloud/cloud_index_change_compaction.cpp
@@ -69,6 +69,11 @@ Status CloudIndexChangeCompaction::prepare_compact() {
 
     _input_rowsets.push_back(input_rowset);
 
+    // Apply transaction size truncation (usually only 1 rowset for index 
change)
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+    cloud::truncate_rowsets_by_txn_size(_input_rowsets, kept_size, 
truncated_size);
+
     for (auto& rs : _input_rowsets) {
         _input_row_num += rs->num_rows();
         _input_segments += rs->num_segments();
@@ -473,4 +478,4 @@ Status CloudIndexChangeCompaction::garbage_collection() {
     return st;
 }
 
-} // namespace doris
\ No newline at end of file
+} // namespace doris
diff --git a/be/src/cloud/config.cpp b/be/src/cloud/config.cpp
index db6de7b718e..4b59820c4e7 100644
--- a/be/src/cloud/config.cpp
+++ b/be/src/cloud/config.cpp
@@ -56,6 +56,7 @@ DEFINE_mInt32(check_auto_compaction_interval_seconds, "5");
 DEFINE_mInt32(max_base_compaction_task_num_per_disk, "2");
 DEFINE_mBool(prioritize_query_perf_in_compaction, "false");
 DEFINE_mInt32(compaction_max_rowset_count, "10000");
+DEFINE_mInt64(compaction_txn_max_size_bytes, "7340032"); // 7MB
 
 DEFINE_mInt32(refresh_s3_info_interval_s, "60");
 DEFINE_mInt32(vacuum_stale_rowsets_interval_s, "300");
diff --git a/be/src/cloud/config.h b/be/src/cloud/config.h
index 80cfd6de2ed..94ac091f332 100644
--- a/be/src/cloud/config.h
+++ b/be/src/cloud/config.h
@@ -96,6 +96,7 @@ DECLARE_mInt32(check_auto_compaction_interval_seconds);
 DECLARE_mInt32(max_base_compaction_task_num_per_disk);
 DECLARE_mBool(prioritize_query_perf_in_compaction);
 DECLARE_mInt32(compaction_max_rowset_count);
+DECLARE_mInt64(compaction_txn_max_size_bytes);
 
 // CloudStorageEngine config
 DECLARE_mInt32(refresh_s3_info_interval_s);
diff --git a/be/src/olap/compaction.cpp b/be/src/olap/compaction.cpp
index 9c101cd1d28..6826d1d79ae 100644
--- a/be/src/olap/compaction.cpp
+++ b/be/src/olap/compaction.cpp
@@ -39,6 +39,7 @@
 #include "cloud/cloud_meta_mgr.h"
 #include "cloud/cloud_storage_engine.h"
 #include "cloud/cloud_tablet.h"
+#include "cloud/pb_convert.h"
 #include "common/config.h"
 #include "common/status.h"
 #include "cpp/sync_point.h"
@@ -1523,6 +1524,97 @@ int64_t CloudCompactionMixin::initiator() const {
     return HashUtil::hash64(_uuid.data(), _uuid.size(), 0) & 
std::numeric_limits<int64_t>::max();
 }
 
+namespace cloud {
+size_t truncate_rowsets_by_txn_size(std::vector<RowsetSharedPtr>& rowsets, 
int64_t& kept_size_bytes,
+                                    int64_t& truncated_size_bytes) {
+    if (rowsets.empty()) {
+        kept_size_bytes = 0;
+        truncated_size_bytes = 0;
+        return 0;
+    }
+
+    int64_t max_size = config::compaction_txn_max_size_bytes;
+    int64_t cumulative_meta_size = 0;
+    size_t keep_count = 0;
+
+    for (size_t i = 0; i < rowsets.size(); ++i) {
+        const auto& rs = rowsets[i];
+
+        // Estimate rowset meta size using doris_rowset_meta_to_cloud
+        auto cloud_meta = 
cloud::doris_rowset_meta_to_cloud(rs->rowset_meta()->get_rowset_pb(true));
+        int64_t rowset_meta_size = cloud_meta.ByteSizeLong();
+
+        cumulative_meta_size += rowset_meta_size;
+
+        if (keep_count > 0 && cumulative_meta_size > max_size) {
+            // Rollback and stop
+            cumulative_meta_size -= rowset_meta_size;
+            break;
+        }
+
+        keep_count++;
+    }
+
+    // Ensure at least 1 rowset is kept
+    if (keep_count == 0) {
+        keep_count = 1;
+        // Recalculate size for the first rowset
+        const auto& rs = rowsets[0];
+        auto cloud_meta = 
cloud::doris_rowset_meta_to_cloud(rs->rowset_meta()->get_rowset_pb());
+        cumulative_meta_size = cloud_meta.ByteSizeLong();
+    }
+
+    // Calculate truncated size
+    int64_t truncated_total_size = 0;
+    size_t truncated_count = rowsets.size() - keep_count;
+    if (truncated_count > 0) {
+        for (size_t i = keep_count; i < rowsets.size(); ++i) {
+            auto cloud_meta =
+                    
cloud::doris_rowset_meta_to_cloud(rowsets[i]->rowset_meta()->get_rowset_pb());
+            truncated_total_size += cloud_meta.ByteSizeLong();
+        }
+        rowsets.resize(keep_count);
+    }
+
+    kept_size_bytes = cumulative_meta_size;
+    truncated_size_bytes = truncated_total_size;
+    return truncated_count;
+}
+} // namespace cloud
+
+size_t CloudCompactionMixin::apply_txn_size_truncation_and_log(const 
std::string& compaction_name) {
+    if (_input_rowsets.empty()) {
+        return 0;
+    }
+
+    int64_t original_count = _input_rowsets.size();
+    int64_t original_start_version = _input_rowsets.front()->start_version();
+    int64_t original_end_version = _input_rowsets.back()->end_version();
+
+    int64_t final_size = 0;
+    int64_t truncated_size = 0;
+    size_t truncated_count =
+            cloud::truncate_rowsets_by_txn_size(_input_rowsets, final_size, 
truncated_size);
+
+    if (truncated_count > 0) {
+        int64_t original_size = final_size + truncated_size;
+        LOG(INFO) << compaction_name << " txn size estimation truncate"
+                  << ", tablet_id=" << _tablet->tablet_id() << ", 
original_version_range=["
+                  << original_start_version << "-" << original_end_version
+                  << "], final_version_range=[" << 
_input_rowsets.front()->start_version() << "-"
+                  << _input_rowsets.back()->end_version()
+                  << "], original_rowset_count=" << original_count
+                  << ", final_rowset_count=" << _input_rowsets.size()
+                  << ", truncated_rowset_count=" << truncated_count
+                  << ", original_size_bytes=" << original_size
+                  << ", final_size_bytes=" << final_size
+                  << ", truncated_size_bytes=" << truncated_size
+                  << ", threshold_bytes=" << 
config::compaction_txn_max_size_bytes;
+    }
+
+    return truncated_count;
+}
+
 Status CloudCompactionMixin::execute_compact() {
     TEST_INJECTION_POINT("Compaction::do_compaction");
     int64_t permits = get_compaction_permits();
diff --git a/be/src/olap/compaction.h b/be/src/olap/compaction.h
index fa111590933..5e11e253f1e 100644
--- a/be/src/olap/compaction.h
+++ b/be/src/olap/compaction.h
@@ -228,6 +228,10 @@ protected:
 
     virtual Status garbage_collection();
 
+    // Helper function to apply truncation and log the result
+    // Returns the number of rowsets that were truncated
+    size_t apply_txn_size_truncation_and_log(const std::string& 
compaction_name);
+
     CloudStorageEngine& _engine;
 
     std::string _uuid;
@@ -254,4 +258,14 @@ private:
     bool should_cache_compaction_output();
 };
 
+namespace cloud {
+
+// Truncate rowsets based on estimated transaction metadata size
+// Returns the number of rowsets that were truncated (removed from the end)
+// Only considers rowset meta size (using doris_rowset_meta_to_cloud for 
estimation)
+size_t truncate_rowsets_by_txn_size(std::vector<RowsetSharedPtr>& rowsets, 
int64_t& kept_size_bytes,
+                                    int64_t& truncated_size_bytes);
+
+} // namespace cloud
+
 } // namespace doris
diff --git a/be/test/cloud/cloud_compaction_test.cpp 
b/be/test/cloud/cloud_compaction_test.cpp
index bfbc6e1baf2..9800b40d5eb 100644
--- a/be/test/cloud/cloud_compaction_test.cpp
+++ b/be/test/cloud/cloud_compaction_test.cpp
@@ -226,6 +226,14 @@ public:
         _input_rowsets = rowsets;
     }
 
+    // Get input rowsets for verification
+    const std::vector<RowsetSharedPtr>& get_input_rowsets() const { return 
_input_rowsets; }
+
+    // Expose the protected method for testing
+    size_t test_apply_txn_size_truncation_and_log(const std::string& 
compaction_name) {
+        return apply_txn_size_truncation_and_log(compaction_name);
+    }
+
     Status prepare_compact() override { return Status::OK(); }
 
     ReaderType compaction_type() const override { return 
ReaderType::READER_CUMULATIVE_COMPACTION; }
@@ -430,4 +438,273 @@ TEST_F(CloudCompactionTest, 
should_cache_compaction_output) {
     ASSERT_EQ(cloud_base_compaction.should_cache_compaction_output(), true);
     LOG(INFO) << "should_cache_compaction_output done";
 }
+
+TEST_F(CloudCompactionTest, test_truncate_rowsets_by_txn_size_empty_input) {
+    std::vector<RowsetSharedPtr> rowsets;
+    int64_t kept_size = 100;
+    int64_t truncated_size = 50;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(kept_size, 0);
+    ASSERT_EQ(truncated_size, 0);
+    ASSERT_EQ(rowsets.size(), 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_truncate_rowsets_by_txn_size_single_rowset_under_limit) {
+    // Create a single rowset
+    std::vector<RowsetSharedPtr> rowsets;
+    RowsetSharedPtr rowset1 = create_rowset(Version(2, 2), 1, false, 1024);
+    ASSERT_TRUE(rowset1 != nullptr);
+    rowsets.push_back(rowset1);
+
+    // Set a large max size
+    config::compaction_txn_max_size_bytes = 1024 * 1024 * 1024; // 1GB
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(rowsets.size(), 1);
+    ASSERT_GT(kept_size, 0);
+    ASSERT_EQ(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_truncate_rowsets_by_txn_size_multiple_rowsets_all_fit) {
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 0; i < 5; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    config::compaction_txn_max_size_bytes = 1024 * 1024 * 1024; // 1GB
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(rowsets.size(), 5);
+    ASSERT_GT(kept_size, 0);
+    ASSERT_EQ(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, test_truncate_rowsets_by_txn_size_exceeds_limit) {
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 0; i < 10; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    // Set a very small max size to force truncation
+    config::compaction_txn_max_size_bytes = 50; // 50 bytes, should keep only 
a few rowsets
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    // Should truncate some rowsets
+    ASSERT_GT(truncated, 0);
+    ASSERT_LT(rowsets.size(), 10);
+    ASSERT_GT(rowsets.size(), 0); // At least 1 rowset kept
+    ASSERT_GT(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_truncate_rowsets_by_txn_size_first_rowset_exceeds_limit) {
+    std::vector<RowsetSharedPtr> rowsets;
+    RowsetSharedPtr rowset1 = create_rowset(Version(0, 0), 1, false, 1024);
+    ASSERT_TRUE(rowset1 != nullptr);
+    rowsets.push_back(rowset1);
+
+    // Set max size smaller than the first rowset's metadata size
+    config::compaction_txn_max_size_bytes = 1; // 1 byte
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    // Should keep at least 1 rowset even if it exceeds the limit
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(rowsets.size(), 1);
+    ASSERT_GT(kept_size, config::compaction_txn_max_size_bytes);
+    ASSERT_EQ(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, test_truncate_rowsets_by_txn_size_exact_boundary) {
+    std::vector<RowsetSharedPtr> rowsets;
+    RowsetSharedPtr rowset1 = create_rowset(Version(0, 0), 1, false, 1024);
+    ASSERT_TRUE(rowset1 != nullptr);
+    rowsets.push_back(rowset1);
+
+    // Get the actual size of the first rowset
+    int64_t first_kept_size = 0;
+    int64_t first_truncated_size = 0;
+
+    std::vector<RowsetSharedPtr> temp_rowsets = {rowset1};
+    cloud::truncate_rowsets_by_txn_size(temp_rowsets, first_kept_size, 
first_truncated_size);
+
+    // Add more rowsets
+    for (int i = 1; i < 5; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    // Set max size to exactly the size of first rowset
+    config::compaction_txn_max_size_bytes = first_kept_size;
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    // Should keep only 1 rowset at the boundary
+    ASSERT_EQ(rowsets.size(), 1);
+    ASSERT_EQ(truncated, 4);
+    ASSERT_EQ(kept_size, first_kept_size);
+    ASSERT_GT(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_truncate_rowsets_by_txn_size_output_parameters) {
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 0; i < 3; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    config::compaction_txn_max_size_bytes = 1024 * 1024;
+
+    int64_t kept_size = 0;
+    int64_t truncated_size = 0;
+
+    size_t truncated = cloud::truncate_rowsets_by_txn_size(rowsets, kept_size, 
truncated_size);
+
+    // Verify output parameters are set correctly
+    ASSERT_EQ(truncated, 0); // All rowsets fit
+    ASSERT_EQ(rowsets.size(), 3);
+    ASSERT_GT(kept_size, 0);
+    ASSERT_EQ(truncated_size, 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_apply_txn_size_truncation_and_log_empty_input) {
+    CloudTabletSPtr tablet = std::make_shared<CloudTablet>(_engine, 
_tablet_meta);
+    TestableCloudCompaction compaction(_engine, tablet);
+
+    // Test with empty input rowsets
+    std::vector<RowsetSharedPtr> empty_rowsets;
+    compaction.set_input_rowsets(empty_rowsets);
+
+    size_t truncated = 
compaction.test_apply_txn_size_truncation_and_log("test_compaction");
+
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(compaction.get_input_rowsets().size(), 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_apply_txn_size_truncation_and_log_no_truncation) {
+    CloudTabletSPtr tablet = std::make_shared<CloudTablet>(_engine, 
_tablet_meta);
+    TestableCloudCompaction compaction(_engine, tablet);
+
+    // Create rowsets that fit within the limit
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 0; i < 3; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    compaction.set_input_rowsets(rowsets);
+
+    // Set a large max size
+    config::compaction_txn_max_size_bytes = 1024 * 1024 * 1024; // 1GB
+
+    size_t truncated = 
compaction.test_apply_txn_size_truncation_and_log("test_compaction");
+
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(compaction.get_input_rowsets().size(), 3);
+}
+
+TEST_F(CloudCompactionTest, 
test_apply_txn_size_truncation_and_log_with_truncation) {
+    CloudTabletSPtr tablet = std::make_shared<CloudTablet>(_engine, 
_tablet_meta);
+    TestableCloudCompaction compaction(_engine, tablet);
+
+    // Create multiple rowsets
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 0; i < 10; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    compaction.set_input_rowsets(rowsets);
+
+    // Set a small max size to force truncation
+    config::compaction_txn_max_size_bytes = 100; // Very small to force 
truncation
+
+    size_t truncated = 
compaction.test_apply_txn_size_truncation_and_log("test_compaction");
+
+    // Should have truncated some rowsets
+    ASSERT_GT(truncated, 0);
+    ASSERT_LT(compaction.get_input_rowsets().size(), 10);
+    ASSERT_GT(compaction.get_input_rowsets().size(), 0);
+}
+
+TEST_F(CloudCompactionTest, 
test_apply_txn_size_truncation_and_log_version_range) {
+    CloudTabletSPtr tablet = std::make_shared<CloudTablet>(_engine, 
_tablet_meta);
+    TestableCloudCompaction compaction(_engine, tablet);
+
+    // Create rowsets with consecutive versions
+    std::vector<RowsetSharedPtr> rowsets;
+    for (int i = 10; i < 20; i++) {
+        RowsetSharedPtr rowset = create_rowset(Version(i, i), 1, false, 1024);
+        ASSERT_TRUE(rowset != nullptr);
+        rowsets.push_back(rowset);
+    }
+
+    compaction.set_input_rowsets(rowsets);
+
+    // Set a size that will keep first 5 rowsets
+    config::compaction_txn_max_size_bytes = 100; // Small enough to truncate
+
+    size_t truncated = 
compaction.test_apply_txn_size_truncation_and_log("base_compaction");
+
+    if (truncated > 0) {
+        // Verify that the version range is adjusted correctly
+        ASSERT_GT(compaction.get_input_rowsets().size(), 0);
+        // First rowset should still start at version 10
+        ASSERT_EQ(compaction.get_input_rowsets().front()->start_version(), 10);
+        // Last rowset version should be less than 19
+        ASSERT_LT(compaction.get_input_rowsets().back()->end_version(), 20);
+    }
+}
+
+TEST_F(CloudCompactionTest, 
test_apply_txn_size_truncation_and_log_single_large_rowset) {
+    CloudTabletSPtr tablet = std::make_shared<CloudTablet>(_engine, 
_tablet_meta);
+    TestableCloudCompaction compaction(_engine, tablet);
+
+    // Create a single large rowset
+    std::vector<RowsetSharedPtr> rowsets;
+    RowsetSharedPtr rowset = create_rowset(Version(0, 0), 1, false, 1024 * 
1024);
+    ASSERT_TRUE(rowset != nullptr);
+    rowsets.push_back(rowset);
+
+    compaction.set_input_rowsets(rowsets);
+
+    // Set max size smaller than the rowset's metadata size
+    config::compaction_txn_max_size_bytes = 1;
+
+    size_t truncated = 
compaction.test_apply_txn_size_truncation_and_log("cumu_compaction");
+
+    // Should keep at least 1 rowset even if it exceeds the limit
+    ASSERT_EQ(truncated, 0);
+    ASSERT_EQ(compaction.get_input_rowsets().size(), 1);
+}
 } // namespace doris


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

Reply via email to