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

deardeng 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 30272d60cb5 [fix](fe) Fix colocate replica allocation edit log (#65457)
30272d60cb5 is described below

commit 30272d60cb549cef9a873e4fd703e3ab40e2e8f6
Author: deardeng <[email protected]>
AuthorDate: Mon Jul 13 16:07:32 2026 +0800

    [fix](fe) Fix colocate replica allocation edit log (#65457)
    
    Related PR: #49569
    
    Problem Summary: Related PR #49569 changed the colocate replica
    allocation helper boolean from needEditLog to isReplay, but kept the old
    call-site values. As a result, normal ALTER COLOCATE GROUP replica
    allocation changes were treated as replay and skipped
    logColocateModifyRepliaAlloc, so the new replica allocation was not
    persisted for follower replay or master failover. The replay path was
    treated as a normal operation and could append another edit log while
    loading journal entries. This patch flips the two call-site values:
    leader ALTER uses isReplay = false and writes the edit log, while replay
    uses isReplay = true and does not append a new edit log. It also adds FE
    unit tests covering both behaviors.
---
 .../apache/doris/catalog/ColocateTableIndex.java   |  4 +-
 .../apache/doris/catalog/ColocateTableTest.java    | 95 ++++++++++++++++++++++
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/ColocateTableIndex.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/ColocateTableIndex.java
index 381fa9dcbf5..29ef3be84d9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/ColocateTableIndex.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/ColocateTableIndex.java
@@ -680,7 +680,7 @@ public class ColocateTableIndex implements Writable {
         writeLock();
         try {
             modifyColocateGroupReplicaAllocation(info.getGroupId(), 
info.getReplicaAlloc(),
-                    info.getBackendsPerBucketSeq(), false);
+                    info.getBackendsPerBucketSeq(), true /* isReplay */);
         } finally {
             writeUnlock();
         }
@@ -888,7 +888,7 @@ public class ColocateTableIndex implements Writable {
                 backendsPerBucketSeq = newBackendsPerBucketSeq;
                 Preconditions.checkState(backendsPerBucketSeq.size() == 
replicaAlloc.getAllocMap().size());
                 modifyColocateGroupReplicaAllocation(groupSchema.getGroupId(), 
replicaAlloc,
-                        backendsPerBucketSeq, true);
+                        backendsPerBucketSeq, false /* isReplay */);
             } else {
                 throw new DdlException("Unknown colocate group property: " + 
properties.keySet());
             }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColocateTableTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColocateTableTest.java
index 3f0079fb945..ef96012d64e 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/ColocateTableTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/ColocateTableTest.java
@@ -21,12 +21,15 @@ import org.apache.doris.catalog.ColocateTableIndex.GroupId;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.jmockit.Deencapsulation;
 import org.apache.doris.nereids.parser.NereidsParser;
+import org.apache.doris.nereids.trees.plans.commands.AlterColocateGroupCommand;
 import org.apache.doris.nereids.trees.plans.commands.AlterTableCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateDatabaseCommand;
 import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
 import org.apache.doris.nereids.trees.plans.commands.DropDatabaseCommand;
 import org.apache.doris.nereids.trees.plans.commands.info.DropDatabaseInfo;
 import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.persist.ColocatePersistInfo;
+import org.apache.doris.persist.EditLog;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.StmtExecutor;
 import org.apache.doris.resource.Tag;
@@ -42,8 +45,11 @@ import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -118,6 +124,44 @@ public class ColocateTableTest {
         }
     }
 
+    private static void alterColocateGroup(String sql) throws Exception {
+        NereidsParser nereidsParser = new NereidsParser();
+        LogicalPlan parsed = nereidsParser.parseSingle(sql);
+        StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql);
+        if (parsed instanceof AlterColocateGroupCommand) {
+            ((AlterColocateGroupCommand) parsed).run(connectContext, 
stmtExecutor);
+        } else {
+            Assert.fail("Expected AlterColocateGroupCommand, but parsed: " + 
parsed.getClass().getSimpleName());
+        }
+    }
+
+    private static void createSingleReplicaColocateTable(String tableName) 
throws Exception {
+        createTable("create table " + dbName + "." + tableName + " (\n"
+                + " `k1` int NULL COMMENT \"\",\n"
+                + " `k2` varchar(10) NULL COMMENT \"\"\n"
+                + ") ENGINE=OLAP\n"
+                + "DUPLICATE KEY(`k1`, `k2`)\n"
+                + "COMMENT \"OLAP\"\n"
+                + "DISTRIBUTED BY HASH(`k1`, `k2`) BUCKETS 1\n"
+                + "PROPERTIES (\n"
+                + " \"replication_num\" = \"1\",\n"
+                + " \"colocate_with\" = \"" + groupName + "\"\n"
+                + ");");
+    }
+
+    private static Map<Tag, List<List<Long>>> copyBackendsPerBucketSeq(
+            Map<Tag, List<List<Long>>> backendsPerBucketSeq) {
+        Map<Tag, List<List<Long>>> copied = new HashMap<>();
+        for (Map.Entry<Tag, List<List<Long>>> entry : 
backendsPerBucketSeq.entrySet()) {
+            List<List<Long>> copiedBuckets = new ArrayList<>();
+            for (List<Long> backends : entry.getValue()) {
+                copiedBuckets.add(new ArrayList<>(backends));
+            }
+            copied.put(entry.getKey(), copiedBuckets);
+        }
+        return copied;
+    }
+
     @Test
     public void testCreateOneTable() throws Exception {
         createTable("create table " + dbName + "." + tableName1 + " (\n"
@@ -161,6 +205,57 @@ public class ColocateTableTest {
         Assert.assertEquals((short) 1, 
groupSchema.getReplicaAlloc().getTotalReplicaNum());
     }
 
+    @Test
+    public void testAlterColocateGroupReplicaAllocationLogsEditLog() throws 
Exception {
+        createSingleReplicaColocateTable(tableName1);
+
+        Env env = Env.getCurrentEnv();
+        EditLog originalEditLog = env.getEditLog();
+        EditLog mockEditLog = Mockito.mock(EditLog.class);
+        env.setEditLog(mockEditLog);
+        try {
+            alterColocateGroup("ALTER COLOCATE GROUP " + dbName + "." + 
groupName
+                    + " SET (\"replication_num\" = \"1\")");
+
+            Mockito.verify(mockEditLog, Mockito.times(1))
+                    
.logColocateModifyRepliaAlloc(Mockito.any(ColocatePersistInfo.class));
+
+            ColocateTableIndex index = Env.getCurrentColocateIndex();
+            Database db = 
Env.getCurrentInternalCatalog().getDbOrMetaException(fullDbName);
+            String fullGroupName = GroupId.getFullGroupName(db.getId(), 
groupName);
+            Assert.assertEquals((short) 1,
+                    
index.getGroupSchema(fullGroupName).getReplicaAlloc().getTotalReplicaNum());
+        } finally {
+            env.setEditLog(originalEditLog);
+        }
+    }
+
+    @Test
+    public void testReplayModifyReplicaAllocationDoesNotLogEditLog() throws 
Exception {
+        createSingleReplicaColocateTable(tableName1);
+
+        ColocateTableIndex index = Env.getCurrentColocateIndex();
+        Database db = 
Env.getCurrentInternalCatalog().getDbOrMetaException(fullDbName);
+        long tableId = db.getTableOrMetaException(tableName1).getId();
+        GroupId groupId = index.getGroup(tableId);
+        ColocatePersistInfo info = 
ColocatePersistInfo.createForModifyReplicaAlloc(
+                groupId, new ReplicaAllocation((short) 1),
+                
copyBackendsPerBucketSeq(index.getBackendsPerBucketSeq(groupId)));
+
+        Env env = Env.getCurrentEnv();
+        EditLog originalEditLog = env.getEditLog();
+        EditLog mockEditLog = Mockito.mock(EditLog.class);
+        env.setEditLog(mockEditLog);
+        try {
+            index.replayModifyReplicaAlloc(info);
+
+            Mockito.verify(mockEditLog, Mockito.never())
+                    
.logColocateModifyRepliaAlloc(Mockito.any(ColocatePersistInfo.class));
+        } finally {
+            env.setEditLog(originalEditLog);
+        }
+    }
+
     @Test
     public void testCreateTwoTableWithSameGroup() throws Exception {
         createTable("create table " + dbName + "." + tableName1 + " (\n"


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

Reply via email to