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

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


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new b4c460023b6 branch-4.1: [fix](fe) Scope Hive file cache entries by 
table (#68575)
b4c460023b6 is described below

commit b4c460023b694ba5c93bf1d67e8ff65e723aa31f
Author: 924060929 <[email protected]>
AuthorDate: Tue Sep 29 21:33:39 2026 +0800

    branch-4.1: [fix](fe) Scope Hive file cache entries by table (#68575)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: None
    
    Problem Summary: Two Hive partition tables can legitimately share a
    partition location. On branch-4.1, the partition file-list cache key
    uses the catalog, location, and partition values, but omits the table
    ID. In contrast, `REFRESH TABLE` invalidates file-list entries by table
    ID. If table a loads the old listing, table b can hit that entry after
    writing a new file and refreshing b, so its scan omits the new file and
    returns incomplete results. Include the table ID in the cache key's
    equality and hash code. Each table then owns the listings that its
    refresh invalidates.
    
    The new FE unit test uses the same catalog, location, format, and
    partition value for a and b. It failed on the original code because b
    retrieved a's cached value. After the change, b misses a's value, both
    entries coexist, and refreshing b removes only b's entry.
    
    ### Release note
    
    Fix missing rows after refreshing a Hive table that shares a partition
    location with another table.
    
    ### Check List (For Author)
    
    - Test
        - [ ] Regression test
    - [x] Unit Test: `HiveMetaStoreCacheTest` (13 tests passed; new case
    failed before the fix)
        - [ ] Manual test
        - [ ] No need to test or manual test
    - FE Checkstyle: 0 violations.
    - Local `./build.sh --fe` was not completed because this isolated
    worktree lacked the complete thirdparty installation; `run buildall` is
    requested on this PR.
    - Behavior changed:
        - [ ] No.
    - [x] Yes. `REFRESH TABLE` reloads the current Hive table's file listing
    even when another table shares its partition location.
    - Does this need documentation?
        - [x] No.
        - [ ] Yes.
    
    ### Check List (For Reviewer who merge this PR)
    
    - [ ] Confirm the release note
    - [ ] Confirm test cases
    - [ ] Confirm document
    - [ ] Add branch pick label
---
 .../datasource/hive/HiveExternalMetaCache.java     |  4 ++-
 .../datasource/hive/HiveMetaStoreCacheTest.java    | 39 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveExternalMetaCache.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveExternalMetaCache.java
index cdf58a9adc6..ce288bc37ae 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveExternalMetaCache.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveExternalMetaCache.java
@@ -1112,6 +1112,7 @@ public class HiveExternalMetaCache extends 
AbstractExternalMetaCache {
         private String inputFormat;
         // The values of partitions.
         protected List<String> partitionValues;
+        // Keep cache identity aligned with table-scoped invalidation.
         private long id;
 
         public FileCacheKey(long catalogId, long id, String location, String 
inputFormat,
@@ -1142,6 +1143,7 @@ public class HiveExternalMetaCache extends 
AbstractExternalMetaCache {
                 return dummyKey == ((FileCacheKey) obj).dummyKey;
             }
             return catalogId == ((FileCacheKey) obj).catalogId
+                    && id == ((FileCacheKey) obj).id
                     && location.equals(((FileCacheKey) obj).location)
                     && Objects.equals(partitionValues, ((FileCacheKey) 
obj).partitionValues);
         }
@@ -1155,7 +1157,7 @@ public class HiveExternalMetaCache extends 
AbstractExternalMetaCache {
             if (dummyKey != 0) {
                 return Objects.hash(dummyKey);
             }
-            return Objects.hash(catalogId, location, partitionValues);
+            return Objects.hash(catalogId, id, location, partitionValues);
         }
 
         @Override
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/hive/HiveMetaStoreCacheTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/hive/HiveMetaStoreCacheTest.java
index 9cc96f58b7d..f067c879705 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/datasource/hive/HiveMetaStoreCacheTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/datasource/hive/HiveMetaStoreCacheTest.java
@@ -104,6 +104,45 @@ public class HiveMetaStoreCacheTest {
         }
     }
 
+    @Test
+    public void testRefreshTableWithSharedPartitionLocation() {
+        ThreadPoolExecutor executor = 
ThreadPoolManager.newDaemonFixedThreadPool(
+                1, 1, "refresh", 1, false);
+        ThreadPoolExecutor listExecutor = 
ThreadPoolManager.newDaemonFixedThreadPool(
+                1, 1, "file", 1, false);
+        try {
+            HiveExternalMetaCache cache = new HiveExternalMetaCache(executor, 
listExecutor);
+            cache.initCatalog(0, new HashMap<>());
+            MetaCacheEntry<HiveExternalMetaCache.FileCacheKey, 
HiveExternalMetaCache.FileCacheValue> fileCache =
+                    cache.entry(0, HiveExternalMetaCache.ENTRY_FILE,
+                            HiveExternalMetaCache.FileCacheKey.class,
+                            HiveExternalMetaCache.FileCacheValue.class);
+
+            String location = "/warehouse/shared/p=p1";
+            List<String> values = Collections.singletonList("p1");
+            HiveExternalMetaCache.FileCacheKey keyA = new 
HiveExternalMetaCache.FileCacheKey(
+                    0, Util.genIdByName("db", "a"), location, "parquet", 
values);
+            HiveExternalMetaCache.FileCacheKey keyB = new 
HiveExternalMetaCache.FileCacheKey(
+                    0, Util.genIdByName("db", "b"), location, "parquet", 
values);
+            HiveExternalMetaCache.FileCacheValue oldFiles = new 
HiveExternalMetaCache.FileCacheValue();
+            fileCache.put(keyA, oldFiles);
+
+            // b must list the directory after its write instead of reusing 
a's old file list.
+            Assertions.assertNull(fileCache.getIfPresent(keyB));
+            HiveExternalMetaCache.FileCacheValue newFiles = new 
HiveExternalMetaCache.FileCacheValue();
+            fileCache.put(keyB, newFiles);
+            Assertions.assertSame(oldFiles, fileCache.getIfPresent(keyA));
+            Assertions.assertSame(newFiles, fileCache.getIfPresent(keyB));
+
+            cache.invalidateTable(0, "db", "b");
+            Assertions.assertNull(fileCache.getIfPresent(keyB));
+            Assertions.assertSame(oldFiles, fileCache.getIfPresent(keyA));
+        } finally {
+            executor.shutdownNow();
+            listExecutor.shutdownNow();
+        }
+    }
+
     @Test
     public void testInvalidateTableCache() {
         ThreadPoolExecutor executor = 
ThreadPoolManager.newDaemonFixedThreadPool(


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

Reply via email to