Skip to content

[refactor](fe) Unify catalog and connector metadata cache ownership - #69458

Closed
924060929 wants to merge 5 commits into
apache:masterfrom
924060929:codex/unify-fe-cache-owner
Closed

924060929 wants to merge 5 commits into
apache:masterfrom
924060929:codex/unify-fe-cache-owner

Conversation

@924060929

@924060929 924060929 commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Problem Summary:

External catalog metadata is cached in several dependent layers: database/table membership, FE object and ID lookup, schemas, row counts, and connector metadata such as partitions, files, and snapshots. Previously these layers had separate owners and callers manually invalidated both sides. A refresh could leave a stale membership or object lookup behind; a load started before invalidation could republish an obsolete object or identity, particularly after a drop and same-name recreation. Keeping the old FE database object after eviction also allowed its cleanup to affect a replacement.

Use one CatalogMetaCache root per external catalog. FE registrations and instance-owned connector domains share its resource generations and existing budgets. Embedded connectors use child domains. Retiring an instance removes only its exact registrations; semantic resource invalidation is independent of instance lifetime. Local names, remote names, and numeric derived-state identities use distinct coordinate spaces.

CatalogMetadataChanges is the common boundary for refresh, successful writes/DDL, metastore events, and replay. It projects affected local and remote resources and invalidates them at one publication barrier. Connectors describe cross-resource dependencies through a pure SPI projection instead of imperative sibling invalidation. DDL journal records preserve remote identities for replay; old records fall back to broader remote-only invalidation without initializing remote metadata. Content changes preserve table-name snapshots and FE lookups, while explicit table/database refresh also invalidates the appropriate membership snapshot.

ID mappings survive ordinary object eviction but participate in semantic invalidation. Publication is guarded by the same resource generation, and accepted operations pin their auxiliary index until completion. Row-count futures belong to catalog roots while a shared retention-policy index preserves the existing process-wide entry limit. Cache callbacks retain the owning plugin classloader context.

Automatic row-count refresh keeps the last successful value while reloading and on failure. ADBC membership caches register under the shared collection scopes.

For case-insensitive table lookup (mode 2), the root captures an immutable normalization policy for LOCAL table resource scopes. Cache keys and displayed names retain their original spelling, while case-equivalent local identities share the same invalidation fence. REMOTE scopes keep their case semantics. Lookup invalidation (including rename and its event records) additionally fences numeric derived state for the affected database, covering a first object/row-count load that publishes an old spelling after invalidation planning. Sibling FE objects and schemas remain cached; row counts in that database are recalculated. Changing the table-name mode retires the old root and its policy. Planning performs no remote metadata lookup.

This also addresses catalog rename/replay reactivation, disabled database caching with case-insensitive table lookup, and tests that continued to use retired database instances. The connector plugin API major version changes from 19 to 20 with updated surface coverage.

When an ordinary base-table handle lookup definitively reports absence, FE now repairs its stale membership, object, ID and connector dependencies through the same planner. A short-lived observation binds the exact retained table and its matching names snapshot before the remote call. Scope/registration checks and dependency detachment run in one publication write phase; logical retirement, name refresh, content invalidation or replacement reject a delayed negative result. This also protects differently cased replacements such as Foo to FOO. Read-observed absence only repairs the current FE and does not write a DDL journal. The first failed MVCC query can still report the generic schema-cache load error after the missing handle has retired its object; this change repairs cache state and does not unify missing-table error messages. Paimon and Elasticsearch propagate ordinary lookup failures instead of reporting them as table absence.

Release note

Fix stale external-catalog table membership and metadata after refresh or a confirmed missing-table lookup, including drop and same-name recreation. Ordinary data writes keep cached table-name listings.

Check List (For Author)

  • Test: Unit Test / Regression test
    • Selected connector modules and upstream dependencies were tested, including SPI, Hive, Hudi, Iceberg, Paimon, Fluss, ADBC and MaxCompute. Connector SPI suite: 82 tests passed.
    • Latest cache framework and focused FE run: 232 tests passed (176 cache framework, 9 missing-table scenarios, 21 FE entry lifecycle, 26 catalog-owner tests). Coverage includes delayed negatives after refresh/recreation, exact-key replacement, differently cased replacement, logical database retirement with an active load, root replacement, remote failures and session bypass. Existing owner tests verify ordinary writes/replay retain names in both table-name modes.
    • ES HTTP/IO classification: 9 tests passed; Paimon metadata: 24 passed. Related metadata-change, system-table/MVCC and row-count classes passed 52 tests.
    • Full FE build and Checkstyle passed using ./build.sh --fe -j4 with JDK 17.
    • test_hive_catalog_owner_refresh was regenerated against the newly packaged isolated FE and real HMS, then passed without generation: 1 suite, zero failed/fatal/skipped. It checks explicit refresh and automatic membership cleanup after an observed missing-table lookup.
    • Existing nested Iceberg namespace regression was also regenerated and compared against a packaged FE and real REST/MinIO. That earlier runtime used a cached native 4.1 BE with be_exec_version=13; it does not replace current-head CI validation.
    • Independent Astra xhigh source review of this follow-up is clean after fixing its lifecycle, case-equivalent replacement and failure-classification findings.
    • No multi-FE cluster, actual Trino service, or current-head BE data-execution validation.
  • Behavior changed: Yes. Explicit refresh and definitive missing-table observations invalidate dependent membership and metadata together; content-only changes preserve names and object lookup. Connector plugin API major version is 20.
  • Does this need documentation: No. Internal ownership and SPI integration are documented in fe/fe-connector/README.md.

### What problem does this PR solve?

Issue Number: None

Problem Summary: FE external catalog names, lookup objects, and schemas had separate owners. Explicit refresh could retain a dropped table in its membership list, and independent lifecycle handling allowed stale loads or discarded database instances to outlive their cache registrations. Share one catalog invalidation owner while preserving per-database capacity/TTL. Explicit refresh invalidates the target and parent membership together; write-triggered refresh remains metadata-only, including replay. Retire database-instance entries without blocking remote loads, let schema runtimes borrow rather than close the shared owner, and keep cold replay safe after cache reconfiguration. Lookup handles retain count-based admission while names and schema payloads use configured byte budgets.

### Release note

Explicit external table and database refresh now invalidates cached lookup objects and parent membership consistently. Ordinary write-triggered metadata refresh keeps cached table names.

### Check List (For Author)

- Test: Unit Test (290 related tests passed); Regression test (Hive metadata refresh against an isolated FE and real HMS); FE build and Checkstyle passed. No multi-FE cluster, actual Trino, or BE data execution validation.
- Behavior changed: Yes (explicit refresh also invalidates lookup and parent membership; ordinary write-triggered refresh remains metadata-only)
- Does this need documentation: No (existing refresh commands and retention policy; cache-definition API documents byte-accounting boundaries)
@924060929
924060929 requested a review from CalvinKirs as a code owner October 22, 2026 09:10
@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

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.

Request changes: three verified inline findings (one P1, two P2). Catalog rename/replay permanently retires the reused catalog instance; disabled database caching with case-insensitive table names breaks DROP/RENAME event application; existing refresh tests retain objects whose replacement lifetimes invalidate their timestamp assertions.

Reviewed all 20 authoritative changed paths at ae04d1e, including related callers, replay, connectors and tests. There were no existing inline threads or blocking IDs and no additional user-provided focus. All three reviewers returned NO_NEW_VALUABLE_FINDINGS on the unchanged final comment set in round 2. Every candidate and initial risk has an evidence-based disposition; no static scope gap remains.

Critical checkpoint conclusions:

  1. Goal and correctness: the shared owner connects identity, membership and schema invalidation; ordinary write-triggered refresh preserves lookup/name caches. The rename and retired-database findings prevent fully correct integration. Internal row visibility, visible versions and delete bitmaps are unchanged.
  2. Scope and reuse: the change stays focused on FE cache ownership, refresh behavior and supporting tests, using the existing cache framework.
  3. Concurrency and locks: traced query workers, commonRefreshExecutor, refresh, events, replay and ALTER. Cache publication uses adapter stripes, scope generations and key-node locks; remote cache loaders run outside publication locks and removal callbacks are deferred. No separate deadlock or stale-publication defect was substantiated.
  4. Lifecycle: exact-registration removal and borrowed schema runtimes preserve replacement entries. Terminal retirement is incorrectly reused by rename, and never-initialized retired database handles expose the event-path failure. No C++ static-initialization concern applies.
  5. Configuration: no new user setting. Existing count/TTL/stripe and payload-byte settings remain; ALTER retirement/reconfiguration was traced. TTL-zero operation is the verified conditional failure.
  6. Compatibility: the Gson-annotated refresh flag defaults false in old records, while new explicit refresh sets true. No function ABI, data-storage format or connector-SPI module change. Rename replay shares the verified retirement regression.
  7. Thrift/protobuf: no changed definitions or field IDs.
  8. Parallel paths: inspected default/Remote Doris, explicit/mutation/event/partition/rename refresh, hot/cold replay, system databases, name-case modes and session bypass. Metadata-only writes retain their intended scope.
  9. Conditions and errors: synthetic scope keys avoid user-name collisions; admission and retirement branches were checked. Missing plugin table handles now raise a named CacheException with scope cleanup in finally. The retired mode-2 unregister branch needs correction.
  10. Tests: new latch-based tests cover blocked loads, recreation, retirement, reconfiguration, budgets, replay and statistics. The Hive regression exercises independent catalogs. Rename and disabled-cache event cases need coverage, and both existing refresh timestamp tests need adaptation as detailed inline.
  11. Expected results: regression listing order, error assertions and int/text/bigint schema outputs match the scripted operations. Output generation and the author's reported test runs were not independently reproduced.
  12. Observability: unified statistics include naming-only owners and deduplicate engine/name rows; existing refresh and event logs identify the affected objects. No further observability defect was found.
  13. Persistence/failover: refresh EditLog writes and matching replay dispatches are paired, including explicit lookup scope and legacy defaults. Cold replay remains cache-only. Rename replay is affected by the P1 finding.
  14. Data writes and crash behavior: no transaction or data-write protocol is changed. Committed external-mutation logs still precede fallible local invalidation; cache generations and exact cleanup fence discarded loads. No additional crash-related leak was demonstrated.
  15. FE/BE passing: no new transmitted variables or BE paths.
  16. Performance and ownership: COUNT_ONLY preserves lookup count/TTL retention without traversing mutable catalog backreferences; names/schema remain byte-budgeted. No additional substantiated CPU, memory or complexity issue remained after the missed-path sweeps.

Validation limits: static source review only, as required. No builds, tests, runtime reproduction, multi-FE execution or performance measurements were performed. Repository source was not modified.

Review converged after 2 round(s).

@Override
public final void onClose() {
synchronized (this) {
feCacheRetired = true;

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] Allow renamed catalogs to initialize a new cache owner

CatalogMgr.alterCatalogName() calls cleanupRemovedCatalog() (and therefore onClose()), then renames and re-registers the same catalog instance. Setting this flag permanently means ALTER CATALOG old RENAME new succeeds, but every subsequent metadata access fails in getFeMetaCacheOwner() with "External catalog cache owner has been retired". resetToUninitialized() never clears the flag, and replayAlterCatalogName() reuses the instance in the same way, so followers are affected too. Distinguish terminal removal from rename cleanup, or explicitly reactivate/recreate the owner when re-registering the catalog; cover rename and its replay.

localTableName = resolveTableNameForInvalidation(tableName);
// Always clean local names/object/ID state, even when the object entry is cold or already evicted.
invalidateTableCache(localTableName);
if (!cacheEntriesReleased) {

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.

[P2] Skip cache-based name resolution for retired databases

With external_cache_expire_time_seconds_after_access=0 and lower_case_table_names=2, the database lookup returns an uncached database and its new discard callback retires it before tables is initialized. An HMS DROP/RENAME event reaches unregisterTable(), but makeSureInitialized() now returns immediately for that database and resolveTableNameForInvalidation() still runs before this guard. Its case-insensitive fallback dereferences tables.findIfPresent() on null. Event application then fails and the sync driver resets its cursor for a full resync. Include name resolution in the retired-entry handling (or provide a transient resolver), and cover this disabled-cache configuration.

try {
db.resetMetaToUninitialized();
} finally {
((ExternalCatalog) db.getCatalog()).invalidateDatabaseLookup(db.getFullName());

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.

[P2] Update the existing refresh tests for replacement objects

Lookup eviction changes the object lifetime, but RefreshDbTest.testRefreshDatabase() still retains db1 across refresh and asserts that its lastUpdateTime later increases. That database is now permanently retired, so subsequent live reads leave its timestamp unchanged and the l4 > l3 assertion fails. Likewise, RefreshTableTest.testRefreshTable() retains the evicted table and expects getFullSchema() to advance its timestamp; the schema loader now resolves and updates the replacement table instead. Update both existing tests to reacquire the current objects and assert the intended replacement behavior so the FE suite remains compatible with this change.

### What problem does this PR solve?

Issue Number: None

Problem Summary:

External catalog metadata is cached in several dependent layers: database/table membership, FE object and ID lookup, schemas, row counts, and connector metadata such as partitions, files, and snapshots. Previously these layers had separate owners and callers manually invalidated both sides. A refresh could leave a stale membership or object lookup behind; a load started before invalidation could republish an obsolete object or identity, particularly after a drop and same-name recreation. Keeping the old FE database object after eviction also allowed its cleanup to affect a replacement.

Use one `CatalogMetaCache` root per external catalog. FE registrations and instance-owned connector domains share its resource generations and existing budgets. Embedded connectors use child domains. Retiring an instance removes only its exact registrations; semantic resource invalidation is independent of instance lifetime. Local names, remote names, and numeric derived-state identities use distinct coordinate spaces.

`CatalogMetadataChanges` is the common boundary for refresh, successful writes/DDL, metastore events, and replay. It projects affected local and remote resources and invalidates them at one publication barrier. Connectors describe cross-resource dependencies through a pure SPI projection instead of imperative sibling invalidation. DDL journal records preserve remote identities for replay; old records fall back to broader remote-only invalidation without initializing remote metadata. Content changes preserve table-name snapshots and FE lookups, while explicit table/database refresh also invalidates the appropriate membership snapshot.

ID mappings survive ordinary object eviction but participate in semantic invalidation. Publication is guarded by the same resource generation, and accepted operations pin their auxiliary index until completion. Row-count futures belong to catalog roots while a shared retention-policy index preserves the existing process-wide entry limit. Cache callbacks retain the owning plugin classloader context.

Automatic row-count refresh keeps the last successful value while reloading and on failure. ADBC membership caches register under the shared collection scopes.

This also addresses catalog rename/replay reactivation, disabled database caching with case-insensitive table lookup, and tests that continued to use retired database instances. The connector plugin API major version changes from 19 to 20 with updated surface coverage.

### Release note

Fix stale external-catalog table membership and metadata after refresh, including drop and same-name recreation. Ordinary data writes keep cached table-name listings.

### Check List (For Author)

- Test: Unit Test / Regression test
    - Selected connector modules and upstream dependencies packaged with their own tests, including SPI, Hive, Hudi, Iceberg, Paimon, Fluss, ADBC, and MaxCompute.
    - Current cache framework suite: 172 tests passed; connector SPI own suite: 82 tests passed.
    - Related FE coverage: 320 unique tests. A broad 317-test run had one obsolete dynamic-proxy error; after fixing its null collection return, the affected class and cache-entry lifecycle tests passed all 24 tests, including the added retirement concurrency case. The independent Astra review found two additional gaps; after reproducing both on the old implementation, the fixes passed 40 targeted tests (16 row-count and 24 ADBC tests), including successful/failed automatic refresh and root-level membership invalidation.
    - Full FE build and Checkstyle passed using `./build.sh --fe -j4` with JDK 17.
    - `test_hive_catalog_owner_refresh` passed against the newly packaged isolated FE and real HMS: 1 suite, zero failed/fatal/skipped, comparing the checked-in expected output.
    - No multi-FE cluster, actual Trino service, or BE data-execution validation.
- Behavior changed: Yes. Explicit refresh invalidates dependent membership and metadata together; content-only changes preserve names and object lookup. Connector plugin API major version is 20.
- Does this need documentation: No. Internal ownership and SPI integration are documented in `fe/fe-connector/README.md`.
@924060929 924060929 changed the title [refactor](fe) Unify external catalog metadata cache ownership [refactor](fe) Unify catalog and connector metadata cache ownership Oct 22, 2026
@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.

No new actionable findings at head 328deaa948135f3b4a2798e366e87dae566835d1. Static review covered all 78 changed paths (32 connector, 44 FE core, 2 regression), related callers, and the existing inline threads. Two complete-scope reviewers and an additional publication/lifecycle risk reviewer all returned NO_NEW_VALUABLE_FINDINGS in round 1; main-agent verification found no unresolved candidates. The review converged.

Existing thread dispositions: 4346749470 is addressed by registry reactivation through onRegistered() and replacement cache-owner creation for rename/replay. 4346749481 is addressed by the retired/uninitialized database guard before cache-based name resolution. 4346749491 is addressed by reacquiring replacement database/table objects in the refresh tests. None remains an independently confirmed P0/P1 blocker, and none is reposted.

Critical checkpoint conclusions:

Checkpoint Conclusion
Goal and evidence Shared catalog ownership, separate instance retirement, and coordinated LOCAL/REMOTE/ID invalidation implement the stated cache-consistency goal. Added domain, FE lifecycle, replay, and Hive regression coverage matches that behavior.
Scope and reuse The change is substantial but focused on the ownership/invalidation migration and reuses typed cache definitions and journal carriers.
Concurrency and locking Traced query loads, refresh/DDL, event/replay workers, asynchronous refresh/removal, and retirement. Nested shared reads avoid the suspected gate/index cycle; identity invalidation uses its entry-local gate. Remote loading stays outside publication guards. No reachable new deadlock was verified.
Lifecycle Exact registrations and identity tokens isolate old instances from replacements; accepted table operations pin auxiliary cleanup. Closed roots and retired databases have explicit replacement/transient paths. No cross-TU initialization applies.
Configuration No new configuration keys. Existing TTL/count/weight settings and ALTER retirement/rebuild paths remain in use; schema-only reconfiguration borrows the root without retiring siblings.
Compatibility SPI major version changes from 19.0 to 20.0 with the plugin surface baseline updated. Added Gson journal fields retain legacy defaults and cache-only fallback. No storage or FE/BE wire format change was identified.
Thrift/protobuf No changed definitions; field-ID checks are inapplicable.
Parallel paths Checked explicit/content/partition refresh, create/drop/rename/truncate, events, mapped/case-insensitive names, warm/cold replay, generic/remote-Doris schema routing, and connector siblings.
Conditional checks Closed/retired states, disabled retention, lookup versus content changes, and unknown remote identities have concrete lifecycle/configuration cases and focused tests.
Test coverage Inspected unit coverage for publication races, retirement, sibling preservation, TCCL, identity invalidation, row-count retry/refresh/global retention, and replay. Hive regression covers membership and schema across drop, database refresh, and recreation.
Changed results Expected sorted names and INT/text/BIGINT schemas match the regression SQL sequence. Result-generation provenance cannot be established by static inspection.
Observability Existing refresh/error logs and cache metrics remain; catalog statistics enumerate shared registrations. No concrete additional observability defect was verified.
Persistence and failover Matching write/replay paths preserve remote identities before fallible post-commit bookkeeping; legacy replay widens only remote invalidation without loading remote metadata.
Writes and atomicity Connector transaction behavior is unchanged; post-commit invalidation uses one root publication barrier across dependent cache coordinates.
FE/BE propagation No new transmitted variable or plan field.
Performance Content changes retain names/lookups, cleanup removes exact registrations, and row counts retain a process-wide count bound. No new remote I/O in cache projection/replay or substantiated performance regression was found.
Other issues and user focus No additional substantiated issue. No additional user-provided focus was supplied.

Limits: this was a static-only review. No builds or tests were run and no source files were modified. Runtime, multi-FE failover, external-service, and BE execution behavior were not independently validated. No changed-path coverage gap or unresolved candidate remains within the authorized review scope.

Review converged after 1 round(s).

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16433	5124	5059	5059
q2	2119	314	264	264
q3	9723	1386	823	823
q4	4454	461	337	337
q5	7140	812	547	547
q6	177	184	153	153
q7	752	790	597	597
q8	9042	1332	1050	1050
q9	5492	4175	4163	4163
q10	6823	1291	1022	1022
q11	433	248	226	226
q12	643	399	281	281
q13	17719	3666	3042	3042
q14	284	272	244	244
q15	q16	737	722	664	664
q17	1223	762	597	597
q18	7040	6216	6132	6132
q19	1098	953	589	589
q20	382	326	233	233
q21	4514	2102	2270	2102
q22	356	293	245	245
Total cold run time: 96584 ms
Total hot run time: 28370 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5598	5567	5561	5561
q2	694	586	541	541
q3	5180	5445	4899	4899
q4	2017	2137	1560	1560
q5	5283	5197	5172	5172
q6	235	185	144	144
q7	2455	2205	1922	1922
q8	3047	2707	2768	2707
q9	8277	8053	7918	7918
q10	3768	3677	3250	3250
q11	623	465	421	421
q12	693	677	522	522
q13	3574	3792	3373	3373
q14	310	300	292	292
q15	q16	708	737	644	644
q17	8176	7595	7527	7527
q18	13097	12285	12905	12285
q19	919	782	773	773
q20	2149	2163	1908	1908
q21	5633	4723	4782	4723
q22	511	451	410	410
Total cold run time: 72947 ms
Total hot run time: 66552 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150805 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 328deaa948135f3b4a2798e366e87dae566835d1, data reload: false

query5	4308	586	447	447
query6	425	211	195	195
query7	4812	444	229	229
query8	322	166	153	153
query9	8761	3059	3125	3059
query10	475	317	250	250
query11	5958	3881	3595	3595
query12	154	94	90	90
query13	1259	444	326	326
query14	6117	3974	3682	3682
query14_1	3428	3459	3442	3442
query15	209	206	184	184
query16	953	455	384	384
query17	897	657	529	529
query18	2424	418	316	316
query19	203	168	134	134
query20	90	86	86	86
query21	216	126	109	109
query22	12942	12989	12819	12819
query23	13477	12812	12459	12459
query23_1	12656	12410	12503	12410
query24	7058	817	478	478
query24_1	469	463	470	463
query25	536	424	367	367
query26	1271	257	143	143
query27	2777	434	271	271
query28	4452	1962	1903	1903
query29	1546	598	456	456
query30	295	220	184	184
query31	1012	942	825	825
query32	147	92	91	91
query33	526	310	249	249
query34	875	854	490	490
query35	732	761	647	647
query36	810	813	736	736
query37	129	96	101	96
query38	1764	1739	1678	1678
query39	789	793	741	741
query39_1	741	731	738	731
query40	218	126	100	100
query41	76	68	70	68
query42	93	86	83	83
query43	350	374	316	316
query44	1302	698	694	694
query45	179	177	174	174
query46	821	957	607	607
query47	2759	2890	2836	2836
query48	287	302	212	212
query49	568	397	289	289
query50	668	266	203	203
query51	10392	10425	10308	10308
query52	77	80	70	70
query53	190	202	150	150
query54	232	197	175	175
query55	69	70	69	69
query56	254	239	222	222
query57	1661	1587	1582	1582
query58	283	283	258	258
query59	2101	2187	1950	1950
query60	287	240	228	228
query61	145	137	150	137
query62	391	341	282	282
query63	188	154	158	154
query64	2651	931	790	790
query65	3321	3277	3272	3272
query66	1759	428	308	308
query67	20229	20045	19945	19945
query68	2935	994	609	609
query69	378	298	258	258
query70	855	792	765	765
query71	301	236	213	213
query72	2755	2558	2249	2249
query73	509	522	285	285
query74	4650	4531	4338	4338
query75	2314	2309	1924	1924
query76	1987	1027	571	571
query77	341	370	274	274
query78	9779	9850	9238	9238
query79	978	882	512	512
query80	774	439	337	337
query81	565	320	274	274
query82	547	134	105	105
query83	294	193	181	181
query84	309	126	97	97
query85	985	430	375	375
query86	381	245	235	235
query87	1996	1993	1864	1864
query88	3631	2672	2661	2661
query89	340	282	246	246
query90	1751	159	167	159
query91	160	151	127	127
query92	121	86	92	86
query93	1023	1000	566	566
query94	500	307	244	244
query95	576	328	367	328
query96	671	485	236	236
query97	2493	2433	2305	2305
query98	160	152	156	152
query99	790	765	642	642
Total cold run time: 233153 ms
Total hot run time: 150805 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.10	0.05	0.05
query3	0.26	0.08	0.08
query4	1.61	0.11	0.09
query5	0.24	0.27	0.25
query6	1.17	0.69	0.66
query7	0.05	0.01	0.01
query8	0.06	0.04	0.04
query9	0.40	0.36	0.33
query10	0.61	0.58	0.58
query11	0.20	0.15	0.14
query12	0.18	0.15	0.14
query13	0.50	0.50	0.48
query14	1.03	1.03	1.03
query15	0.64	0.63	0.60
query16	0.35	0.35	0.36
query17	1.16	1.10	1.15
query18	0.19	0.19	0.20
query19	2.16	2.01	1.96
query20	0.02	0.01	0.01
query21	15.52	0.20	0.14
query22	4.78	0.06	0.05
query23	16.25	0.36	0.13
query24	3.33	0.58	0.40
query25	0.10	0.07	0.08
query26	0.85	0.21	0.16
query27	0.05	0.03	0.04
query28	2.73	0.72	0.37
query29	12.45	4.15	3.24
query30	0.29	0.13	0.11
query31	2.78	0.57	0.33
query32	3.28	0.59	0.50
query33	3.25	3.20	3.32
query34	15.29	4.03	3.40
query35	3.35	3.36	3.33
query36	0.55	0.44	0.44
query37	0.10	0.06	0.07
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.16	0.14	0.14
query41	0.08	0.03	0.03
query42	0.04	0.03	0.02
query43	0.05	0.04	0.03
Total cold run time: 96.31 s
Total hot run time: 24.33 s

### What problem does this PR solve?

Issue Number: None

Problem Summary: Full CI exposed four FE test assumptions left behind by the unified metadata cache lifecycle: missing connector handles now fail explicitly, initialization constructs an empty shared cache owner, and the deadlock fixture needs real catalog properties. Update the assertions and fixture while retaining the per-session isolation and lock-order checks. Database DROP now invalidates membership immediately, so the nested Iceberg namespace regression must expect live inferred parents rather than a stale pre-refresh list. Regenerate its expected output with the regression runner.

### Release note

None

### Check List (For Author)

- Test: Unit Test (36 related FE tests passed); Checkstyle (zero violations); Regression test (complete iceberg_and_internal_nested_namespace suite generated and then compared successfully against the packaged FE and real REST/MinIO). The temporary native ARM runtime used a cached 4.1 BE with be_exec_version=13; no new BE build or full CI success is claimed.
- Behavior changed: No. Tests follow the already implemented cache 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.

Static review of head 450da63290057dac1995f90561fdaa97e152e64d: one new P2 finding, posted inline. Rename must also invalidate a case-equivalent cached destination and its numeric identity when lower_case_table_names=2; otherwise by-ID statistics and constraint readers can retain the dropped destination.

All 84 changed paths were reviewed by the main agent and assigned coverage reviewers, with a separate reviewer for publication/retirement risks. The final frozen inline set was checked in the second round. No additional user focus was supplied.

The three prior threads are fixed on this head and are not duplicated: catalog rename/replay reactivates the registered instance (4346749470); retired/uninitialized database name resolution is guarded (4346749481); refresh tests reacquire replacement objects (4346749491). No previously reported P0/P1 was independently confirmed to remain applicable.

The reviewed flow is SQL refresh / successful external DDL / metastore event / follower replay -> cache-only identity projection -> shared catalog publication barrier -> LOCAL, REMOTE and numeric-ID invalidation. Connector construction acquires instance domains; embedded connectors acquire child domains; physical retirement removes exact registrations.

Critical checkpoint Conclusion
Goal and proof Unified ownership and the distinction between content mutation and lookup refresh are implemented with substantial owner, cache, replay and regression coverage. The canonical rename-destination case has the inline P2 gap. Tests were inspected, not executed.
Scope and reuse The 84-path refactor is cohesive: shared CatalogMetaCache ownership and CatalogMetadataChanges replace scattered invalidation. No unrelated source change identified.
Concurrency and locks Traced query loads, background refresh, HMS events, eviction, ALTER and DROP/rename. Publication uses per-entry bulk phases, the shared root phase and key nodes; nested root reads are reentrant. Removal callbacks drain after publication locks. No additional reachable lock cycle established. Remote loading occurs outside the short publication barrier.
Lifecycle Database eviction retires instance registrations; accepted operations pin auxiliary indices until completion. Old cleanup uses exact identities. Terminal catalog retirement prevents resurrection; registry publication explicitly reactivates rename/replay. No C++ static initialization involved.
Configuration No new configuration declaration. Existing TTL, refresh, count and weight policies are reused; property updates retire the appropriate runtime/group and subsequent access uses the updated policy.
Compatibility Connector API major changes from 19 to 20 with matching recorded plugin surface. New journal identity/scope fields are optional Gson additions; old records use existing replay fallbacks and broader remote invalidation when identity is unavailable.
Thrift/protobuf No changed definitions, field IDs or enum values.
Parallel paths Checked direct refresh, external writes/DDL, structural and partition events, new/old journal replay, cold and mapped identities, sibling domains, default schema caching and Remote Doris. The rename-destination canonicalization gap is the one accepted new issue.
Conditional logic Cache-only replay, disabled-cache transient access, content-versus-lookup scope and retirement guards have concrete lifecycle reasons. Destination canonicalization is missing from the rename branch.
Test coverage Inspected latch-based late-publication/retirement tests, owner replacement and rename/replay tests, identity-index tests, row-count refresh/retention tests, connector/SPI tests, and Hive refresh/recreation regression coverage. No new production issue established from the remaining test changes.
Expected results Both changed regression outputs agree with the suite operations and intended membership behavior. Auto-generation provenance and runtime results were not independently verified.
Observability Root/domain entries are included in cache statistics; projection/load failures have existing logging and propagation. Missing table handles now preserve a table-not-found error. No additional observability finding established.
Persistence and failover Checked create/drop database/table, truncate and rename journal writes and Env/EditLog dispatch. Persisted remote identities support cold follower replay without connector initialization; legacy records have fallback paths. The inline rename issue affects leader and replay.
Writes, atomicity and crashes Remote commits remain followed by journaling and local cache reconciliation; shared generation invalidation fences late publication. No internal transaction or storage-write protocol changes. No additional crash/failover leak identified by static tracing.
FE/BE variables No new transmitted variable or FE/BE protocol change.
Performance and memory Projection is cache-only; shared resource generations avoid manual sibling lists. Exact retirement and the global row-count retention policy were checked; payload-byte budgets remain distinct from count-only handles. No benchmark or runtime memory measurement performed.
Core invariants and other issues The accepted issue concerns stale external metadata. Internal visible versions, MoW delete bitmaps and BE memory tracking are unaffected. Known candidates and risks have explicit dispositions in the ledger; no unresolved review candidate remains.

Review limits: static inspection only, as required by this invocation. No builds, unit/regression tests, multi-FE failover, external-service execution or performance measurements were run. Author-reported test results are not claimed as independently reproduced.

Review converged after 2 round(s).

}
if (change.getNewTableName() != null) {
scopes.add(local(ScopePath.table(change.getDbName(), change.getTableName())));
scopes.add(local(ScopePath.table(change.getDbName(), change.getNewTableName())));

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.

[P2] Invalidate the case-equivalent rename destination

With lower_case_table_names=2, warm a destination named Dest, drop it outside Doris, then rename another table to DEST in a case-preserving Iceberg catalog. This branch invalidates only the exact DEST key and its numeric ID; the cached Dest object, ID, schema and row count survive. By-ID readers (ExternalDatabase.getTableNullable(long), used by statistics and constraints) can therefore still resolve the dropped destination after the rename. Previously invalidateTableRename() resolved both names through resolveTableNameForInvalidation(). Add the canonical destination's LOCAL and ID scopes to this barrier on the leader and replay paths, and cover this mode-2 replacement case.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16435	5155	5063	5063
q2	2112	321	266	266
q3	9670	1395	843	843
q4	4454	457	341	341
q5	7124	802	529	529
q6	178	183	147	147
q7	752	804	594	594
q8	9062	1328	1100	1100
q9	5522	4185	4226	4185
q10	6837	1290	1019	1019
q11	427	240	228	228
q12	639	401	286	286
q13	17878	3607	3004	3004
q14	276	269	246	246
q15	q16	735	709	664	664
q17	1200	743	583	583
q18	7049	6195	6117	6117
q19	1100	956	601	601
q20	376	348	229	229
q21	4923	2102	2305	2102
q22	346	305	262	262
Total cold run time: 97095 ms
Total hot run time: 28409 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5630	5627	5640	5627
q2	685	591	519	519
q3	5190	5572	4897	4897
q4	2021	2146	1575	1575
q5	5243	5146	5146	5146
q6	241	180	141	141
q7	2557	2171	1886	1886
q8	3123	2749	2786	2749
q9	8311	8145	8053	8053
q10	3816	3658	3278	3278
q11	615	434	420	420
q12	702	702	524	524
q13	3518	3825	3360	3360
q14	304	302	299	299
q15	q16	716	731	639	639
q17	8229	7575	7368	7368
q18	13107	12262	12902	12262
q19	943	846	833	833
q20	2154	2143	1933	1933
q21	5817	4764	4891	4764
q22	517	444	430	430
Total cold run time: 73439 ms
Total hot run time: 66703 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150301 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 450da63290057dac1995f90561fdaa97e152e64d, data reload: false

query5	4328	601	435	435
query6	427	198	187	187
query7	4798	430	222	222
query8	320	162	148	148
query9	8779	3102	3110	3102
query10	481	318	261	261
query11	6029	3834	3593	3593
query12	152	90	87	87
query13	1253	451	302	302
query14	6130	3887	3609	3609
query14_1	3346	3398	3369	3369
query15	202	191	176	176
query16	940	410	418	410
query17	842	648	515	515
query18	2423	413	294	294
query19	184	161	127	127
query20	81	82	80	80
query21	202	122	104	104
query22	12928	13015	12699	12699
query23	13382	12776	12397	12397
query23_1	12466	12576	12474	12474
query24	7098	812	453	453
query24_1	474	474	479	474
query25	530	420	354	354
query26	1265	259	138	138
query27	2771	439	270	270
query28	4453	1938	1943	1938
query29	1548	597	465	465
query30	295	216	178	178
query31	1003	936	840	840
query32	157	94	97	94
query33	526	318	247	247
query34	879	846	488	488
query35	720	761	645	645
query36	819	817	717	717
query37	129	102	83	83
query38	1771	1688	1683	1683
query39	813	799	737	737
query39_1	737	726	731	726
query40	221	120	97	97
query41	72	71	69	69
query42	86	85	81	81
query43	344	361	314	314
query44	1305	689	688	688
query45	183	176	164	164
query46	813	959	553	553
query47	2814	2931	2622	2622
query48	302	314	226	226
query49	591	411	296	296
query50	697	277	214	214
query51	10511	10527	10369	10369
query52	81	82	72	72
query53	196	214	155	155
query54	253	211	206	206
query55	71	68	67	67
query56	238	233	223	223
query57	1649	1604	1558	1558
query58	294	272	261	261
query59	2076	2173	1922	1922
query60	305	255	231	231
query61	165	171	167	167
query62	379	331	291	291
query63	193	162	161	161
query64	2721	914	732	732
query65	3318	3268	3270	3268
query66	1771	436	305	305
query67	20104	20109	20132	20109
query68	3186	1005	602	602
query69	404	293	258	258
query70	849	787	760	760
query71	292	229	202	202
query72	2833	2551	2310	2310
query73	539	575	287	287
query74	4660	4530	4336	4336
query75	2343	2295	1872	1872
query76	2088	992	610	610
query77	345	378	254	254
query78	9781	9765	9192	9192
query79	978	840	508	508
query80	761	426	323	323
query81	553	316	269	269
query82	552	141	102	102
query83	274	190	172	172
query84	308	123	109	109
query85	981	427	402	402
query86	383	238	217	217
query87	1977	1987	1804	1804
query88	3658	2670	2649	2649
query89	330	278	241	241
query90	1756	173	162	162
query91	161	150	130	130
query92	113	86	93	86
query93	1018	985	571	571
query94	511	312	273	273
query95	564	328	305	305
query96	673	489	230	230
query97	2408	2424	2325	2325
query98	158	152	148	148
query99	787	761	662	662
Total cold run time: 233414 ms
Total hot run time: 150301 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.09	0.06	0.05
query3	0.26	0.09	0.09
query4	1.61	0.10	0.11
query5	0.26	0.24	0.25
query6	1.17	0.69	0.67
query7	0.04	0.01	0.01
query8	0.05	0.04	0.04
query9	0.40	0.34	0.36
query10	0.57	0.60	0.60
query11	0.20	0.13	0.14
query12	0.17	0.15	0.15
query13	0.50	0.49	0.49
query14	1.01	1.01	1.02
query15	0.64	0.59	0.60
query16	0.35	0.36	0.35
query17	1.12	1.13	1.16
query18	0.22	0.21	0.19
query19	2.07	2.02	1.99
query20	0.02	0.01	0.01
query21	15.47	0.20	0.13
query22	4.81	0.05	0.06
query23	16.31	0.31	0.12
query24	3.18	0.50	0.32
query25	0.10	0.08	0.06
query26	1.05	0.21	0.15
query27	0.05	0.05	0.06
query28	3.75	0.77	0.36
query29	12.49	4.11	3.23
query30	0.29	0.13	0.10
query31	2.77	0.55	0.32
query32	3.23	0.60	0.50
query33	3.12	3.14	3.17
query34	15.47	4.07	3.39
query35	3.35	3.35	3.33
query36	0.57	0.44	0.56
query37	0.10	0.07	0.08
query38	0.05	0.04	0.04
query39	0.04	0.04	0.03
query40	0.17	0.16	0.15
query41	0.08	0.03	0.02
query42	0.04	0.03	0.02
query43	0.04	0.03	0.03
Total cold run time: 97.28 s
Total hot run time: 24.23 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

2 similar comments
@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16655	5213	5064	5064
q2	2134	308	246	246
q3	9909	1380	821	821
q4	4617	460	335	335
q5	7438	787	544	544
q6	186	181	150	150
q7	739	803	601	601
q8	9379	1356	1039	1039
q9	5459	4161	4187	4161
q10	6846	1291	1036	1036
q11	437	245	227	227
q12	640	398	280	280
q13	18118	3593	2994	2994
q14	269	273	244	244
q15	q16	732	710	669	669
q17	1171	747	585	585
q18	6982	6197	6110	6110
q19	1099	959	590	590
q20	385	344	223	223
q21	4715	2538	2524	2524
q22	378	315	322	315
Total cold run time: 98288 ms
Total hot run time: 28758 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5926	5873	5936	5873
q2	740	603	577	577
q3	5612	5700	5245	5245
q4	2005	2162	1573	1573
q5	5879	5723	5610	5610
q6	243	188	146	146
q7	2268	2075	1773	1773
q8	3002	2694	2681	2681
q9	7887	7538	7511	7511
q10	3672	3577	3172	3172
q11	578	424	390	390
q12	679	683	507	507
q13	3302	3579	2988	2988
q14	283	290	269	269
q15	q16	662	683	616	616
q17	7706	7070	6843	6843
q18	12988	12186	12903	12186
q19	892	773	805	773
q20	2158	2147	1947	1947
q21	5635	4595	4748	4595
q22	492	465	420	420
Total cold run time: 72609 ms
Total hot run time: 65695 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150829 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 450da63290057dac1995f90561fdaa97e152e64d, data reload: false

query5	4313	577	459	459
query6	447	207	188	188
query7	4802	443	233	233
query8	330	171	148	148
query9	8754	3118	3098	3098
query10	471	313	255	255
query11	6046	3883	3597	3597
query12	151	96	89	89
query13	1255	416	322	322
query14	6166	3946	3635	3635
query14_1	3418	3440	3435	3435
query15	210	201	184	184
query16	944	435	413	413
query17	866	658	546	546
query18	2425	434	312	312
query19	203	176	157	157
query20	87	83	82	82
query21	220	133	107	107
query22	12923	13074	12767	12767
query23	13501	12876	12579	12579
query23_1	12578	12459	12641	12459
query24	7226	817	467	467
query24_1	469	464	484	464
query25	540	425	362	362
query26	1252	255	144	144
query27	2775	446	270	270
query28	4513	1959	1954	1954
query29	1557	602	448	448
query30	298	223	184	184
query31	1007	931	819	819
query32	151	94	95	94
query33	545	293	246	246
query34	888	844	502	502
query35	733	776	633	633
query36	864	817	719	719
query37	123	98	81	81
query38	1790	1769	1709	1709
query39	785	798	738	738
query39_1	747	718	741	718
query40	214	126	92	92
query41	64	65	61	61
query42	87	79	80	79
query43	341	358	304	304
query44	1287	685	689	685
query45	174	179	162	162
query46	827	951	569	569
query47	2988	2931	2657	2657
query48	288	305	212	212
query49	566	405	286	286
query50	673	266	210	210
query51	10270	10518	10445	10445
query52	82	75	74	74
query53	184	213	151	151
query54	245	192	169	169
query55	74	68	63	63
query56	240	209	201	201
query57	1644	1602	1568	1568
query58	291	260	253	253
query59	2095	2117	1905	1905
query60	279	246	224	224
query61	151	148	146	146
query62	389	336	281	281
query63	185	151	159	151
query64	2691	970	799	799
query65	3371	3249	3239	3239
query66	1778	420	300	300
query67	20367	20157	20043	20043
query68	2950	990	615	615
query69	391	285	242	242
query70	811	744	770	744
query71	286	229	201	201
query72	2714	2591	2290	2290
query73	515	523	294	294
query74	4601	4538	4376	4376
query75	2318	2319	1912	1912
query76	2177	1013	608	608
query77	340	362	268	268
query78	9756	9732	9180	9180
query79	999	835	514	514
query80	529	419	379	379
query81	528	317	269	269
query82	547	131	109	109
query83	306	198	183	183
query84	310	119	102	102
query85	795	438	378	378
query86	316	237	223	223
query87	2003	1966	1823	1823
query88	3583	2657	2639	2639
query89	329	282	240	240
query90	1872	165	166	165
query91	153	157	123	123
query92	106	86	108	86
query93	993	1004	569	569
query94	449	297	270	270
query95	570	403	317	317
query96	657	481	228	228
query97	2437	2437	2377	2377
query98	161	157	151	151
query99	763	759	656	656
Total cold run time: 233261 ms
Total hot run time: 150829 ms

@hello-stephen

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

query1	0.00	0.01	0.01
query2	0.14	0.09	0.08
query3	0.34	0.14	0.13
query4	1.61	0.15	0.14
query5	0.27	0.25	0.26
query6	1.15	0.66	0.66
query7	0.04	0.01	0.01
query8	0.09	0.07	0.07
query9	0.43	0.36	0.34
query10	0.56	0.63	0.61
query11	0.31	0.18	0.17
query12	0.31	0.20	0.19
query13	0.51	0.52	0.52
query14	0.94	0.96	0.92
query15	0.66	0.59	0.58
query16	0.35	0.37	0.35
query17	1.05	1.03	1.01
query18	0.29	0.28	0.27
query19	1.93	1.85	1.91
query20	0.02	0.01	0.01
query21	15.39	0.35	0.31
query22	4.93	0.13	0.13
query23	15.87	0.48	0.30
query24	2.10	0.56	0.40
query25	0.15	0.11	0.11
query26	0.76	0.28	0.20
query27	0.11	0.09	0.11
query28	3.43	0.87	0.41
query29	12.62	4.37	3.34
query30	0.35	0.16	0.14
query31	2.76	0.60	0.33
query32	3.23	0.59	0.48
query33	3.04	2.97	3.00
query34	15.91	4.10	3.45
query35	3.40	3.36	3.37
query36	0.59	0.49	0.46
query37	0.12	0.09	0.09
query38	0.06	0.07	0.07
query39	0.06	0.06	0.06
query40	0.20	0.16	0.16
query41	0.10	0.05	0.06
query42	0.06	0.06	0.06
query43	0.07	0.06	0.05
Total cold run time: 96.31 s
Total hot run time: 25.19 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

3 similar comments
@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 73.90% (552/747) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None

Problem Summary: With case-insensitive external table lookup, a rename destination can have a different spelling and deterministic ID from a previously cached table at the same case-equivalent name. Invalidating only the new spelling leaves the old destination object and derived caches reachable by ID. Normalize LOCAL table resource identities at the catalog root using an immutable case policy, keeping keys and remote scopes unchanged. On mode 2 lookup invalidation, fence numeric derived state for the database to cover IDs published after planning. Retire the root when table-name mode changes. Live changes and replay share this publication barrier without remote I/O.

### Release note

Fix stale external table metadata after a rename replaces a case-equivalent cached destination.

### Check List (For Author)

- Test: Unit Test
    - Reproduced stale destination identities in leader, cold-name replay and refreshed-name replay tests before the final fix.
    - All 437 tests passed using run-fe-ut.sh: cache framework 173, connector SPI 82, related FE 182.
    - Full FE build and Checkstyle passed using build.sh --fe -j4 with JDK 17.
- Behavior changed: Yes. Case-insensitive lookup invalidation clears case-equivalent local identities and recalculates row counts in the affected database; sibling objects and schemas remain cached.
- 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.

Reviewed #69458 at 8e4f3a06ce033214d9da2e14958069469520bb1e against the supplied aggregate diff. One new P2 finding: Fluss retains historical lake-path mappings across catalog refreshes, causing unbounded retention and growing dependency scans.

All four existing threads are addressed at this head: catalog rename/replay reactivates the registered instance; retired databases skip cache-based name resolution; refresh tests reacquire replacement objects; case-equivalent table rename destinations and numeric state are fenced. None of the previously reported P0/P1 findings still applies, and none is reposted. No additional user focus was supplied; the entire PR was reviewed.

Critical checkpoint Conclusion
Goal and supporting tests The implementation unifies catalog ownership and LOCAL/REMOTE/ID invalidation. New unit and regression cases cover refresh, replacement, replay and disabled caches; the Fluss mapping lifetime remains incomplete.
Scope and clarity The broad refactor stays focused on ownership and invalidation, including connector migrations and test updates.
Concurrency and lock order Query workers, refresh executors, DDL, event daemon and replay were traced. Resource publication uses short reentrant read phases, invalidation detaches in a writer phase, and cleanup runs afterward. No additional concrete deadlock or publication defect was verified.
Lifecycle Exact registrations isolate retired instances from replacements; accepted FE operations pin their adapters. The inline Fluss finding identifies auxiliary state outside that lifecycle.
Configuration No new deployment setting. Existing cache configuration and case-policy changes recreate the affected domains/root.
Compatibility SPI major version moves to 20 with its surface baseline. Optional Gson journal fields retain old-record fallbacks; no new storage format was introduced.
Thrift and protobuf Neither is changed.
Parallel paths SQL refresh, content mutation, DDL, structural/partition events, cold replay and embedded sibling paths were checked.
Conditional checks and errors Disabled caches, case modes, cold identities and projection failures were examined. Known dependencies are invalidated before projection errors propagate; no further verified error-handling issue.
Test coverage Added tests exercise important positive, negative and concurrency paths. Missing coverage for Fluss auxiliary-map retirement is part of the inline finding.
Modified expected results The Hive and nested-namespace outputs match the changed SQL expectations by inspection. Generation provenance and runtime results were not verified.
Observability Existing cache metrics, registration/engine attribution and operation logs remain available; no additional concrete observability defect found.
Persistence and failover New DDL records retain local/remote identities; replay applies the same semantic changes with legacy fallbacks. Committed remote mutation records precede fallible cache bookkeeping.
Writes, atomicity and crashes This changes post-mutation metadata invalidation, not transaction commit/visibility protocols. Replacement roots and exact-registration cleanup were inspected; no further verified crash/replay defect.
FE-to-BE variables No new transmitted variable or sending path.
Performance and memory The inline P2 describes unbounded Fluss history and linear synchronized dependency projection. Catalog/global payload budgets, count-only handles and row-count retention were also reviewed.
Other issues and core invariants No additional verified finding after independent reviews and missed-case sweeps. No BE allocation, partition-visible-version or delete-bitmap code is changed.

Validation was static only, as required: no builds, tests, cluster execution or source modifications. No unresolved candidate or uncovered changed-file scope remains; runtime behavior and test execution remain unverified.

Review converged after 2 round(s).


@Override
public void invalidateAll() {
metaCache.invalidateCatalog();

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.

[P2] Retire Fluss lake-path history on catalog refresh

After querying lake-enabled Fluss tables, dropping them externally and issuing REFRESH CATALOG, every source/lake TablePath pair now remains in lakeTablePaths. Previously catalog refresh called FlussConnector.invalidateAll(), which cleared this map; the new engine path invalidates the shared root directly, and the map is only cleared by close(). A long-lived catalog with table churn therefore retains all historical names indefinitely, and each database dependency projection scans that history under the connector monitor. Give this auxiliary mapping a lifetime coordinated with root catalog invalidation, preserving dependencies until sibling scopes are fenced. Restoring a clear only in this method is insufficient because engine refresh bypasses it; cover repeated catalog refreshes in a regression test.

@924060929 924060929 closed this Oct 23, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#69458

Problem Summary: A remote lookup could report a missing external table while FE continued to list its cached name. Observe the exact retained table and matching name snapshot before handle lookup, then conditionally invalidate their dependencies under one catalog publication writer. Reject observations after replacement, names refresh, content invalidation or registration retirement so a late missing response cannot evict a recreated table. Reuse the common dependency planner without writing a DDL journal. Preserve Paimon and Elasticsearch lookup failures instead of treating them as table absence.

### Release note

Clear stale external-table names and metadata after a lookup confirms that the table is missing, while protecting same-name replacements from delayed responses.

### Check List (For Author)

- Test: Unit Test / Regression test
    - Cache framework: 176 tests passed; focused FE missing-table, lifecycle and owner tests: 56 passed.
    - ES/Paimon failure classification and related FE system-table, row-count and metadata-change tests passed.
    - Full FE build and Checkstyle passed. Real HMS owner-refresh regression was generated and compared successfully (1 suite, zero failed/fatal/skipped).
- Behavior changed: Yes. Confirmed missing-table reads repair this FE's cached lookup state.
- Does this need documentation: No. Internal cache ownership contract is documented in the connector README.
@924060929 924060929 reopened this Oct 23, 2026
@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.

Static review of PR #69458 at 77b60ac4e47159920ea7937b83daa7fc59097f39, covering all 91 changed files and their relevant callers. Two new P2 findings are inline: valid Iceberg views authorize missing-table repair, and natural parent-database eviction leaves a delayed-negative observation window. No new P0/P1 finding was verified.

Existing review context was independently revalidated. The catalog-rename P1 (#4346749470), disabled-cache handling (#4346749481), refresh tests (#4346749491), and case-equivalent rename destination (#4351655200) are addressed at this head. The Fluss lake-path history P2 (#4355558692) still applies and is not duplicated. No existing P0/P1 remains applicable. No additional user focus was supplied.

Critical checkpoint conclusions:

  • Goal and proof: the shared root/planner coordinates LOCAL, REMOTE and ID dependencies; read-observed absence remains incomplete in the two inline cases. Added tests demonstrate intended scenarios in source; they were not executed here.
  • Scope and abstraction: this is a substantial but cohesive cache-ownership refactor. Instance domains, typed scopes and a common semantic planner reuse the shared cache framework.
  • Concurrency: query loaders, background refresh, retention/removal callbacks, events and replay were traced. Shared publication fencing covers explicit invalidation and exact-key replacement; the natural parent-eviction gap is inline.
  • Lock cost and order: loaders perform remote work outside publication phases; read reentrancy and deferred callbacks avoid the examined gate/index cycles. No separate new deadlock was substantiated.
  • Lifecycle: domains retire exact registrations, accepted adapter operations pin auxiliary indices, and catalog rename reactivates ownership. Parent replacement must additionally fence the old missing observation.
  • Configuration: no new setting is introduced. Table-name-mode and catalog-budget changes retire the root; schema-entry reconfiguration borrows it. Existing TTL/count and payload-weight policies remain explicit.
  • Compatibility: connector API major 20 and its changed surface baseline are updated. Optional Gson journal fields have legacy fallback paths; mixed-version deployment behavior was inspected statically, not exercised.
  • Thrift/protobuf: no changes under gensrc; cross-branch field-ID comparison is inapplicable.
  • Parallel paths: explicit refresh, content writes, successful DDL, structural/partition events, replay, sibling connectors, RemoteDoris, system tables and session bypass were checked. The view path needs the inline correction.
  • Conditional logic: case-mode canonicalization, cold replay fallback, bypass and retirement conditions have concrete roles. No further speculative-condition defect was verified.
  • Tests: positive, failure, replay, replacement and latch-driven race coverage was inspected. Retained Iceberg-view binding and natural eviction before callback retirement need dedicated coverage.
  • Result files: changed Hive and nested-Iceberg outputs are consistent with the supplied suites on static inspection. Their generation and runtime correctness were not independently verified.
  • Observability: existing cache metrics, per-registration engine stats and contextual failures cover the changed mechanisms; no additional observability finding was substantiated.
  • Persistence/failover: changed DDL carriers and Env/EditLog dispatch preserve remote identities and lookup intent. Committed DDL is journaled before fallible invalidation; old-log replay remains cache-only.
  • Writes/crashes/atomicity: this modifies post-mutation metadata invalidation rather than transaction commit/version rules. Scope detachment is coordinated; the delayed-negative parent race is separately reported. No runtime crash/failover test was performed.
  • FE/BE propagation: no new transmitted variable or protocol path is introduced. BE visible-version, delete-bitmap and allocator invariants are unaffected.
  • Performance and other concerns: row-count retention remains globally bounded with root-owned futures, and failed automatic refresh retains successful values. View cache churn is inline; Fluss historical-map growth is already reported. No further verified issue remains outside the declared findings.

Validation was static only: no builds, tests, service execution or repository source changes. All changed paths and assigned risk focuses were covered; runtime and multi-FE behavior remain unexecuted validation limits.

Review converged after 2 round(s).

return metadata.getTableHandle(session, dbName, getRemoteName());
Optional<ConnectorTableHandle> handle = metadata.getTableHandle(session, dbName, getRemoteName());
if (!handle.isPresent()) {
observation.ifPresent(CatalogMetadataChanges.MissingTableObservation::missing);

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.

[P2] Exclude existing views from missing-table repair

For a valid Iceberg view, tableExists() is false while viewExists() is true. Such views are still constructed as PluginDrivenMvccExternalTable, and BindRelation.getLogicalPlan() calls loadSnapshots() before its isView() branch. An ordinary SELECT therefore reaches this new missing() call through materializeLatest(), evicting the valid view's object, ID, schema and parent table-name snapshot. Repeated view queries now force remote namespace listings and adapter recreation instead of retaining that metadata for its configured TTL. Exclude confirmed views from shared missing-table repair, or establish that neither a table nor a view exists, and cover a retained Iceberg view through the MVCC bind path.

}
// Name refresh can change the canonical spelling without replacing the old exact table key.
return tableNames.observe("", names).flatMap(nameObservation ->
tables.observe(table.getName(), table).map(nameObservation::and));

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.

[P2] Include the retained parent database in the observation

These tokens only observe this database instance's child entries. During natural database-cache eviction, ScopedMetaCache physically removes the parent before draining the deferred removal listener that calls releaseCachedEntries(). If an old missing-table lookup is pending, another query can publish a replacement database and recreated table in that interval. The old children still have current registrations and retired == false, so the delayed negative passes this check and invalidates the replacement's table, schema, IDs and names through their shared scopes. Explicit-refresh generation fencing does not cover this natural-eviction path. Include the exact parent database registration in the observation, and cover a delayed eviction callback with replacement publication before the old negative completes.

@924060929 924060929 closed this Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants