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]