From d316dbb3bda1df1638563e25b413102f7ce972d1 Mon Sep 17 00:00:00 2001 From: "Mingyu Chen (Rayner)" Date: Tue, 22 Jul 2025 19:00:51 -0700 Subject: [PATCH] branch-2.1: [fix](catalog) fix deadlock of catalog and database(#53626) (#53629) bp #53626 --- .../doris/datasource/ExternalDatabase.java | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalDatabase.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalDatabase.java index 8608a57876..a4f7893a47 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalDatabase.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalDatabase.java @@ -153,40 +153,46 @@ public abstract class ExternalDatabase return initialized; } - public final synchronized void makeSureInitialized() { + public final void makeSureInitialized() { + // Must call this method before any operation on the database to avoid deadlock of synchronized block extCatalog.makeSureInitialized(); - if (!initialized) { - if (extCatalog.getUseMetaCache().get()) { - if (metaCache == null) { - metaCache = Env.getCurrentEnv().getExtMetaCacheMgr().buildMetaCache( - name, - OptionalLong.of(86400L), - OptionalLong.of(Config.external_cache_expire_time_minutes_after_access * 60L), - Config.max_meta_object_cache_num, - ignored -> listTableNames(), - localTableName -> Optional.ofNullable( - buildTableForInit(null, localTableName, - Util.genIdByName(extCatalog.getName(), name, localTableName), extCatalog, - this, true)), - (key, value, cause) -> value.ifPresent(ExternalTable::unsetObjectCreated)); - } - setLastUpdateTime(System.currentTimeMillis()); - } else { - if (!Env.getCurrentEnv().isMaster()) { - // Forward to master and wait the journal to replay. - int waitTimeOut = ConnectContext.get() == null ? 300 : ConnectContext.get().getExecTimeout(); - MasterCatalogExecutor remoteExecutor = new MasterCatalogExecutor(waitTimeOut * 1000); - try { - remoteExecutor.forward(extCatalog.getId(), id); - } catch (Exception e) { - Util.logAndThrowRuntimeException(LOG, - String.format("failed to forward init external db %s operation to master", name), e); + synchronized (this) { + if (!initialized) { + if (extCatalog.getUseMetaCache().get()) { + if (metaCache == null) { + metaCache = Env.getCurrentEnv().getExtMetaCacheMgr().buildMetaCache( + name, + OptionalLong.of(86400L), + OptionalLong.of(Config.external_cache_expire_time_minutes_after_access * 60L), + Config.max_meta_object_cache_num, + ignored -> listTableNames(), + localTableName -> Optional.ofNullable( + buildTableForInit(null, localTableName, + Util.genIdByName(extCatalog.getName(), name, localTableName), + extCatalog, + this, true)), + (key, value, cause) + -> value.ifPresent(ExternalTable::unsetObjectCreated)); } - return; + setLastUpdateTime(System.currentTimeMillis()); + } else { + if (!Env.getCurrentEnv().isMaster()) { + // Forward to master and wait the journal to replay. + int waitTimeOut = ConnectContext.get() == null ? 300 : ConnectContext.get().getExecTimeout(); + MasterCatalogExecutor remoteExecutor = new MasterCatalogExecutor(waitTimeOut * 1000); + try { + remoteExecutor.forward(extCatalog.getId(), id); + } catch (Exception e) { + Util.logAndThrowRuntimeException(LOG, + String.format("failed to forward init external db %s operation to master", name), + e); + } + return; + } + init(); } - init(); + initialized = true; } - initialized = true; } }