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

liaoxin01 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 c36a40c67b9 [fix](regression) Fix test_ttl_lru_evict and 
test_stale_rowset in cloud file cache (#69847)
c36a40c67b9 is described below

commit c36a40c67b90b7f6b491d88c2d7aa5912f347e03
Author: Xin Liao <[email protected]>
AuthorDate: Mon Nov 2 17:16:23 2026 +0800

    [fix](regression) Fix test_ttl_lru_evict and test_stale_rowset in cloud 
file cache (#69847)
---
 .../cache/compaction/test_stale_rowset.groovy      | 19 ++++++---
 .../cloud_p0/cache/ttl/test_ttl_lru_evict.groovy   | 45 +++++++++++++++++++---
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git 
a/regression-test/suites/cloud_p0/cache/compaction/test_stale_rowset.groovy 
b/regression-test/suites/cloud_p0/cache/compaction/test_stale_rowset.groovy
index bc65e78584a..b1ac9ff5892 100644
--- a/regression-test/suites/cloud_p0/cache/compaction/test_stale_rowset.groovy
+++ b/regression-test/suites/cloud_p0/cache/compaction/test_stale_rowset.groovy
@@ -171,13 +171,20 @@ suite("test_stale_rowset") {
     select count(*) from ${tableName};
     """
 
-    sleep(60000);
-    def backendIdToAfterCompactionCacheSize = getCurCacheSize()
-    for (String[] backend in backends) {
-        if (backend[9].equals("true") && 
backend[19].contains("regression_cluster_name1")) {
-            assertTrue(backendIdToAfterLoadCacheSize.get(backend[0]) >
-                backendIdToAfterCompactionCacheSize.get(backend[0]))
+    // The cache of the input rowsets is removed only when the BE sweeps the 
stale rowsets, and the
+    // file_cache_cache_size metric is refreshed every few seconds after that. 
So poll until it
+    // shrinks instead of reading it once after a fixed wait.
+    def backendIdToAfterCompactionCacheSize = [:]
+    def shrunk = false
+    long deadline = System.currentTimeMillis() + 180000
+    while (!shrunk && System.currentTimeMillis() < deadline) {
+        sleep(5000)
+        backendIdToAfterCompactionCacheSize = getCurCacheSize()
+        shrunk = backendIdToAfterLoadCacheSize.every { id, size ->
+            size > backendIdToAfterCompactionCacheSize.get(id)
         }
     }
+    assertTrue(shrunk, "file cache did not shrink after compaction, after 
load: " +
+            "${backendIdToAfterLoadCacheSize}, after compaction: 
${backendIdToAfterCompactionCacheSize}")
     sql new File("""${context.file.parent}/../ddl/${table}_delete.sql""").text
 }
diff --git 
a/regression-test/suites/cloud_p0/cache/ttl/test_ttl_lru_evict.groovy 
b/regression-test/suites/cloud_p0/cache/ttl/test_ttl_lru_evict.groovy
index e69e59f2e6a..32703fb907b 100644
--- a/regression-test/suites/cloud_p0/cache/ttl/test_ttl_lru_evict.groovy
+++ b/regression-test/suites/cloud_p0/cache/ttl/test_ttl_lru_evict.groovy
@@ -232,11 +232,35 @@ suite("test_ttl_lru_evict") {
 
     long ttl_cache_evict_size_begin = 
getMetricValues("ttl_cache_evict_size")[0]
     long ttl_cache_size_begin = getMetricValues("ttl_cache_size")[0]
-    long cache_capacity = getMetricValues("file_cache_capacity").sum()
+    def path_capacities = getMetricValues("file_cache_capacity")
+    // The capacity is reset for all cache paths at once, so it can only be 
restored when they
+    // have the same capacity.
+    assertEquals(1, path_capacities.unique(false).size(),
+            "cache paths have different capacities: ${path_capacities}")
+    long path_capacity = path_capacities[0]
+    long cache_capacity = path_capacity
+
+    // Sets the capacity of every cache path of the BE.
+    def resetCapacity = { long capacity ->
+        def (code, out, err) = curl("GET", ("http://"; + 
backendIdToBackendIP.get(backendId) + ":" +
+                backendIdToBackendHttpPort.get(backendId) +
+                "/api/file_cache?op=reset&capacity=${capacity}").toString())
+        assertEquals(0, code)
+        assertEquals([capacity] * path_capacities.size(), 
getMetricValues("file_cache_capacity"))
+        cache_capacity = capacity
+        logger.info("file cache capacity of each path reset to ${capacity}")
+    }
+    onFinish {
+        if (cache_capacity != path_capacity) {
+            resetCapacity(path_capacity)
+        }
+    }
 
     // first, we test whether ttl evict actively.
-    // Load to this dup table until the TTL queue overflows. A fixed number of 
loads only
-    // overflows it on a small enough cache, so keep loading, bounded by the 
cache capacity.
+    // Load to this dup table until the TTL queue overflows. TTL blocks are 
evicted only when the
+    // whole cache is full, and filling a large cache can take longer than the 
TTL. Once the TTL
+    // expires, the blocks become NORMAL and are no longer evicted as TTL. So 
the cache is shrunk
+    // to a few loads after the first one.
     long evicted = 0
     long loads = 0
     long max_loads = 10
@@ -244,10 +268,16 @@ suite("test_ttl_lru_evict") {
         load_customer_once("customer_ttl")
         loads++
         if (loads == 1) {
+            // ttl_cache_size is refreshed by the cache monitor, so wait for a 
refresh that
+            // includes the whole load.
+            
sleep(get_be_param("file_cache_background_monitor_interval_ms").toLong() + 1000)
             long bytes_per_load = getMetricValues("ttl_cache_size")[0] - 
ttl_cache_size_begin
             assertTrue(bytes_per_load > 0, "the first load did not add any TTL 
cache")
-            // The TTL queue is part of the capacity, so this many loads 
overflow it for sure.
-            max_loads = Math.max(max_loads, 
cache_capacity.intdiv(bytes_per_load) + 2)
+            if (bytes_per_load * 4 < path_capacity) {
+                resetCapacity(bytes_per_load * 4)
+            }
+            // This many loads overflow the cache for sure.
+            max_loads = Math.max(max_loads, 
cache_capacity.intdiv(bytes_per_load) + 3)
             logger.info("cache capacity: ${cache_capacity}, TTL bytes per 
load: ${bytes_per_load}, " +
                     "max loads: ${max_loads}")
         }
@@ -313,6 +343,11 @@ suite("test_ttl_lru_evict") {
     logger.info("skip cache diff:" + (skip_cache_count_end - 
skip_cache_count_begin).toString())
     assertTrue((skip_cache_count_end - skip_cache_count_begin) < 1000000)
 
+    // The rest of the case does not need a full cache.
+    if (cache_capacity != path_capacity) {
+        resetCapacity(path_capacity)
+    }
+
     // finally, we test whether LRU queue clean itself up when all ttl
     // cache evict after expiration
     // Note: this only applies when the case is run


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

Reply via email to