Skip to content

[refactor](catalog) Unify external metadata cache framework - #66633

Merged
924060929 merged 10 commits into
apache:masterfrom
924060929:prototype-scoped-metacache-ut
Aug 31, 2026
Merged

[refactor](catalog) Unify external metadata cache framework#66633
924060929 merged 10 commits into
apache:masterfrom
924060929:prototype-scoped-metacache-ut

Conversation

@924060929

@924060929 924060929 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #66407

Problem Summary:

FE naming caches and connector metadata caches currently use duplicate cache wrappers and independently maintained invalidation dependencies. Each connector must remember every sibling cache affected by catalog, database, table, or partition invalidation. Concurrent loads, refresh, eviction callbacks, and catalog close also need consistent publication and cleanup semantics across these implementations.

This PR makes fe-connector-cache the shared metadata-cache runtime while preserving one cache owner per catalog. It introduces declarative cache definitions and hierarchical scopes, then migrates ADBC, Hive, HMS, Hudi, Iceberg, MaxCompute, and Paimon caches to the shared framework. FE keeps a thin adapter for Doris-specific naming, object, and IdNameIndex publication semantics.

The shared runtime provides:

  • catalog/database/table/partition scoped invalidation without connector-maintained sibling-cache lists;
  • state-identity publication fencing so loads started before invalidation cannot publish stale values afterward;
  • exact-key and bulk-load invalidation fencing;
  • load deduplication, refresh, eviction cleanup, metrics, and catalog lifecycle management;
  • expected-value physical cleanup so delayed removal callbacks cannot remove newer publications;
  • per-catalog isolation without registry-wide publication locks on normal cache operations.

The change also removes duplicate CacheSpec, CacheFactory, and legacy connector-cache entry implementations. FE-specific cache publication retains the lock order names -> object -> IdNameIndex, and validates identity before mutating cache state. After synchronizing the latest master, Iceberg's snapshot-scoped equality-delete field-ID cache is also managed by the same per-catalog owner, so catalog invalidation and close cover both manifest and equality-delete metadata.

Performance measurements on the final commit show approximately 85.8 ns/op for the public CatalogMetaCache -> MetaCache hit path. Eight-thread publication reached 2.85M ops/s for one cache and 2.51M ops/s for separate caches in one registry. Invalidating and physically cleaning 120,000 entries took approximately 32 ms on the local benchmark.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
      • fe-connector-cache: 100 tests passed
      • FE targeted metadata-cache tests: 93 tests passed
      • Iceberg cache tests: 66 tests passed
      • Latest-master conflict verification: 144 Iceberg tests passed (IcebergScanPlanProviderTest and IcebergManifestCacheTest)
      • ./build.sh --fe: all 73 Maven reactor modules passed, including Checkstyle; the outer script subsequently returned non-zero while assembling already-built filesystem plugin archives into output/
    • Manual test
      • Re-profiled the final commit with CPU, allocation, and lock async-profiler runs
      • Ran hit, cold-load, eight-thread publication, logical invalidation, and 120,000-entry cleanup benchmarks
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No. This is an internal cache-framework refactor preserving external metadata semantics.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929
924060929 marked this pull request as ready for review August 11, 2026 01:04
@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 28473 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 527066179d0e7025c52b6385e51f38b73102c567, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17621	3918	3904	3904
q2	2013	325	197	197
q3	10311	1344	789	789
q4	4676	469	336	336
q5	7501	807	544	544
q6	186	171	138	138
q7	752	809	596	596
q8	9768	1548	1555	1548
q9	6019	4104	4072	4072
q10	6778	1637	1351	1351
q11	493	345	314	314
q12	769	576	461	461
q13	18081	3269	2652	2652
q14	269	257	240	240
q15	q16	732	723	654	654
q17	1399	1169	949	949
q18	6476	5567	5597	5567
q19	1690	1326	1040	1040
q20	779	694	548	548
q21	5903	2546	2275	2275
q22	428	352	298	298
Total cold run time: 102644 ms
Total hot run time: 28473 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4304	4215	4205	4205
q2	270	332	208	208
q3	4521	4858	4410	4410
q4	2166	2251	1429	1429
q5	4304	4142	4158	4142
q6	230	172	130	130
q7	1688	1603	1605	1603
q8	2536	2315	2037	2037
q9	7246	7270	7238	7238
q10	4246	4232	3827	3827
q11	557	410	369	369
q12	710	742	499	499
q13	3152	3632	2828	2828
q14	295	323	307	307
q15	q16	699	745	651	651
q17	1328	1308	1278	1278
q18	12261	11039	11751	11039
q19	1280	1183	1147	1147
q20	2246	2204	1957	1957
q21	5652	4797	4700	4700
q22	535	453	401	401
Total cold run time: 60226 ms
Total hot run time: 54405 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 159564 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 527066179d0e7025c52b6385e51f38b73102c567, data reload: false

query5	4377	596	467	467
query6	485	242	221	221
query7	4847	568	362	362
query8	354	186	164	164
query9	8835	4108	4072	4072
query10	486	380	315	315
query11	5875	2203	2050	2050
query12	164	107	103	103
query13	1293	631	444	444
query14	6130	4324	4009	4009
query14_1	3833	3822	3804	3804
query15	215	199	184	184
query16	1037	520	436	436
query17	970	747	618	618
query18	2462	507	371	371
query19	227	203	165	165
query20	109	109	108	108
query21	239	162	145	145
query22	13087	12936	12815	12815
query23	15667	14982	14589	14589
query23_1	14709	14786	14669	14669
query24	7551	1705	1241	1241
query24_1	1262	1274	1246	1246
query25	603	489	432	432
query26	1324	378	231	231
query27	2617	611	402	402
query28	4595	2104	2053	2053
query29	1103	678	532	532
query30	344	269	234	234
query31	1192	1130	1056	1056
query32	118	71	75	71
query33	555	345	275	275
query34	1177	1155	642	642
query35	761	751	645	645
query36	786	772	713	713
query37	162	116	100	100
query38	1833	1788	1702	1702
query39	820	815	776	776
query39_1	783	814	786	786
query40	266	173	171	171
query41	85	83	81	81
query42	104	97	96	96
query43	322	328	281	281
query44	1456	789	777	777
query45	201	182	187	182
query46	1058	1180	701	701
query47	1598	1564	1521	1521
query48	428	426	313	313
query49	601	425	312	312
query50	1070	436	353	353
query51	10656	10320	10437	10320
query52	90	95	77	77
query53	263	286	202	202
query54	313	247	233	233
query55	78	80	72	72
query56	316	327	295	295
query57	1031	1024	969	969
query58	313	281	270	270
query59	1555	1603	1409	1409
query60	329	275	269	269
query61	181	182	187	182
query62	408	331	277	277
query63	243	202	202	202
query64	3069	1274	1067	1067
query65	3871	3776	3784	3776
query66	1876	506	399	399
query67	20145	20116	19888	19888
query68	3214	1543	972	972
query69	430	315	285	285
query70	881	801	775	775
query71	372	347	308	308
query72	3318	2930	2606	2606
query73	840	795	442	442
query74	4662	4498	4312	4312
query75	2400	2349	1985	1985
query76	2363	1141	761	761
query77	335	382	286	286
query78	11091	11169	10506	10506
query79	1440	1142	791	791
query80	1049	589	520	520
query81	553	323	287	287
query82	631	178	143	143
query83	389	342	315	315
query84	341	171	138	138
query85	1082	717	629	629
query86	376	233	223	223
query87	1987	1963	1825	1825
query88	3738	2823	2818	2818
query89	412	328	295	295
query90	1896	198	195	195
query91	224	212	187	187
query92	70	65	61	61
query93	1615	1499	913	913
query94	639	362	329	329
query95	822	536	510	510
query96	1122	767	359	359
query97	2459	2492	2348	2348
query98	196	197	185	185
query99	755	736	624	624
Total cold run time: 246876 ms
Total hot run time: 159564 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 23.61 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 527066179d0e7025c52b6385e51f38b73102c567, data reload: false

query1	0.01	0.01	0.01
query2	0.09	0.05	0.04
query3	0.25	0.13	0.14
query4	1.61	0.14	0.14
query5	0.24	0.22	0.23
query6	1.15	0.83	0.78
query7	0.03	0.00	0.01
query8	0.06	0.04	0.04
query9	0.38	0.30	0.32
query10	0.56	0.54	0.55
query11	0.18	0.13	0.13
query12	0.17	0.14	0.14
query13	0.46	0.46	0.46
query14	1.00	0.98	0.99
query15	0.61	0.58	0.60
query16	0.33	0.34	0.29
query17	1.07	1.05	1.02
query18	0.21	0.19	0.20
query19	2.06	1.94	1.92
query20	0.02	0.01	0.01
query21	15.43	0.19	0.13
query22	4.94	0.06	0.05
query23	16.15	0.32	0.12
query24	2.96	0.41	0.32
query25	0.11	0.05	0.04
query26	0.72	0.22	0.16
query27	0.05	0.04	0.04
query28	3.54	0.81	0.34
query29	12.46	4.02	3.16
query30	0.27	0.16	0.15
query31	2.76	0.54	0.32
query32	3.22	0.58	0.49
query33	3.19	3.16	3.17
query34	15.57	3.91	3.28
query35	3.24	3.22	3.18
query36	0.55	0.42	0.40
query37	0.09	0.06	0.06
query38	0.06	0.04	0.04
query39	0.04	0.03	0.02
query40	0.17	0.14	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.18 s
Total hot run time: 23.61 s

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for three production-reachable concurrency regressions in the unified metadata-cache publication paths:

  • a cold FE database/table object becomes visible before its IdNameIndex action while the adapter reacquires its stripe;
  • an incremental database/table-name remap can overwrite a newer concurrent refresh snapshot; and
  • a delayed refresh can overwrite a newer value loaded after eviction.

Checkpoint conclusions:

  • Goal and proof: the catalog-local owner and hierarchical invalidation design largely accomplish the consolidation goal, and the new unit suites cover most load, invalidation, hierarchy, close, and pruning contracts. They do not cover the three accepted interleavings.
  • Scope and design: this is a broad but cohesive cache-framework refactor. Existing mechanisms were reused appropriately, and no unrelated code change was found.
  • Concurrency: remote loads stay outside gates/monitors and the gate/lock ordering showed no deadlock. The three inline findings are correctness gaps in cross-layer publication and refresh replacement.
  • Lifecycle: owner close, detached-state cleanup, removal callbacks, bulk handles, and node/tombstone pruning were traced. The queued-refresh lease concern was dismissed because it had no distinct current production impact beyond the already-retained Runnable graph.
  • Configuration and compatibility: no new configuration key, persistence format, FE-BE variable, or protocol was added. CacheSpec parsing, Maven/runtime closure, plugin classloading, and mixed old/new FE-plugin fallback showed no concrete compatibility defect.
  • Parallel paths and conditions: database/table paths, all migrated connectors, Hive collection/value scopes, replay/DDL/event invalidations, Iceberg authorization-sensitive gates, and deliberate catalog-scoped exceptions were checked. No additional distinct issue remained.
  • Tests and results: changed tests are deterministic and substantial, but latch coverage is missing for the three reported races. Per the review-runner instructions, no build or test command was run.
  • Observability and performance: existing metrics/logging remain adequate for ordinary cache operations; remote I/O remains outside locks, and no separate material performance or observability defect was substantiated.
  • Persistence, transactions, data writes, and storage/FE-BE compatibility: not applicable to this metadata-cache-only refactor.

There was no additional user-provided focus. The full 70-file authoritative diff was reviewed. After three rounds, all normal and risk-focused reviewers returned NO_NEW_VALUABLE_FINDINGS; the review is converged with no unresolved or duplicate candidate.

token = beginAction(stripe, key);
}
try {
V value = cached == null ? get(key) : cached;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Keep a cold object hidden until its ID mapping is published

On a miss, get(key) installs the object in the shared MetaCache before this method reaches the pre-action hook and reacquires the FE stripe. If another same-stripe mutation holds that monitor, cache-only/name paths can already observe the object while ExternalCatalog.getDbNullable(id) or ExternalDatabase.getTableNullable(id) still reads an empty IdNameIndex and returns null. The base path also put immediately before the index action, so unlocked readers had a very small interval, but it acquired the stripe (and passed the test hook) before publishing either side; this refactor turns that into an interval that can block behind stripe contention. Please keep the value unpublished until the validated auxiliary action succeeds, and cover database/table by-ID lookups with a latch-based test.

Runnable validation = Objects.requireNonNull(validationAction, "validationAction can not be null");
StripeState<K> stripe = stripeState(key);
synchronized (stripe) {
V updated = effectiveEnabled ? remapper.apply(key, data.getIfPresent(key)) : null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Make name-snapshot remapping atomic with refresh

updated is derived from the current cached snapshot here, but the later invalidate/put pair is protected only by the FE stripe. Shared-runtime refresh does not take that stripe, so it can publish a newer snapshot N1 after this read; the remapper then invalidates N1 and installs U derived from the older N0, dropping any unrelated database/table names that arrived in the refresh until another full reload. Both database- and table-name caches enable auto-refresh, and their incremental add/drop paths use these remappers. Please add an exact-key atomic remap/compare-and-retry primitive so a concurrent refresh forces the function to re-evaluate the new value, with latch tests for both name caches.

V refreshed = loadAndRecord(key, loader);
if (refreshed != null) {
synchronized (lease.keyNode) {
publishCommitted(lease, key, refreshed);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not let an old refresh replace a newer miss result

This commit validates only the refresh lease's key/scope states, not that the wrapper which triggered the refresh is still current. A concrete production schedule is: refresh R starts from V1 and captures the old remote result; capacity/expiry evicts V1 without changing KeyState or loadPublicationState; a normal miss then loads and publishes V2 using those same identities; finally R reaches this line and overwrites V2 with stale V1. Bounded multi-key FE schema caches enable auto-refresh, so eviction makes this reachable. Please require the exact current wrapper/registration to remain current at refresh commit (or use expected-value conditional replacement), and add a latch test for eviction plus a newer miss.

924060929 added a commit to 924060929/incubator-doris that referenced this pull request Aug 11, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66407

Problem Summary: The unified metadata cache still exposed duplicate invalidation ownership through CachingHmsClient, retained an engine registry and route abstraction for two built-in FE cache types, and used FE-only names that were easy to confuse with the connector cache API. This change makes the connector CatalogMetaCache the sole invalidation owner, publishes partition collection and partition invalidation atomically, removes redundant Hive and Hudi client type branches, and renames FE-only cache adapters and catalog runtimes to describe their actual roles. Remote Doris schema and backend caching remain catalog-scoped, while statistics caches keep their independent asynchronous semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Connector cache, HMS, Hive, and Hudi Maven unit tests
    - Targeted FE unit tests for cache runtime, naming cache, Remote Doris, external catalog/database, and refresh replay
- Behavior changed: No. Internal cache ownership and invalidation publication are refactored without changing external SQL behavior.
- Does this need documentation: No
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one new blocking correctness issue, attached inline.

Review status: converged after two complete rounds. The second runtime, connector/FE, and risk-focused passes all returned NO_NEW_VALUABLE_FINDINGS after revalidating the accepted issue and the dismissed candidates.

Checkpoint conclusions:

  • Correctness and concurrency: batched cold-leaf invalidation can let a pre-refresh HMS partition result publish afterward; this is the inline P1. Miss deduplication, exact-key and ancestor fencing, expected-wrapper refresh replacement, FE auxiliary-index publication, and pruning/removal paths otherwise held up.
  • Lifecycle and cleanup: connector-owned CatalogMetaCache instances, lazy HMS construction, close races, refresh teardown, removal callbacks, scope/key pruning, and sibling connector invalidation were traced without another production-reachable defect.
  • Configuration and compatibility: legacy Hive TTL mappings, independent per-entry enable/TTL/capacity controls, disabled-cache behavior, FE/plugin Caffeine linkage, aliases, and default-versus-Remote-Doris routing were checked. No storage/protocol, rolling FE/BE, persisted-state, or FE-BE variable compatibility change applies.
  • Parallel consumers: ADBC, Hive/HMS/Hudi, Iceberg, MaxCompute, Paimon, FE schema/backends caches, local-versus-remote names, ancestor collection scopes, replay/drop/rename/refresh routes, and immutable Iceberg caches were reviewed. No second scope or routing mismatch survived verification.
  • Tests and observability: the new hierarchy, concurrency, leak, disabled-cache, connector, and FE latch tests were inspected; the accepted issue lacks the cold batch-invalidation latch described inline. Cache metrics and failure logging remain available. No builds or tests were run because the authoritative review bundle explicitly prohibits them.

The three pre-existing inline P1 threads were rechecked against the current head and appear addressed: cold FE objects publish their ID mapping inside the guarded commit, name remaps retry exact-wrapper CAS, and refresh replaces only its expected wrapper.

924060929 added a commit to 924060929/incubator-doris that referenced this pull request Aug 11, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66407

Problem Summary: The unified metadata cache still exposed duplicate invalidation ownership through CachingHmsClient, retained an engine registry and route abstraction for two built-in FE cache types, and used FE-only names that were easy to confuse with the connector cache API. This change makes the connector CatalogMetaCache the sole invalidation owner, publishes partition collection and partition invalidation atomically, removes redundant Hive and Hudi client type branches, and renames FE-only cache adapters and catalog runtimes to describe their actual roles. Remote Doris schema and backend caching remain catalog-scoped, while statistics caches keep their independent asynchronous semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Connector cache, HMS, Hive, and Hudi Maven unit tests
    - Targeted FE unit tests for cache runtime, naming cache, Remote Doris, external catalog/database, and refresh replay
- Behavior changed: No. Internal cache ownership and invalidation publication are refactored without changing external SQL behavior.
- Does this need documentation: No
@924060929
924060929 force-pushed the prototype-scoped-metacache-ut branch from 2b2a1b6 to 04e684b Compare August 11, 2026 03:46
@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes: one distinct concurrency/lifecycle correctness issue remains.

Finding

  • [P2] An identity-preserving ScopedMetaCache.compareAndSet still installs a replacement wrapper. During a FeMetaCacheEntry.computeAfterValidation retry, this synchronously reports the exact still-current ExternalDatabase as removed and resets its initialized table caches, ID index, and downstream database scope. The inline comment is attached at ScopedMetaCache.java:293.

Critical checkpoint conclusions

  • Goal and proof: the PR centralizes FE and connector metadata caches behind a catalog-scoped runtime with hierarchical invalidation, shared configuration, lifecycle, and statistics. The implementation and its added unit tests cover most load, refresh, invalidation, bulk-publication, close, and routing schedules, but no test combines an outer names-CAS retry, nested identity-preserving object publication, and the synchronous database removal listener; the accepted finding shows the goal is not fully met.
  • Focus and scope: review_focus.txt contains no additional user-provided focus. All 85 changed files and their production callers/tests were reviewed. The refactor is broad but cohesive; compatibility adapters and connector-local wrappers keep the changes focused on metadata-cache unification.
  • Concurrency and locking: event/refresh/query threads, FE stripes, key monitors, publication gates, generations, and exact wrapper registrations were traced. Late load/refresh/bulk publication and cleanup are otherwise fenced. The accepted same-instance replacement callback is the remaining race. The proposed broader callback deadlock was dismissed because the database entry, table entries, and FE schema runtime use independent CatalogMetaCache owners/registries with no reverse lock edge.
  • Lifecycle and ownership: connector owners close before their remote resources, scoped registrations are pruned, and catalog remove/recreate paths close the appropriate runtime. No static-initialization issue or additional leak/close race was found.
  • Configuration: legacy TTL overlays, non-positive TTL folding, independent enable/capacity controls, disabled-cache semantics, and ephemeral schema-cache property overlay were preserved. No new global dynamic configuration contract requires runtime propagation.
  • Compatibility: cache API/module relocation, preserved signatures, plugin classloading fallbacks, default versus remote-Doris routing, aliases, stats identity, replay, and catalog remove/recreate behavior were checked. No FE-BE protocol or storage-format change is involved.
  • Parallel paths and conditions: ADBC, Hive/HMS/Hudi, Iceberg, MaxCompute, Paimon, FE schema caches, DDL/event/replay paths, exact and collection invalidation, sibling forwarding, credentials, and time-travel variants were traced. No distinct missed path or unjustified condition remained.
  • Tests and results: the PR adds extensive latch/barrier-based FE and cache unit tests, including the previously discussed cold ID publication, names remap, expected-wrapper refresh, and cold bulk-descendant races. The exact accepted removal-listener retry is missing. No generated result file is changed. Tests/builds were not run by this reviewer under the review-only bundle instructions.
  • Error handling and data correctness: loader exception, null-as-miss, disabled-cache, conflict validation, and canonical partition-key behavior were checked. Aside from the accepted lifecycle reset, no silent error, stale publication, ID/name inconsistency, or incorrect invalidation survived review.
  • Observability: cache metrics, per-entry statistics, sorting/deduplication, and existing lifecycle logging are sufficient for the new paths; no additional critical metric or identifier gap was found.
  • Persistence, transactions, and writes: no transaction or user-data write path changes. Persisted catalog properties are not mutated by the derived overlay; EditLog/replay navigation and cold fallbacks were checked without a new persistence issue.
  • FE-BE variables: no new variable or protocol field is passed between FE and BE.
  • Memory safety and BE nullable handling: the change is FE Java metadata-cache code; BE allocator, C++ ownership, and nullable-column checkpoints are not applicable. Java cache ownership, defensive key copies, cleanup, and close were reviewed without another issue.
  • Performance: gate scope, synchronous loaders/callbacks, single-flight admission, bounded caches, node pruning, metrics, and connector-specific cache granularity were checked. No distinct production performance regression or obvious redundant operation was substantiated.
  • Other issues and duplicates: existing discussions 3754745907, 3754745909, 3754745910, and 3755059016 cover the fixed cold object/ID publication, names remap, refresh replacement, and cold bulk-descendant issues and were not duplicated.

Review status: converged after two full rounds. One inline comment is requested; every other candidate was duplicate-suppressed or dismissed with concrete code evidence.

924060929 added a commit to 924060929/incubator-doris that referenced this pull request Aug 11, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66407

Problem Summary: The unified metadata cache still exposed duplicate invalidation ownership through CachingHmsClient, retained an engine registry and route abstraction for two built-in FE cache types, and used FE-only names that were easy to confuse with the connector cache API. This change makes the connector CatalogMetaCache the sole invalidation owner, publishes partition collection and partition invalidation atomically, removes redundant Hive and Hudi client type branches, and renames FE-only cache adapters and catalog runtimes to describe their actual roles. Remote Doris schema and backend caching remain catalog-scoped, while statistics caches keep their independent asynchronous semantics.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - Connector cache, HMS, Hive, and Hudi Maven unit tests
    - Targeted FE unit tests for cache runtime, naming cache, Remote Doris, external catalog/database, and refresh replay
- Behavior changed: No. Internal cache ownership and invalidation publication are refactored without changing external SQL behavior.
- Does this need documentation: No
@924060929
924060929 force-pushed the prototype-scoped-metacache-ut branch from 04e684b to 97ef95e Compare August 11, 2026 10:13
@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review complete for head 97ef95eaa15a40ce82eba7f02877a35ea4602f88: no new actionable findings. This is a comment-only, no-blocker opinion.

Critical checkpoint conclusions:

  • Goal and proof: the PR unifies FE and connector metadata caches behind catalog-owned runtimes with shared configuration, hierarchical invalidation, lifecycle, and statistics. The implementation accomplishes that goal, and the added unit suites cover load/publication, exact and ancestor invalidation, refresh, bulk loading, close, pruning/leak behavior, routing, and connector migrations.
  • Scope and design: this is necessarily broad, but the changes stay focused on the cache-framework consolidation, its compatibility adapters, connector migrations, and their tests. Existing mechanisms are reused and no unrelated behavior change was found.
  • Concurrency and locking: query/event/refresh threads, FE stripes, phase gates, key monitors, scope/key generations, Caffeine removal callbacks, and refresh executors were traced. Remote loads and other heavy work remain outside publication locks; reachable production paths have consistent lock ordering; exact wrapper/state checks fence stale load, refresh, CAS, and bulk publication; and callbacks are deferred outside gates. No reachable deadlock or stale-publication defect remains.
  • Lifecycle and configuration: connector-owned runtimes close before their remote clients/catalogs, Hive closes built siblings, FE engine runtimes are removed and closed, and key/scope/tombstone state is reclaimed on eviction, invalidation, handle release, and close. Legacy enable/TTL/capacity parsing, disabled behavior, plugin overlays, and rebuild-on-property-change semantics are preserved; no new dynamic configuration contract was introduced.
  • Compatibility and parallel paths: default versus Remote Doris routing, the external_doris alias, local/remote name mappings, missing-catalog cleanup, replay/DDL/event paths, and ADBC, Hive/HMS/Hudi, Iceberg, MaxCompute, and Paimon scope projections were checked. Snapshot, branch, system-table, namespace, and partition variants converge on their owning ancestor invalidations. No storage format, public symbol, persisted-state encoding, or FE/BE protocol compatibility change is involved.
  • Tests and results: 24 changed unit-test files include deterministic latch/barrier coverage for the altered concurrency boundaries plus hierarchy, leak, configuration, routing, and connector invalidation cases. No generated regression result changes apply. Builds and tests were not run because the authoritative review instructions explicitly prohibit them, so this conclusion is based on static review of the current head and test sources.
  • Error handling, memory, observability, and performance: loader failures/null misses, disabled-cache pass-through, refresh rejection, callback failures, metrics/statistics, bounded hierarchy traversal, single-flight admission, and cleanup accounting were reviewed. Failures are surfaced or logged at the existing boundaries, remote I/O is not performed under cache locks, and no additional material correctness, leak, observability, or performance issue was substantiated.
  • Persistence, transactions, data writes, and FE/BE variables: not applicable; this refactor does not alter transaction or user-data write paths, EditLog formats, storage visibility, or variables sent between FE and BE.

The five existing live inline findings—cold object/ID publication, name-snapshot remapping, expected-wrapper refresh replacement, cold descendant batch invalidation, and identity-preserving CAS removal—are addressed in the current head and were not duplicated. There was no additional user-provided review focus.

Review status: converged after two complete full-scope rounds and independent risk-focused rechecks. All 85 authoritative changed paths were swept, every candidate was validated or dismissed with concrete production-path evidence, and no unresolved point or inline comment remains.

0AyanamiRei added a commit to 0AyanamiRei/doris that referenced this pull request Aug 20, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66634

Problem Summary: Routine Load cannot safely use the legacy Expr object graph as an image or journal compatibility surface. Keep the current effective load definition in origStmt, remove the duplicate execMemLimit JSON source, and cover all SQL-representable load clauses through CREATE image restore, ALTER merge, and a second image restore.

### Release note

Routine Load now persists ALTERed load clauses in the effective origin SQL used during FE recovery.

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.load.routineload.RoutineLoadJobPersistenceTest
    - ./run-fe-ut.sh --run org.apache.doris.load.routineload.KafkaRoutineLoadJobTest,org.apache.doris.load.routineload.KinesisRoutineLoadJobTest,org.apache.doris.persist.AlterRoutineLoadOperationLogTest
    - Docker regression case added but not run locally
- Behavior changed: Yes, ALTERed Routine Load definitions survive journal replay and image recovery
- Does this need documentation: Yes, the existing design document and PR description must be updated
0AyanamiRei added a commit to 0AyanamiRei/doris that referenced this pull request Aug 20, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66634

Problem Summary: Routine Load images already persist and replay origStmt. The persistence bug is that ALTER load clauses changed runtime fields without updating that statement. Keep the existing gsonPostProcess recovery path unchanged, persist the original ALTER SQL in the journal, and rewrite origStmt to a complete effective CREATE statement after leader and follower ALTER application. Remove direct-field persistence, cache hydration, CSV validation, and other adjacent changes from this PR.

### Release note

Routine Load now preserves ALTERed load clauses across follower replay, checkpoints, and FE restart by maintaining the effective CREATE statement.

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.load.routineload.RoutineLoadJobPersistenceTest
    - ./run-fe-ut.sh --run org.apache.doris.load.routineload.KinesisRoutineLoadJobTest
    - KafkaRoutineLoadJobTest and AlterRoutineLoadOperationLogTest passed in the combined targeted run
    - Docker regression case added but not run locally
- Behavior changed: Yes, ALTERed load clauses update the persisted origin statement
- Does this need documentation: Yes, document mixed-version ALTER limitations
0AyanamiRei added a commit to 0AyanamiRei/doris that referenced this pull request Aug 20, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66634

Problem Summary: Treat the effective Routine Load fields as authoritative metadata instead of rewriting origStmt after ALTER. Persist the load-definition fields directly in images, persist RoutineLoadDesc deltas in ALTER journals, and use the original CREATE statement only when reading legacy images whose nullable effective fields are absent. Empty new definitions may also use the fallback safely because ALTER cannot unset all load clauses.

### Release note

Routine Load now preserves ALTERed load clauses across journal replay and FE restart through direct metadata persistence.

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.load.routineload.RoutineLoadJobPersistenceTest,org.apache.doris.load.routineload.KafkaRoutineLoadJobTest,org.apache.doris.load.routineload.KinesisRoutineLoadJobTest,org.apache.doris.persist.AlterRoutineLoadOperationLogTest
- Behavior changed: Yes, image and ALTER journal persist effective Routine Load definitions directly
- Does this need documentation: Yes, document mixed-version ALTER limitations
0AyanamiRei added a commit to 0AyanamiRei/doris that referenced this pull request Aug 20, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66634

Problem Summary: Metadata consumers now persist legacy Expr objects directly, but the existing Expr Gson test only checked subtype and JSON idempotence. Add stable serialization for SQL-relevant fields that were silently dropped, persist function ORDER BY metadata, require every Expr instance field to be serialized or explicitly classified as non-durable, and verify SQL output with and without table names for every concrete registered subtype. Add an analysis review guide for future Expr changes.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.analysis.ExprGsonSerializationTest
    - ./run-fe-ut.sh --run org.apache.doris.analysis.ExprGsonSerializationTest,org.apache.doris.load.routineload.RoutineLoadJobPersistenceTest,org.apache.doris.persist.AlterRoutineLoadOperationLogTest
- Behavior changed: No user-facing SQL behavior; metadata Expr round trips now preserve SQL semantics
- Does this need documentation: No, contributor guidance is included in analysis/AGENTS.md
0AyanamiRei added a commit to 0AyanamiRei/doris that referenced this pull request Aug 20, 2026
### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66634

Problem Summary: The first restoration of direct Routine Load persistence omitted parts of the previously reviewed design. Restore the exact persistence implementation from commit 4394fa3, including execMemLimit and memtableOnSinkNode image fields, jobProperties cache hydration, CSV ALTER cache synchronization, leader-only validation, legacy image migration, and the original Kafka/Kinesis persistence tests. Keep the separate Expr serde hardening on top.

### Release note

Routine Load persists its effective load definition and non-default task configuration directly across FE recovery.

### Check List (For Author)

- Test: Unit Test
    - ./run-fe-ut.sh --run org.apache.doris.analysis.ExprGsonSerializationTest,org.apache.doris.load.routineload.RoutineLoadJobPersistenceTest,org.apache.doris.load.routineload.KafkaRoutineLoadJobTest,org.apache.doris.load.routineload.KinesisRoutineLoadJobTest,org.apache.doris.persist.AlterRoutineLoadOperationLogTest
- Behavior changed: Yes, restore the complete direct-state image and ALTER journal persistence contract
- Does this need documentation: Yes, document mixed-version ALTER limitations
924060929 added a commit to 924060929/incubator-doris that referenced this pull request Aug 24, 2026
Problem Summary:
PR apache#64160 added row-count cache invalidation and a test-only engine cache replacement hook after this branch diverged. Merging current master conflicted with the scoped metadata cache test setup and left the old registry-based test hook incompatible with the new cacheTypes framework.

Solution:
Preserve the row-count cache implementation and invalidation ordering from apache#64160. Resolve RefreshManagerTest against FeMetaCacheEntry and migrate replaceEngineCachesForTest to register replacement engines and aliases through the new cacheTypes model.

Tests:
- 116 focused FE unit tests passed
- 104 connector cache unit tests passed
- Maven Checkstyle reactor passed with 0 violations

Issue Number: close apache#66633
Related PR: apache#64160
924060929 added a commit to 924060929/incubator-doris that referenced this pull request Aug 24, 2026
Problem Summary:
Master advanced after the initial conflict resolution and introduced Paimon HMS identity isolation changes that overlapped the scoped Paimon cache refactor at the connector imports.

Solution:
Preserve the new HMS FileIO and catalog construction path while retaining CatalogMetaCache-based invalidation. Drop only the obsolete Identifier import, which is no longer used after table invalidation is routed through the scoped cache hierarchy.

Tests:
- 554 Paimon connector tests passed (1 skipped)
- Checkstyle validation passed in the FE reactor

Issue Number: close apache#66633
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 82249 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 118299877361395b2b17bb22eb430e651b45371a, data reload: false

query5	4278	389	331	331
query6	397	141	121	121
query7	4983	428	224	224
query8	298	124	116	116
query9	8679	2906	2892	2892
query10	414	217	180	180
query11	5402	1023	922	922
query12	121	73	73	73
query13	1200	454	319	319
query14	6000	2204	2082	2082
query14_1	1985	1976	1965	1965
query15	177	122	109	109
query16	3125	385	344	344
query17	783	451	363	363
query18	2086	333	243	243
query19	169	139	110	110
query20	72	67	70	67
query21	201	102	88	88
query22	5547	5367	5427	5367
query23	6615	6241	5998	5998
query23_1	6015	6189	6062	6062
query24	7341	1117	791	791
query24_1	775	787	778	778
query25	454	312	267	267
query26	1213	216	135	135
query27	2787	431	262	262
query28	4645	1507	1468	1468
query29	954	447	367	367
query30	387	149	132	132
query31	848	400	333	333
query32	129	77	77	77
query33	496	220	183	183
query34	1022	818	485	485
query35	397	391	340	340
query36	595	597	542	542
query37	125	81	72	72
query38	1031	853	841	841
query39	518	500	470	470
query39_1	505	464	459	459
query40	250	89	78	78
query41	59	57	57	57
query42	78	70	71	70
query43	237	245	209	209
query44	1046	545	572	545
query45	107	109	107	107
query46	742	870	528	528
query47	806	770	703	703
query48	307	310	237	237
query49	553	223	179	179
query50	764	262	194	194
query51	8547	8358	8201	8201
query52	67	68	92	68
query53	191	194	141	141
query54	218	174	171	171
query55	74	61	53	53
query56	181	164	149	149
query57	684	644	669	644
query58	193	168	155	155
query59	1174	1197	1071	1071
query60	230	177	172	172
query61	121	119	118	118
query62	391	211	181	181
query63	166	131	144	131
query64	2342	706	571	571
query65	1579	1577	1546	1546
query66	1743	285	214	214
query67	10029	9738	9768	9738
query68	2864	1209	776	776
query69	522	222	200	200
query70	680	626	607	607
query71	249	171	165	165
query72	2441	1741	1516	1516
query73	711	589	312	312
query74	1853	1230	1125	1125
query75	1168	1097	966	966
query76	1868	740	532	532
query77	250	261	214	214
query78	3871	3736	3247	3247
query79	2391	794	574	574
query80	1530	328	277	277
query81	514	153	132	132
query82	745	133	93	93
query83	293	219	197	197
query84	299	115	92	92
query85	823	359	300	300
query86	442	193	168	168
query87	1030	978	894	894
query88	2808	2087	2079	2079
query89	301	198	177	177
query90	1977	127	120	120
query91	133	125	98	98
query92	82	69	72	69
query93	1518	1056	735	735
query94	660	232	221	221
query95	525	328	235	235
query96	809	556	271	271
query97	1070	1113	1025	1025
query98	160	146	137	137
query99	511	340	301	301
Total cold run time: 181165 ms
Total hot run time: 82249 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.66 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 118299877361395b2b17bb22eb430e651b45371a, data reload: false

query1	0.01	0.00	0.00
query2	0.31	0.04	0.03
query3	0.60	0.11	0.11
query4	1.71	0.10	0.09
query5	0.18	0.15	0.15
query6	1.56	0.71	0.67
query7	0.04	0.01	0.01
query8	0.05	0.03	0.03
query9	0.64	0.22	0.21
query10	0.35	0.34	0.35
query11	0.28	0.11	0.12
query12	0.21	0.12	0.12
query13	0.32	0.31	0.31
query14	0.46	0.45	0.44
query15	0.38	0.34	0.34
query16	0.23	0.22	0.22
query17	0.70	0.66	0.68
query18	0.18	0.18	0.17
query19	1.49	1.18	1.20
query20	0.02	0.01	0.01
query21	16.78	0.16	0.12
query22	4.76	0.05	0.04
query23	16.92	0.25	0.11
query24	16.75	0.33	0.26
query25	0.10	0.04	0.03
query26	0.71	0.17	0.12
query27	0.04	0.03	0.04
query28	3.63	0.53	0.26
query29	12.60	3.12	2.56
query30	0.25	0.12	0.12
query31	2.89	0.37	0.18
query32	3.56	0.31	0.22
query33	1.37	1.47	1.52
query34	15.35	2.23	1.76
query35	1.74	1.71	1.68
query36	0.47	0.30	0.29
query37	0.26	0.04	0.03
query38	0.04	0.03	0.03
query39	0.25	0.03	0.02
query40	0.20	0.08	0.07
query41	0.37	0.02	0.02
query42	0.15	0.02	0.02
query43	0.04	0.03	0.02
Total cold run time: 108.95 s
Total hot run time: 14.66 s

### What problem does this PR solve?

Issue Number: close apache#66633

Related PR: apache#66914

Problem Summary: The unified cache runtime used the removal callback for values that never became cache-owned and acquired refresh publication leases before asynchronous tasks started. A disabled or invalidation-rejected FE database load could therefore return an already-reset object, identity refresh could retire the same object, and discarded queued refresh work could retain publication state. Separate unpublished-value discard from published-value removal, keep identity refresh wrapper ownership, acquire refresh leases inside tasks, release refresh admission on close, and remove a stale external-table comment.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - fe-connector-cache module tests (110 tests)
    - FeMetaCacheEntryTest (14 tests)
    - IcebergTableCacheTest (12 tests)
    - Full FE build
- Behavior changed: No. Preserves pre-refactor ownership and cleanup semantics.
- Does this need documentation: No
@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review result: request changes. I found one new actionable FE publication race and attached it inline. I read the existing review threads and raw comments first; no existing issue is duplicated. There was no additional user-provided focus.

Checkpoint conclusions:

  • Goal, accomplishment, and tests: The change establishes the shared catalog-scoped metadata-cache framework and migrates the intended FE/connector caches with substantial focused unit coverage. MAIN-01 shows that the FE name/object/ID publication goal is not yet complete for incremental database registration.
  • Scope and clarity: The diff is large but cohesive around one cache-framework migration. Framework, FE adapter, and connector-specific responsibilities are generally separated clearly.
  • Concurrency: I traced miss election, refresh, direct put/CAS, bulk publication, exact and hierarchical invalidation, pruning, synchronous callbacks, and close across the phase gates, per-key monitors, and FE stripes. The inline issue is a distinct unlocked ID-index visibility window before the object CAS. I found no additional lock inversion, stale-publication, leak, or double-retirement schedule beyond the already-live threads.
  • Lifecycle and initialization: Shared owners are closed by each migrated connector; late loads are fenced, and Iceberg cache/loader/borrower/catalog-generation references remain balanced. Static initialization and connector classloader boundaries did not expose a new issue.
  • Configuration: Enable/disable, TTL, refresh, capacity, stripe-count, and connector-specific cache knobs retain their intended construction-time behavior. No new dynamic-config handling defect was found.
  • Compatibility and rolling behavior: The moved cache API is not a connector SPI contract; plugin dependency/classloader closure and current call sites were checked. Remote Doris/default routing and exact built-in engine constants remain reachable. No wire, persisted-format, or mixed-FE/BE compatibility change was introduced.
  • Parallel paths: ADBC, Hive/HMS/Hudi, Iceberg, MaxCompute, Paimon, FE database/table caches, and missing-catalog cleanup were compared. Scope/invalidation parity is preserved; the one surviving discrepancy is the incremental FE database path described inline.
  • Special conditions and related paths: Cold/hot entries, disabled caches, rejected publication, eviction, refresh, batch invalidation, catalog/database/table/partition invalidation, close, and late completion were checked. Similar tests and callers were inspected, and comments match the current mechanisms.
  • Test coverage and modularity: The framework has focused hierarchy, concurrency, leak, lifecycle, and connector tests. The missing negative case is a latch test that lets a by-ID database lookup publish between validation.run() and the CAS. No local build or test was run because this review task explicitly prohibited it.
  • Test results: At review time, BE UT, Cloud UT, coverage, dependency review, style, license, and secret checks passed; compile, FE UT, performance, and the code-review workflow were still pending. I did not infer success for pending checks.
  • Observability: Cache hit/miss/load/eviction/error and hierarchy metrics remain available; refresh/close failures retain logging. No new observability blocker was found.
  • Transactions and persistence: This refactor does not change transaction boundaries, edit logs, durable metadata formats, or failover replay semantics.
  • Data writes and crash safety: The change affects ephemeral metadata caching rather than storage-engine writes, so atomic durable-write/crash-recovery checks are not applicable.
  • FE/BE variables and nullable semantics: The changed behavior is FE/connector-local and adds no FE-to-BE variable or protocol path. BE nullable-column handling is not applicable.
  • Performance: Remote loaders remain outside critical sections, shared scopes are bounded/pruned, and cache capacities remain explicit. I found no distinct new performance regression.
  • Other issues: No additional valuable findings survived validation and duplicate fencing.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16978 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 5c0c8571519df064afda155d5ff9f0c39f912096, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17665	3119	3133	3119
q2	2230	266	225	225
q3	10101	864	519	519
q4	4686	247	201	201
q5	7669	576	368	368
q6	161	114	97	97
q7	536	503	381	381
q8	9275	924	904	904
q9	3474	2433	2398	2398
q10	6492	866	696	696
q11	492	193	176	176
q12	650	250	195	195
q13	18131	1503	1153	1153
q14	156	149	143	143
q15	q16	448	392	363	363
q17	1453	933	809	809
q18	3086	2238	2230	2230
q19	1273	937	819	819
q20	396	286	205	205
q21	5591	1753	1797	1753
q22	339	265	224	224
Total cold run time: 94304 ms
Total hot run time: 16978 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3552	3418	3405	3405
q2	500	394	362	362
q3	2207	2337	2185	2185
q4	1183	1167	896	896
q5	2204	2137	2080	2080
q6	170	127	87	87
q7	1021	912	850	850
q8	1612	1413	1418	1413
q9	3147	3152	3134	3134
q10	1832	1777	1619	1619
q11	359	269	249	249
q12	450	434	349	349
q13	1521	1523	1173	1173
q14	176	179	160	160
q15	q16	407	389	369	369
q17	3573	3291	3159	3159
q18	4930	4413	4693	4413
q19	991	901	880	880
q20	1020	971	795	795
q21	3776	3056	3205	3056
q22	394	349	309	309
Total cold run time: 35025 ms
Total hot run time: 30943 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 81459 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 5c0c8571519df064afda155d5ff9f0c39f912096, data reload: false

query5	4299	414	348	348
query6	398	137	134	134
query7	4912	430	235	235
query8	294	128	114	114
query9	8682	2897	2872	2872
query10	394	224	180	180
query11	5369	1038	906	906
query12	123	71	74	71
query13	1213	438	325	325
query14	6184	2181	2084	2084
query14_1	1962	1944	1936	1936
query15	172	115	110	110
query16	957	364	365	364
query17	805	449	359	359
query18	2335	331	243	243
query19	170	138	109	109
query20	73	71	70	70
query21	210	114	94	94
query22	5482	5341	5316	5316
query23	7058	6226	5988	5988
query23_1	6107	5972	6115	5972
query24	7370	1081	762	762
query24_1	771	766	772	766
query25	442	315	262	262
query26	1248	220	130	130
query27	2804	420	260	260
query28	4651	1519	1507	1507
query29	950	433	362	362
query30	265	155	134	134
query31	837	398	333	333
query32	128	73	71	71
query33	472	233	181	181
query34	1004	828	466	466
query35	418	407	342	342
query36	555	543	533	533
query37	126	83	70	70
query38	993	844	809	809
query39	488	485	456	456
query39_1	472	445	434	434
query40	211	95	84	84
query41	58	55	55	55
query42	75	71	72	71
query43	250	244	214	214
query44	1054	558	552	552
query45	114	107	100	100
query46	766	859	505	505
query47	789	750	713	713
query48	306	301	208	208
query49	534	246	180	180
query50	728	264	195	195
query51	8335	8153	7995	7995
query52	69	69	59	59
query53	193	195	143	143
query54	235	155	157	155
query55	74	69	81	69
query56	229	184	151	151
query57	654	665	626	626
query58	218	169	161	161
query59	1206	1199	1087	1087
query60	228	195	188	188
query61	128	141	136	136
query62	426	202	178	178
query63	172	139	141	139
query64	2725	694	585	585
query65	1657	1576	1600	1576
query66	1933	258	213	213
query67	9737	9671	9528	9528
query68	2775	1200	733	733
query69	359	219	187	187
query70	674	572	586	572
query71	253	176	161	161
query72	2340	1729	1516	1516
query73	631	628	327	327
query74	1573	1202	1137	1137
query75	1168	1085	958	958
query76	2289	745	558	558
query77	243	262	200	200
query78	3818	3720	3215	3215
query79	2459	853	585	585
query80	1588	322	304	304
query81	528	156	133	133
query82	696	136	91	91
query83	288	214	192	192
query84	324	115	86	86
query85	816	358	283	283
query86	420	177	171	171
query87	986	974	901	901
query88	2795	2090	2085	2085
query89	295	190	183	183
query90	1975	124	126	124
query91	135	119	97	97
query92	78	70	71	70
query93	1431	1119	659	659
query94	670	257	209	209
query95	522	321	225	225
query96	800	578	262	262
query97	1062	1057	1014	1014
query98	150	134	132	132
query99	431	338	303	303
Total cold run time: 178275 ms
Total hot run time: 81459 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.64 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 5c0c8571519df064afda155d5ff9f0c39f912096, data reload: false

query1	0.01	0.00	0.01
query2	0.08	0.04	0.04
query3	0.25	0.11	0.12
query4	1.60	0.11	0.10
query5	0.17	0.16	0.16
query6	1.23	0.70	0.74
query7	0.04	0.00	0.00
query8	0.05	0.03	0.03
query9	0.29	0.22	0.21
query10	0.35	0.35	0.36
query11	0.16	0.12	0.11
query12	0.14	0.13	0.12
query13	0.30	0.32	0.29
query14	0.45	0.44	0.44
query15	0.35	0.34	0.35
query16	0.20	0.23	0.21
query17	0.63	0.68	0.69
query18	0.18	0.17	0.17
query19	1.18	1.14	1.15
query20	0.01	0.01	0.01
query21	15.44	0.15	0.13
query22	5.08	0.04	0.04
query23	16.19	0.26	0.11
query24	2.96	0.33	0.25
query25	0.11	0.03	0.04
query26	0.74	0.17	0.13
query27	0.04	0.03	0.03
query28	3.64	0.51	0.29
query29	12.46	3.13	2.56
query30	0.27	0.12	0.12
query31	2.75	0.37	0.17
query32	3.53	0.32	0.23
query33	1.40	1.34	1.43
query34	15.38	2.17	1.74
query35	1.75	1.73	1.73
query36	0.48	0.29	0.29
query37	0.06	0.04	0.04
query38	0.04	0.03	0.03
query39	0.03	0.02	0.02
query40	0.11	0.08	0.07
query41	0.07	0.03	0.03
query42	0.03	0.02	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.26 s
Total hot run time: 14.64 s

@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

### What problem does this PR solve?

Issue Number: close apache#64159

Related PR: apache#64160

Problem Summary: Incremental metadata events published the ID-to-name mapping before the matching database or table object was committed to the shared cache. A concurrent lookup by ID could therefore load and publish a different object in that gap, which was then replaced and cleaned up by the event update. Publish the ID mapping and object inside one guarded cache commit, fence overlapping loads, and make the object-and-ID step run only once when the outer name-cache CAS retries so a newer object is never replaced by replaying an already completed event update.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - ScopedMetaCacheConcurrencyTest
    - FeMetaCacheEntryTest
    - ExternalCatalogTest
    - ExternalDatabaseTest
    - ./build.sh --fe
- Behavior changed: No
- Does this need documentation: No
@924060929
924060929 force-pushed the prototype-scoped-metacache-ut branch from 529ed2d to f04e5f3 Compare August 27, 2026 07:55
@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Codex completed, but no new pull request review was submitted for the current head SHA.
Workflow run: https://github.com/apache/doris/actions/runs/33049284769

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

@924060929

Copy link
Copy Markdown
Contributor Author

run buildall

@924060929

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review result: NO_NEW_VALUABLE_FINDINGS at f04e5f3f8cab42a6ac3f18a5f10e19a7aa028e82.

Checkpoint conclusions:

  • Goal and proof: The current head unifies FE and connector metadata caches behind one catalog-scoped runtime while preserving scoped invalidation, publication fencing, cleanup, and connector-specific ownership. The changed unit tests exercise the shared hierarchy/concurrency contracts and the FE/connector adapters.
  • Scope and focus: The 88-file change is large but cohesive: shared runtime, all affected connector migrations, FE adaptation/routing, dependencies, and their tests. No unrelated behavior change was found. There was no additional user-provided review focus.
  • Concurrency: Query misses, asynchronous refresh, invalidation/event threads, eviction callbacks, and catalog close can race. The reviewed order is bulk phase gate -> registry publication gate -> key state/monitor, with FE name/object stripes around their local publication actions. Remote loads and physical removal cleanup stay outside the publication locks; no distinct remaining deadlock, stale-publication, or cleanup leak was substantiated.
  • Lifecycle and ownership: Per-catalog owners close their cache registries; queued refresh owns no pre-run lease; invalidation/close fence later publication; FE removal and discard ownership are separated; and Iceberg table/cache/borrower references drain before resource close. No circular or unbounded retained ownership was found.
  • Configuration: No new global dynamic configuration is introduced. Existing enable/TTL/capacity semantics and legacy Hive/HMS property translations are retained, with new-key precedence. Cache specs are captured at catalog/runtime construction as before.
  • Compatibility and rolling upgrade: No storage, journal, RPC, FE-BE protocol, or serialized metadata format changes are present. Legacy catalog properties are translated, and the shared cache API/runtime is present in the FE and connector dependency/classloader paths.
  • Parallel paths: ADBC, Hive/HMS/Hudi, Iceberg, MaxCompute, Paimon, generic external catalogs, and Remote Doris routing were checked. Local/remote identity domains, sibling invalidation, partition collection/value scopes, and Iceberg's catalog-scoped manifest exception remain aligned with their callers.
  • Conditions and error paths: Disabled caches, null/failed loads, refresh rejection, direct put/CAS, bulk publication, exact and hierarchical invalidation, dropped catalogs, alias routing, callback failures, and close races were reviewed. The special branches have matching contracts/tests or preserve the previous behavior.
  • Test coverage: The changed tests cover hierarchy, phase gates, miss/refresh/invalidation races, callback reentrancy, pruning/leak checks, FE database/table publication ordering, connector invalidation, and Iceberg resource ownership. No SQL regression or end-to-end result files are added; this is an internal FE/connector cache refactor.
  • Test results: Source assertions and expected outcomes were reviewed and are consistent with the intended contracts. Per the authoritative review prompt, I did not run builds or tests; the PR description reports the author's unit-test and FE-build results.
  • Observability: Cache metrics retain hits, misses, loads, latency, evictions, invalidations, size, and last-error timestamps; failure logging includes the relevant cache/catalog context. No additional distributed tracing surface is needed for this internal runtime.
  • Transactions and persistence: No transaction, EditLog, replay format, or master-failover protocol is modified.
  • Data writes and atomicity: No user-data write path is changed. Metadata publication/invalidation uses identity-conditional replacement and logical fencing before physical cleanup; no new crash-time persistence obligation is introduced.
  • FE-BE variables: No variable, thrift field, planner payload, or other FE-BE transmission path is added or changed.
  • Performance: Misses remain deduplicated, refresh remains asynchronous, caches stay bounded by TTL/capacity, and hot-path invalidation uses scoped registration instead of full predicate scans. Lock-held work is limited to publication state; no new material CPU, allocation, or memory-growth issue was substantiated.
  • Other issues: Existing review threads and all raw review comments were used as duplicate fences. After the main audit plus normal-runtime, integration, and risk-focused second passes, every candidate was either already covered or dismissed with current/base code evidence; no new inline issue remains.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 16856 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit f04e5f3f8cab42a6ac3f18a5f10e19a7aa028e82, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17656	3049	3035	3035
q2	2121	248	224	224
q3	10240	850	506	506
q4	4672	240	205	205
q5	7682	555	379	379
q6	140	112	91	91
q7	528	507	395	395
q8	9240	892	949	892
q9	3469	2419	2415	2415
q10	6504	861	718	718
q11	395	199	181	181
q12	610	261	195	195
q13	18142	1513	1176	1176
q14	158	149	140	140
q15	q16	427	399	366	366
q17	1371	896	782	782
q18	3054	2224	2260	2224
q19	1115	868	804	804
q20	365	282	197	197
q21	4832	1698	1792	1698
q22	313	264	233	233
Total cold run time: 93034 ms
Total hot run time: 16856 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3411	3325	3304	3304
q2	505	403	364	364
q3	2204	2376	2246	2246
q4	1179	1153	887	887
q5	2158	2123	2140	2123
q6	168	123	90	90
q7	1036	900	875	875
q8	1600	1406	1417	1406
q9	3108	3090	3089	3089
q10	1832	1781	1629	1629
q11	363	269	253	253
q12	452	424	344	344
q13	1464	1535	1121	1121
q14	166	164	163	163
q15	q16	398	401	353	353
q17	3616	3309	3355	3309
q18	4879	4360	4734	4360
q19	921	809	878	809
q20	1019	981	834	834
q21	3847	3092	3278	3092
q22	396	349	313	313
Total cold run time: 34722 ms
Total hot run time: 30964 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 82003 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit f04e5f3f8cab42a6ac3f18a5f10e19a7aa028e82, data reload: false

query5	4265	409	340	340
query6	381	137	121	121
query7	4957	436	236	236
query8	286	130	110	110
query9	8669	2880	2856	2856
query10	389	219	182	182
query11	5370	1026	899	899
query12	114	73	78	73
query13	1210	425	331	331
query14	6031	2170	2072	2072
query14_1	1962	1931	1928	1928
query15	175	117	108	108
query16	913	374	359	359
query17	803	460	382	382
query18	2322	316	238	238
query19	162	135	107	107
query20	70	67	68	67
query21	197	97	85	85
query22	5298	5285	5330	5285
query23	6722	6209	6081	6081
query23_1	6040	6046	6174	6046
query24	7238	1077	741	741
query24_1	764	762	794	762
query25	401	286	234	234
query26	1214	222	128	128
query27	2808	427	246	246
query28	4702	1486	1489	1486
query29	923	425	328	328
query30	251	151	129	129
query31	814	388	322	322
query32	128	85	77	77
query33	462	217	178	178
query34	992	804	466	466
query35	396	404	334	334
query36	566	561	527	527
query37	118	79	68	68
query38	1062	828	823	823
query39	488	509	468	468
query39_1	469	477	455	455
query40	198	91	78	78
query41	57	51	51	51
query42	73	72	71	71
query43	242	239	204	204
query44	1009	548	559	548
query45	111	103	100	100
query46	783	804	515	515
query47	753	752	720	720
query48	318	316	222	222
query49	531	255	213	213
query50	748	268	192	192
query51	8013	7918	8001	7918
query52	68	69	74	69
query53	195	199	150	150
query54	230	208	185	185
query55	74	60	57	57
query56	192	190	173	173
query57	714	682	614	614
query58	206	182	163	163
query59	1302	1201	1131	1131
query60	240	190	181	181
query61	112	117	116	116
query62	364	197	173	173
query63	167	144	140	140
query64	2723	716	631	631
query65	1682	1634	1596	1596
query66	1802	260	205	205
query67	9749	9820	9615	9615
query68	3012	1142	753	753
query69	357	209	198	198
query70	668	610	613	610
query71	247	165	167	165
query72	2359	1942	1718	1718
query73	662	593	328	328
query74	2004	1218	1141	1141
query75	1180	1098	953	953
query76	2386	732	541	541
query77	244	256	211	211
query78	3933	3674	3228	3228
query79	2789	808	602	602
query80	1553	325	277	277
query81	518	160	132	132
query82	613	126	100	100
query83	273	208	184	184
query84	295	110	92	92
query85	838	357	294	294
query86	473	172	175	172
query87	1003	971	889	889
query88	3167	2117	2085	2085
query89	282	196	177	177
query90	2169	127	121	121
query91	131	123	104	104
query92	97	68	68	68
query93	2695	1077	708	708
query94	642	250	180	180
query95	523	262	289	262
query96	822	575	267	267
query97	1057	1028	1041	1028
query98	182	138	132	132
query99	413	336	307	307
Total cold run time: 179807 ms
Total hot run time: 82003 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 14.48 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit f04e5f3f8cab42a6ac3f18a5f10e19a7aa028e82, data reload: false

query1	0.00	0.00	0.00
query2	0.09	0.04	0.03
query3	0.24	0.10	0.12
query4	1.60	0.10	0.10
query5	0.17	0.16	0.15
query6	1.26	0.68	0.68
query7	0.04	0.00	0.01
query8	0.04	0.03	0.03
query9	0.29	0.21	0.22
query10	0.33	0.35	0.35
query11	0.17	0.11	0.12
query12	0.14	0.12	0.11
query13	0.30	0.32	0.29
query14	0.45	0.44	0.43
query15	0.37	0.35	0.34
query16	0.23	0.22	0.20
query17	0.68	0.69	0.69
query18	0.18	0.17	0.18
query19	1.20	1.15	1.13
query20	0.01	0.00	0.00
query21	15.45	0.17	0.11
query22	5.06	0.04	0.05
query23	16.18	0.26	0.10
query24	2.99	0.33	0.26
query25	0.09	0.04	0.04
query26	0.82	0.16	0.13
query27	0.04	0.03	0.04
query28	3.69	0.52	0.26
query29	12.44	3.13	2.54
query30	0.25	0.12	0.11
query31	2.76	0.36	0.17
query32	3.54	0.32	0.22
query33	1.37	1.38	1.39
query34	15.33	2.21	1.76
query35	1.76	1.74	1.70
query36	0.44	0.30	0.29
query37	0.06	0.03	0.04
query38	0.05	0.03	0.03
query39	0.03	0.03	0.02
query40	0.11	0.08	0.07
query41	0.08	0.02	0.03
query42	0.04	0.02	0.02
query43	0.04	0.03	0.03
Total cold run time: 90.41 s
Total hot run time: 14.48 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 73.41% (265/361) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 60.11% (217/361) 🎉
Increment coverage report
Complete coverage report

@924060929
924060929 merged commit 9a7174e into apache:master Aug 31, 2026
32 of 33 checks passed
@924060929
924060929 deleted the prototype-scoped-metacache-ut branch August 31, 2026 11:21
@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants