Skip to content

[fix](fe) Guard stream load schema metadata reads - #68964

Merged
Gabriel39 merged 3 commits into
apache:masterfrom
OIiveirra:fix/stream-load-schema-lock
Oct 15, 2026
Merged

Gabriel39 merged 3 commits into
apache:masterfrom
OIiveirra:fix/stream-load-schema-lock

Conversation

@OIiveirra

@OIiveirra OIiveirra commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

Issue Number: N/A

Related PR: #68726

Problem Summary:

Stream Load reads the base schema version from table metadata outside the planning lock. Concurrent schema change removes the old base-index metadata before switching the base index ID under the table write lock. An unlocked read in that interval can dereference missing metadata and fail the load. A deterministic unit test reproduces the null dereference on the pre-optimization baseline.

For regular Stream Load, populate the response database ID, table ID, and base schema version inside the existing generatePlan(OlapTable) read-lock scope. Populate them only for the first planned table when a response is present, preserving multi-table behavior. Planning and response metadata use the same lock scope without an additional lock acquisition.

For HTTP load_sql, obtain the response table ID and base schema version from the generated OlapTableSink. These values were already captured during planning under the existing table lock. Keep the other table-property reads as before. This removes the second metadata-lock acquisition and the transaction-abort branch introduced solely for its timeout. Existing transaction handling and Thrift fields are preserved.

This fix is separate from the scheduling and file TVF COUNT optimization in #68726.

Release note

Prevent Stream Load response schema-version reads from racing with schema change by reusing the existing planning lock and planned sink metadata.

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

    Validation performed:

    • Standard focused FE UT reactor passed StreamLoadHandlerTest (14) and HttpStreamLoadTablePropertiesTest (2): 16 tests, zero failures/errors. Maven Checkstyle passed.
    • Unit coverage includes real concurrent base-index replacement with one read-lock acquisition, metadata read-lock ownership and exceptional release, the existing planning timeout, first-table response semantics, and planning without a response. HTTP tests verify planned metadata is used even when current base-index metadata is absent, for both regular loads and Group Commit, without another read-lock acquisition.
    • Standard ASAN FE/BE build, deployment, and health checks passed in the personal shared-nothing single-BE environment. P0 load_p0/http_stream/test_stream_load_schema_metadata and load_p0/http_stream/test_http_stream_properties passed with zero failed suites/fatal scripts. Existing regression snapshots were compared without regeneration or manual edits.
    • P0 schema_change_p0/test_schema_change_unique_mow also passed: one suite, zero failed suites/fatal scripts. All three targeted suites used the binaries built from this revised implementation. Source changes pass git diff --check.
    • The concurrency unit test controls the race window; SQL regression exercises compatibility and does not guarantee it hits that exact window. This local shared-nothing single-BE environment is not complete TeamCity or Cloud coverage.
  • Behavior changed:

    • No.
    • Yes. Response metadata comes from the existing protected planning scope or the completed HTTP plan, avoiding an unlocked base-index lookup and additional lock waiting. Multi-table first-table behavior and protocol fields are preserved.
  • 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: N/A

Related PR: apache#68726

Problem Summary: Concurrent schema change can remove base-index metadata before switching the base index ID. Protect regular and HTTP Stream Load result metadata reads with the table read lock. Abort the already-begun normal HTTP transaction if the metadata lock times out; group commit does not begin that transaction. Keep the original timeout and record cleanup failures.

### Release note

Prevent Stream Load schema-version races and clean up HTTP transactions on metadata lock timeout.

### Check List (For Author)

- Test: Standard FE UT reactor passed StreamLoadHandlerTest (10) and HttpStreamLoadTablePropertiesTest (5), 15 tests with zero failures/errors. Maven Checkstyle and git diff --check passed.
- Behavior changed: Yes. Bound metadata read-lock waiting by RPC timeout and abort normal HTTP transaction on timeout.
- Does this need documentation: No
Copilot AI balanced review requested due to automatic review settings October 12, 2026 09:21
@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?

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68964

Problem Summary: Add regression coverage for regular Stream Load and HTTP load_sql metadata reads during schema change, including HTTP Group Commit. Add unit coverage for lock timeout and exceptional metadata reads so the read lock is not bypassed and is always released.

### Release note

None

### Check List (For Author)

- Test: 17 focused FE unit tests, Checkstyle, quick checks, new HTTP Stream Load P0 suite snapshot generation and comparison, existing schema-change P0 suite, and existing HTTP Stream Load properties P0 suite; all passed.
- Behavior changed: No.
- Does this need documentation: No
@OIiveirra

Copy link
Copy Markdown
Collaborator Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17597	5548	5493	5493
q2	2061	303	256	256
q3	10283	1386	842	842
q4	4682	471	361	361
q5	7443	793	544	544
q6	190	187	149	149
q7	772	801	603	603
q8	9241	1336	1075	1075
q9	5707	4484	4425	4425
q10	6808	1295	1029	1029
q11	432	256	241	241
q12	633	393	288	288
q13	18039	3056	2367	2367
q14	278	267	243	243
q15	q16	737	726	657	657
q17	1160	749	572	572
q18	7068	6234	6165	6165
q19	1104	962	613	613
q20	369	334	224	224
q21	4889	2225	2403	2225
q22	356	316	272	272
Total cold run time: 99849 ms
Total hot run time: 28644 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6140	6143	6095	6095
q2	706	573	564	564
q3	5184	5384	4920	4920
q4	2048	2102	1544	1544
q5	5266	5161	5811	5161
q6	270	199	146	146
q7	2299	2051	1880	1880
q8	3157	2768	2713	2713
q9	8294	8272	8250	8250
q10	3882	3765	3299	3299
q11	617	453	416	416
q12	732	742	520	520
q13	2878	3241	2566	2566
q14	330	322	301	301
q15	q16	694	734	666	666
q17	8398	7638	7410	7410
q18	13229	12256	13087	12256
q19	911	798	792	792
q20	2198	2167	1938	1938
q21	5713	4646	4730	4646
q22	498	460	430	430
Total cold run time: 73444 ms
Total hot run time: 66513 ms

@hello-stephen

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

query5	4315	593	459	459
query6	420	213	193	193
query7	4811	454	224	224
query8	315	176	174	174
query9	8762	3925	3960	3925
query10	446	314	253	253
query11	5965	3416	3215	3215
query12	139	89	86	86
query13	1252	432	325	325
query14	6523	4733	4513	4513
query14_1	4218	4253	4217	4217
query15	205	206	183	183
query16	940	439	421	421
query17	875	697	512	512
query18	2426	409	299	299
query19	184	151	125	125
query20	79	77	76	76
query21	215	134	110	110
query22	12930	12924	12828	12828
query23	13081	12426	12074	12074
query23_1	12248	12049	12191	12049
query24	7077	802	465	465
query24_1	455	464	455	455
query25	510	387	326	326
query26	1237	248	139	139
query27	2763	433	267	267
query28	4621	1944	1960	1944
query29	1550	555	427	427
query30	287	221	186	186
query31	901	762	641	641
query32	144	111	89	89
query33	500	308	232	232
query34	897	847	513	513
query35	750	774	630	630
query36	848	810	745	745
query37	126	112	84	84
query38	1777	1764	1653	1653
query39	725	717	668	668
query39_1	626	673	657	657
query40	215	126	99	99
query41	82	78	71	71
query42	91	87	96	87
query43	363	382	328	328
query44	1306	705	701	701
query45	187	174	167	167
query46	843	969	577	577
query47	2883	2971	2862	2862
query48	302	313	222	222
query49	569	409	307	307
query50	731	274	224	224
query51	10554	10451	11021	10451
query52	82	82	71	71
query53	188	207	154	154
query54	253	218	188	188
query55	76	68	68	68
query56	233	232	233	232
query57	1592	1573	1565	1565
query58	292	278	257	257
query59	2371	2372	2134	2134
query60	300	253	235	235
query61	170	170	171	170
query62	401	348	293	293
query63	203	166	166	166
query64	2865	1041	877	877
query65	3669	3376	3397	3376
query66	1773	402	295	295
query67	20300	20383	19888	19888
query68	2880	993	619	619
query69	387	286	245	245
query70	923	823	810	810
query71	295	236	215	215
query72	2710	2605	2254	2254
query73	504	520	295	295
query74	4571	4484	4313	4313
query75	2337	2304	1918	1918
query76	2286	1016	610	610
query77	360	380	297	297
query78	9103	8983	8400	8400
query79	992	834	513	513
query80	1235	438	351	351
query81	584	318	271	271
query82	607	135	108	108
query83	317	194	175	175
query84	305	121	111	111
query85	843	425	361	361
query86	399	235	224	224
query87	1999	1936	1797	1797
query88	3604	2686	2666	2666
query89	342	294	268	268
query90	1864	175	178	175
query91	157	149	124	124
query92	90	79	86	79
query93	975	985	566	566
query94	656	306	293	293
query95	585	344	377	344
query96	662	511	229	229
query97	2434	2407	2302	2302
query98	158	151	141	141
query99	786	765	675	675
Total cold run time: 234709 ms
Total hot run time: 151495 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.04	0.05
query3	0.26	0.12	0.12
query4	1.61	0.13	0.12
query5	0.28	0.25	0.24
query6	1.16	0.69	0.67
query7	0.04	0.01	0.00
query8	0.05	0.04	0.04
query9	0.42	0.35	0.34
query10	0.57	0.57	0.56
query11	0.21	0.14	0.14
query12	0.18	0.15	0.14
query13	0.48	0.48	0.50
query14	0.98	0.95	0.96
query15	0.63	0.60	0.62
query16	0.32	0.34	0.34
query17	1.12	1.13	1.13
query18	0.22	0.21	0.20
query19	2.07	2.01	1.98
query20	0.01	0.01	0.01
query21	15.48	0.28	0.14
query22	4.52	0.06	0.05
query23	16.25	0.30	0.12
query24	3.31	0.60	0.36
query25	0.11	0.06	0.04
query26	1.06	0.25	0.16
query27	0.05	0.04	0.04
query28	1.60	0.61	0.40
query29	12.68	4.14	3.29
query30	0.30	0.14	0.13
query31	2.77	0.57	0.33
query32	3.22	0.61	0.52
query33	3.16	3.26	3.17
query34	15.44	4.03	3.39
query35	3.35	3.33	3.34
query36	0.55	0.44	0.42
query37	0.10	0.06	0.06
query38	0.05	0.04	0.03
query39	0.04	0.02	0.02
query40	0.18	0.15	0.15
query41	0.09	0.04	0.03
query42	0.04	0.03	0.03
query43	0.04	0.03	0.03
Total cold run time: 95.11 s
Total hot run time: 24.35 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 45.16% (14/31) 🎉
Increment coverage report
Complete coverage report

@OIiveirra

Copy link
Copy Markdown
Collaborator Author

run feut

924060929
924060929 previously approved these changes Oct 13, 2026
@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 96.77% (30/31) 🎉
Increment coverage report
Complete coverage report

Gabriel39 pushed a commit that referenced this pull request Oct 13, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: #68964

Problem Summary:

Repeated queries against a single remotely accessible file split can
repeatedly select the same backend when external file caching and
consistent-hash scheduling are disabled. The round-robin scheduler
reconstructed its candidate list from a host map, discarding the
query-local randomized order selected during initialization. This change
preserves that order for round-robin assignment and keeps local
scheduling and split redistribution inside the active backend
candidates.

For unfiltered, ungrouped `COUNT(*)` and `COUNT(1)` over File, HDFS,
HTTP, Local, and S3 TVFs, the existing file COUNT pushdown is now used
under the existing session switches. The instance reduction is limited
to a file TVF row-count scan with exactly one assigned static physical
split. Dynamic `split_source` entries, multiple physical splits in one
range envelope, and existing external-table COUNT paths retain their
original parallelism. DISTINCT, grouped aggregates, filtered plans,
merge stages, and stream/ingest TVFs remain outside this path.

The single-split CSV COUNT benchmark improved median QPS from 169.600 to
543.733 (3.206x) under the conditions below. Dynamic batch scans retain
baseline fragment-instance parallelism.

Stream Load schema-version locking has been removed from this PR: a
differential unit test reproduces the race on the pre-optimization
baseline. It is handled separately in #68964, including HTTP transaction
cleanup on table-lock timeout. This PR retains the external scan
scheduling and file TVF COUNT changes.

### Release note

Improve round-robin scheduling for external file scans and reduce
execution overhead for unfiltered file TVF row-count queries with a
single assigned static physical split.

### Check List (For Author)

- Test
    - [x] Regression test
    - [x] Unit Test
    - [x] 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

  Validation performed:
- After separating the independent Stream Load schema-lock fix, the
standard focused FE UT reactor passed 33 tests:
`FederationBackendPolicyTest` (12), `FileTvfCountPushDownTest` (5),
`UnassignedScanSingleRemoteTableJobTest` (7), and the upstream
`StreamLoadHandlerTest` (9). Maven Checkstyle passed. This is functional
validation of head `0afd4837804`; the benchmark numbers below are from
the earlier measured revision.
- Standard full FE packaging and Checkstyle passed. Standard focused FE
UT reactor passed: `FederationBackendPolicyTest` (12),
`FileTvfCountPushDownTest` (4), and
`UnassignedScanSingleRemoteTableJobTest` (7), 23 tests total, zero
failures/errors. Parallelism tests cover dynamic split sources, multiple
physical splits in a single range envelope, external-table exclusion,
and actual local-shuffle instance assignment.
- New `test_file_tvf_count_pushdown` passed both framework snapshot
generation and normal comparison (1 suite, zero failures/fatal scripts).
It exercises CSV, JSON, Parquet, and ORC with scanner V1/V2 and pushdown
enabled/disabled, including COUNT star/one/nullable/DISTINCT, filters,
grouping, empty inputs, multiple files, and CSV headers/blank records/no
final newline. Zero-byte JSON is included alongside nonempty files
because standalone schema inference is unavailable.
- `test_s3_tvf_compression` passed against the personal MinIO equivalent
using the same public compression fixtures (1 suite, zero failures/fatal
scripts). The standard Aliyun OSS profile remains unvalidated because
valid credentials are unavailable; community CI should rerun it with its
configured credentials.
- Full Release BE build passed. Both FE versions were tested with
identical newly built BE binaries; the new four-format and compressed
TVF suites were also repeated successfully on this runtime.
- Single static split CSV (`COUNT(*)`, 1,000,000 rows, 64 clients):
three baseline QPS values were **165.533 / 170.800 / 169.600**;
candidate values were **449.133 / 544.967 / 543.733**. Median QPS
increased from **169.600 to 543.733 (3.206x)**. This measures the
combined scheduling and COUNT changes for this workload; it does not
establish a scheduling-only multiplier.
- Real dynamic Iceberg batch (`COUNT(value)`, 64 data files, 1,000,000
rows, expected count 500,000, 16 clients): baseline QPS **29.533 /
30.367 / 28.233**, candidate **30.167 / 29.767 / 29.267**; medians
**29.533 / 29.767 (1.008x)**. Distributed plans assigned **192 scan
fragment instances, 64 per BE**, for both versions in all rounds,
confirming dynamic sources keep their baseline instance parallelism.
These are assigned fragment instances, not active scanner-thread counts.
This throughput comparison is limited to the tested fixture and its
observed variability.
- All twelve measurements had verified COUNT results, zero errors, and
3/3 post-measurement backend health. Final artifact inspection found ten
connector/dependency JARs with an older API-version manifest because
size/mtime-based synchronization skipped them. ZIP entry comparisons
confirmed identical classes/resources; the Iceberg provider JAR itself
and FE core matched the intended builds. API gating reads the provider's
defining JAR, so the differing SPI dependency manifest is outside this
check. The measurements are therefore a comparison of the tested
workload paths, not a claim of identical complete FE packaging.
Unrelated ADBC/ES/Hudi/Trino providers were rejected during startup. A
subsequent checksum deployment matched all 2,213 FE artifact hashes and
all three BE binaries to the frozen build manifest. All previously
rejected providers and Iceberg loaded successfully; static
COUNT=1,000,000, dynamic nullable COUNT=500,000, and 3/3 health passed.
This deployment smoke did not rerun the performance measurements.
- Manual benchmark procedure: alternate baseline/candidate FE builds in
three rounds (B/C, C/B, B/C), restart all three isolated BEs after each
FE switch, require 3/3 health and the expected COUNT result, warm up for
10 seconds, then measure verified successful queries over 30 seconds.
Use identical Release BE binaries and session settings
(`parallel_pipeline_task_num=64`, file cache/consistent hash/SQL
cache/query cache disabled, COUNT pushdown and scanner V2 enabled). Use
64 clients for the single-split CSV and 16 for the dynamic Iceberg
batch; keep profiling disabled during measurement. All measurements
require zero errors. The three-BE restart prevents stale cached FE RPC
connections after version swaps; startup failures are excluded before
measurement.
- Benchmarks use three BEs on one shared host and report only the tested
workload; no equivalent multiplier is claimed for all queries or
customer deployments.

- Behavior changed:
    - [ ] No.
- [x] Yes. Round-robin assignment preserves initialized candidate order;
preferred load subsets are honored by local scheduling and
redistribution; eligible file TVF COUNT scans use pushdown and one
instance per worker when that worker has exactly one static physical
split; dynamic sources and existing external-table COUNT parallelism
remain unchanged.

- Does this need documentation?
    - [x] No.
    - [ ] Yes.

### Check List (For Reviewer who merge this PR)

- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68964

Problem Summary: Stream Load response metadata reads can race with concurrent base-index replacement. Populate the first table's response metadata under the existing regular planning lock and use the generated sink metadata for HTTP load_sql. Remove the additional lock acquisition and the transaction cleanup branch introduced for its timeout. Preserve multi-table behavior and protocol fields.

### Release note

Avoid Stream Load schema-version races without additional metadata lock waiting.

### Check List (For Author)

- Test: Standard FE UT reactor passed 16 tests (14 StreamLoadHandlerTest and 2 HttpStreamLoadTablePropertiesTest). Standard ASAN FE/BE build and Checkstyle passed. Three targeted P0 suites passed: test_stream_load_schema_metadata, test_http_stream_properties, test_schema_change_unique_mow. Source diff whitespace check passed.
- Behavior changed: Yes. Response metadata uses the existing planning lock or generated sink.
- Does this need documentation: No
@OIiveirra

Copy link
Copy Markdown
Collaborator Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17576	5634	5534	5534
q2	2105	304	249	249
q3	10249	1403	859	859
q4	4679	485	347	347
q5	7433	804	542	542
q6	189	183	154	154
q7	815	810	629	629
q8	9245	1469	1169	1169
q9	5777	4498	4453	4453
q10	6822	1267	1009	1009
q11	433	256	236	236
q12	630	401	291	291
q13	18046	3067	2382	2382
q14	266	266	241	241
q15	q16	785	729	659	659
q17	1202	750	584	584
q18	7049	6232	6222	6222
q19	1269	972	655	655
q20	409	341	231	231
q21	5732	2584	2698	2584
q22	404	365	317	317
Total cold run time: 101115 ms
Total hot run time: 29347 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6681	6562	6724	6562
q2	742	608	572	572
q3	5598	5777	5297	5297
q4	2039	2146	1589	1589
q5	5610	5518	5802	5518
q6	242	192	155	155
q7	2232	2032	1746	1746
q8	3218	2681	2773	2681
q9	8201	8210	8112	8112
q10	3665	3603	3231	3231
q11	602	412	365	365
q12	656	694	493	493
q13	2723	3309	2393	2393
q14	277	294	253	253
q15	q16	671	679	610	610
q17	7846	6941	6960	6941
q18	13085	12230	13008	12230
q19	938	835	827	827
q20	2166	2171	1919	1919
q21	5871	4931	4940	4931
q22	519	462	396	396
Total cold run time: 73582 ms
Total hot run time: 66821 ms

@hello-stephen

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

query5	4325	648	473	473
query6	436	226	204	204
query7	4808	455	234	234
query8	326	188	178	178
query9	8766	4031	4027	4027
query10	501	319	269	269
query11	5980	3471	3211	3211
query12	145	90	87	87
query13	1263	449	331	331
query14	6548	4839	4540	4540
query14_1	4329	4214	4271	4214
query15	210	206	178	178
query16	964	456	416	416
query17	882	691	543	543
query18	2425	430	320	320
query19	209	163	140	140
query20	84	80	81	80
query21	213	139	111	111
query22	12947	13049	12878	12878
query23	13297	13037	12210	12210
query23_1	12280	12256	12296	12256
query24	7063	874	494	494
query24_1	481	480	488	480
query25	541	442	370	370
query26	1260	270	142	142
query27	2748	438	272	272
query28	4619	1949	1947	1947
query29	1580	609	469	469
query30	294	226	188	188
query31	894	774	678	678
query32	156	101	90	90
query33	510	312	254	254
query34	917	854	518	518
query35	779	785	675	675
query36	805	789	717	717
query37	128	107	95	95
query38	1816	1792	1687	1687
query39	689	692	683	683
query39_1	679	681	682	681
query40	229	117	94	94
query41	69	62	64	62
query42	85	84	81	81
query43	375	385	329	329
query44	1364	723	704	704
query45	183	178	158	158
query46	873	974	580	580
query47	3001	2957	2798	2798
query48	297	310	222	222
query49	568	391	297	297
query50	695	287	216	216
query51	10498	10551	10549	10549
query52	79	79	70	70
query53	192	212	154	154
query54	237	190	194	190
query55	77	71	65	65
query56	223	210	200	200
query57	1596	1589	1559	1559
query58	274	264	248	248
query59	2371	2377	2131	2131
query60	287	235	225	225
query61	149	139	179	139
query62	390	344	285	285
query63	197	166	168	166
query64	2743	956	771	771
query65	3449	3358	3394	3358
query66	1783	415	302	302
query67	20042	20025	19794	19794
query68	2929	1018	618	618
query69	379	289	233	233
query70	906	868	845	845
query71	291	236	218	218
query72	2693	2511	2262	2262
query73	525	550	295	295
query74	4602	4453	4317	4317
query75	2338	2279	1958	1958
query76	2297	1033	628	628
query77	371	417	292	292
query78	9208	9021	8492	8492
query79	988	923	546	546
query80	768	430	345	345
query81	561	319	272	272
query82	732	140	109	109
query83	289	204	186	186
query84	312	129	102	102
query85	953	428	422	422
query86	348	238	230	230
query87	2009	1945	1830	1830
query88	3676	2740	2699	2699
query89	378	298	267	267
query90	1714	185	190	185
query91	161	154	128	128
query92	103	92	89	89
query93	1028	1002	577	577
query94	503	316	293	293
query95	580	419	326	326
query96	676	527	241	241
query97	2480	2400	2344	2344
query98	154	149	146	146
query99	775	763	642	642
Total cold run time: 234662 ms
Total hot run time: 152576 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.10	0.05	0.05
query3	0.27	0.12	0.12
query4	1.61	0.12	0.13
query5	0.27	0.25	0.23
query6	1.17	0.68	0.67
query7	0.03	0.01	0.01
query8	0.05	0.04	0.03
query9	0.41	0.35	0.36
query10	0.58	0.56	0.56
query11	0.20	0.14	0.15
query12	0.19	0.15	0.14
query13	0.50	0.49	0.49
query14	0.97	0.96	0.95
query15	0.64	0.61	0.62
query16	0.31	0.32	0.33
query17	1.14	1.11	1.13
query18	0.22	0.21	0.20
query19	2.11	2.02	2.02
query20	0.02	0.02	0.01
query21	15.50	0.28	0.14
query22	4.40	0.06	0.05
query23	16.30	0.32	0.12
query24	3.13	0.70	0.41
query25	0.10	0.04	0.04
query26	1.36	0.25	0.14
query27	0.05	0.03	0.03
query28	1.89	0.60	0.41
query29	12.50	4.15	3.30
query30	0.28	0.14	0.13
query31	2.76	0.58	0.35
query32	3.23	0.62	0.53
query33	3.21	3.26	3.21
query34	15.41	3.99	3.38
query35	3.31	3.33	3.37
query36	0.56	0.43	0.48
query37	0.09	0.06	0.07
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.17	0.16	0.14
query41	0.09	0.03	0.03
query42	0.03	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 95.29 s
Total hot run time: 24.48 s

@liaoxin01 liaoxin01 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.

LGTM

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 92.86% (13/14) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 92.86% (13/14) 🎉
Increment coverage report
Complete coverage report

@liaoxin01

Copy link
Copy Markdown
Contributor

/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 all six changed files and their relevant FE/BE planning, schema-change, transaction, and test-framework paths at ed917f9. No actionable new findings or existing blocking inline comments were identified. The review converged in round 1: both complete-scope reviewers and the additional risk reviewer returned NO_NEW_VALUABLE_FINDINGS, and all candidates and risk focuses were independently verified and disposed of.

The static evidence supports the fix: regular Stream Load captures response schema metadata within its existing planning read lock; HTTP load_sql copies metadata from the sink initialized under the target-table planning lock. Both avoid the old-index deletion/base-index switch window without another lock acquisition.

Critical checkpoint conclusions:

  1. Goal and proof: the protected reads address the concrete schema-replacement race. Added latch-based unit coverage exercises replacement; HTTP helper coverage verifies planned values remain usable when live base-index metadata is absent. Tests were inspected, not executed.
  2. Scope and clarity: the two production changes are focused metadata relocation/helper extraction, with corresponding unit and regression coverage.
  3. Concurrency: the Stream Load RPC thread's table read lock excludes the schema-change worker's write-locked old-index deletion/base-id switch. HTTP sink finalization captures version and table id under the target read lock. New locked work is constant-time assignment, with no added IO, RPC, lock acquisition, or lock-order change.
  4. Lifecycle: request-local response/fragment state and saved thrift payload have clear ownership. Existing finally blocks release acquired locks on errors; timeout does not unlock an unacquired lock. No new static initialization or resource lifecycle.
  5. Configuration: no new configuration, defaults, or dynamic-update behavior.
  6. Compatibility: existing response fields, public interfaces, and storage formats remain compatible; no new rolling-upgrade dependency.
  7. Thrift/protobuf: no definitions, field IDs, enum values, or required fields change.
  8. Parallel paths: regular/cloud planners, HTTP ordinary and explicit/internal Group Commit, first-table response semantics, and null-response multi-table callers were traced. GroupCommitBlockSink retains its inherited OLAP payload and finalization even with txn=-1. Empty plans fail existing HTTP validation before response extraction.
  9. Conditions: the non-null response and empty-fragment-list guard has concrete no-response/first-table purposes, with direct tests. Failure continues to return non-OK RPC status before BE execution.
  10. Test coverage: positive replacement, timeout, exceptional unlock, first-table and no-response unit cases are present. Regression covers regular/HTTP loads across replacement and addition, plus HTTP sync Group Commit. Actual HTTP Group Commit follows its existing load_sql path and does not encounter the regular light-schema eligibility gate.
  11. Test results: ordered golden rows match repeated same-key MoW upserts and DEFAULT 7 for the added column. The suite drops before use and preserves its table. Actual golden generation and runtime pass were not independently verified.
  12. Observability: existing SQL/query/label/transaction logs and error conversion cover the affected paths; no new operational stage needs metrics.
  13. Transactions, persistence, and failover: transaction index/partial-update capture remains protected; begin, abort, commit, publish, journal, and replay behavior are unchanged. Response metadata adds no persisted state or new failover phase.
  14. Writes, atomicity, and crashes: no new data-write or visibility transition is introduced. Committed/uncommitted visibility, partition-version authority, and MoW delete-bitmap behavior are unaffected. No new BE memory allocation, cleanup duty, leak, or deadlock mechanism was found.
  15. FE-BE passing: existing db/table/schema-version fields are populated on the inspected response paths; HTTP uses the saved sink snapshot. BE Group Commit still matches sink schema version/index count and rejects incompatibility.
  16. Performance: no additional metadata lock, scan, collection allocation, or RPC; the helper reads saved scalar values.
  17. Other issues and user focus: no additional user-provided focus or further actionable defect. No inline duplicates were posted.

Review limits: this was static-only, with no builds or tests. Planner/payload mocks do not establish executed integration or cloud/failover coverage, and the HTTP regression does not deterministically schedule the exact race. Arbitrary multi-fragment HTTP SQL retains a pre-existing one-fragment dispatch limitation; it is not a newly introduced regression or an unresolved changed-code candidate. All six changed files and assigned risks are covered, with no unresolved review coverage gap.

Review converged after 1 round(s).

@Gabriel39
Gabriel39 merged commit ffe5031 into apache:master Oct 15, 2026
45 checks passed
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.

6 participants