This is an automated email from the ASF dual-hosted git repository.
hello-stephen 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 01f3d7c8f08 [fix](regression) Wait for stable colocate groups in plan
tests (#64361)
01f3d7c8f08 is described below
commit 01f3d7c8f08ce759c13349c8d53718f8c06aae59
Author: morrySnow <[email protected]>
AuthorDate: Wed Jun 10 20:36:53 2026 +0800
[fix](regression) Wait for stable colocate groups in plan tests (#64361)
Problem Summary:
Colocate join plan assertions may run before
`ColocateTableCheckerAndBalancer` marks the colocate group stable. In
that state, Nereids can omit `COLOCATE` from the plan and make otherwise
correct regression cases fail intermittently.
This PR adds a shared `waitForColocateGroupStable` helper to the
regression test framework. It polls `SHOW PROC '/colocation_group'`
until the target group's `IsStable` value is true, and fails on timeout.
All positive `COLOCATE` plan assertions backed by explicit
`colocate_with` groups now wait for stability first. The existing
backup/restore-local waiting closure is replaced with the shared helper.
---
.../org/apache/doris/regression/suite/Suite.groovy | 15 +++++++++++
.../test_backup_restore_colocate.groovy | 31 ++++------------------
.../test_colocate_join_of_column_order.groovy | 2 ++
.../query_p0/join/colocate_join_with_rollup.groovy | 1 +
4 files changed, 23 insertions(+), 26 deletions(-)
diff --git
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
index 4c5d48b115b..d1f6dd2c4fd 100644
---
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
+++
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
@@ -992,6 +992,21 @@ class Suite implements GroovyInterceptable {
throw new RuntimeException("dictionary ${dictName} are not ready,
status: ${result}")
}
+ void waitForColocateGroupStable(String groupName, int timeoutSeconds = 60)
{
+ waitForColocateGroupStable(context.dbName, groupName, timeoutSeconds)
+ }
+
+ void waitForColocateGroupStable(String dbName, String groupName, int
timeoutSeconds = 60) {
+ String fullGroupName = "${dbName}.${groupName}"
+ logger.info("wait colocate group ${fullGroupName} stable")
+ awaitUntil(timeoutSeconds) {
+ def groups = sql_return_maparray("SHOW PROC '/colocation_group'")
+ def group = groups.find { it.GroupName == fullGroupName }
+ return group != null && group.IsStable == "true"
+ }
+ logger.info("colocate group ${fullGroupName} is stable")
+ }
+
void flightRecord(Closure actionSupplier) {
runAction(new FlightRecordAction(context), actionSupplier)
}
diff --git
a/regression-test/suites/backup_restore/test_backup_restore_colocate.groovy
b/regression-test/suites/backup_restore/test_backup_restore_colocate.groovy
index 92e907fcb92..f53146dca8d 100644
--- a/regression-test/suites/backup_restore/test_backup_restore_colocate.groovy
+++ b/regression-test/suites/backup_restore/test_backup_restore_colocate.groovy
@@ -95,6 +95,7 @@ suite("test_backup_restore_colocate",
"backup_restore,external") {
res = sql "SELECT * FROM ${dbName}.${tableName2}"
assertEquals(res.size(), insert_num)
+ waitForColocateGroupStable(dbName, groupName)
explain {
sql("${query}")
contains("COLOCATE")
@@ -200,7 +201,7 @@ suite("test_backup_restore_colocate",
"backup_restore,external") {
res = sql "SELECT * FROM ${dbName}.${tableName2}"
assertEquals(res.size(), insert_num)
-
+ waitForColocateGroupStable(dbName, groupName)
explain {
sql("${query}")
contains("COLOCATE")
@@ -376,26 +377,6 @@ suite("test_backup_restore_colocate_with_partition",
"backup_restore") {
assertTrue(result.ColocateMismatchNum as int == 0)
}
- // Wait until the colocate group of `db_name`.`group_name` becomes stable.
- // After RESTORE creates a brand-new colocate group in a new db, the group
- // is unstable until ColocateTableCheckerAndBalancer scans it (default
every
- // tablet_checker_interval_ms = 20s). Nereids skips colocate join while the
- // group is unstable, so EXPLAIN right after RESTORE FINISHED can miss
COLOCATE.
- def waitColocateGroupStable = { db_name, group_name ->
- def fullName = "${db_name}.${group_name}".toString()
- def deadline = System.currentTimeMillis() + 60_000
- while (System.currentTimeMillis() < deadline) {
- def groups = sql_return_maparray("SHOW PROC '/colocation_group'")
- def g = groups.find { it.GroupName == fullName }
- if (g != null && g.IsStable == "true") {
- log.info("colocate group ${fullName} is stable")
- return
- }
- sleep(1000)
- }
- log.warn("colocate group ${fullName} did not become stable within 60s")
- }
-
def syncer = getSyncer()
syncer.createS3Repository(repoName)
@@ -466,6 +447,7 @@ suite("test_backup_restore_colocate_with_partition",
"backup_restore") {
res = sql "SELECT * FROM ${dbName}.${tableName2}"
assertEquals(res.size(), insert_num)
+ waitForColocateGroupStable(dbName, groupName)
explain {
sql("${query}")
contains("COLOCATE")
@@ -569,7 +551,7 @@ suite("test_backup_restore_colocate_with_partition",
"backup_restore") {
res = sql "SELECT * FROM ${dbName}.${tableName2}"
assertEquals(res.size(), insert_num)
-
+ waitForColocateGroupStable(dbName, groupName)
explain {
sql("${query}")
contains("COLOCATE")
@@ -644,10 +626,7 @@ suite("test_backup_restore_colocate_with_partition",
"backup_restore") {
query = "select * from ${newDbName}.${tableName1} as t1,
${newDbName}.${tableName2} as t2 where t1.id=t2.id;"
- // RESTORE to a brand-new db creates a new colocate group that is initially
- // unstable; wait for ColocateTableCheckerAndBalancer to mark it stable,
otherwise
- // EXPLAIN below may fall back to BROADCAST/SHUFFLE.
- waitColocateGroupStable(newDbName, groupName)
+ waitForColocateGroupStable(newDbName, groupName)
explain {
sql("${query}")
diff --git
a/regression-test/suites/correctness_p0/test_colocate_join_of_column_order.groovy
b/regression-test/suites/correctness_p0/test_colocate_join_of_column_order.groovy
index efef9969506..68f34db07df 100644
---
a/regression-test/suites/correctness_p0/test_colocate_join_of_column_order.groovy
+++
b/regression-test/suites/correctness_p0/test_colocate_join_of_column_order.groovy
@@ -68,6 +68,7 @@ suite("test_colocate_join_of_column_order") {
sql("select * from test_colocate_join_of_column_order_t1 a join
test_colocate_join_of_column_order_t2 b on a.k1=b.k2 and a.v=b.v;")
notContains "COLOCATE"
}
+ waitForColocateGroupStable("group_column_order")
explain {
sql("select * from test_colocate_join_of_column_order_t1 a join
test_colocate_join_of_column_order_t2 b on a.k1=b.k2 and a.k2=b.k1;")
contains "COLOCATE"
@@ -100,6 +101,7 @@ suite("test_colocate_join_of_column_order") {
sql """insert into test_colocate_join_of_column_order_tb values(1,1);"""
sql """insert into test_colocate_join_of_column_order_tc values(1,1);"""
+ waitForColocateGroupStable("group_column_order3")
explain {
sql("""select /*+ set_var(disable_join_reorder=true) */ * from
test_colocate_join_of_column_order_ta join [shuffle] (select cast((c2 + 1) as
bigint) c2 from test_colocate_join_of_column_order_tb)
test_colocate_join_of_column_order_tb on
test_colocate_join_of_column_order_ta.c1 =
test_colocate_join_of_column_order_tb.c2 join [shuffle]
test_colocate_join_of_column_order_tc on
test_colocate_join_of_column_order_tb.c2 =
test_colocate_join_of_column_order_tc.c1;""");
contains "COLOCATE"
diff --git
a/regression-test/suites/query_p0/join/colocate_join_with_rollup.groovy
b/regression-test/suites/query_p0/join/colocate_join_with_rollup.groovy
index 539a801486c..c727ea991f7 100644
--- a/regression-test/suites/query_p0/join/colocate_join_with_rollup.groovy
+++ b/regression-test/suites/query_p0/join/colocate_join_with_rollup.groovy
@@ -120,6 +120,7 @@ suite("colocate_join_with_rollup", "query_p0") {
(20220107, 102, 202, 200, 100),
(20220108, 101, 202, 200, 100);"""
+ waitForColocateGroupStable("group1")
explain {
sql("""select sum_col1,sum_col2
from
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]