Skip to content

[feature](executor) Add the time-sharing executor framework and use it in the scanner section. - #51690

Merged
morningman merged 8 commits into
apache:masterfrom
kaka11chen:time_sharing_executor_master
Jul 20, 2025
Merged

morningman merged 8 commits into
apache:masterfrom
kaka11chen:time_sharing_executor_master

Conversation

@kaka11chen

@kaka11chen kaka11chen commented Jun 12, 2025 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Problem Summary:

When concurrent large queries occupy all resources, small queries become hungry and run very slowly.

Release note

In order to solve the problem that when concurrent large queries occupy all resources, small queries become hungry and run very slowly.

A dynamic multi-level priority scheduling is introduced.

  1. The time-sharing executor framework is implemented. Source code in be/src/vec/exec/executor and be/src/vec/exec/executor/time_sharing

  2. Currently, this mechanism is used in the scanner, and will be used in the computing layer in the future. Time-sharing executor framework framework currently have options for automatic scheduling and concurrency control. Since the current implementation of the scanning part relies on manual scheduling and already has the ability of concurrency control, the automatic scheduling and concurrency control of the framework should be turned off when integrating the scanning part. Also keep the original implementation of scanner scheduler. Controlled by enable_task_executor_in_internal_table and enable_task_executor_in_external_table .

  3. A task executor simulator is introduced。By controlling the total number of tasks, the number of concurrency, the number of splits of each task, and the splits generated by different generators of splits (Leaf and Intermediate) (for example, different rates, different waiting times, etc.), we can simulate scenarios and observe relevant performance indicators. In order to compare with the scenario before the code was modified, a test fifo queue was introduced to compare with the current multi-level priority queue.

    • Source code in be/src/vec/exec/executor/simulator.
    • Command: run-task-executor-simulator.sh task_executor_simulator/conf/experiment_starve_slow_splits.json

Task Executor Simulator Performance Results

A system is constructed that first generates many slow splits to simulate the situation of concurrent large queries, and then executes fast splits to simulate the situation of small queries.
task_executor_simulator/conf/experiment_starve_slow_splits.json

From the results, the multi-level priority queue is the first-in-first-out queue in terms of the task completion rate of fast leaf, while the task completion rates of the middle and slow leaf are not as good as the first-in-first-out queue.

Multi-level Priority Queue

Fast Leaf
Completed tasks           : 4338
In-progress tasks         : 40
Intermediate
Completed tasks           : 220
In-progress tasks         : 40
Slow Leaf
Completed tasks           : 81
In-progress tasks         : 40

FIFO Queue

Fast Leaf
Completed tasks           : 1644
In-progress tasks         : 40
Intermediate
Completed tasks           : 316
In-progress tasks         : 40
Slow Leaf
Completed tasks           : 285
In-progress tasks         : 40

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.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

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

@hello-stephen

Copy link
Copy Markdown
Contributor

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

Please clearly describe your PR:

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

@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from a41436a to 36e6551 Compare June 12, 2025 16:18
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

1 similar comment
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch 2 times, most recently from 05fa082 to ace919d Compare June 13, 2025 07:41
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from ace919d to 7dbf1d1 Compare June 13, 2025 09:05
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 7dbf1d1 to 0a21731 Compare June 13, 2025 11:49
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 0a21731 to 6898e1b Compare June 14, 2025 12:48
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 6898e1b to cfb5444 Compare June 15, 2025 03:24
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from cfb5444 to b98871e Compare June 16, 2025 05:46
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from b98871e to 0ec00f6 Compare June 16, 2025 14:21
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 0ec00f6 to 8f8daca Compare June 17, 2025 15:46
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

Copy link
Copy Markdown

BE UT Coverage Report

Increment line coverage 63.23% (657/1039) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.24% (15113/26873)
Line Coverage 45.09% (135003/299415)
Region Coverage 44.19% (67781/153386)
Branch Coverage 38.78% (34765/89636)

@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

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

------ Round 1 ----------------------------------
q1	17604	5452	5157	5157
q2	1958	288	196	196
q3	10354	1226	748	748
q4	10240	950	522	522
q5	7513	2385	2159	2159
q6	188	167	134	134
q7	917	764	617	617
q8	9244	1373	1251	1251
q9	7190	5230	5258	5230
q10	6894	2415	1965	1965
q11	478	298	279	279
q12	356	349	223	223
q13	17820	3688	3073	3073
q14	228	224	205	205
q15	567	484	480	480
q16	430	444	371	371
q17	627	856	356	356
q18	7595	7071	7124	7071
q19	1884	959	549	549
q20	338	344	240	240
q21	4099	2599	2443	2443
q22	1085	1030	971	971
Total cold run time: 107609 ms
Total hot run time: 34240 ms

----- Round 2, with runtime_filter_mode=off -----
q1	5074	4988	5025	4988
q2	263	338	232	232
q3	2205	2608	2294	2294
q4	1361	1751	1332	1332
q5	4265	4823	4783	4783
q6	201	165	131	131
q7	2084	2032	1870	1870
q8	2514	2850	2625	2625
q9	7310	7204	7438	7204
q10	3093	3294	2880	2880
q11	569	508	506	506
q12	720	783	624	624
q13	3563	3889	3144	3144
q14	275	290	267	267
q15	507	468	466	466
q16	424	465	421	421
q17	1176	1683	1211	1211
q18	7428	7112	7105	7105
q19	807	989	1079	989
q20	1918	2052	1875	1875
q21	4772	4181	4330	4181
q22	1102	1052	997	997
Total cold run time: 51631 ms
Total hot run time: 50125 ms

@doris-robot

Copy link
Copy Markdown
TPC-DS: Total hot run time: 187422 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 4942541c79945f55fcdd86eb1bdfe6554f6222fd, data reload: false

query1	985	386	412	386
query2	6550	2037	1892	1892
query3	6750	226	231	226
query4	27743	23709	23440	23440
query5	4897	620	460	460
query6	307	226	219	219
query7	4628	489	294	294
query8	286	227	221	221
query9	8603	2673	2697	2673
query10	511	366	287	287
query11	17461	15073	14789	14789
query12	174	113	112	112
query13	1651	561	447	447
query14	10230	6365	6507	6365
query15	256	195	197	195
query16	7896	637	492	492
query17	1597	742	604	604
query18	2115	414	311	311
query19	279	208	171	171
query20	126	119	122	119
query21	220	133	114	114
query22	4019	4152	4114	4114
query23	34063	33197	33315	33197
query24	7826	2235	2208	2208
query25	530	477	413	413
query26	1188	282	161	161
query27	2698	507	358	358
query28	4542	2187	2142	2142
query29	713	576	444	444
query30	294	223	202	202
query31	922	858	749	749
query32	79	88	68	68
query33	510	380	315	315
query34	755	880	547	547
query35	822	862	738	738
query36	987	1042	957	957
query37	116	101	85	85
query38	4133	4064	4190	4064
query39	1450	1412	1429	1412
query40	217	130	116	116
query41	65	66	74	66
query42	140	126	116	116
query43	524	544	507	507
query44	1372	881	869	869
query45	182	175	177	175
query46	844	1013	639	639
query47	1759	1787	1717	1717
query48	421	421	323	323
query49	764	478	380	380
query50	648	663	425	425
query51	4179	4140	4136	4136
query52	112	113	107	107
query53	237	274	187	187
query54	593	591	518	518
query55	94	90	89	89
query56	317	323	299	299
query57	1179	1218	1133	1133
query58	278	279	274	274
query59	2719	2752	2605	2605
query60	342	328	346	328
query61	141	143	129	129
query62	771	713	697	697
query63	244	197	197	197
query64	4371	1015	698	698
query65	4272	4202	4212	4202
query66	1076	416	327	327
query67	15716	15443	15265	15265
query68	8717	908	605	605
query69	473	335	284	284
query70	1247	1151	1130	1130
query71	470	334	299	299
query72	5802	5191	4957	4957
query73	694	766	378	378
query74	9307	9058	8652	8652
query75	4377	3112	2785	2785
query76	3749	1173	755	755
query77	782	377	299	299
query78	10096	10347	9487	9487
query79	4540	796	579	579
query80	718	576	465	465
query81	491	266	236	236
query82	594	130	106	106
query83	296	266	248	248
query84	296	107	102	102
query85	795	355	361	355
query86	364	317	284	284
query87	4504	4452	4280	4280
query88	3900	2321	2315	2315
query89	450	326	294	294
query90	1960	219	220	219
query91	151	147	116	116
query92	78	68	61	61
query93	3068	930	594	594
query94	676	399	314	314
query95	378	306	302	302
query96	515	610	305	305
query97	2744	2714	2639	2639
query98	243	214	205	205
query99	1523	1346	1257	1257
Total cold run time: 286487 ms
Total hot run time: 187422 ms

@doris-robot

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

query1	0.03	0.03	0.03
query2	0.08	0.03	0.04
query3	0.23	0.08	0.08
query4	1.60	0.10	0.10
query5	0.43	0.41	0.43
query6	1.19	0.66	0.66
query7	0.02	0.02	0.01
query8	0.05	0.03	0.04
query9	0.58	0.51	0.52
query10	0.55	0.56	0.57
query11	0.17	0.11	0.12
query12	0.15	0.11	0.11
query13	0.63	0.60	0.62
query14	0.80	0.82	0.82
query15	0.89	0.84	0.84
query16	0.38	0.38	0.42
query17	1.12	1.06	1.06
query18	0.26	0.23	0.22
query19	1.95	1.93	1.88
query20	0.02	0.02	0.01
query21	15.46	0.95	0.56
query22	0.74	0.87	0.66
query23	15.23	1.39	0.56
query24	3.72	2.43	1.77
query25	0.28	0.40	0.14
query26	0.25	0.14	0.14
query27	0.07	0.05	0.04
query28	14.04	0.96	0.44
query29	12.59	4.03	3.33
query30	0.25	0.10	0.07
query31	2.83	0.63	0.41
query32	3.22	0.56	0.46
query33	3.10	3.10	3.13
query34	15.95	5.51	4.84
query35	4.83	4.80	4.87
query36	0.67	0.53	0.51
query37	0.10	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.02	0.02
query40	0.18	0.13	0.13
query41	0.08	0.02	0.02
query42	0.04	0.02	0.03
query43	0.03	0.03	0.03
Total cold run time: 104.88 s
Total hot run time: 30.6 s

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 4942541 to 82a3076 Compare June 20, 2025 16:54
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 57.17% (654/1144) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.36% (15152/26882)
Line Coverage 45.24% (135521/299581)
Region Coverage 44.34% (68004/153361)
Branch Coverage 38.98% (34923/89596)

@kaka11chen

Copy link
Copy Markdown
Contributor Author

simulator should be placed to tools dir

ok

@kaka11chen
kaka11chen force-pushed the time_sharing_executor_master branch from 4ee29a5 to d752709 Compare July 19, 2025 13:21
@kaka11chen

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

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

------ Round 1 ----------------------------------
q1	17589	5225	5122	5122
q2	1945	297	195	195
q3	10468	1386	706	706
q4	10273	1022	522	522
q5	8116	2405	2653	2405
q6	200	170	139	139
q7	931	787	623	623
q8	9334	1347	1122	1122
q9	7086	5221	5216	5216
q10	6969	2418	1957	1957
q11	512	313	293	293
q12	370	370	234	234
q13	17784	3726	3088	3088
q14	242	267	232	232
q15	598	536	523	523
q16	449	449	400	400
q17	595	877	378	378
q18	7515	7204	7179	7179
q19	1390	985	611	611
q20	343	362	240	240
q21	4157	2576	2361	2361
q22	1049	1083	1017	1017
Total cold run time: 107915 ms
Total hot run time: 34563 ms

----- Round 2, with runtime_filter_mode=off -----
q1	5182	5104	5162	5104
q2	273	369	248	248
q3	2207	2670	2322	2322
q4	1330	1840	1357	1357
q5	4414	4431	4402	4402
q6	217	184	136	136
q7	2050	1942	1864	1864
q8	2668	2565	2723	2565
q9	7361	7316	7229	7229
q10	3205	3362	2853	2853
q11	581	543	502	502
q12	678	778	622	622
q13	3616	4016	3345	3345
q14	297	324	294	294
q15	551	519	513	513
q16	459	494	455	455
q17	1191	1879	1412	1412
q18	7959	7700	7713	7700
q19	834	823	962	823
q20	2030	2079	2028	2028
q21	5178	4753	4473	4473
q22	1095	1062	1030	1030
Total cold run time: 53376 ms
Total hot run time: 51277 ms

@doris-robot

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

query1	1041	393	444	393
query2	6567	1738	1730	1730
query3	6749	231	226	226
query4	26673	23599	23269	23269
query5	4480	729	585	585
query6	345	247	236	236
query7	4644	522	312	312
query8	370	300	298	298
query9	8595	2893	2894	2893
query10	495	361	331	331
query11	16050	15058	14911	14911
query12	172	127	126	126
query13	1667	559	422	422
query14	8812	6177	6107	6107
query15	234	224	176	176
query16	7508	678	470	470
query17	1245	757	649	649
query18	2051	461	410	410
query19	199	194	180	180
query20	145	132	135	132
query21	239	143	128	128
query22	4422	4334	4285	4285
query23	34748	33445	33451	33445
query24	8161	2434	2424	2424
query25	554	497	425	425
query26	1243	280	167	167
query27	2719	526	352	352
query28	4399	2225	2201	2201
query29	795	592	466	466
query30	303	238	206	206
query31	953	879	827	827
query32	99	89	87	87
query33	588	399	364	364
query34	809	859	540	540
query35	845	853	750	750
query36	999	1015	942	942
query37	130	112	100	100
query38	4189	4223	4124	4124
query39	1544	1517	1472	1472
query40	235	163	137	137
query41	107	102	105	102
query42	132	122	124	122
query43	535	544	490	490
query44	1349	873	885	873
query45	199	194	176	176
query46	839	1023	655	655
query47	1838	1883	1757	1757
query48	423	446	338	338
query49	806	580	490	490
query50	679	714	424	424
query51	5633	5438	5472	5438
query52	129	121	120	120
query53	256	290	211	211
query54	628	623	558	558
query55	98	97	93	93
query56	349	359	339	339
query57	1252	1255	1183	1183
query58	328	324	318	318
query59	2736	2682	2599	2599
query60	382	372	357	357
query61	151	153	176	153
query62	842	756	676	676
query63	248	219	217	217
query64	4361	1058	752	752
query65	4295	4251	4213	4213
query66	1354	589	571	571
query67	15984	15821	15558	15558
query68	7918	906	554	554
query69	508	348	310	310
query70	1285	1153	1167	1153
query71	479	366	333	333
query72	5677	4761	4797	4761
query73	722	631	375	375
query74	9213	9020	9072	9020
query75	3939	3179	2692	2692
query76	3654	1158	738	738
query77	856	448	388	388
query78	10023	10167	9392	9392
query79	2662	817	617	617
query80	773	585	524	524
query81	512	283	248	248
query82	470	144	120	120
query83	281	348	260	260
query84	261	111	96	96
query85	828	421	353	353
query86	417	321	330	321
query87	4446	4488	4299	4299
query88	3655	2455	2344	2344
query89	424	347	309	309
query90	1845	243	238	238
query91	159	155	123	123
query92	96	83	80	80
query93	2085	940	594	594
query94	691	424	317	317
query95	407	333	338	333
query96	504	593	291	291
query97	2737	2828	2639	2639
query98	261	231	234	231
query99	1688	1438	1314	1314
Total cold run time: 281425 ms
Total hot run time: 191448 ms

@doris-robot

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

query1	0.04	0.03	0.03
query2	0.08	0.04	0.05
query3	0.24	0.07	0.07
query4	1.62	0.11	0.11
query5	0.44	0.41	0.42
query6	1.16	0.66	0.69
query7	0.03	0.03	0.02
query8	0.05	0.04	0.04
query9	0.60	0.53	0.52
query10	0.59	0.58	0.58
query11	0.17	0.11	0.11
query12	0.15	0.13	0.12
query13	0.63	0.61	0.61
query14	0.83	0.82	0.82
query15	0.90	0.86	0.87
query16	0.38	0.38	0.39
query17	1.06	1.04	1.05
query18	0.23	0.22	0.22
query19	2.00	1.87	1.92
query20	0.02	0.01	0.01
query21	15.40	0.90	0.54
query22	0.77	1.26	0.79
query23	14.76	1.39	0.64
query24	7.10	0.85	0.52
query25	0.47	0.22	0.09
query26	0.61	0.18	0.13
query27	0.09	0.06	0.06
query28	9.11	1.00	0.46
query29	12.56	3.90	3.28
query30	3.19	3.07	3.08
query31	2.82	0.60	0.38
query32	3.24	0.56	0.48
query33	3.20	3.15	3.10
query34	15.98	5.43	4.82
query35	4.83	4.92	4.91
query36	0.71	0.52	0.50
query37	0.09	0.08	0.07
query38	0.06	0.05	0.05
query39	0.04	0.03	0.02
query40	0.18	0.16	0.16
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.03	0.04
Total cold run time: 106.6 s
Total hot run time: 32.68 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 57.10% (897/1571) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 57.41% (15879/27658)
Line Coverage 46.23% (142639/308559)
Region Coverage 35.72% (107454/300841)
Branch Coverage 38.21% (47407/124062)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 75.61% (1181/1562) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 81.02% (21991/27142)
Line Coverage 73.67% (226984/308093)
Region Coverage 61.25% (189012/308570)
Branch Coverage 65.05% (81608/125454)

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 20, 2025
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

PR approved by anyone and no changes requested.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 75.61% (1181/1562) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 81.02% (21991/27142)
Line Coverage 73.67% (226984/308093)
Region Coverage 61.25% (189012/308570)
Branch Coverage 65.05% (81608/125454)

@morningman
morningman merged commit b408144 into apache:master Jul 20, 2025
airborne12 pushed a commit that referenced this pull request Aug 18, 2025
…cs with other thread pool (#54910)

Related PR: #51690

TimeSharingTaskExecutor is using a individual metrics name called
`doris_be_split_thread_pool_xxxx`, this is miss leading.

TimeSharingTaskExecutor is actually a specialized ThreadPool, which uses
a time_sharing queuing policy. We want to use `doris_be_thread_pool_xxx`
to record its metrics.
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 9, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed one scheduling gap between
the two admission paths. apache#65814 stops the TaskExecutor path
(`ScannerContext::_pull_next_scan_task`) from submitting pending scanners
once the shared scan LIMIT is exhausted while a completed or in-flight task
can still wake the operator. The thread pool admission rewritten in apache#67070
(`ScannerContext::can_admit_scan_task`) does not apply this rule, so for a
`SELECT ... LIMIT n` over many tablets every remaining pending scanner would
still be admitted and run `prepare()`/`open()` (tablet reader init) only to
report EOS right away. The same rule is now applied in
`can_admit_scan_task`, including the existing escape that admits one pending
scanner when nothing else can wake the pipeline task.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans) and
      `ScannerContextTest.thread_pool_admission_stops_after_shared_limit`
      (fails without the admission fix); ran `WorkloadGroupManagerTest.*`,
      `ScannerContextTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 9, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed one scheduling gap between
the two admission paths. apache#65814 stops the TaskExecutor path
(`ScannerContext::_pull_next_scan_task`) from submitting pending scanners
once the shared scan LIMIT is exhausted while a completed or in-flight task
can still wake the operator. The thread pool admission rewritten in apache#67070
(`ScannerContext::can_admit_scan_task`) does not apply this rule, so for a
`SELECT ... LIMIT n` over many tablets every remaining pending scanner would
still be admitted and run `prepare()`/`open()` (tablet reader init) only to
report EOS right away. The same rule is now applied in
`can_admit_scan_task`, including the existing escape that admits one pending
scanner when nothing else can wake the pipeline task.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans) and
      `ScannerContextTest.thread_pool_admission_stops_after_shared_limit`
      (fails without the admission fix); ran `WorkloadGroupManagerTest.*`,
      `ScannerContextTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 9, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed one scheduling gap between
the two admission paths. apache#65814 stops the TaskExecutor path
(`ScannerContext::_pull_next_scan_task`) from submitting pending scanners
once the shared scan LIMIT is exhausted while a completed or in-flight task
can still wake the operator. The thread pool admission rewritten in apache#67070
(`ScannerContext::can_admit_scan_task`) does not apply this rule, so for a
`SELECT ... LIMIT n` over many tablets every remaining pending scanner would
still be admitted and run `prepare()`/`open()` (tablet reader init) only to
report EOS right away. The same rule is now applied in
`can_admit_scan_task`, including the existing escape that admits one pending
scanner when nothing else can wake the pipeline task.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans) and
      `ScannerContextTest.thread_pool_admission_stops_after_shared_limit`
      (fails without the admission fix); ran `WorkloadGroupManagerTest.*`,
      `ScannerContextTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 9, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed one scheduling gap between
the two admission paths. apache#65814 stops the TaskExecutor path
(`ScannerContext::_pull_next_scan_task`) from submitting pending scanners
once the shared scan LIMIT is exhausted while a completed or in-flight task
can still wake the operator. The thread pool admission rewritten in apache#67070
(`ScannerContext::can_admit_scan_task`) does not apply this rule, so for a
`SELECT ... LIMIT n` over many tablets every remaining pending scanner would
still be admitted and run `prepare()`/`open()` (tablet reader init) only to
report EOS right away. The same rule is now applied in
`can_admit_scan_task`, including the existing escape that admits one pending
scanner when nothing else can wake the pipeline task.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans) and
      `ScannerContextTest.thread_pool_admission_stops_after_shared_limit`
      (fails without the admission fix); ran `WorkloadGroupManagerTest.*`,
      `ScannerContextTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 9, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed one scheduling gap between
the two admission paths. apache#65814 stops the TaskExecutor path
(`ScannerContext::_pull_next_scan_task`) from submitting pending scanners
once the shared scan LIMIT is exhausted while a completed or in-flight task
can still wake the operator. The thread pool admission rewritten in apache#67070
(`ScannerContext::can_admit_scan_task`) does not apply this rule, so for a
`SELECT ... LIMIT n` over many tablets every remaining pending scanner would
still be admitted and run `prepare()`/`open()` (tablet reader init) only to
report EOS right away. The same rule is now applied in
`can_admit_scan_task`, including the existing escape that admits one pending
scanner when nothing else can wake the pipeline task.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans) and
      `ScannerContextTest.thread_pool_admission_stops_after_shared_limit`
      (fails without the admission fix); ran `WorkloadGroupManagerTest.*`,
      `ScannerContextTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 14, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

With the thread pool path as the default, a `SELECT ... LIMIT n` over many
tablets keeps admitting its remaining pending scanners after peer scanners
have exhausted the shared scan LIMIT (`ScannerContext::can_admit_scan_task`,
rewritten in apache#67070, only applies the concurrency limit). Admission is kept
that way on purpose: holding pending scanners back based on the in-flight or
completed task counters, as apache#65814 does on the TaskExecutor path, ties the
schedule to bookkeeping that is easy to get wrong and can leave a context
with nothing to wake the operator. Instead, `Scanner::get_block_after_projects()`
now checks the shared LIMIT before it reads: once the counter is exhausted,
the scanner returns an empty block with EOS, so an admitted scanner never
reads its range for rows the operator will cut anyway.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans),
      `ScannerContextTest.thread_pool_admission_ignores_shared_limit`
      (a pending scanner is still admitted after the shared LIMIT is
      exhausted while tasks are in flight or completed) and
      `ScannerProjectionTest.shared_limit_exhausted_before_call_reports_eos_without_reading`
      (the admitted scanner reports EOS with an empty block without reading);
      ran `WorkloadGroupManagerTest.*`, `ScannerContextTest.*`,
      `ScannerProjectionTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 14, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

With the thread pool path as the default, a `SELECT ... LIMIT n` over many
tablets keeps admitting its remaining pending scanners after peer scanners
have exhausted the shared scan LIMIT (`ScannerContext::can_admit_scan_task`,
rewritten in apache#67070, only applies the concurrency limit). Admission is kept
that way on purpose: holding pending scanners back based on the in-flight or
completed task counters, as apache#65814 does on the TaskExecutor path, ties the
schedule to bookkeeping that is easy to get wrong and can leave a context
with nothing to wake the operator. Instead, `Scanner::get_block_after_projects()`
now checks the shared LIMIT before it reads: once the counter is exhausted,
the scanner returns an empty block with EOS, so an admitted scanner never
reads its range for rows the operator will cut anyway.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans),
      `ScannerContextTest.thread_pool_admission_ignores_shared_limit`
      (a pending scanner is still admitted after the shared LIMIT is
      exhausted while tasks are in flight or completed) and
      `ScannerProjectionTest.shared_limit_exhausted_before_call_reports_eos_without_reading`
      (the admitted scanner reports EOS with an empty block without reading);
      ran `WorkloadGroupManagerTest.*`, `ScannerContextTest.*`,
      `ScannerProjectionTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit to mrhhsg/doris that referenced this pull request Oct 15, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#51690, apache#58144, apache#58273, apache#65814, apache#67070

Problem Summary: Workload groups pick the scan scheduler for internal and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor) for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is still
maturing (for example the self-deadlock fixed in apache#58273; the internal-table
default was already reverted once in apache#58144), so the default should be the
`ThreadPoolSimplifiedScanScheduler` for both internal and external tables.

This change sets both configs' default values to `false`. The task executor
can still be enabled explicitly through `be.conf`.

With the thread pool path as the default, a `SELECT ... LIMIT n` over many
tablets keeps admitting its remaining pending scanners after peer scanners
have exhausted the shared scan LIMIT (`ScannerContext::can_admit_scan_task`,
rewritten in apache#67070, only applies the concurrency limit). Admission is kept
that way on purpose: holding pending scanners back based on the in-flight or
completed task counters, as apache#65814 does on the TaskExecutor path, ties the
schedule to bookkeeping that is easy to get wrong and can leave a context
with nothing to wake the operator. Instead, `Scanner::get_block_after_projects()`
now checks the shared LIMIT before it reads: once the counter is exhausted,
the scanner returns an empty block with EOS, so an admitted scanner never
reads its range for rows the operator will cut anyway.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`; internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
    - Unit Test: added `WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`
      (registered defaults are `false` and the workload group creates
      thread pool schedulers for local and remote scans),
      `ScannerContextTest.thread_pool_admission_ignores_shared_limit`
      (a pending scanner is still admitted after the shared LIMIT is
      exhausted while tasks are in flight or completed) and
      `ScannerProjectionTest.shared_limit_exhausted_before_call_reports_eos_without_reading`
      (the admitted scanner reports EOS with an empty block without reading);
      ran `WorkloadGroupManagerTest.*`, `ScannerContextTest.*`,
      `ScannerProjectionTest.*` and other scanner/scheduler/task-executor UTs
    - Regression test: ran existing suites on a local cluster with the new
      default: correctness_p0/test_shared_scan_limit_pending_tasks,
      query_p0 limit pushdown suites, query_p0/scan_range, and stream load
      CSV suites
- Behavior changed: Yes (default scan scheduler for internal and external
  table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
mrhhsg added a commit that referenced this pull request Oct 19, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: #51690, #58144, #58273, #65814, #67070

Problem Summary: Workload groups pick the scan scheduler for internal
and
external table scans from `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table`. Both configs currently default
to
`true` on master, so every workload group creates
`TaskExecutorSimplifiedScanScheduler` (the time-sharing task executor)
for
local (`ls_*`) and remote (`rs_*`) scans. The time-sharing executor is
still
maturing (for example the self-deadlock fixed in #58273; the
internal-table
default was already reverted once in #58144), so the default should be
the
`ThreadPoolSimplifiedScanScheduler` for both internal and external
tables.

This change sets both configs' default values to `false`. The task
executor
can still be enabled explicitly through `be.conf`.

Making the thread pool path the default exposed four gaps.

1. Pending scanners after an exhausted shared LIMIT. For a `SELECT ...
LIMIT n`
over many tablets, the thread pool admission
(`ScannerContext::can_admit_scan_task`,
rewritten in #67070) keeps admitting the remaining pending scanners
after peer
scanners have exhausted the shared scan LIMIT. Admission is kept that
way on
purpose: holding pending scanners back based on the in-flight or
completed
task counters, as #65814 does on the TaskExecutor path, ties the
schedule to
bookkeeping that is easy to get wrong and can leave a context with
nothing to
wake the operator. Instead, `Scanner::get_block_after_projects()` now
checks
the shared LIMIT before it reads: once the counter is exhausted, the
scanner
returns an empty block, so an admitted scanner never reads its range for
rows
the operator will cut anyway. It does not report EOS for that: EOS means
the
underlying read is exhausted, while the LIMIT is applied by the scan
operator,
which stops the scanners after `reached_limit()`;
`ScannerContext::get_block_from_queue()` also finishes the context once
the
counter is exhausted with nothing in flight. The two pre-existing checks
in
`Scanner::get_block()` that set `eof` from the shared counter are
removed for
the same reason, so the shared LIMIT is handled in one place.

2. Rows held in scanner padding under a shared LIMIT.
`Scanner::get_block()`
charges the shared LIMIT counter as soon as rows pass the filters, but
with
projections `get_block_after_projects()` may keep a small block in
`_padding_block` and emit a later block first. Once peer scanners
exhaust the
counter, the context reaches EOS without running that scanner again, and
the
charged rows it holds are lost; for example, a parallel projected
`LIMIT 4096` could return 4086 rows. The counter is now decremented only
by
the rows a call actually returns, so held padding is never charged and
the
counter equals "LIMIT minus returned rows" between calls. The padding
batch
target is capped by the remaining LIMIT when a call starts, so a scanner
does
not read on just to fill half a batch when fewer rows are needed, and
the
read loop stops as soon as peers exhaust the LIMIT, returning the rows
it
already holds. Projected scans with selective filters keep coalescing
small
blocks. The scan does not cap its output at the LIMIT (the operator cuts
extra rows), so no further accounting is needed.

3. Exceptions in the row-ID fetch RPC callback. `multiget_data_v2`
submits
its callback to the remote scan scheduler; on a `ThreadPool` worker
there is
no exception boundary, and `RowIdStorageReader::read_by_rowids()`
constructs
`SlotDescriptor(pslot)` before its local `try`, so an unknown
`PTypeNode.type` would throw `doris::Exception` and terminate the BE.
The
callback now calls `RowIdStorageReader::read_by_rowids_for_rpc()`, which
converts a thrown exception into an error status on the response before
the
closure completes the RPC. `ExecEnv::set_id_manager()` is added under
`BE_TEST` for the unit test.

4. The shared LIMIT pointer of a scanner initialized while the counter
is
negative. `ScanLocalState::shared_scan_limit_ptr()` returned null
whenever
the live counter was negative, and `Scanner::init()` caches that pointer
once. Concurrent scanners can return more than the LIMIT before the
operator
makes its final cut, leaving the counter negative, so a scanner whose
local
state opened at that moment never checked or charged the shared LIMIT
and
could read a long selective tail after peers had satisfied the query.
The pointer is now returned whenever the operator has a SQL LIMIT, which
is
how `ScannerContext` already decides it.

### Release note

The BE configs `enable_task_executor_in_internal_table` and
`enable_task_executor_in_external_table` now default to `false`;
internal
and external table scans use the thread pool scan scheduler by default.

### Check List (For Author)

- Test:
- Unit Test: added
`WorkloadGroupManagerTest.DefaultScanSchedulersUseThreadPool`,
      `ScannerContextTest.thread_pool_admission_ignores_shared_limit`,

`ScannerProjectionTest.shared_limit_exhausted_before_call_returns_empty_block_without_eos`,
      `ScannerProjectionTest.shared_limit_counts_only_emitted_rows`,

`ScannerProjectionTest.shared_limit_drops_padding_after_peer_satisfies_limit`,

`ScannerProjectionTest.shared_limit_flushes_padding_before_reading_more`,
`ScannerProjectionTest.shared_limit_flushes_merged_padding_at_limit`,

`ScannerProjectionTest.shared_limit_counts_returned_rows_without_projection`,

`ScannerProjectionTest.shared_limit_counts_returned_rows_without_padding`,
      `ScannerProjectionTest.shared_limit_keeps_padding_small_blocks`,

`ScannerProjectionTest.shared_limit_exhausted_by_own_rows_stops_reading_without_eos`,

`ScannerProjectionTest.shared_limit_exhausted_by_peer_mid_read_returns_held_rows_without_eos`,

`ScannerProjectionTest.shared_limit_observed_by_scanner_initialized_under_negative_counter`,
      `ScannerProjectionTest.no_shared_limit_without_sql_limit`
and
`RowIdStorageReaderTest.RpcHelperReportsThrownExceptionOnThreadPoolPath`
(runs the RPC helper on a real `ThreadPoolSimplifiedScanScheduler`;
      the test process aborts without the fix);
      ran `ScannerProjectionTest.*`, `ScannerContextTest.*`,
      `ScannerLateArrivalRfTest.*`, `WorkloadGroupManagerTest.*`,
      `RowIdStorageReaderTest.*`, `SubmitExternalScanTasksTest.*`
    - Regression test: ran on a local cluster with the new
      default: query_p0/limit (19 suites) and
      correctness_p0/test_shared_scan_limit_pending_tasks
- Behavior changed: Yes (default scan scheduler for internal and
external
table scans changes from the task executor to the thread pool; it can be
  switched back via the two BE configs)
- Does this need documentation: No
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants