diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java index c3d36ea39714c0..3e60a489c932da 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/MTMV.java @@ -176,6 +176,19 @@ public MTMVStatus alterStatus(MTMVStatus newStatus) { public void addTaskResult(MTMVTask task, MTMVRelation relation, Map partitionSnapshots) { + MTMVCache mtmvCache = null; + boolean needUpdateCache = false; + if (task.getStatus() == TaskStatus.SUCCESS && !Env.isCheckpointThread() + && !Config.enable_check_compatibility_mode) { + needUpdateCache = true; + try { + // shouldn't do this while holding mvWriteLock + mtmvCache = MTMVCache.from(this, MTMVPlanUtil.createMTMVContext(this), true); + } catch (Throwable e) { + mtmvCache = null; + LOG.warn("generate cache failed", e); + } + } writeMvLock(); try { if (task.getStatus() == TaskStatus.SUCCESS) { @@ -183,13 +196,8 @@ public void addTaskResult(MTMVTask task, MTMVRelation relation, this.status.setSchemaChangeDetail(null); this.status.setRefreshState(MTMVRefreshState.SUCCESS); this.relation = relation; - if (!Env.isCheckpointThread() && !Config.enable_check_compatibility_mode) { - try { - this.cache = MTMVCache.from(this, MTMVPlanUtil.createMTMVContext(this), true); - } catch (Throwable e) { - this.cache = null; - LOG.warn("generate cache failed", e); - } + if (needUpdateCache) { + this.cache = mtmvCache; } } else { this.status.setRefreshState(MTMVRefreshState.FAIL); @@ -268,17 +276,24 @@ public Set getExcludedTriggerTables() { * Called when in query, Should use one connection context in query */ public MTMVCache getOrGenerateCache(ConnectContext connectionContext) throws AnalysisException { - if (cache == null) { - writeMvLock(); - try { - if (cache == null) { - this.cache = MTMVCache.from(this, connectionContext, true); - } - } finally { - writeMvUnlock(); + readMvLock(); + try { + if (cache != null) { + return cache; } + } finally { + readMvUnlock(); + } + // Concurrent situations may result in duplicate cache generation, + // but we tolerate this in order to prevent nested use of readLock and write MvLock for the table + MTMVCache mtmvCache = MTMVCache.from(this, connectionContext, true); + writeMvLock(); + try { + this.cache = mtmvCache; + return cache; + } finally { + writeMvUnlock(); } - return cache; } public MTMVCache getCache() {