github-actions[bot] commented on code in PR #68196:
URL: https://github.com/apache/doris/pull/68196#discussion_r4129218827


##########
fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java:
##########
@@ -486,8 +507,42 @@ public void removeCatalogByEngine(long catalogId, String 
engine) {
     }
 
     public void invalidateDb(long catalogId, String dbName) {
-        routeCatalogEngines(catalogId, cache -> safeInvalidate(
-                cache, catalogId, "invalidateDb", () -> 
cache.invalidateDb(catalogId, dbName)));
+        Optional<ExternalDatabase<? extends ExternalTable>> db = 
getCachedDb(catalogId, dbName);
+        if (db.isPresent()) {
+            invalidateDb(catalogId, db.get().getId(), db.get().getFullName());
+            return;
+        }
+        Optional<Pair<String, Long>> identity = 
getDbIdentityForReplay(catalogId, dbName);
+        if (identity.isPresent()) {
+            invalidateDb(catalogId, identity.get().second, 
identity.get().first);
+        } else {
+            invalidateDb(catalogId, dbName, OptionalLong.empty(), true);
+        }
+    }
+
+    public void invalidateDb(long catalogId, long dbId, String dbName) {
+        invalidateDb(catalogId, dbName, OptionalLong.of(dbId), true);
+    }
+
+    void invalidateDb(long catalogId, long dbId, String dbName, boolean 
invalidateRowCountCache) {
+        invalidateDb(catalogId, dbName, OptionalLong.of(dbId), 
invalidateRowCountCache);
+    }
+
+    private void invalidateDb(long catalogId, String dbName, OptionalLong 
dbId, boolean invalidateRowCountCache) {
+        try {
+            routeCatalogEngines(catalogId, cache -> safeInvalidate(

Review Comment:
   [P1] Fence direct DB invalidation before evicting engine entries. Cold 
REFRESH DB/TABLE replay calls this explicit-ID route after the DB object was 
evicted, while its completed table row count can survive. `routeCatalogEngines` 
clears Hive entries before the only row-count fence in `finally`; a concurrent 
query can rebuild the cold table and read new metadata with the old count in 
that gap. The unresolved replay catalog route has the same ordering. Open the 
matching DB/catalog row-count fence before routed eviction, retain the 
completion fence, and latch a query after engine eviction.



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalMetaCacheMgr.java:
##########
@@ -497,16 +552,28 @@ public void invalidateDb(ExternalDatabase<?> database) {
     }
 
     public void invalidateTable(long catalogId, String dbName, String 
tableName) {
-        invalidateLanceTableAccess(catalogId);
-        routeCatalogEngines(catalogId, cache -> safeInvalidate(
-                cache, catalogId, "invalidateTable",
-                () -> cache.invalidateTable(catalogId, dbName, tableName)));
+        Optional<ExternalDatabase<? extends ExternalTable>> db = 
Optional.empty();
+        try {
+            invalidateLanceTableAccess(catalogId);
+            db = getCachedDb(catalogId, dbName);
+            routeCatalogEngines(catalogId, cache -> safeInvalidate(
+                    cache, catalogId, "invalidateTable",
+                    () -> cache.invalidateTable(catalogId, dbName, 
tableName)));
+        } finally {
+            invalidateTableRowCount(catalogId, db, tableName);
+        }
     }
 
     public void invalidateTableByEngine(long catalogId, String engine, String 
dbName, String tableName) {
-        routeSpecifiedEngine(engine, cache -> safeInvalidate(
-                cache, catalogId, "invalidateTableByEngine",
-                () -> cache.invalidateTable(catalogId, dbName, tableName)));
+        Optional<ExternalDatabase<? extends ExternalTable>> db = 
Optional.empty();
+        try {
+            db = getCachedDb(catalogId, dbName);
+            routeSpecifiedEngine(engine, cache -> safeInvalidate(

Review Comment:
   [P2] Open the row-count fence before this engine-specific table eviction. 
`HMSExternalTable.getHivePartitionValues` calls this route after detecting 
inconsistent Hive partition cache state. `routeSpecifiedEngine` removes 
partition/file entries before `invalidateTableRowCount` runs in `finally`, so 
another planner can reload corrected partition data and still consume the old 
completed count during the gap. Fence the resolved table (or DB when cold) 
before routing and keep the completion fence; test the ordering with an 
invalidation paused after entry removal.



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/paimon/PaimonExternalCatalog.java:
##########
@@ -173,6 +173,25 @@ public synchronized void invalidatePaimonDatabase(String 
remoteDbName) throws Ex
         }));
     }
 
+    public synchronized void invalidatePaimonDatabaseByLocalName(String 
localDbName) throws Exception {
+        if (!isInitialized()) {
+            return;
+        }
+        withSdkCatalogCacheWriteLock(() -> executionAuthenticator.execute(() 
-> {
+            boolean caseSensitive = catalog.caseSensitive();
+            int nameMode = getLowerCaseDatabaseNames();
+            invalidateCachedPaimonTables(identifier -> {
+                String remoteName = identifier.getDatabaseName();
+                String candidateLocalName = nameMode == 2 ? remoteName : 
fromRemoteDatabaseName(remoteName);
+                if (nameMode == 1) {
+                    candidateLocalName = 
candidateLocalName.toLowerCase(Locale.ROOT);

Review Comment:
   [P2] Match the catalog's mode-1 local-name normalization here. On a 
Turkish-locale FE, Doris stores remote Paimon DB `I` as local `ı` using 
default-locale `toLowerCase()`, but this new SDK cache predicate converts the 
same remote name to `i` with `Locale.ROOT`. For a case-sensitive Paimon 
catalog, `identifierPartEquals` fails, so a cold DB refresh or DROP leaves 
SDK-only table handles in `CachingCatalog.tableCache` even though the retained 
DB identity was found. Use the same normalization as `ExternalCatalog` (or make 
both use one locale-independent rule), and cover a cached SDK handle with a 
locale-sensitive database name.



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalCatalog.java:
##########
@@ -941,19 +954,46 @@ public Optional<ExternalDatabase<? extends 
ExternalTable>> getDbForReplay(String
             LOG.debug("getDbForReplay from metacache, db: {}.{}, catalog id: 
{}, is catalog init: {}",
                     this.name, dbName, this.id, isInitialized());
         }
-        if (!isInitialized()) {
+        if (!isInitialized() || metaCache == null) {
             return Optional.empty();
         }
 
         // Apply case-insensitive lookup with isReplay=true (no remote calls)
         String localDbName = getLocalDatabaseName(dbName, true);
         if (localDbName == null) {
             localDbName = dbName;  // Fallback to original name
+        } else if (getLowerCaseDatabaseNames() == 2 && 
!localDbName.equals(dbName)) {
+            // The current case-insensitive mapping may have rebound after a 
DROP. A replay
+            // record names the historical object, not a new same-folded 
replacement.
+            long historicalId = Util.genIdByName(name, dbName);
+            if (metaCache.getNameByIdIfPresent(historicalId).isPresent()) {

Review Comment:
   [P1] Preserve ordinary mode-2 aliases in replay-safe lookup. With canonical 
`MixedDb`, Hive can successfully run `CREATE TABLE mixeddb.t` using the 
canonical remote DB, but this new check looks for a separate `mixeddb` ID slot 
and returns empty. Its `afterCreateTable` hook then skips 
`resetMetaCacheNames`, so a primed table list can hide `t` until refresh; 
follower replay has the same caller spelling. Other post-create hooks use this 
lookup too. The merge-base lookup resolved the warm canonical DB. Keep 
historical DROP identity handling separate from normal alias resolution, and 
cover alternate-case CREATE with a primed table-name cache.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to