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

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


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 63269374d45 branch-3.1: [fix](mtmv)Fix the mapping issue where base 
tables could still reference a dropped MTMV #53383 (#54082)
63269374d45 is described below

commit 63269374d4500d5c595ce1a5a356406b4b895cef
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jul 30 18:01:43 2025 +0800

    branch-3.1: [fix](mtmv)Fix the mapping issue where base tables could still 
reference a dropped MTMV #53383 (#54082)
    
    Cherry-picked from #53383
    
    Co-authored-by: zhangdong <[email protected]>
---
 .../java/org/apache/doris/catalog/Database.java    |  7 +-
 .../org/apache/doris/mtmv/MTMVRelationManager.java |  3 +
 .../java/org/apache/doris/mtmv/MTMVService.java    | 18 ++++-
 .../org/apache/doris/mtmv/MTMVConcurrentTest.java  | 85 ++++++++++++++++++++++
 4 files changed, 106 insertions(+), 7 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
index 8c7b1df73c5..f1f9db5e33f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
@@ -461,9 +461,6 @@ public class Database extends MetaObject implements 
Writable, DatabaseIf<Table>,
         }
         Table table = getTableNullable(tableName);
         if (table != null) {
-            if (table instanceof MTMV) {
-                Env.getCurrentEnv().getMtmvService().unregisterMTMV((MTMV) 
table);
-            }
             this.nameToTable.remove(tableName);
             this.lowerCaseToTableName.remove(tableName.toLowerCase());
             this.idToTable.remove(table.getId());
@@ -471,6 +468,10 @@ public class Database extends MetaObject implements 
Writable, DatabaseIf<Table>,
                 Env.getCurrentEnv().unregisterTempTable(table);
             }
             table.markDropped();
+            // will check mtmv if exist by markDrop, so unregisterMTMV() need 
after markDropped()
+            if (table instanceof MTMV) {
+                Env.getCurrentEnv().getMtmvService().unregisterMTMV((MTMV) 
table);
+            }
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
index ba498636d73..05ab6eb01f1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVRelationManager.java
@@ -251,6 +251,9 @@ public class MTMVRelationManager implements MTMVHookService 
{
     public void refreshComplete(MTMV mtmv, MTMVRelation relation, MTMVTask 
task) {
         if (task.getStatus() == TaskStatus.SUCCESS) {
             Objects.requireNonNull(relation);
+            if (mtmv.isDropped) {
+                return;
+            }
             refreshMTMVCache(relation, new BaseTableInfo(mtmv));
         }
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVService.java 
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVService.java
index 2ee42c0aa2c..9496bff0a51 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVService.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVService.java
@@ -87,8 +87,13 @@ public class MTMVService implements EventListener {
     public void unregisterMTMV(MTMV mtmv) {
         Objects.requireNonNull(mtmv, "mtmv can not be null");
         LOG.info("deregisterMTMV: " + mtmv.getName());
-        for (MTMVHookService mtmvHookService : hooks.values()) {
-            mtmvHookService.unregisterMTMV(mtmv);
+        mtmv.writeMvLock();
+        try {
+            for (MTMVHookService mtmvHookService : hooks.values()) {
+                mtmvHookService.unregisterMTMV(mtmv);
+            }
+        } finally {
+            mtmv.writeMvUnlock();
         }
     }
 
@@ -147,8 +152,13 @@ public class MTMVService implements EventListener {
         Objects.requireNonNull(mtmv, "mtmv can not be null");
         Objects.requireNonNull(task, "task can not be null");
         LOG.info("refreshComplete: " + mtmv.getName());
-        for (MTMVHookService mtmvHookService : hooks.values()) {
-            mtmvHookService.refreshComplete(mtmv, cache, task);
+        mtmv.writeMvLock();
+        try {
+            for (MTMVHookService mtmvHookService : hooks.values()) {
+                mtmvHookService.refreshComplete(mtmv, cache, task);
+            }
+        } finally {
+            mtmv.writeMvUnlock();
         }
     }
 
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVConcurrentTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVConcurrentTest.java
new file mode 100644
index 00000000000..97f341e8e59
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/mtmv/MTMVConcurrentTest.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.mtmv;
+
+import org.apache.doris.catalog.Env;
+import org.apache.doris.catalog.MTMV;
+import org.apache.doris.catalog.Table;
+import org.apache.doris.job.common.TaskStatus;
+import org.apache.doris.job.extensions.mtmv.MTMVTask;
+import org.apache.doris.utframe.TestWithFeService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+public class MTMVConcurrentTest extends TestWithFeService {
+    @Test
+    public void testAlterMTMV() throws Exception {
+        createDatabaseAndUse("mtmv_concurrent_test");
+
+        createTable("CREATE TABLE `stu` (`sid` int(32) NULL, `sname` 
varchar(32) NULL)\n"
+                + "ENGINE=OLAP\n"
+                + "DUPLICATE KEY(`sid`)\n"
+                + "DISTRIBUTED BY HASH(`sid`) BUCKETS 1\n"
+                + "PROPERTIES ('replication_allocation' = 
'tag.location.default: 1')");
+
+        createMvByNereids("CREATE MATERIALIZED VIEW mv_a BUILD DEFERRED 
REFRESH COMPLETE ON MANUAL\n"
+                + "DISTRIBUTED BY HASH(`sid`) BUCKETS 1\n"
+                + "PROPERTIES ('replication_allocation' = 
'tag.location.default: 1') "
+                + "AS select * from stu limit 1");
+
+
+        MTMVRelationManager relationManager = 
Env.getCurrentEnv().getMtmvService().getRelationManager();
+        Table table = 
Env.getCurrentInternalCatalog().getDb("mtmv_concurrent_test").get()
+                .getTableOrMetaException("stu");
+        BaseTableInfo baseTableInfo = new BaseTableInfo(table);
+        MTMV mtmv = (MTMV) 
Env.getCurrentInternalCatalog().getDb("mtmv_concurrent_test").get()
+                .getTableOrMetaException("mv_a");
+        MTMVRelation relation = mtmv.getRelation();
+        Set<BaseTableInfo> mtmvsByBaseTable = 
relationManager.getMtmvsByBaseTable(baseTableInfo);
+        Assertions.assertEquals(1, mtmvsByBaseTable.size());
+        MTMVTask mtmvTask = new MTMVTask(mtmv, relation, null);
+        mtmvTask.setStatus(TaskStatus.SUCCESS);
+
+        // Create threads for concurrent operations
+        Thread dropThread = new Thread(() -> {
+            try {
+                dropMvByNereids("drop materialized view mv_a");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        Thread refreshThread = new Thread(() -> {
+            relationManager.refreshComplete(mtmv, relation, mtmvTask);
+        });
+
+        // Start both threads
+        dropThread.start();
+        refreshThread.start();
+
+        // Wait for both threads to complete
+        dropThread.join();
+        refreshThread.join();
+
+        mtmvsByBaseTable = relationManager.getMtmvsByBaseTable(baseTableInfo);
+        Assertions.assertEquals(0, mtmvsByBaseTable.size());
+    }
+}


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

Reply via email to