Skip to content

[fix](fe) Forward four local exchange session variables to the master - #70197

Merged
morningman merged 1 commit into
apache:masterfrom
morningman:b2m-t04b-forward-local-exchange-vars
Nov 6, 2026
Merged

morningman merged 1 commit into
apache:masterfrom
morningman:b2m-t04b-forward-local-exchange-vars

Conversation

@morningman

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #69273, #70177

Problem Summary:

In short. Found while bringing branch-4.2 #66216 to the FE local shuffle planner (#70177): four session variables that decide the local exchanges of a plan are not forwarded to the master. #69273 made the planner and executor variables travel with a statement that a follower or an observer forwards to the master, enable_local_exchange_before_agg among them, but not enable_local_exchange_before_streaming_agg, enable_streaming_agg_hash_join_force_passthrough, enable_distinct_streaming_agg_force_passthrough and force_to_local_shuffle. A session-level SET of one of them is dropped on that path, and the master plans the statement with its own global value. This PR forwards the four as well.

Background. A statement that has to run on the master FE (INSERT INTO ... SELECT, CREATE TABLE ... AS SELECT, ...) and arrives at a follower or an observer is forwarded: FEOpExecutor sends SessionVariable#getForwardVariables(), and ConnectProcessor on the master applies them with setForwardedSessionVariables() to a session that starts from the master's global variables. Only variables whose @VarAttr sets needForward (or one of the affectQueryResult* attributes) are sent.

The problem, and what it cost. These four do not set it:

Variable Default What it decides
enable_local_exchange_before_streaming_agg (#66222) false whether a streaming pre-aggregation asks for a local hash exchange on its grouping keys: BE StreamingAggOperatorX, and the FE planner with #70177
enable_streaming_agg_hash_join_force_passthrough true whether a streaming pre-aggregation right above a hash join asks for a passthrough local exchange: the FE planner (AggregationNode) and BE StreamingAggOperatorX
enable_distinct_streaming_agg_force_passthrough true the same for a distinct streaming pre-aggregation: the FE planner and BE DistinctStreamingAggOperatorX
force_to_local_shuffle false makes every scan serial (ScanNode#isSerialNode), so the FE planner pools the scan and adds a local shuffle above it

So a session that sets one of them gets that plan only for the statements its own FE runs. A forwarded statement, such as an INSERT INTO ... SELECT or a CTAS issued through a follower or an observer, is planned with the master's global value, and EXPLAIN on the follower shows a plan that the master does not run. Query results stay the same, since these variables only decide how rows move between the pipeline tasks of a BE; what differs is the plan, and with it the speed of the statement.

How this PR fixes it. Set needForward = true on the four, as #69273 does for the others, and add them to the list in SessionVariablesTest#testForwardPlanAndExecutionKnobs.

Results.

Statement forwarded from a follower after SET <variable> = <non-default value> Before After
Value the master plans it with the master's global value the session's value

branch-4.1 and branch-4.2 have the same gap, and #69273 is not on them either.

Release note

The session variables enable_local_exchange_before_streaming_agg, enable_streaming_agg_hash_join_force_passthrough, enable_distinct_streaming_agg_force_passthrough and force_to_local_shuffle now apply to statements that a follower or observer FE forwards to the master, as they do to statements an FE runs itself.

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

    SessionVariablesTest#testForwardPlanAndExecutionKnobs checks that the four are in getForwardVariables(). With SessionVariable.java reverted to master it fails at the first of the four in the list (enable_distinct_streaming_agg_force_passthrough must be forwarded to the master), and no other test fails. The 6 test classes that call getForwardVariables() or setForwardedSessionVariables() pass (89 tests), and fe-core Checkstyle reports nothing. Not run on a cluster with two FEs.

  • Behavior changed:

    • No.
    • Yes.
      A forwarded statement uses the session's value of these four variables instead of the master's global value.
  • 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#69273, apache#70177

Problem Summary: A statement that has to run on the master FE (INSERT
INTO ... SELECT, CTAS, ...) and arrives at a follower or an observer is
forwarded with the session variables that
`SessionVariable#getForwardVariables()` sends, and the master applies
them to a session that starts from its own global variables. Only
variables whose `@VarAttr` sets `needForward` are sent. apache#69273 flagged
the planner and executor variables, `enable_local_exchange_before_agg`
among them, but not four that also decide the local exchanges of a plan:
`enable_local_exchange_before_streaming_agg` (a local hash exchange
before a streaming pre-aggregation, BE `StreamingAggOperatorX` and the
FE planner with apache#70177), `enable_streaming_agg_hash_join_force_passthrough`
and `enable_distinct_streaming_agg_force_passthrough` (a passthrough
local exchange below a streaming pre-aggregation, FE `AggregationNode`
and the BE operators), and `force_to_local_shuffle` (every scan serial,
`ScanNode#isSerialNode`). A session-level SET of one of them was dropped
when the statement was forwarded, so the master planned it with its
global value and EXPLAIN on the follower showed a plan the master did
not run. Results do not change, only the plan and its speed. The four
now set `needForward = true`, as apache#69273 does for the others.

### Release note

The session variables enable_local_exchange_before_streaming_agg,
enable_streaming_agg_hash_join_force_passthrough,
enable_distinct_streaming_agg_force_passthrough and
force_to_local_shuffle now apply to statements that a follower or
observer FE forwards to the master.

### Check List (For Author)

- Test: Unit Test
    - `SessionVariablesTest#testForwardPlanAndExecutionKnobs` lists the
      four; with `SessionVariable.java` reverted it fails. The test
      classes that call `getForwardVariables()` or
      `setForwardedSessionVariables()` pass, and fe-core Checkstyle
      reports nothing. Not run on a cluster with two FEs.
- Behavior changed: Yes. A forwarded statement uses the session's value
  of these four variables instead of the master's global value.
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <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

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17615	5091	5052	5052
q2	2107	339	257	257
q3	10220	1381	796	796
q4	4678	467	352	352
q5	7438	788	530	530
q6	183	182	151	151
q7	737	795	588	588
q8	9244	1362	1046	1046
q9	5444	4179	4146	4146
q10	6814	1284	1036	1036
q11	441	246	225	225
q12	647	409	275	275
q13	18067	3615	3052	3052
q14	266	272	246	246
q15	q16	724	725	654	654
q17	1199	740	565	565
q18	6928	6173	6125	6125
q19	1131	953	603	603
q20	381	331	230	230
q21	5292	2502	2453	2453
q22	405	317	277	277
Total cold run time: 99961 ms
Total hot run time: 28659 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5904	5905	6094	5905
q2	743	609	585	585
q3	5453	5824	5415	5415
q4	2038	2134	1555	1555
q5	5744	5892	5715	5715
q6	235	190	137	137
q7	2198	2019	1799	1799
q8	2969	2616	2657	2616
q9	7985	7775	7460	7460
q10	3618	3549	3144	3144
q11	608	406	372	372
q12	669	662	505	505
q13	3263	3630	3084	3084
q14	283	284	272	272
q15	q16	663	674	615	615
q17	7667	7038	6861	6861
q18	12980	12172	12829	12172
q19	877	767	789	767
q20	2138	2135	1915	1915
q21	5575	4634	4684	4634
q22	480	433	431	431
Total cold run time: 72090 ms
Total hot run time: 65959 ms

@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Selected model is at capacity. Please try a different model.
Workflow run: https://github.com/apache/doris/actions/runs/41802739074

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

@hello-stephen

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

query5	4324	581	440	440
query6	426	213	194	194
query7	4820	450	237	237
query8	326	161	149	149
query9	8760	3175	3098	3098
query10	483	321	246	246
query11	5994	3842	3572	3572
query12	150	97	93	93
query13	1250	442	323	323
query14	6120	3883	3615	3615
query14_1	3389	3401	3396	3396
query15	208	198	181	181
query16	944	476	450	450
query17	857	664	538	538
query18	2427	426	315	315
query19	205	166	142	142
query20	89	98	83	83
query21	206	128	107	107
query22	12985	12947	12747	12747
query23	13470	12846	12532	12532
query23_1	12544	12557	12608	12557
query24	7369	833	472	472
query24_1	496	475	489	475
query25	535	421	357	357
query26	1265	260	143	143
query27	2757	445	272	272
query28	4618	2019	2037	2019
query29	1588	605	457	457
query30	307	225	184	184
query31	1004	926	819	819
query32	154	89	95	89
query33	531	311	247	247
query34	923	856	513	513
query35	742	794	630	630
query36	814	812	732	732
query37	121	91	75	75
query38	1771	1708	1657	1657
query39	806	800	735	735
query39_1	740	726	732	726
query40	218	110	90	90
query41	66	61	63	61
query42	83	87	81	81
query43	346	356	312	312
query44	1342	705	699	699
query45	185	177	164	164
query46	810	972	570	570
query47	2779	2921	2824	2824
query48	287	300	230	230
query49	568	392	292	292
query50	681	274	219	219
query51	10693	10771	10749	10749
query52	76	82	68	68
query53	183	214	156	156
query54	260	210	189	189
query55	76	67	63	63
query56	219	215	202	202
query57	1693	1627	1585	1585
query58	276	263	248	248
query59	2217	2193	2007	2007
query60	278	246	219	219
query61	148	147	146	146
query62	399	332	290	290
query63	191	153	155	153
query64	2769	969	769	769
query65	3332	3252	3264	3252
query66	1819	422	298	298
query67	20667	20225	19972	19972
query68	3276	1017	616	616
query69	401	287	250	250
query70	833	768	759	759
query71	297	234	199	199
query72	2811	2784	2281	2281
query73	535	518	302	302
query74	4645	4522	4337	4337
query75	2344	2287	1894	1894
query76	2409	1007	600	600
query77	356	370	281	281
query78	9886	9672	9203	9203
query79	1003	888	528	528
query80	736	405	347	347
query81	564	318	279	279
query82	578	132	105	105
query83	308	198	180	180
query84	311	131	99	99
query85	865	421	361	361
query86	356	241	230	230
query87	1996	1942	1805	1805
query88	3737	2758	2746	2746
query89	334	274	242	242
query90	1787	166	164	164
query91	160	163	130	130
query92	103	90	87	87
query93	996	1005	572	572
query94	514	306	271	271
query95	565	390	303	303
query96	674	483	243	243
query97	2465	2472	2335	2335
query98	159	152	146	146
query99	767	764	658	658
Total cold run time: 235834 ms
Total hot run time: 151502 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.09	0.05	0.05
query3	0.26	0.09	0.09
query4	1.60	0.10	0.11
query5	0.23	0.24	0.24
query6	1.17	0.68	0.66
query7	0.04	0.00	0.00
query8	0.05	0.04	0.04
query9	0.41	0.36	0.33
query10	0.60	0.56	0.58
query11	0.21	0.14	0.15
query12	0.19	0.14	0.15
query13	0.50	0.50	0.50
query14	1.03	1.00	1.04
query15	0.62	0.60	0.62
query16	0.35	0.36	0.34
query17	1.17	1.17	1.09
query18	0.19	0.20	0.19
query19	2.10	1.90	2.03
query20	0.02	0.02	0.01
query21	15.48	0.19	0.14
query22	4.84	0.06	0.05
query23	16.29	0.31	0.12
query24	2.79	0.50	0.43
query25	0.13	0.04	0.05
query26	1.49	0.22	0.16
query27	0.05	0.05	0.05
query28	3.26	0.78	0.36
query29	12.50	4.10	3.30
query30	0.28	0.13	0.10
query31	2.78	0.57	0.32
query32	3.22	0.61	0.50
query33	3.15	3.24	3.31
query34	15.35	3.98	3.39
query35	3.33	3.35	3.34
query36	0.56	0.44	0.44
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.15	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.02
query43	0.05	0.03	0.04
Total cold run time: 96.88 s
Total hot run time: 24.32 s

@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 70197 at head 097b15b found no verified new findings. The four needForward annotations consistently add the existing FE statement forwarding path: getForwardVariables() sends them in TMasterOpRequest, proxy execution applies them to a fresh context, and the three aggregation values continue to flow through the existing TQueryOptions assignments. force_to_local_shuffle is an FE planner control consumed by ScanNode and now survives follower-to-master planning. Rolling-version handling remains compatible because forwarded values are looked up only for fields known by the receiving FE. The added test constants cover all four forwarding keys in the existing forwarding-map check. No existing P0/P1 inline finding applies, and there were no prior inline threads. FE Core checkpoints are unaffected: the patch changes no locking, exception/RPC boundary, or visible-version logic. The review focus file contains no additional user focus. No builds or tests were executed; this was a static review as required. Convergence is false because the dedicated risk-focused child review could not start: the original child and all replacement attempts returned model-capacity errors before writing results. Main-agent rechecks covered that risk scope, but the delegated convergence condition was not met within the three-round bound.

Review did not converge after 3 rounds. This automated review cannot pass the review check.

The dedicated risk-focused subagent required for strict convergence was unavailable: the original and replacement child attempts all failed with model-capacity errors before producing ledger results. Main-agent verification found no candidate, and the complete-file reviewer found no candidate, but delegated convergence could not be proven by round 3.

@morningman

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Selected model is at capacity. Please try a different model.
Workflow run: https://github.com/apache/doris/actions/runs/41986371354

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

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

Reviewed apache/doris PR 70197 at the verified exact head 097b15b against base 0eb5131. The patch adds needForward=true to enable_streaming_agg_hash_join_force_passthrough, enable_local_exchange_before_streaming_agg, enable_distinct_streaming_agg_force_passthrough, and force_to_local_shuffle, and adds all four names to SessionVariablesTest.

The forwarding path was traced from SessionVariable.getForwardVariables() through FEOpExecutor.buildStmtForwardParams() and ConnectProcessor.proxyExecute() into the master session. The three aggregation/local-exchange flags already populate TQueryOptions and have matching BE RuntimeState consumers; force_to_local_shuffle affects ScanNode.isSerialNode(), and its enableLocalShuffle and enableNereidsPlanner companion inputs are already forwarded. Private-field reflection and mixed-version name-map handling are safe. No accepted, duplicate, or unresolved findings remain, and there are no existing inline review threads or P0/P1 findings to carry forward.

Critical review checkpoints: the change is focused and meets its stated forwarding goal; no new concurrency, lifecycle, persistence, security, Thrift/Protobuf, or FE-BE schema behavior is introduced; direct and forwarded statement paths were inspected; the annotation-driven unit-test coverage was inspected. This was a static review under the contract, so no build or runtime tests were executed. The user focus file contains no additional focus points. Both independent review passes returned NO_NEW_VALUABLE_FINDINGS, so this review converged in round 1.

Review converged after 1 round(s).

@morningman
morningman merged commit c79dc9c into apache:master Nov 6, 2026
37 of 38 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.

3 participants