Skip to content

[fix](fe) Load FE images that carry Lance catalogs written by 4.1.4+ - #69575

Open
morningman wants to merge 2 commits into
apache:masterfrom
morningman:b2m-t00a-lance-gson-compat
Open

morningman wants to merge 2 commits into
apache:masterfrom
morningman:b2m-t00a-lance-gson-compat

Conversation

@morningman

@morningman morningman commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #65730, #68781

Original author: @u70b3 (the op 500 and image-module tombstones follow branch-4.1 #68781; the commit carries Co-authored-by)

Problem Summary:

In short. This PR makes master read the metadata that branch-4.1's Lance catalog (#65730, released in 4.1.4) and its since-removed index job framework (tombstoned by #68781) wrote: an FE image written by 4.1.4 or later with a Lance catalog in it now loads. Before this PR the image failed to parse, so a cluster with a Lance catalog could not be upgraded from any released 4.1.4 / 4.1.4.1 / 4.1.5 build (or from 4.2) to a master-based build: the FE did not start. The Lance catalog's GSON labels are mapped to the plugin-driven classes, as the Iceberg, Paimon and LakeSoul labels already are, and the catalog stays registered, unusable until a Lance connector plugin is installed. The two pieces of metadata that only unreleased branch-4.x builds wrote (the Lance index job edit-log record and image module) are kept readable as tombstones, as branch-4.1 #68781 does.

Background. branch-4.1 added a Lance catalog as fe-core classes in #65730 (released in 4.1.4). Like every external catalog, it is persisted in the image's datasource module as GSON JSON whose clazz field names the class, LanceExternalCatalog, with logType LANCE. master has no Lance classes: external catalogs are served by connector plugins, and the labels of the catalogs that used to be fe-core classes are redirected to PluginDrivenExternalCatalog / PluginDrivenExternalDatabase / PluginDrivenMvccExternalTable by registerCompatibleSubtype in GsonUtils. A Lance connector plugin does not exist on master yet; it will be ported later.

branch-4.1 also had, for a while, a durable Lance index job framework (#67235) that wrote edit-log op 500 (OP_LANCE_INDEX_JOB_UPSERT) and an image module named lanceIndexJobManager. #68781 removed it before any release. 4.1.5 and branch-4.2 keep op 500 as a tombstone that is read and discarded, and list the module as deprecated, so the journals and images of the builds in between stay readable.

The upgrade fixtures on master (upgrade/413) were generated from 4.1.3, before Lance existed, so no test caught this.

The problem, and what it cost. Compared on master against fixtures emitted by real 4.1.5 bytecode:

Metadata from a 4.1.4+ FE master before this PR after this PR
image whose datasource module has a Lance catalog (every 4.1.4+ cluster with one) image fails to parse: cannot deserialize interface org.apache.doris.datasource.CatalogIf subtype named LanceExternalCatalog; did you forget to register a subtype?; the FE cannot start loads; the catalog is a PluginDrivenExternalCatalog of type lance with all its properties, comment and auto-analyze policies; using it fails with No ConnectorProvider found for plugin-driven catalog: <name>, type: lance. Ensure the connector plugin is installed.
OP_CREATE_CATALOG of a Lance catalog replays as a degraded catalog (the entry carries only properties) unchanged
op 500 (only from unreleased branch-4.x builds) replay fails: UNKNOWN Operation Type 500 read and discarded
image module lanceIndexJobManager (only from unreleased branch-4.x builds) image fails: Unknown meta module: lanceIndexJobManager unless ignore_unknown_metadata_module = true skipped as deprecated

The only labels in the GSON registries of 4.1.4.1, 4.1.5 and 4.2.0-rc01 that master does not know are LanceExternalCatalog, LanceExternalDatabase and LanceExternalTable.

How this PR fixes it.

  • GsonUtils: LanceExternalCatalog → PluginDrivenExternalCatalog, LanceExternalDatabase → PluginDrivenExternalDatabase, LanceExternalTable → PluginDrivenMvccExternalTable (LanceExternalTable implemented MvccTable). 4.1.x never persists an external database or table, so only the catalog label can actually appear; the other two complete the registry, as for the other migrated connectors.
  • InitCatalogLog.Type keeps LANCE, so the logType 4.1.4+ wrote still deserializes to itself. Nothing depends on it: a Lance catalog always persists its type property (no resource type creates one), and PluginDrivenExternalCatalog#gsonPostProcess rewrites the logType to PLUGIN.
  • OperationType.OP_LANCE_INDEX_JOB_UPSERT = 500 is reserved: JournalEntity reads its Text-framed JSON and discards it, EditLog replays nothing. lanceIndexJobManager joins PersistMetaModules.DEPRECATED_MODULE_NAMES. Both follow branch-4.1 branch-4.1: [refactor](lance) Remove the durable Lance index job framework (#66497) #68781.
  • BdbjeJournalDataProcNode, which renders SHOW PROC '/bdbje/<db>/<journalId>' in BDBJE debug mode, prints a record read without a payload as null, as BDBTool already does, instead of failing with a NullPointerException. This covers op 500 and the retired operation types already on master: the PL/SQL ones of [clean](plsql) remove plsql #58700 and the external-catalog ones whose reader keeps no payload.

Until a Lance connector plugin is installed, an upgraded cluster lists its Lance catalogs and fails only when one is used; installing the plugin makes them work without any metadata change, since the catalog properties are handed to the connector unchanged.

Results.

  • New golden fixtures fe/fe-core/src/test/resources/upgrade/415/, emitted by 4.1.5-release bytecode like upgrade/413 (generator and PROVENANCE.txt included, byte-deterministic): the datasource module with three Lance catalogs (filesystem on S3, filesystem on file://, REST with bearer auth), their OP_CREATE_CATALOG entries, and 4.1.5's label registries.
  • Legacy415LanceUpgradeTest (9 tests): the image loads and every Lance catalog becomes a PluginDrivenExternalCatalog of type lance with the PLUGIN logType; every persisted property, the comment, lastUpdateTime and the auto-analyze policy survive; the persisted logType names still deserialize; without a plugin the catalog fails only when used, with the message above; a provider claiming lance receives exactly the persisted properties, from the image and from the journal; the journal entries replay with and without a plugin; an op 500 record followed by a real 4.1.5 entry is consumed exactly, and replaying it needs no Env; lanceIndexJobManager stays deprecated.
  • LanceGsonCompatReplayTest (4 tests): the three labels replay as the expected classes (the table as the MVCC variant), and they are the only labels 4.1.5 registered beyond 4.1.3.
  • Each of these changes, undone on its own, turns tests red: dropping the catalog label (5 tests, with the parse error above), the database label, mapping the table label to the non-MVCC class, removing LANCE, the JournalEntity case (UNKNOWN Operation Type 500), the EditLog case (the replay ends in System.exit(-1), as on a real FE) or the deprecated-module entry.
  • BdbjeJournalDataProcNodeTest (2 tests): an op 500 record and a retired PL/SQL record, in their written form, show their journal ID, operation name, size and null data in the debug view; a live OP_SAVE_NEXTID record still shows its payload. With getData().toString() back, the first test fails with a NullPointerException.
  • 127 tests of the two new classes and 17 related upgrade, GSON and journal suites (Legacy413*, *GsonCompat*, CatalogMgrTest, ExternalCatalogTest, ConstraintPersistTest, BDBJEJournalTest, ...) pass; fe-core checkstyle passes. After the review fix, BdbjeJournalDataProcNodeTest, Legacy415LanceUpgradeTest and BDBDebuggerTest (12 tests) pass.

Release note

Fix: an FE upgraded from 4.1.4 or later (or 4.2) to this version loads an image that contains a Lance catalog. The catalog is kept but cannot be used until a Lance connector plugin is installed.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • 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.
    • Yes.
      An image with a Lance catalog loads instead of failing; journals with op 500 and images with the lanceIndexJobManager module are read instead of failing. In BDBJE debug mode, SHOW PROC '/bdbje/<db>/<journalId>' shows a record kept without a payload (op 500, the retired PL/SQL and external-catalog operation types) with null data instead of failing.
  • 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

### What problem does this PR solve?

Issue Number: None

Related PR: apache#65730, apache#68781

Problem Summary:

branch-4.1 added the Lance catalog as fe-core classes in apache#65730, released in
4.1.4. 4.1.4, 4.1.4.1, 4.1.5 and branch-4.2 persist it in the image's
datasource module under the GSON label LanceExternalCatalog (logType LANCE).
master has no Lance classes and no compatible-subtype mapping for that label,
so loading such an image fails with a JsonParseException and the FE does not
start: a cluster with a Lance catalog cannot be upgraded to a master-based
build. The upgrade fixtures on master were generated from 4.1.3, which
predates Lance, so no test caught it. The only labels in the 4.1.4.1, 4.1.5
and 4.2.0-rc01 registries that master does not know are LanceExternalCatalog,
LanceExternalDatabase and LanceExternalTable.

The branch-4.x builds that carried the durable Lance index job framework
(apache#67235, removed by apache#68781 before any release) also wrote edit-log op 500
(OP_LANCE_INDEX_JOB_UPSERT) and an image module named lanceIndexJobManager.
master fails on both ("UNKNOWN Operation Type 500", "Unknown meta module").

Fix, following the other connectors migrated to plugins and apache#68781:
- GsonUtils maps LanceExternalCatalog, LanceExternalDatabase and
  LanceExternalTable to PluginDrivenExternalCatalog,
  PluginDrivenExternalDatabase and PluginDrivenMvccExternalTable
  (LanceExternalTable implemented MvccTable).
- InitCatalogLog.Type keeps LANCE, so the persisted logType still
  deserializes to itself.
- op 500 is reserved as a tombstone: JournalEntity reads its Text-framed JSON
  and discards it, EditLog replays nothing; lanceIndexJobManager joins
  PersistMetaModules.DEPRECATED_MODULE_NAMES.

Until a Lance connector plugin is installed, a migrated Lance catalog stays
registered and fails only when used ("No ConnectorProvider found for
plugin-driven catalog: <name>, type: lance").

Tests: golden fixtures emitted by 4.1.5-release bytecode under
fe-core/src/test/resources/upgrade/415 (generator and PROVENANCE included),
Legacy415LanceUpgradeTest and LanceGsonCompatReplayTest.

### Release note

Fix: an FE upgraded from 4.1.4 or later (or 4.2) to this version loads an
image that contains a Lance catalog. The catalog is kept but cannot be used
until a Lance connector plugin is installed.

### Check List (For Author)

- Test: Unit Test
    - Legacy415LanceUpgradeTest (9) and LanceGsonCompatReplayTest (4), with
      17 related upgrade / GSON / journal suites: 127 tests pass
- Behavior changed: Yes. An image with a Lance catalog loads instead of
  failing; a journal with op 500 and an image with the lanceIndexJobManager
  module are read instead of failing.
- Does this need documentation: No

Co-authored-by: kid <lucian1412@outlook.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@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?

@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@morningman

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 #69575 at 7357266f189018a60ae86a39d5544df666390823: one low-priority finding in BDBJE inspection of retired op500 records. No verified P0/P1 findings or existing blocking comments. The inspected catalog migration, journal replay, and deprecated-image handling preserve forward metadata readability.

All 22 changed paths were reviewed. Both complete-scope reviewers and the separate risk reviewer completed the final unchanged-payload pass with NO_NEW_VALUABLE_FINDINGS. Review converged after 2 rounds; no unresolved candidate or uncovered changed file remains. No additional user focus was supplied.

Required checkpoint Conclusion
Goal and proving tests Legacy Lance aliases restore catalog loading, preserve configuration, and defer missing-plugin failure to access. New 4.1.5 image/CREATE fixtures and focused unit-test source cover this contract.
Scope and reuse Six production files use existing compatibility patterns; shared fixture helpers retain the 4.1.3 APIs and defaults. Generated-file license exemptions are narrow.
Concurrency and locks No new threads, shared runtime state, locks, or lock-order changes. Existing synchronized initialization guards lazy provider creation; test manager installation/teardown and fresh JVMs isolate registry state.
Lifecycle and static initialization Deserialization resets runtime flags without creating connector/JNI resources. Canonical GSON types precede read aliases; type backfill occurs before logType normalization. No new static dependency cycle.
Configuration No configuration items added or changed.
Format and version compatibility Legacy class/enum names remain readable, canonical write labels are unchanged, and historical op500 framing and image checksum behavior match the new readers. Runtime rolling-upgrade or downgrade behavior was not executed.
Thrift/protobuf IDs No generated protocol definitions changed.
Parallel functional paths Image and CREATE replay checked independently, including absent/present providers; cloud shares the external aliases. PluginDriven database rebuilding forces PLUGIN and preserves MVCC table routing. BDB and local journal cursors checked.
Special conditions and failures Explicit tombstones intentionally discard retired state; malformed Text frames still fail. The missing base LANCE builder case is unreachable after the PluginDriven override.
Functional, negative, and unit coverage Inspected tests cover subtype identity, property/state retention, missing-plugin diagnostics, provider handoff, CREATE replay, adjacent-record EOF, and module deprecation. The debug-consumer case in the inline finding is uncovered.
Changed expected results No regression .out changes. Read-only checks verified exact binary framing/EOF, provenance hash, JSON equality, journal index completeness, and the three Lance-only label additions.
Observability Missing-provider errors identify catalog/type. The inline P3 identifies a null payload that breaks journal inspection; no additional critical metrics path was introduced.
Persistence and failover Both read and replay cases exist for the retired opcode; old image modules are skipped without changing the historical checksum. No current producer or durable metadata transition was added.
Data writes, atomicity, and crashes No transaction/data-write algorithm changed. Committed-data visibility, visible-version, delete-bitmap, and BE memory-accounting paths are unaffected.
FE/BE variable propagation No transmitted field or variable added.
Performance Bounded registry additions and one Text-frame read on historical replay; no added hot-path scan, retained native resource, or redundant production copy.
Other issues and final sweep Rechecked real historical constructors, inherited state, no-provider startup, cloud paths, opcode reservation, nonempty/last module skipping, helper callers, and all journal data consumers. Only the reported P3 remains.

Validation was static inspection and read-only fixture-data analysis. No builds, unit/regression tests, fixture regeneration, cluster startup, or actual Lance connector execution were performed. Full-image skip behavior was checked against the historical writer and current offset/checksum logic, rather than executed. A future Lance plugin's query semantics are outside this compatibility patch.

Review converged after 2 round(s).

}
case OperationType.OP_LANCE_INDEX_JOB_UPSERT: {
// Text-framed JSON of the removed branch-4.x Lance index job framework; consumed and ignored.
Text.readString(in);

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.

[P3] Retain a printable payload for the retired journal record

When an operator enables enable_bdbje_debug_mode and inspects a historical op500 entry with SHOW PROC '/bdbje/<db>/<journalId>', this branch succeeds but leaves JournalEntity.data null. BDBDebugger.getJournalEntity() consequently returns a non-null entity, and BdbjeJournalDataProcNode.fetchResult() calls entity.entity.getData().toString(), so the inspection fails with NullPointerException. Retain the consumed JSON in an inert Text payload, or make the debug consumer handle tombstone payloads; replay can still ignore the record.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed, and fixed in b0e09ae835e in the debug reader rather than in the tombstone. BdbjeJournalDataProcNode called getData().toString() without a null check, and master already has twelve retired operation types whose records are read without keeping a payload: the four PL/SQL ones that #58700 turned into Text.readString(in) (the form this PR copies for op 500, as branch-4.1/4.2 do) and eight external-catalog ones (329, 350–356) whose reader keeps no payload either. SHOW PROC '/bdbje/<db>/<journalId>' on any of those records already failed the same way. BDBTool, the other BDBJE inspection path, prints a missing payload as null; the proc node now does the same through String.valueOf, so op 500 and the existing tombstones are all printable, and the op 500 tombstone stays identical to #58700's and branch-4.x's. BdbjeJournalDataProcNodeTest reads an op 500 record and a retired PL/SQL record in their written form and checks the rows, and a live OP_SAVE_NEXTID record still shows its payload.

For scale: op 500 only exists in journals of unreleased branch-4.1/4.2 builds from between #67630 and #68781 on which the off-by-default enable_lance_index_mutation was turned on, and only until a checkpoint deletes those journals. The failure was limited to that one debug-mode statement; replay and checkpointing never read the payload. branch-4.1/4.2 have the same proc node and the same op 500 tombstone.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16613	5093	5036	5036
q2	2124	307	254	254
q3	9924	1362	809	809
q4	4604	462	347	347
q5	7418	803	520	520
q6	181	181	148	148
q7	744	783	599	599
q8	9406	1265	981	981
q9	5468	4179	4144	4144
q10	6829	1291	1001	1001
q11	434	239	218	218
q12	633	398	277	277
q13	18098	3519	2998	2998
q14	264	279	242	242
q15	q16	729	721	668	668
q17	1180	743	555	555
q18	6987	6168	6093	6093
q19	1122	954	584	584
q20	381	333	219	219
q21	4618	2111	2244	2111
q22	340	294	247	247
Total cold run time: 98097 ms
Total hot run time: 28051 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5595	5597	5562	5562
q2	680	548	529	529
q3	5172	5407	4906	4906
q4	1965	2132	1584	1584
q5	5259	5169	5137	5137
q6	234	184	144	144
q7	2504	2051	1789	1789
q8	3070	2694	2682	2682
q9	8042	8029	7846	7846
q10	3682	3692	3250	3250
q11	617	438	399	399
q12	690	680	518	518
q13	3617	3799	3298	3298
q14	316	309	274	274
q15	q16	697	693	629	629
q17	8203	7472	7110	7110
q18	13021	12210	12897	12210
q19	945	828	779	779
q20	2135	2124	1939	1939
q21	5626	4768	4712	4712
q22	489	520	411	411
Total cold run time: 72559 ms
Total hot run time: 65708 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 150692 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 7357266f189018a60ae86a39d5544df666390823, data reload: false

query5	4302	568	446	446
query6	422	211	190	190
query7	4810	434	220	220
query8	316	166	150	150
query9	8770	3098	3044	3044
query10	467	324	254	254
query11	6005	3845	3578	3578
query12	147	89	86	86
query13	1262	439	304	304
query14	6165	3915	3634	3634
query14_1	3402	3410	3393	3393
query15	200	187	176	176
query16	932	440	413	413
query17	845	652	503	503
query18	2404	425	294	294
query19	194	160	136	136
query20	83	84	78	78
query21	205	125	103	103
query22	12947	13031	12733	12733
query23	13458	12968	12487	12487
query23_1	12570	12666	12718	12666
query24	7163	822	455	455
query24_1	470	474	453	453
query25	519	397	348	348
query26	1259	258	141	141
query27	2779	439	271	271
query28	4520	1945	1921	1921
query29	1560	598	470	470
query30	296	228	187	187
query31	1020	937	817	817
query32	145	97	89	89
query33	525	307	246	246
query34	899	839	496	496
query35	730	756	653	653
query36	797	812	716	716
query37	124	107	85	85
query38	1782	1733	1653	1653
query39	803	795	750	750
query39_1	721	733	754	733
query40	225	121	98	98
query41	73	70	69	69
query42	87	88	82	82
query43	343	369	311	311
query44	1312	692	703	692
query45	183	190	165	165
query46	846	964	565	565
query47	2749	2869	2686	2686
query48	311	319	220	220
query49	578	405	288	288
query50	685	284	206	206
query51	10495	10510	10531	10510
query52	82	80	74	74
query53	188	211	154	154
query54	260	207	195	195
query55	78	77	64	64
query56	231	237	218	218
query57	1657	1606	1600	1600
query58	296	278	259	259
query59	2133	2165	1954	1954
query60	298	252	229	229
query61	167	164	162	162
query62	384	332	293	293
query63	196	162	159	159
query64	2806	960	774	774
query65	3343	3262	3257	3257
query66	1766	419	286	286
query67	20252	20002	20021	20002
query68	3007	986	597	597
query69	392	284	261	261
query70	866	777	751	751
query71	299	243	215	215
query72	2749	2520	2309	2309
query73	514	528	291	291
query74	4646	4558	4350	4350
query75	2326	2283	1922	1922
query76	2152	1004	571	571
query77	351	375	265	265
query78	9862	9694	9158	9158
query79	963	851	509	509
query80	761	412	326	326
query81	554	323	270	270
query82	554	135	103	103
query83	301	196	189	189
query84	309	116	99	99
query85	840	410	368	368
query86	375	246	235	235
query87	2020	1981	1815	1815
query88	3634	2653	2650	2650
query89	335	279	242	242
query90	1824	160	170	160
query91	174	154	126	126
query92	100	87	89	87
query93	1020	1015	574	574
query94	513	292	266	266
query95	574	332	371	332
query96	655	491	230	230
query97	2472	2439	2304	2304
query98	159	148	153	148
query99	767	763	663	663
Total cold run time: 233822 ms
Total hot run time: 150692 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.14	0.09	0.09
query3	0.34	0.13	0.13
query4	1.62	0.14	0.13
query5	0.27	0.25	0.25
query6	1.15	0.66	0.66
query7	0.05	0.02	0.00
query8	0.10	0.08	0.07
query9	0.45	0.36	0.37
query10	0.56	0.61	0.58
query11	0.31	0.18	0.18
query12	0.31	0.20	0.19
query13	0.53	0.53	0.52
query14	0.94	0.94	0.93
query15	0.67	0.58	0.58
query16	0.33	0.36	0.36
query17	1.03	0.98	1.02
query18	0.28	0.28	0.28
query19	1.98	1.93	1.88
query20	0.03	0.02	0.01
query21	15.40	0.36	0.30
query22	4.93	0.14	0.12
query23	15.84	0.50	0.29
query24	2.27	0.55	0.38
query25	0.15	0.11	0.11
query26	0.76	0.27	0.21
query27	0.11	0.09	0.10
query28	3.51	0.84	0.41
query29	12.58	4.34	3.38
query30	0.36	0.19	0.16
query31	2.76	0.58	0.33
query32	3.22	0.62	0.48
query33	3.05	2.99	2.96
query34	15.92	4.05	3.45
query35	3.38	3.38	3.37
query36	0.58	0.50	0.49
query37	0.12	0.10	0.11
query38	0.07	0.06	0.07
query39	0.06	0.07	0.06
query40	0.20	0.17	0.16
query41	0.12	0.05	0.06
query42	0.06	0.06	0.06
query43	0.08	0.05	0.06
Total cold run time: 96.63 s
Total hot run time: 25.26 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (8/8) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 50.00% (4/8) 🎉
Increment coverage report
Complete coverage report

…ebug view

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69575

Problem Summary: In BDBJE debug mode (enable_bdbje_debug_mode),
SHOW PROC '/bdbje/<db>/<journalId>' renders a record through
BdbjeJournalDataProcNode, which called getData().toString() without a null
check. The readers of retired operation types consume the payload without
keeping it, so their data is null: the op 500 tombstone added by this PR,
the four PL/SQL operation types retired by apache#58700 (the same
Text.readString(in) form) and the payload-less external-catalog operation
types. Viewing any of those records failed with a NullPointerException. For
op 500 this is a regression of this PR: before it the record failed to read
and the row showed "Not Found". BDBTool, the other BDBJE inspection path,
already prints a missing payload as null.

The proc node now prints the payload with String.valueOf, so such a record
shows null as its data. The op 500 tombstone stays the same as apache#58700's and
branch-4.x's. Replay and checkpointing never read these payloads and are
unaffected.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - BdbjeJournalDataProcNodeTest: an op 500 record and a retired PL/SQL record, in their written form, show their journal ID, operation name, size and null data; a live OP_SAVE_NEXTID record still shows its payload
    - Legacy415LanceUpgradeTest, BDBDebuggerTest
- Behavior changed: No (the debug view no longer fails on these records)
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@morningman

Copy link
Copy Markdown
Contributor Author

Addressed the first review round in b0e09ae835e. Per finding:

  • 4367233851 (P3, BDBJE debug view of a retired journal record): fixed in BdbjeJournalDataProcNode, which now prints a record read without a payload as null, as BDBTool does. This covers op 500 and the retired PL/SQL and external-catalog operation types already on master; the op 500 tombstone itself is unchanged.

New BdbjeJournalDataProcNodeTest (2 tests); Legacy415LanceUpgradeTest and BDBDebuggerTest still pass; fe-core checkstyle passes. The PR description is updated.

@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@morningman

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 all 24 changed paths at b0e09ae found no new actionable defects. The two complete-review agents and the independent risk reviewer each returned NO_NEW_VALUABLE_FINDINGS in round 1; both initial risk focuses were resolved with source evidence.

Existing P3 4367233851 is fixed: String.valueOf renders retired records without a payload safely, with tests retaining live-record display. It was not reposted. No supplied existing P0/P1 finding remains to carry forward. No additional user focus was supplied.

Critical checkpoint Conclusion
Goal and proving tests Legacy Lance catalog labels now deserialize into plugin catalogs, preserving configuration and deferring a missing-provider error until access. Golden 4.1.5 fixtures and targeted JUnit cases cover image loading, replay, properties, aliases and debug display; inspected statically.
Scope and reuse Small production changes reuse existing compatible-subtype, retired-opcode and deprecated-module mechanisms. Fixture readers share the existing release-root helpers.
Concurrency and locking No new threads, lock acquisition/order or shared runtime mutation. Fresh journal entities and existing synchronized catalog initialization retain ownership guarantees.
Lifecycle and static initialization Postprocessing resets initialized/objectCreated before lazy connector creation, including previously initialized images. Canonical plugin write labels remain unchanged; no new initialization cycle or resource lifetime is introduced.
Configuration No configuration added or changed.
Format and upgrade compatibility Historical op500 writers use the exact Text frame now consumed. Retired module load/save leave the checksum unchanged, so offset-based skipping preserves following modules and footer validation. No new persisted format is emitted by these compatibility additions. Runtime rolling upgrades were not exercised.
Thrift and protobuf IDs Neither directory changes.
Parallel paths Image and create-catalog replay, catalog/database/MVCC-table aliases, both journal cursors, both debug readers, and cloud/shared-nothing module placement were traced.
Conditional checks Null-payload rendering matches the existing BDBTool behavior. Legacy initialization and empty/nonempty/final module cases have concrete, supported paths.
Test coverage Covers S3/local/REST properties, identity/comment/time/auto-analyze state, absent and recording providers, exact target classes, op500 followed by a real record, no-op replay, module registration, and live/retired debug rows. A full nonempty historical image is not exercised by the added membership test; its offset/checksum contract was verified against the historical writer.
Test results and fixtures No execution results are claimed. Binary frame lengths, opcode values, JSON payload identity, provenance hash, indexes and label inventories agree; the 4.1.3 helper roots remain intact. No regression result files are added.
Observability Existing migration logs, skipped-module warnings, catalog-name/type errors and journal operation/size display cover these paths.
Persistence and failover Catalog image and replay retain the persisted state; op500 is fully consumed and inert while replay advances normally. Checkpoints omit the retired module and use canonical plugin labels. No transaction persistence mode changes.
Data writes and crash atomicity No data write or transaction mutation is added. Transaction visibility, partition visible versions and delete-bitmap invariants are unaffected; no BE allocation or memory-tracking change.
FE/BE variable propagation No transmitted variable or send path changes.
Performance Fixed registry additions and one retired-record dispatch introduce no material query hot-path work. No redundant scan or remote operation found.
Other issues and final recheck Historical persistence boundaries exclude cached Lance database/table graphs; MVCC aliases and unknown legacy table-type normalization are consistent. No unresolved candidate or uncovered changed path remains.

Review converged in one round. Validation was static only: no builds, tests, FE startup, fixture regeneration, live Lance connector queries or mixed-version deployment were run.

Review converged after 1 round(s).

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16472	5139	5039	5039
q2	2136	298	245	245
q3	9933	1372	827	827
q4	4611	459	342	342
q5	7417	809	548	548
q6	187	184	156	156
q7	745	792	606	606
q8	9385	1322	1093	1093
q9	5680	4196	4211	4196
q10	6828	1273	1020	1020
q11	426	240	227	227
q12	631	409	285	285
q13	18088	3611	3005	3005
q14	282	276	248	248
q15	q16	728	708	687	687
q17	1170	756	571	571
q18	6989	6167	6100	6100
q19	1107	965	594	594
q20	389	353	225	225
q21	5238	2164	2260	2164
q22	345	294	253	253
Total cold run time: 98787 ms
Total hot run time: 28431 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5602	5594	5599	5594
q2	662	588	528	528
q3	5233	5390	4902	4902
q4	2012	2140	1519	1519
q5	5325	5138	5415	5138
q6	261	205	160	160
q7	2352	2027	1891	1891
q8	3058	2662	2756	2662
q9	8018	7925	8043	7925
q10	3724	3694	3254	3254
q11	620	444	526	444
q12	691	715	530	530
q13	3464	3952	3297	3297
q14	301	297	284	284
q15	q16	714	739	678	678
q17	8225	7544	7009	7009
q18	12947	12190	12845	12190
q19	903	767	766	766
q20	2141	2142	1929	1929
q21	5672	4733	4722	4722
q22	519	491	425	425
Total cold run time: 72444 ms
Total hot run time: 65847 ms

@hello-stephen

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

query5	4311	569	445	445
query6	445	202	187	187
query7	4797	446	221	221
query8	312	162	148	148
query9	8768	3071	3090	3071
query10	476	305	257	257
query11	6018	3860	3554	3554
query12	148	92	83	83
query13	1243	445	323	323
query14	6088	3926	3630	3630
query14_1	3353	3357	3393	3357
query15	201	197	183	183
query16	966	465	422	422
query17	848	664	531	531
query18	2422	422	308	308
query19	196	166	143	143
query20	85	94	82	82
query21	208	128	108	108
query22	13038	13028	12723	12723
query23	13360	12841	12397	12397
query23_1	12631	12548	12543	12543
query24	7177	825	475	475
query24_1	480	479	484	479
query25	538	421	356	356
query26	1259	253	142	142
query27	2783	429	276	276
query28	4517	1946	1943	1943
query29	1543	587	459	459
query30	345	225	183	183
query31	1014	932	789	789
query32	139	89	81	81
query33	515	289	222	222
query34	877	830	493	493
query35	728	743	640	640
query36	814	804	704	704
query37	121	101	82	82
query38	1785	1699	1645	1645
query39	795	769	741	741
query39_1	733	720	746	720
query40	217	112	94	94
query41	68	62	64	62
query42	84	82	79	79
query43	331	368	305	305
query44	1267	675	681	675
query45	178	188	167	167
query46	814	952	561	561
query47	2940	2884	2833	2833
query48	314	307	219	219
query49	567	384	282	282
query50	666	274	202	202
query51	10332	10482	10614	10482
query52	84	79	70	70
query53	187	215	152	152
query54	234	186	168	168
query55	72	68	64	64
query56	210	207	195	195
query57	1640	1615	1565	1565
query58	285	258	249	249
query59	2117	2171	1969	1969
query60	302	239	227	227
query61	173	145	144	144
query62	378	332	285	285
query63	181	157	157	157
query64	2673	921	777	777
query65	3331	3274	3252	3252
query66	1775	419	302	302
query67	20257	20249	20200	20200
query68	3131	981	600	600
query69	389	294	249	249
query70	818	753	759	753
query71	292	233	213	213
query72	2794	2563	2302	2302
query73	521	517	295	295
query74	4617	4525	4370	4370
query75	2330	2263	1907	1907
query76	2119	987	622	622
query77	349	371	264	264
query78	9723	9693	9187	9187
query79	893	822	512	512
query80	559	394	331	331
query81	516	318	268	268
query82	543	132	103	103
query83	296	197	180	180
query84	310	115	106	106
query85	802	409	371	371
query86	312	236	229	229
query87	1987	1983	1787	1787
query88	3603	2659	2634	2634
query89	318	292	242	242
query90	1910	164	168	164
query91	160	148	123	123
query92	106	88	89	88
query93	995	970	572	572
query94	440	297	260	260
query95	583	385	312	312
query96	672	478	235	235
query97	2438	2441	2355	2355
query98	164	146	150	146
query99	767	755	627	627
Total cold run time: 232898 ms
Total hot run time: 150631 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.13	0.08	0.08
query3	0.34	0.12	0.12
query4	1.61	0.14	0.14
query5	0.27	0.25	0.26
query6	1.16	0.65	0.65
query7	0.03	0.01	0.00
query8	0.09	0.07	0.08
query9	0.44	0.37	0.35
query10	0.58	0.58	0.56
query11	0.32	0.18	0.17
query12	0.30	0.18	0.19
query13	0.56	0.52	0.52
query14	0.94	0.94	0.91
query15	0.65	0.58	0.59
query16	0.35	0.34	0.36
query17	1.00	0.98	1.03
query18	0.29	0.29	0.27
query19	1.94	1.90	1.86
query20	0.02	0.02	0.02
query21	15.40	0.34	0.30
query22	4.92	0.13	0.12
query23	15.86	0.49	0.30
query24	2.27	0.54	0.39
query25	0.15	0.10	0.11
query26	0.77	0.27	0.22
query27	0.10	0.09	0.10
query28	3.36	0.86	0.39
query29	12.57	4.36	3.36
query30	0.35	0.17	0.14
query31	2.76	0.60	0.33
query32	3.23	0.59	0.47
query33	2.94	3.11	2.95
query34	15.91	4.14	3.44
query35	3.39	3.35	3.36
query36	0.58	0.47	0.48
query37	0.12	0.09	0.10
query38	0.08	0.06	0.07
query39	0.06	0.06	0.06
query40	0.18	0.16	0.16
query41	0.10	0.05	0.05
query42	0.07	0.06	0.06
query43	0.06	0.06	0.06
Total cold run time: 96.25 s
Total hot run time: 25.01 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 8.33% (4/48) 🎉
Increment coverage report
Complete coverage report

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants