Skip to content

[fix](be) Reap only the owned CDC client process - #68492

Merged
morningman merged 7 commits into
apache:masterfrom
morningman:fix-cdc-client-sigchld
Sep 28, 2026
Merged

morningman merged 7 commits into
apache:masterfrom
morningman:fix-cdc-client-sigchld

Conversation

@morningman

@morningman morningman commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Problem Summary:

When BE starts the CDC client, CdcClientMgr installs a process-wide SIGCHLD handler. The handler previously called waitpid(-1, ..., WNOHANG), which could reap any child of BE. The embedded JVM also starts subprocesses and waits for their exit codes. If the CDC handler reaps one first, the JVM can observe ECHILD and report exit code 0 even when the command failed. One observed result was a failed libc-detection probe appearing successful, causing RocksDB JNI to select the musl library on a glibc host.

The handler now waits only for the CDC child. A generation-qualified identity and an exclusive operation claim coordinate it with startup, health inspection, and shutdown, so those paths cannot act on a PID after it has been reaped and reused. A pending-reap handoff preserves SIGCHLD notifications arriving during inspection. The latest review identified another handoff window: an old handler could read generation N before claiming, then claim N after N+1 was published and hide N+1's only exit notification. The handler now rechecks the published generation after releasing that stale claim. A deterministic test pauses at both sides of this window and verifies that N+1 is reaped.

The affected tests now fail if their process setup fails, observe SIGTERM through child-reported markers and phase handshakes instead of kill(pid, 0), and reap an unrelated direct child even when a fatal handler checkpoint fails. The forced-shutdown test uses a direct child that ignores SIGTERM; the handler/shutdown test waits for an actual failed ownership claim; and the stale-generation helper starts with a controlled signal environment.

The ownership rule changes what a failed startup does to its forked child. The health-check failure path now terminates and reaps it, where the PID used to be dropped and the child left running unmanaged. That abandoned child could finish warming up and be adopted by a later start_cdc_client call. On a host whose cold cdc-client.jar JVM consistently answers /actuator/health later than the unchanged startup window, pre-start the CDC client so the adoption path finds it, or give the JVM more room. The cleanup also removes the unmanaged JVM left holding cdc_client_port.

The macOS BE test compatibility changes, including the Decimal64 literal fix, were merged separately in #68520. This branch was rebased onto that merge and its duplicate test-only commit was dropped.

Release note

Fix CDC client lifecycle handling so BE preserves the exit status of unrelated child processes and reaps an exited replacement CDC client even if an older SIGCHLD handler resumes late. A startup that fails its health check now terminates and reaps the client it forked instead of leaving it running unmanaged; on a host where that JVM reliably needs longer than the startup health-check window, start it before BE so the adoption path finds it.

Check List (For Author)

  • Test

    • Unit Test: BUILD_TYPE_UT=Debug ./run-be-ut.sh --run --filter='CdcClientMgrTest.*:FormatRoundTest.*' -j 8 passed locally: 44/44 tests (36 CDC manager, 8 FormatRound). Debug was used because ASAN test startup hangs on this macOS 26.5 machine. To build the UT binary locally, I temporarily excluded unrelated SNII and segment tests that fail to compile or link on this Mac and supplied a worktree-local Faiss include link; the CMake exclusion was reverted before commit. The BE_TEST fast path does not exercise production-only fork, health-check, and adoption orchestration; that remains an integration-test follow-up.
    • Manual test: build-support/clang-format.sh, build-support/check-format.sh, build-support/check-build-hygiene.sh, and git diff --check passed.
    • ASAN BE build: an earlier attempt stopped during CLucene CMake configuration after two try_run probes hung on this Mac, before compiling the changed source.
    • Clang-tidy: attempted against the Debug UT compilation database; it could not complete because of libc++ system-header parse errors on this Mac. Existing diagnostics from unchanged code are also reported.
  • Behavior changed:

    • Yes. The handler reaps only the CDC child and rechecks the current generation after releasing a stale claim. A failed startup now terminates and reaps the child it forked rather than leaving it running unmanaged.
  • Does this need documentation?

    • No.

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?

@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@morningman

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Static review of exact head e2898117c453b3b1a825649b58bfd846880d38f1 found two test-validity issues, both left inline.

Critical checkpoints:

  • Goal/correctness: the production change statically achieves exact-child reaping; the generation-qualified identity and exclusive operation claim prevent unrelated-child reaping and stale-PID operations under the reviewed interleavings.
  • Scope/clarity: the change is focused on the CDC manager and its tests, and the ownership state machine is documented.
  • Concurrency/lifecycle: both production callers, the single ExecEnv-owned manager, startup publication, pending handoff, health failure, adoption, stop, and destruction were traced. No concrete double owner, lost reap request, deadlock, or post-release syscall was found.
  • Error handling/compatibility: EINTR, ECHILD, early exit, terminal reap, and PID reuse were checked. There is no protocol, storage, persistence, configuration, authorization, or rolling-upgrade contract change.
  • Parallel paths/performance/observability: both callers share the same manager; spinning is limited to short lifecycle handoffs, and normal-thread logging remains available.
  • Tests: the added cases cover unrelated-child isolation, owned reap and errno, stale generations, handler handoff, and graceful SIGTERM, but the forced-SIGKILL test is now vacuous and the stop/handler overlap test is nondeterministic. Please address the inline items.
  • Validation: static review only; no build or test was run by this reviewer, as required by the automation instructions. Header hygiene and git diff --check passed locally. At submission time compile, clang-format, and checkstyle passed; BE UT was pending. The Cloud P0 check was failing, with no reviewed evidence connecting it to these changes.
  • User focus: no additional focus was supplied.

Comment thread be/src/runtime/cdc_client_mgr.cpp Resolved
Comment thread be/test/runtime/cdc_client_mgr_test.cpp Resolved
@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (2/2) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.11% (29842/46549)
Line Coverage 48.73% (311009/638290)
Region Coverage 44.20% (250690/567124)
Branch Coverage 45.78% (116569/254646)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17748	4184	4051	4051
q2	2202	381	316	316
q3	10076	1464	917	917
q4	4683	472	346	346
q5	7456	823	557	557
q6	191	179	143	143
q7	744	780	594	594
q8	9287	1534	1594	1534
q9	5426	4260	4209	4209
q10	6822	1328	1023	1023
q11	444	296	248	248
q12	626	419	317	317
q13	18034	2624	2002	2002
q14	258	265	242	242
q15	q16	730	722	665	665
q17	1712	1126	1027	1027
q18	6498	5576	5555	5555
q19	1187	1326	1084	1084
q20	493	409	270	270
q21	5495	3577	3027	3027
q22	466	389	316	316
Total cold run time: 100578 ms
Total hot run time: 28443 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4915	5118	4742	4742
q2	741	596	560	560
q3	4863	5141	4578	4578
q4	2245	2307	1452	1452
q5	4570	4421	4669	4421
q6	252	187	134	134
q7	1831	1739	1528	1528
q8	2408	2156	2093	2093
q9	7265	7254	7269	7254
q10	3722	3547	3133	3133
q11	527	405	376	376
q12	715	701	516	516
q13	2276	2616	2021	2021
q14	280	273	254	254
q15	q16	655	689	605	605
q17	7352	6816	6614	6614
q18	11879	11107	11745	11107
q19	1082	993	1002	993
q20	2192	2185	1894	1894
q21	5041	4272	4406	4272
q22	523	473	397	397
Total cold run time: 65334 ms
Total hot run time: 58944 ms

@hello-stephen

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

query5	4324	620	466	466
query6	432	202	188	188
query7	4833	540	291	291
query8	339	180	166	166
query9	8790	4075	4027	4027
query10	469	302	254	254
query11	5939	3531	3232	3232
query12	149	87	85	85
query13	1288	630	436	436
query14	6516	4506	4168	4168
query14_1	3945	3933	3989	3933
query15	200	197	181	181
query16	975	460	440	440
query17	903	669	535	535
query18	2426	460	337	337
query19	205	181	141	141
query20	83	82	81	81
query21	217	135	117	117
query22	13101	12928	12688	12688
query23	14133	13071	12459	12459
query23_1	12728	12715	12527	12527
query24	7435	1100	686	686
query24_1	771	791	706	706
query25	557	433	377	377
query26	1250	302	174	174
query27	2685	565	337	337
query28	4579	2036	2043	2036
query29	1616	717	554	554
query30	298	218	180	180
query31	904	756	645	645
query32	148	103	95	95
query33	534	313	262	262
query34	1182	1128	626	626
query35	731	771	639	639
query36	780	802	729	729
query37	144	105	94	94
query38	1829	1760	1688	1688
query39	684	689	669	669
query39_1	639	669	657	657
query40	224	129	104	104
query41	71	69	68	68
query42	96	99	95	95
query43	334	348	298	298
query44	1432	739	744	739
query45	198	176	167	167
query46	1093	1220	764	764
query47	1534	1540	1427	1427
query48	385	406	288	288
query49	592	406	286	286
query50	948	341	263	263
query51	10538	10146	10438	10146
query52	86	92	74	74
query53	239	267	179	179
query54	265	205	207	205
query55	78	72	73	72
query56	231	204	212	204
query57	1435	1401	1339	1339
query58	284	260	257	257
query59	1972	2063	1867	1867
query60	305	237	226	226
query61	145	154	155	154
query62	395	315	268	268
query63	209	184	174	174
query64	2809	1015	809	809
query65	3472	3406	3422	3406
query66	1795	414	308	308
query67	20460	19929	19802	19802
query68	3275	1637	1010	1010
query69	417	307	261	261
query70	898	775	798	775
query71	303	238	207	207
query72	2758	2538	2226	2226
query73	807	767	452	452
query74	4654	4482	4282	4282
query75	2312	2279	1945	1945
query76	2411	1119	777	777
query77	362	397	287	287
query78	9127	9177	8560	8560
query79	1319	1242	763	763
query80	581	466	370	370
query81	546	329	283	283
query82	641	168	127	127
query83	305	218	214	214
query84	314	156	119	119
query85	876	493	390	390
query86	345	247	235	235
query87	1973	1948	1830	1830
query88	3665	2765	2744	2744
query89	380	293	248	248
query90	1870	186	177	177
query91	171	154	140	140
query92	100	89	92	89
query93	1477	1422	912	912
query94	526	322	277	277
query95	666	365	335	335
query96	1023	788	325	325
query97	2463	2442	2336	2336
query98	163	154	146	146
query99	718	736	625	625
Total cold run time: 237499 ms
Total hot run time: 152709 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.09	0.04	0.05
query3	0.26	0.14	0.14
query4	1.63	0.14	0.14
query5	0.24	0.21	0.22
query6	1.17	0.95	0.92
query7	0.04	0.01	0.01
query8	0.05	0.04	0.04
query9	0.39	0.33	0.34
query10	0.54	0.54	0.55
query11	0.19	0.15	0.14
query12	0.18	0.15	0.15
query13	0.46	0.46	0.48
query14	0.98	0.95	0.94
query15	0.62	0.58	0.59
query16	0.31	0.31	0.33
query17	1.15	1.06	1.12
query18	0.21	0.20	0.20
query19	2.00	2.00	1.94
query20	0.02	0.01	0.01
query21	15.49	0.21	0.15
query22	4.84	0.06	0.06
query23	16.16	0.31	0.11
query24	3.02	0.40	0.31
query25	0.11	0.06	0.04
query26	0.74	0.22	0.16
query27	0.04	0.05	0.04
query28	3.49	0.78	0.34
query29	12.60	3.97	3.19
query30	0.29	0.16	0.16
query31	2.77	0.55	0.31
query32	3.23	0.59	0.49
query33	3.16	3.38	3.22
query34	15.60	3.94	3.27
query35	3.22	3.20	3.21
query36	0.56	0.43	0.44
query37	0.09	0.07	0.06
query38	0.06	0.04	0.04
query39	0.04	0.03	0.03
query40	0.17	0.15	0.14
query41	0.08	0.03	0.03
query42	0.03	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.37 s
Total hot run time: 24 s

morningman added a commit to morningman/doris that referenced this pull request Sep 24, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: The existing forced-kill test supplied a shell background PID, which is not a child of the test process. The new ECHILD guard therefore made stop() return before exercising SIGTERM, SIGKILL, or reaping. Spawn a direct child that reports when it ignores SIGTERM, and verify stop() collects it. The new handler/stop overlap test only waited for 20 ms, so it could pass before the stop thread attempted the ownership claim. Record a failed claim in BE_TEST and require the test to observe it while the handler is paused.

### Release note

None

### Check List (For Author)

- Test: Manual test: direct child signal behavior, clang-format, check-format, build hygiene, and git diff --check passed. Unit Test: run-be-ut.sh configuration stalled in OpenBLAS getarch before compilation. Clang-tidy: could not complete because the existing libc++ headers fail to parse on this Mac.
- Behavior changed: No. Production behavior is unchanged; the claim checkpoint is compiled only for BE_TEST.
- Does this need documentation: No
@morningman

Copy link
Copy Markdown
Contributor Author

/review

@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@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 exact head 13005d6f8b18e61397681fa5bcd6f34c9088bf3b found one test-safety issue, left inline.

Critical checkpoints:

  • Goal/correctness: the production change statically achieves exact-child reaping. The generation-qualified identity, exclusive operation claim, and pending-reap handoff prevent unrelated-child reaping, lost notifications, and stale-PID syscalls in the reviewed interleavings.
  • Scope/clarity: the production change is focused on CdcClientMgr and its unit tests. The ownership state machine is complex but locally documented.
  • Concurrency: the process-wide SIGCHLD handler, RPC/file-reader start calls, health inspection, and stop/destruction paths were traced. Start and stop serialize on _start_mutex; handler/normal-thread process operations serialize through always-lock-free atomics. No concrete deadlock, double owner, lost reap request, or post-release syscall was found.
  • Lifecycle/static initialization: ExecEnv owns one production manager; publication, early child exit, health failure, external adoption, terminal reap, and destruction were checked. Namespace-scope atomics are constant-initialized and the handler retains no manager pointer.
  • Error handling/compatibility: EINTR, ECHILD, wait errors, early exit, forced termination, and PID reuse were checked. There is no configuration, FE/BE protocol, storage-format, transaction, persistence, authorization, or rolling-upgrade contract change.
  • Parallel paths/performance/observability: both production callers share the same manager; the handler does exact-PID WNOHANG work without allocation or logging, and normal-thread lifecycle logs remain available. No distinct performance or observability regression was substantiated.
  • Tests: the current head fixes the two prior inline concerns with a direct child that proves SIGTERM is ignored and an observed failed ownership claim. The new stale-generation test still has an unsafe fatal-assertion cleanup order, described inline.
  • Validation: static review only; no build or test was run by this reviewer, as required by the automation instructions. The author reports formatting/build-hygiene checks passed, while the targeted BE unit test, full build, and clang-tidy were not completed locally.
  • User focus: no additional focus was supplied.

Comment thread be/test/runtime/cdc_client_mgr_test.cpp Resolved
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17697	3819	3852	3819
q2	2153	359	294	294
q3	10130	1390	777	777
q4	4685	474	347	347
q5	7531	830	545	545
q6	178	169	134	134
q7	705	780	598	598
q8	9360	1576	1507	1507
q9	5470	4206	4144	4144
q10	6820	1304	998	998
q11	448	279	241	241
q12	640	414	302	302
q13	18064	2615	1982	1982
q14	266	261	234	234
q15	q16	739	715	664	664
q17	1724	1127	934	934
q18	6417	5559	5512	5512
q19	1174	1240	1100	1100
q20	480	397	276	276
q21	5472	3189	2871	2871
q22	433	367	304	304
Total cold run time: 100586 ms
Total hot run time: 27583 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4507	4422	4429	4422
q2	711	577	544	544
q3	4745	5225	4655	4655
q4	2250	2355	1470	1470
q5	4651	4431	4420	4420
q6	226	166	124	124
q7	1854	1756	1552	1552
q8	2326	2121	2047	2047
q9	7488	7360	6853	6853
q10	3614	3561	3095	3095
q11	521	392	337	337
q12	701	705	495	495
q13	2275	2591	1988	1988
q14	273	271	245	245
q15	q16	664	687	603	603
q17	7145	6666	6608	6608
q18	11860	11083	11754	11083
q19	1103	1014	998	998
q20	2200	2199	1919	1919
q21	5028	4380	4429	4380
q22	502	455	405	405
Total cold run time: 64644 ms
Total hot run time: 58243 ms

@hello-stephen

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

query5	4308	594	443	443
query6	422	204	191	191
query7	4821	558	287	287
query8	326	174	156	156
query9	8825	3969	3975	3969
query10	468	308	243	243
query11	5888	3577	3236	3236
query12	158	88	87	87
query13	1298	592	402	402
query14	6504	4495	4193	4193
query14_1	3946	3914	3960	3914
query15	202	196	186	186
query16	987	457	424	424
query17	918	685	552	552
query18	2439	444	359	359
query19	199	179	144	144
query20	83	80	76	76
query21	221	132	116	116
query22	12986	13037	12800	12800
query23	13927	12991	12366	12366
query23_1	12448	12406	12456	12406
query24	7162	1178	719	719
query24_1	675	695	767	695
query25	557	428	372	372
query26	830	311	171	171
query27	2750	555	336	336
query28	4497	2032	1967	1967
query29	1387	694	499	499
query30	285	215	179	179
query31	891	762	627	627
query32	142	88	87	87
query33	510	307	231	231
query34	1168	1119	641	641
query35	729	775	631	631
query36	755	777	701	701
query37	144	95	85	85
query38	1821	1767	1687	1687
query39	695	683	647	647
query39_1	650	642	655	642
query40	206	127	96	96
query41	69	66	62	62
query42	94	91	92	91
query43	325	342	299	299
query44	1380	711	721	711
query45	180	172	159	159
query46	1051	1153	735	735
query47	1468	1479	1418	1418
query48	406	403	283	283
query49	563	400	294	294
query50	985	349	258	258
query51	10680	10576	10061	10061
query52	89	96	83	83
query53	238	257	179	179
query54	246	198	176	176
query55	75	81	67	67
query56	229	254	191	191
query57	1469	1441	1396	1396
query58	280	257	242	242
query59	1962	2073	1858	1858
query60	274	235	220	220
query61	143	143	137	137
query62	399	323	266	266
query63	212	168	172	168
query64	2175	977	781	781
query65	3489	3389	3407	3389
query66	1734	418	304	304
query67	19973	20120	19689	19689
query68	3252	1537	884	884
query69	410	308	265	265
query70	861	832	820	820
query71	284	238	213	213
query72	2657	2546	2299	2299
query73	845	744	430	430
query74	4645	4516	4298	4298
query75	2314	2268	1934	1934
query76	2556	1139	755	755
query77	376	455	297	297
query78	9127	9163	8531	8531
query79	1381	1266	776	776
query80	566	458	361	361
query81	525	325	282	282
query82	648	159	125	125
query83	303	223	196	196
query84	316	142	114	114
query85	856	466	365	365
query86	324	240	225	225
query87	1974	1945	1828	1828
query88	3650	2755	2755	2755
query89	367	279	244	244
query90	1929	179	178	178
query91	166	154	129	129
query92	99	87	87	87
query93	1456	1441	945	945
query94	508	334	269	269
query95	673	449	324	324
query96	1079	853	357	357
query97	2406	2418	2303	2303
query98	158	169	145	145
query99	727	727	616	616
Total cold run time: 234438 ms
Total hot run time: 151727 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.09	0.05	0.05
query3	0.26	0.13	0.14
query4	1.60	0.13	0.14
query5	0.25	0.22	0.22
query6	1.16	0.93	0.91
query7	0.04	0.01	0.00
query8	0.05	0.04	0.04
query9	0.40	0.34	0.33
query10	0.56	0.56	0.54
query11	0.20	0.15	0.15
query12	0.18	0.15	0.15
query13	0.48	0.48	0.49
query14	0.96	0.94	0.94
query15	0.62	0.58	0.60
query16	0.33	0.33	0.34
query17	1.11	1.11	1.09
query18	0.21	0.20	0.21
query19	1.98	1.89	1.86
query20	0.02	0.01	0.02
query21	15.47	0.21	0.14
query22	4.80	0.05	0.06
query23	16.13	0.31	0.12
query24	3.00	0.45	0.31
query25	0.10	0.07	0.04
query26	0.74	0.21	0.16
query27	0.04	0.03	0.04
query28	3.49	0.83	0.33
query29	12.48	4.11	3.27
query30	0.29	0.15	0.15
query31	2.77	0.58	0.31
query32	3.23	0.61	0.49
query33	3.14	3.14	3.13
query34	15.66	4.19	3.28
query35	3.22	3.18	3.24
query36	0.55	0.43	0.41
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.03	0.04	0.04
query40	0.17	0.14	0.14
query41	0.09	0.03	0.03
query42	0.04	0.03	0.04
query43	0.04	0.04	0.03
Total cold run time: 96.12 s
Total hot run time: 23.91 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.33% (34402/45069)
Line Coverage 61.21% (386369/631168)
Region Coverage 57.59% (325378/565020)
Branch Coverage 58.40% (148310/253955)

morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
…ction

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: StaleGenerationCannotTerminateAReusedNumericPid declared its cleanup guard before the manager, and locals are destroyed in reverse declaration order. When one of the test's fatal assertions failed, the manager was destroyed first: its destructor calls stop(), which force-kills and reaps the direct child and thereby frees the numeric pid, and only then did the guard still run kill(pid, SIGKILL) with child_needs_cleanup == true against a pid this process no longer owns. The test's own assertion forbids exactly that - "cleanup retained a stale raw pid and signalled its replacement generation". Declare the manager before the guard so the guard kills and reaps the child while it is still a direct child, and the manager's later stop() observes ECHILD and returns without signalling.

### Release note

None

### Check List (For Author)

- Test: Manual test: clang-format 16 reported no replacements for the changed file, build-support/check-build-hygiene.sh passed, and the diff is a declaration move plus a comment. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac before compiling the changed source.
- Behavior changed: No. Test-only reordering; the production change and its semantics are untouched.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
@morningman
morningman force-pushed the fix-cdc-client-sigchld branch from 2c99b98 to 90d1c84 Compare September 25, 2026 01:06
morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: The existing forced-kill test supplied a shell background PID, which is not a child of the test process. The new ECHILD guard therefore made stop() return before exercising SIGTERM, SIGKILL, or reaping. Spawn a direct child that reports when it ignores SIGTERM, and verify stop() collects it. The new handler/stop overlap test only waited for 20 ms, so it could pass before the stop thread attempted the ownership claim. Record a failed claim in BE_TEST and require the test to observe it while the handler is paused.

### Release note

None

### Check List (For Author)

- Test: Manual test: direct child signal behavior, clang-format, check-format, build hygiene, and git diff --check passed. Unit Test: run-be-ut.sh configuration stalled in OpenBLAS getarch before compilation. Clang-tidy: could not complete because the existing libc++ headers fail to parse on this Mac.
- Behavior changed: No. Production behavior is unchanged; the claim checkpoint is compiled only for BE_TEST.
- Does this need documentation: No
morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
…ction

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: StaleGenerationCannotTerminateAReusedNumericPid declared its cleanup guard before the manager, and locals are destroyed in reverse declaration order. When one of the test's fatal assertions failed, the manager was destroyed first: its destructor calls stop(), which force-kills and reaps the direct child and thereby frees the numeric pid, and only then did the guard still run kill(pid, SIGKILL) with child_needs_cleanup == true against a pid this process no longer owns. The test's own assertion forbids exactly that - "cleanup retained a stale raw pid and signalled its replacement generation". Declare the manager before the guard so the guard kills and reaps the child while it is still a direct child, and the manager's later stop() observes ECHILD and returns without signalling.

### Release note

None

### Check List (For Author)

- Test: Manual test: clang-format 16 reported no replacements for the changed file, build-support/check-build-hygiene.sh passed, and the diff is a declaration move plus a comment. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac before compiling the changed source.
- Behavior changed: No. Test-only reordering; the production change and its semantics are untouched.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@morningman

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Static review of exact head 90d1c8426a17328b9d8fd39c5835780b943a2634 found two additional test-validity/coverage issues. The existing inline threads at cdc_client_mgr.cpp:248 (forced-kill false-positive), cdc_client_mgr_test.cpp:493 (stopper checkpoint), and cdc_client_mgr_test.cpp:533 (fatal cleanup ordering) were treated as hard duplicate fences and are not repeated here.

Critical checkpoints:

  • Goal/correctness: the generation-qualified identity, exclusive operation claim, pending-reap handoff, exact-PID waitpid, and ECHILD/ESRCH handling were traced through the signal handler, stop, startup failure, adoption, and ExecEnv destruction paths. No distinct production race or wrong-child operation was substantiated.
  • Scope/clarity: the production change is focused on CdcClientMgr ownership and reaping, but the state machine is complex and the production-only startup branches need direct test evidence.
  • Concurrency/lifecycle: handler versus normal-thread claim/release interleavings, publication windows, PID reuse, unrelated JVM/Python children, and manager destruction were reviewed. The operation claim remains held through the final process syscall.
  • Error handling/compatibility: EINTR, ECHILD, early child exit, forced termination, and external adoption were checked statically; there is no FE/BE protocol, storage, persistence, configuration, or rolling-upgrade contract change.
  • Parallel paths/performance/observability: both production callers share the ExecEnv-owned manager; the handler uses exact-PID WNOHANG and lock-free state without allocation/logging. No separate performance or observability defect was found.
  • Tests: the two inline findings below remain. Existing force-kill and stopper-barrier comments are already addressed in the current head, while BE_TEST startup tests still bypass the production fork/inspection/adoption path.
  • Validation: static review only; no build or test was run by this reviewer, per the review instructions.
  • User focus: no additional focus was supplied.

Please address the inline findings and add/update coverage for the production-only lifecycle before merge.

Comment thread be/test/runtime/cdc_client_mgr_test.cpp Resolved
// rather than behind CdcClientMgr's mutex. The generation prevents a delayed handler from clearing
// ownership after the kernel has already reused the same numeric pid for a replacement child.
// ExecEnv owns a single CdcClientMgr, so there is a single published identity.
static_assert(sizeof(pid_t) <= sizeof(uint32_t));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Exercise the production startup state machine.

All BE unit tests compile with BE_TEST, so this branch returns after publishing synthetic PID 99999 and never executes the newly changed fork/publication window, early-exit reap, health-check failure cleanup, final inspection, or external-adoption logic below. The ownership helper tests cannot prove those end-to-end transitions. Please add a non-BE_TEST/integration case or inject the fork/health outcomes so these production-only paths are actually driven.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17664	3871	3807	3807
q2	2220	362	321	321
q3	10024	1351	802	802
q4	4680	468	350	350
q5	7598	815	539	539
q6	180	174	137	137
q7	724	763	597	597
q8	9294	1452	1481	1452
q9	5438	4186	4230	4186
q10	6819	1307	1010	1010
q11	441	260	242	242
q12	628	415	289	289
q13	18074	2618	2001	2001
q14	261	251	241	241
q15	q16	738	716	656	656
q17	1680	1140	961	961
q18	6427	5601	5566	5566
q19	1154	1198	1060	1060
q20	504	387	258	258
q21	5481	3014	3056	3014
q22	455	345	310	310
Total cold run time: 100484 ms
Total hot run time: 27799 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4482	4404	4395	4395
q2	726	569	525	525
q3	4846	5145	4762	4762
q4	2255	2333	1478	1478
q5	4548	4400	4423	4400
q6	225	177	126	126
q7	1895	1713	1532	1532
q8	2318	2014	2023	2014
q9	7436	7153	6808	6808
q10	3636	3542	3065	3065
q11	515	367	351	351
q12	705	709	502	502
q13	2256	2593	1994	1994
q14	265	268	251	251
q15	q16	655	678	603	603
q17	7243	6686	6604	6604
q18	11905	11025	11751	11025
q19	1130	989	987	987
q20	2207	2186	1911	1911
q21	4897	4048	4231	4048
q22	488	466	390	390
Total cold run time: 64633 ms
Total hot run time: 57771 ms

morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: SigchldHandlerDoesNotReapOtherChildren slept a fixed 600 ms and then called blocking waitpid(pid), so it never established that handle_sigchld had executed. On a delayed signal delivery this thread's own waitpid can win the race and reap the unrelated child, and the case then passes without exercising the exact-PID replacement for waitpid(-1) at all. Wait instead for the handler to unpublish the identity it was handed, which it only does after its own waitpid has returned; that is a deterministic handler-run checkpoint, and because it is satisfied before this thread reaps anything, the following reap can no longer overtake the handler. This also removes the last sleep-based synchronization in the file; the other ownership cases already use pause hooks or waitid checkpoints.

### Release note

None

### Check List (For Author)

- Test: Manual test: a standalone probe that replicates the identity/claim state machine passes the rewritten case 20/20 with the exact-PID waitpid and reports the case is caught when that line is reverted to waitpid(-1). `git diff --check` and `build-support/check-build-hygiene.sh` passed. clang-format 16 is not installed on this Mac, so the changed file was checked by hand against the 100-column limit and the surrounding style. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac before compiling the changed source.
- Behavior changed: No. Test-only synchronization change; production code is untouched.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
@hello-stephen

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

query5	4360	598	460	460
query6	425	214	195	195
query7	4828	578	318	318
query8	314	176	165	165
query9	8818	4049	4068	4049
query10	460	307	261	261
query11	5928	3541	3227	3227
query12	148	95	88	88
query13	1273	620	446	446
query14	6516	4560	4227	4227
query14_1	4001	3998	3949	3949
query15	205	198	179	179
query16	1006	476	415	415
query17	923	669	546	546
query18	2427	457	350	350
query19	205	184	146	146
query20	83	84	82	82
query21	231	137	116	116
query22	13014	12980	12715	12715
query23	13940	13043	12559	12559
query23_1	12636	12764	12605	12605
query24	7455	1101	672	672
query24_1	757	686	728	686
query25	589	438	376	376
query26	1260	330	170	170
query27	2639	582	351	351
query28	4544	2091	2064	2064
query29	1672	716	538	538
query30	307	227	192	192
query31	894	757	642	642
query32	156	97	96	96
query33	531	318	255	255
query34	1184	1098	622	622
query35	720	746	638	638
query36	797	778	751	751
query37	151	118	90	90
query38	1850	1756	1686	1686
query39	663	683	649	649
query39_1	644	632	633	632
query40	225	127	107	107
query41	70	74	69	69
query42	99	96	96	96
query43	335	345	302	302
query44	1407	766	723	723
query45	183	176	162	162
query46	1086	1170	738	738
query47	1510	1521	1402	1402
query48	400	417	288	288
query49	586	394	301	301
query50	1001	334	249	249
query51	10808	10483	10404	10404
query52	89	89	78	78
query53	251	259	184	184
query54	253	221	186	186
query55	79	77	71	71
query56	249	235	225	225
query57	1495	1337	1316	1316
query58	289	265	265	265
query59	2024	2069	1845	1845
query60	270	236	224	224
query61	148	153	153	153
query62	414	326	265	265
query63	216	187	178	178
query64	2835	995	823	823
query65	3472	3403	3415	3403
query66	1811	426	306	306
query67	20233	20581	19817	19817
query68	3280	1650	1012	1012
query69	399	312	269	269
query70	906	795	789	789
query71	294	228	215	215
query72	2582	2507	2223	2223
query73	852	774	433	433
query74	4626	4516	4302	4302
query75	2315	2269	1952	1952
query76	2435	1158	752	752
query77	359	398	298	298
query78	9130	8975	8485	8485
query79	1399	1147	771	771
query80	1242	464	377	377
query81	598	322	280	280
query82	620	166	124	124
query83	317	219	199	199
query84	316	142	114	114
query85	915	459	392	392
query86	477	236	229	229
query87	1979	2043	1824	1824
query88	3709	2795	2796	2795
query89	356	280	240	240
query90	1959	189	186	186
query91	167	155	126	126
query92	96	90	89	89
query93	1539	1545	877	877
query94	727	355	290	290
query95	683	372	355	355
query96	1081	762	394	394
query97	2450	2466	2321	2321
query98	156	158	146	146
query99	726	731	611	611
Total cold run time: 238833 ms
Total hot run time: 153091 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.09	0.05	0.04
query3	0.26	0.14	0.13
query4	1.61	0.14	0.14
query5	0.26	0.21	0.21
query6	1.16	0.90	0.92
query7	0.04	0.01	0.00
query8	0.05	0.03	0.04
query9	0.38	0.33	0.33
query10	0.55	0.57	0.55
query11	0.20	0.14	0.13
query12	0.19	0.15	0.14
query13	0.45	0.46	0.46
query14	0.96	0.93	0.94
query15	0.60	0.58	0.59
query16	0.32	0.33	0.31
query17	1.07	1.10	1.02
query18	0.20	0.19	0.20
query19	1.99	1.95	1.97
query20	0.01	0.01	0.01
query21	15.47	0.19	0.13
query22	4.97	0.05	0.05
query23	16.14	0.30	0.12
query24	3.02	0.43	0.35
query25	0.13	0.05	0.04
query26	0.76	0.21	0.14
query27	0.04	0.04	0.03
query28	3.50	0.70	0.33
query29	12.49	4.05	3.26
query30	0.32	0.15	0.15
query31	2.77	0.55	0.31
query32	3.22	0.59	0.48
query33	3.14	3.16	3.27
query34	15.62	3.94	3.32
query35	3.25	3.24	3.26
query36	0.56	0.41	0.42
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.03	0.04	0.04
query40	0.18	0.15	0.15
query41	0.10	0.03	0.03
query42	0.04	0.02	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.33 s
Total hot run time: 23.94 s

morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
… preconditions

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: An external review of this PR found that the post-fork early return was placed before the health check, so a forked child that died inside the fork-to-inspection window was reported as a startup error even when the port had come back under an external cdc client. The base ran the health check unconditionally and adopted in exactly that case. Move the decision after the health check: the inspection still reaps the child and revokes its identity, and a failing health check reports the early exit as before. Because the identity is already unpublished by then, the existing final inspection returns NOT_OWNED, which is the branch that reaches adoption, so no new outcome had to be written. The price of restoring base ordering is that an immediately dead child is now reported after the health-check window instead of within microseconds.

Three further findings are fixed. claim_child_identity() asserts a non-zero identity: identity 0 names no generation, so its loop could never observe a change and would spin forever while stop() holds _start_mutex, instead of reporting the impossible input. terminate_and_reap_child() and _publish_child_pid() assert their pid precondition the same way rather than absorbing it with a silent return. The sigaction() install result is checked, because nothing else consumes the published identity and a silently failed install would disable the pending-reap handoff.

On the test side, StopWithRealProcessGraceful is renamed to StopDoesNotSignalANonChildPid: its published pid is a popen grandchild this process can never reap, so it exercises the ECHILD early return rather than a graceful shutdown, and it now asserts the pid is still alive afterwards, which is the property that early return exists for. StaleGenerationCannotTerminateAReusedNumericPid gives its child a SIGTERM trap that reports on a pipe, so the graceful half of the reap sequence is observable instead of being indistinguishable from the forced kill. Two post-join flag assertions that could not fail are removed.

The review also found that a failed health check now terminates and reaps the child this process forked, where the base dropped the PID and left the child running unmanaged. Removing the base's accidental recovery - a later attempt adopting the still-warming JVM - is intended, and is now declared in the PR body and the release note. The reaping rule itself is not altered.

### Release note

See the PR body: a startup that fails its health check now terminates and reaps the CDC client it forked instead of leaving it running unmanaged.

### Check List (For Author)

- Test: Manual test. A standalone probe reproducing the claim/inspect helpers confirms that an initial inspection observing EXITED leaves the identity unpublished and the second inspection returns NOT_OWNED, which is the adoption branch. The rewritten test child reports SIGTERM on the pipe within the grace window in 5/5 runs, and a SIGKILL shows up as EOF rather than a blocking read. `git diff --check` and `build-support/check-build-hygiene.sh` passed. clang-format 16 is not installed on this Mac, so both files were checked by hand against the 100-column limit and the surrounding style. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac.
- Behavior changed: Yes for the reaping rule and the failed-startup cleanup, both declared in the PR body; the adoption-window change restores base behaviour.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
morningman added a commit to morningman/doris that referenced this pull request Sep 25, 2026
… preconditions

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: An external review of this PR found that the post-fork early return was placed before the health check, so a forked child that died inside the fork-to-inspection window was reported as a startup error even when the port had come back under an external cdc client. The base ran the health check unconditionally and adopted in exactly that case. Move the decision after the health check: the inspection still reaps the child and revokes its identity, and a failing health check reports the early exit as before. Because the identity is already unpublished by then, the existing final inspection returns NOT_OWNED, which is the branch that reaches adoption, so no new outcome had to be written. The price of restoring base ordering is that an immediately dead child is now reported after the health-check window instead of within microseconds.

Three further findings are fixed. claim_child_identity() asserts a non-zero identity: identity 0 names no generation, so its loop could never observe a change and would spin forever while stop() holds _start_mutex, instead of reporting the impossible input. terminate_and_reap_child() and _publish_child_pid() assert their pid precondition the same way rather than absorbing it with a silent return. The sigaction() install result is checked, because nothing else consumes the published identity and a silently failed install would disable the pending-reap handoff.

On the test side, StopWithRealProcessGraceful is renamed to StopDoesNotSignalANonChildPid: its published pid is a popen grandchild this process can never reap, so it exercises the ECHILD early return rather than a graceful shutdown, and it now asserts the pid is still alive afterwards, which is the property that early return exists for. StaleGenerationCannotTerminateAReusedNumericPid gives its child a SIGTERM trap that reports on a pipe, so the graceful half of the reap sequence is observable instead of being indistinguishable from the forced kill. Two post-join flag assertions that could not fail are removed.

The review also found that a failed health check now terminates and reaps the child this process forked, where the base dropped the PID and left the child running unmanaged. Removing the base's accidental recovery - a later attempt adopting the still-warming JVM - is intended, and is now declared in the PR body and the release note. The reaping rule itself is not altered.

### Release note

See the PR body: a startup that fails its health check now terminates and reaps the CDC client it forked instead of leaving it running unmanaged.

### Check List (For Author)

- Test: Manual test. A standalone probe reproducing the claim/inspect helpers confirms that an initial inspection observing EXITED leaves the identity unpublished and the second inspection returns NOT_OWNED, which is the adoption branch. The rewritten test child reports SIGTERM on the pipe within the grace window in 5/5 runs, and a SIGKILL shows up as EOF rather than a blocking read. `git diff --check` and `build-support/check-build-hygiene.sh` passed. clang-format 16.0.6 (Homebrew llvm@16) reports no replacements for the three changed files. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac.
- Behavior changed: Yes for the reaping rule and the failed-startup cleanup, both declared in the PR body; the adoption-window change restores base behaviour.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
@morningman
morningman force-pushed the fix-cdc-client-sigchld branch from 88cf0e0 to 7ad6a00 Compare September 25, 2026 02:19

@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 exact head e1699c514239b2168d5fdee02ae7a1675cc56ea5 found two additional liveness issues, both left inline. The nine existing threads were treated as hard duplicate fences and were not repeated.

Critical checkpoints:

  • Goal/correctness: the generation-qualified exact-PID state machine otherwise prevents unrelated-child reaping and stale-PID operations in the reviewed interleavings, but failed-start cleanup can monopolize the CDC lifecycle indefinitely after SIGKILL.
  • Scope/clarity: production changes are localized to CdcClientMgr; the header adds internal lifecycle helpers, and the unrelated Decimal64 test casts preserve the exact Int64 values.
  • Concurrency/lifecycle/static initialization: normal start/stop calls serialize on _start_mutex; the signal path uses constant-initialized, always-lock-free atomics and exact-generation ownership. Pending-reap, stale-generation retry, PID reuse, publication, adoption, health failure, stop, and ExecEnv destruction were traced. No separate lost handoff, double owner, static-order hazard, or post-release PID syscall was found.
  • Error handling/observability/performance: EINTR, ECHILD, early exit, graceful termination, forced termination, and cleanup were checked. Normal lifecycle logging remains available and the handler stays allocation- and lock-free. The unbounded post-kill wait is the remaining production error-path defect.
  • Parallel paths/compatibility: both the RPC heavy-work path and HttpFileReader share the singleton manager; other child owners keep exact-PID waits. There is no new configuration, FE/BE protocol, storage format, persistence, transaction, data-write, authorization, glibc-baseline, or rolling-upgrade contract.
  • Tests: the added cases broadly cover ownership and interleavings, but three handler-contention checks can hang the shared BE test binary instead of failing. The production-only startup coverage gap and other test defects already have existing inline threads.
  • Validation: static review only. Per the review instructions, no build or test was run, and author/CI claims are not independent validation by this reviewer. git diff --check passed for the exact base/head pair.
  • Completion: three independent normal/risk-focused rounds converged with no unresolved candidate beyond the two inline findings.
  • User focus: no additional focus was supplied.

<< ", error=" << strerror(errno);
}
do {
wait_result = waitpid(pid, &status, 0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Keep failed-start cleanup bounded after SIGKILL

The health-check failure path now reaches this helper while start_cdc_client() still holds _start_mutex, but after SIGKILL this blocking waitpid(..., 0) has no deadline. A task stuck in uninterruptible I/O can remain un-waitable despite the pending kill, leaving the request, the operation token, every later start/stop, and eventual manager destruction blocked indefinitely. Doris already handles this condition in PythonUDFProcess::shutdown() with a bounded post-kill wait and a background reaper. Please preserve the exact-generation ownership guarantee by transferring an unreaped child to a unique per-PID asynchronous owner before releasing the foreground claim, so failed startup can return without blocking successor publication.


// This handler sees the successor, but the stale claim prevents it from recording a pending
// reap. The delayed handler must take responsibility after releasing that stale claim.
CdcClientMgr::invoke_sigchld_handler_for_test();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Bound the handler-contention checks

This synchronous invocation runs while the delayed handler deliberately holds the stale generation's operation token, and that owner is not released until line 844. If the foreign-token path regresses to waiting for the token, this call never returns and its only release is unreachable, hanging the whole shared BE test binary instead of failing the case. The same circular harness dependency occurs at second.join() around line 884 and the synchronous invocation around line 950. Please run each challenged handler asynchronously, observe completion with a bounded deadline, then always release/join the owner before failing (or isolate these liveness checks in a subprocess with a timeout).

@hello-stephen

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

query5	4337	620	456	456
query6	425	208	190	190
query7	4846	542	302	302
query8	319	171	169	169
query9	8790	3999	4031	3999
query10	457	308	272	272
query11	5870	3523	3212	3212
query12	151	91	85	85
query13	1316	628	439	439
query14	6508	4518	4277	4277
query14_1	3972	3940	3931	3931
query15	204	197	182	182
query16	990	477	445	445
query17	891	675	562	562
query18	2423	449	347	347
query19	209	185	154	154
query20	86	94	80	80
query21	218	130	113	113
query22	13056	13061	12798	12798
query23	13851	13008	12412	12412
query23_1	12564	12559	12518	12518
query24	7296	1150	661	661
query24_1	726	694	736	694
query25	560	426	371	371
query26	1273	307	173	173
query27	2695	525	327	327
query28	4612	1970	1976	1970
query29	1632	724	542	542
query30	304	221	188	188
query31	895	746	634	634
query32	163	105	93	93
query33	527	307	253	253
query34	1192	1127	645	645
query35	728	745	633	633
query36	781	779	730	730
query37	141	104	114	104
query38	1843	1753	1702	1702
query39	683	691	658	658
query39_1	640	664	649	649
query40	223	133	102	102
query41	71	72	67	67
query42	99	99	96	96
query43	333	352	299	299
query44	1367	745	708	708
query45	181	181	166	166
query46	1076	1195	713	713
query47	1480	1492	1379	1379
query48	426	402	292	292
query49	606	451	289	289
query50	959	345	254	254
query51	10450	10320	10467	10320
query52	87	89	75	75
query53	245	251	175	175
query54	250	206	191	191
query55	75	77	70	70
query56	222	224	201	201
query57	1432	1360	1323	1323
query58	287	268	257	257
query59	1976	2154	1854	1854
query60	290	238	229	229
query61	151	148	143	143
query62	392	318	266	266
query63	217	170	175	170
query64	2828	990	837	837
query65	3502	3396	3411	3396
query66	1799	448	297	297
query67	19991	20294	19870	19870
query68	3282	1505	907	907
query69	406	294	254	254
query70	909	820	796	796
query71	305	235	263	235
query72	2622	2507	2224	2224
query73	851	754	416	416
query74	4639	4522	4318	4318
query75	2370	2319	1984	1984
query76	2336	1173	743	743
query77	373	398	303	303
query78	9226	9167	8544	8544
query79	1492	1177	754	754
query80	1263	465	372	372
query81	597	339	288	288
query82	670	177	123	123
query83	315	222	193	193
query84	314	147	114	114
query85	884	468	389	389
query86	418	241	227	227
query87	1986	1983	1821	1821
query88	3679	2782	2730	2730
query89	366	281	245	245
query90	1947	185	177	177
query91	168	156	131	131
query92	103	90	92	90
query93	1549	1451	900	900
query94	715	342	294	294
query95	652	373	420	373
query96	1035	782	348	348
query97	2422	2418	2334	2334
query98	164	161	144	144
query99	728	735	617	617
Total cold run time: 237513 ms
Total hot run time: 152655 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.10	0.05	0.04
query3	0.26	0.13	0.14
query4	1.61	0.14	0.14
query5	0.24	0.23	0.22
query6	1.16	0.92	0.91
query7	0.04	0.01	0.01
query8	0.05	0.03	0.04
query9	0.39	0.34	0.32
query10	0.54	0.53	0.59
query11	0.20	0.15	0.14
query12	0.18	0.15	0.14
query13	0.48	0.48	0.47
query14	0.96	0.95	0.94
query15	0.62	0.58	0.61
query16	0.31	0.32	0.31
query17	1.10	1.10	1.10
query18	0.21	0.20	0.20
query19	2.04	1.92	1.88
query20	0.02	0.02	0.01
query21	15.47	0.18	0.14
query22	4.98	0.05	0.06
query23	16.14	0.31	0.12
query24	3.02	0.42	0.33
query25	0.10	0.05	0.04
query26	0.74	0.22	0.16
query27	0.04	0.04	0.03
query28	3.48	0.81	0.34
query29	12.46	4.11	3.26
query30	0.29	0.14	0.15
query31	2.78	0.56	0.32
query32	3.22	0.60	0.49
query33	3.20	3.16	3.29
query34	15.56	3.91	3.27
query35	3.22	3.23	3.22
query36	0.56	0.42	0.41
query37	0.10	0.07	0.07
query38	0.05	0.04	0.03
query39	0.03	0.03	0.03
query40	0.17	0.15	0.15
query41	0.08	0.04	0.04
query42	0.04	0.03	0.05
query43	0.04	0.03	0.04
Total cold run time: 96.29 s
Total hot run time: 23.96 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (2/2) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.10% (29842/46557)
Line Coverage 48.71% (310979/638451)
Region Coverage 44.22% (250860/567304)
Branch Coverage 45.77% (116604/254737)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.34% (34404/45069)
Line Coverage 61.25% (386582/631169)
Region Coverage 57.63% (325620/565031)
Branch Coverage 58.44% (148421/253957)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (2/2) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.11% (29848/46558)
Line Coverage 48.72% (311056/638499)
Region Coverage 44.26% (251081/567343)
Branch Coverage 45.80% (116676/254764)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.33% (34401/45069)
Line Coverage 61.24% (386520/631169)
Region Coverage 57.63% (325608/565031)
Branch Coverage 58.43% (148376/253957)

morningman and others added 7 commits September 28, 2026 10:00
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#66399

Problem Summary: BE's process-wide SIGCHLD handler called waitpid(-1), which could reap a child launched by the embedded JVM. The JVM could then report a failed child process as successful. This change scopes reaping to the CDC client and uses a generation-qualified child identity plus an exclusive operation claim to prevent the handler, startup, and shutdown paths from acting on a reused PID. The three CDC manager files are extracted unchanged from apache#66399.

### Release note

Fix CDC client lifecycle handling so BE preserves the exit status of unrelated child processes.

### Check List (For Author)

- Test: Manual test: clang-format, check-format, build hygiene, git diff --check, and exact comparison with apache#66399 passed. Unit Test: CdcClientMgrTest was not run because the local thirdparty installation lacks libsimdutf.a. The ASAN BE build was stopped after CLucene CMake try-run probes hung on this Mac. Clang-tidy could not complete because the existing Release compilation database produced libc++ system-header errors.
- Behavior changed: Yes. SIGCHLD reaps only the owned CDC child; startup and shutdown guard process operations against PID reuse.
- Does this need documentation: No.
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: The existing forced-kill test supplied a shell background PID, which is not a child of the test process. The new ECHILD guard therefore made stop() return before exercising SIGTERM, SIGKILL, or reaping. Spawn a direct child that reports when it ignores SIGTERM, and verify stop() collects it. The new handler/stop overlap test only waited for 20 ms, so it could pass before the stop thread attempted the ownership claim. Record a failed claim in BE_TEST and require the test to observe it while the handler is paused.

### Release note

None

### Check List (For Author)

- Test: Manual test: direct child signal behavior, clang-format, check-format, build hygiene, and git diff --check passed. Unit Test: run-be-ut.sh configuration stalled in OpenBLAS getarch before compilation. Clang-tidy: could not complete because the existing libc++ headers fail to parse on this Mac.
- Behavior changed: No. Production behavior is unchanged; the claim checkpoint is compiled only for BE_TEST.
- Does this need documentation: No
…ction

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: StaleGenerationCannotTerminateAReusedNumericPid declared its cleanup guard before the manager, and locals are destroyed in reverse declaration order. When one of the test's fatal assertions failed, the manager was destroyed first: its destructor calls stop(), which force-kills and reaps the direct child and thereby frees the numeric pid, and only then did the guard still run kill(pid, SIGKILL) with child_needs_cleanup == true against a pid this process no longer owns. The test's own assertion forbids exactly that - "cleanup retained a stale raw pid and signalled its replacement generation". Declare the manager before the guard so the guard kills and reaps the child while it is still a direct child, and the manager's later stop() observes ECHILD and returns without signalling.

### Release note

None

### Check List (For Author)

- Test: Manual test: clang-format 16 reported no replacements for the changed file, build-support/check-build-hygiene.sh passed, and the diff is a declaration move plus a comment. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac before compiling the changed source.
- Behavior changed: No. Test-only reordering; the production change and its semantics are untouched.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: SigchldHandlerDoesNotReapOtherChildren slept a fixed 600 ms and then called blocking waitpid(pid), so it never established that handle_sigchld had executed. On a delayed signal delivery this thread's own waitpid can win the race and reap the unrelated child, and the case then passes without exercising the exact-PID replacement for waitpid(-1) at all. Wait instead for the handler to unpublish the identity it was handed, which it only does after its own waitpid has returned; that is a deterministic handler-run checkpoint, and because it is satisfied before this thread reaps anything, the following reap can no longer overtake the handler. This also removes the last sleep-based synchronization in the file; the other ownership cases already use pause hooks or waitid checkpoints.

### Release note

None

### Check List (For Author)

- Test: Manual test: a standalone probe that replicates the identity/claim state machine passes the rewritten case 20/20 with the exact-PID waitpid and reports the case is caught when that line is reverted to waitpid(-1). `git diff --check` and `build-support/check-build-hygiene.sh` passed. clang-format 16 is not installed on this Mac, so the changed file was checked by hand against the 100-column limit and the surrounding style. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac before compiling the changed source.
- Behavior changed: No. Test-only synchronization change; production code is untouched.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
… preconditions

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: An external review of this PR found that the post-fork early return was placed before the health check, so a forked child that died inside the fork-to-inspection window was reported as a startup error even when the port had come back under an external cdc client. The base ran the health check unconditionally and adopted in exactly that case. Move the decision after the health check: the inspection still reaps the child and revokes its identity, and a failing health check reports the early exit as before. Because the identity is already unpublished by then, the existing final inspection returns NOT_OWNED, which is the branch that reaches adoption, so no new outcome had to be written. The price of restoring base ordering is that an immediately dead child is now reported after the health-check window instead of within microseconds.

Three further findings are fixed. claim_child_identity() asserts a non-zero identity: identity 0 names no generation, so its loop could never observe a change and would spin forever while stop() holds _start_mutex, instead of reporting the impossible input. terminate_and_reap_child() and _publish_child_pid() assert their pid precondition the same way rather than absorbing it with a silent return. The sigaction() install result is checked, because nothing else consumes the published identity and a silently failed install would disable the pending-reap handoff.

On the test side, StopWithRealProcessGraceful is renamed to StopDoesNotSignalANonChildPid: its published pid is a popen grandchild this process can never reap, so it exercises the ECHILD early return rather than a graceful shutdown, and it now asserts the pid is still alive afterwards, which is the property that early return exists for. StaleGenerationCannotTerminateAReusedNumericPid gives its child a SIGTERM trap that reports on a pipe, so the graceful half of the reap sequence is observable instead of being indistinguishable from the forced kill. Two post-join flag assertions that could not fail are removed.

The review also found that a failed health check now terminates and reaps the child this process forked, where the base dropped the PID and left the child running unmanaged. Removing the base's accidental recovery - a later attempt adopting the still-warming JVM - is intended, and is now declared in the PR body and the release note. The reaping rule itself is not altered.

### Release note

See the PR body: a startup that fails its health check now terminates and reaps the CDC client it forked instead of leaving it running unmanaged.

### Check List (For Author)

- Test: Manual test. A standalone probe reproducing the claim/inspect helpers confirms that an initial inspection observing EXITED leaves the identity unpublished and the second inspection returns NOT_OWNED, which is the adoption branch. The rewritten test child reports SIGTERM on the pipe within the grace window in 5/5 runs, and a SIGKILL shows up as EOF rather than a blocking read. `git diff --check` and `build-support/check-build-hygiene.sh` passed. clang-format 16.0.6 (Homebrew llvm@16) reports no replacements for the three changed files. The BE unit test was not run locally: configure still stalls in OpenBLAS getarch on this Mac.
- Behavior changed: Yes for the reaping rule and the failed-startup cleanup, both declared in the PR body; the adoption-window change restores base behaviour.
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
…nal environment

### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68492

Problem Summary: BE UT build 84422 failed CdcClientMgrTest.StaleGenerationCannotTerminateAReusedNumericPid: after stop() returned, the report pipe was at EOF instead of holding the child's 'T', and the test took 1026 ms where its neighbours in the same suite take ~600 ms - the 200 ms grace in terminate_and_reap_child expired and the forced kill collected the child.

The child's trap is the witness for the graceful half of the reap, and it was spawned with posix_spawn(..., &actions, nullptr, ...), so it inherited whatever process-wide signal state doris_be_test was in. Every suite in that binary runs in one process, so 13k tests' worth of state precedes this one, and when SIGTERM is ignored or blocked there the witness cannot fire at all: a non-interactive shell refuses to trap a signal that was ignored on entry, silently - `trap -p TERM` stays empty and nothing is printed - and a blocked signal is never delivered. The forced kill also leaves the pipe at EOF, so the failure reads as "stop() never delivered SIGTERM", which is what the first assertion's message claimed.

Reproduced on this machine with the real test binary: with the pre-fix test body and SIGTERM ignored in the test process, the case fails at cdc_client_mgr_test.cpp:601 and :603 - the same lines and the same shape the CI reported, 256 ms against 26 ms when it passes. The same reproduction was also done with a standalone program that posix_spawns the same child, which additionally shows that bash 3.2, 4.2 and 5.3 all run the trap in under a millisecond when the parent is clean, so the shell is not where the difference lives.

The child therefore gets POSIX_SPAWN_SETSIGDEF (SIGTERM and SIGCHLD to SIG_DFL, which also keeps its own `wait` off an inherited SIGCHLD=SIG_IGN - the case python_env_test.cpp resets by hand) and POSIX_SPAWN_SETSIGMASK with an empty set. This does not narrow what the test exercises: terminate_and_reap_child still signals a child that starts with the default disposition and an empty mask, which is what a freshly exec'd child has in a deployment. The first assertion's message now reports that the child was collected without reporting the trap, instead of asserting that the signal was never sent.

### Release note

None

### Check List (For Author)

- Test: Manual test, on the real binary. Built with BUILD_TYPE_UT=Debug (ASAN deadlocks at startup on this Mac) and ran three ways: (1) the whole suite as run-be-ut.sh builds and runs it - 35/35 passed, this case at 29 ms; (2) the same binary with SIGTERM ignored in the test process, which is the CI's inherited state - passed at 26 ms; (3) the same binary with the pre-fix test body in that same CI-like environment - failed at cdc_client_mgr_test.cpp:601 and :603, reproducing the CI failure. A standalone posix_spawn probe additionally covered the blocked-mask variant of the same state and the shell versions. build-support/check-build-hygiene.sh passes; clang-format 16.0.6 (Homebrew llvm@16) reports no replacements for the changed file.
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Code <[email protected]>
### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: A SIGCHLD handler can read CDC child generation N before claiming its operation token. If N is reaped and generation N+1 is published first, the delayed handler can claim stale N. The N+1 handler then drops its only exit notification behind that stale claim, leaving the child published as a zombie. Recheck the current generation after a stale claim is released so the delayed handler collects the successor. Add a deterministic cross-generation test. Strengthen the non-child, unrelated-child cleanup, and stale-PID tests so their assertions observe the intended signals and release test children on failure.

### Release note

Prevent an exited CDC client from remaining published as a zombie when an older SIGCHLD handler races with a replacement child.

### Check List (For Author)

- Test: Unit Test: BUILD_TYPE_UT=Debug ./run-be-ut.sh --run --filter='CdcClientMgrTest.*:FormatRoundTest.*' -j 8 (44/44 passed, including 36 CDC tests; temporary local exclusions for unrelated macOS-incompatible tests were reverted before commit). Manual test: clang-format, check-format, build hygiene, and git diff --check passed. Clang-tidy was attempted but did not complete because of libc++ system-header parse errors on this Mac.
- Behavior changed: Yes. A delayed handler now rechecks the current CDC generation after releasing a stale claim and can reap its exited successor.
- Does this need documentation: No
@morningman
morningman force-pushed the fix-cdc-client-sigchld branch from e1699c5 to 0608d7a Compare September 28, 2026 02:03
@morningman

Copy link
Copy Markdown
Contributor Author

run buildall

@JNSimba JNSimba left a comment

Copy link
Copy Markdown
Member

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
TPC-H: Total hot run time: 28024 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 0608d7a585c7c523e0243deff76e215cfb403574, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17621	3794	3826	3794
q2	2158	380	321	321
q3	10063	1416	798	798
q4	4683	472	350	350
q5	7464	835	565	565
q6	193	179	137	137
q7	728	793	601	601
q8	9287	1626	1536	1536
q9	5468	4222	4178	4178
q10	6821	1317	1010	1010
q11	427	278	260	260
q12	636	408	287	287
q13	18087	2622	2005	2005
q14	255	263	234	234
q15	q16	736	718	659	659
q17	1812	1213	1117	1117
q18	6511	5598	5535	5535
q19	1187	1243	1109	1109
q20	500	415	277	277
q21	5518	3318	2934	2934
q22	466	386	317	317
Total cold run time: 100621 ms
Total hot run time: 28024 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4651	4683	4386	4386
q2	733	564	532	532
q3	4753	5149	4569	4569
q4	2233	2333	1469	1469
q5	4680	4360	4640	4360
q6	231	171	131	131
q7	1788	1697	1489	1489
q8	2482	2036	2009	2009
q9	7287	7238	7264	7238
q10	3668	3596	3070	3070
q11	573	365	336	336
q12	704	710	502	502
q13	2280	2632	2002	2002
q14	284	287	244	244
q15	q16	661	674	595	595
q17	7300	6716	6660	6660
q18	11948	11131	11725	11131
q19	1082	1005	992	992
q20	2201	2178	1899	1899
q21	4967	4109	4283	4109
q22	514	447	412	412
Total cold run time: 65020 ms
Total hot run time: 58135 ms

@hello-stephen

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

query5	4318	622	449	449
query6	429	207	216	207
query7	4928	514	259	259
query8	318	179	169	169
query9	8804	3956	3938	3938
query10	459	305	264	264
query11	5849	3553	3207	3207
query12	145	86	87	86
query13	1249	561	402	402
query14	6488	4448	4234	4234
query14_1	3941	3965	3953	3953
query15	201	198	186	186
query16	1002	458	434	434
query17	899	675	550	550
query18	2441	458	340	340
query19	200	181	139	139
query20	81	81	80	80
query21	219	132	116	116
query22	12993	12942	12777	12777
query23	13974	12965	12449	12449
query23_1	12689	12543	12448	12448
query24	7282	1174	661	661
query24_1	716	679	750	679
query25	567	439	374	374
query26	1288	299	168	168
query27	2721	565	340	340
query28	4573	2010	1989	1989
query29	1601	739	522	522
query30	301	220	189	189
query31	901	758	633	633
query32	146	105	106	105
query33	522	303	254	254
query34	1177	1149	635	635
query35	708	746	626	626
query36	812	809	738	738
query37	152	111	95	95
query38	1829	1764	1698	1698
query39	719	668	675	668
query39_1	656	651	646	646
query40	224	127	104	104
query41	73	70	69	69
query42	98	95	94	94
query43	333	348	304	304
query44	1370	726	721	721
query45	193	181	163	163
query46	1098	1168	722	722
query47	1500	1537	1388	1388
query48	397	398	299	299
query49	589	417	299	299
query50	995	340	246	246
query51	10702	10721	10831	10721
query52	89	88	73	73
query53	242	249	178	178
query54	245	219	210	210
query55	76	74	68	68
query56	234	208	200	200
query57	1485	1338	1355	1338
query58	287	253	246	246
query59	2004	2066	1859	1859
query60	270	238	218	218
query61	143	143	142	142
query62	394	319	266	266
query63	216	169	170	169
query64	2768	971	802	802
query65	3480	3406	3407	3406
query66	1772	419	316	316
query67	20011	20118	19748	19748
query68	3279	1484	972	972
query69	397	310	246	246
query70	912	832	806	806
query71	291	250	218	218
query72	2576	2528	2281	2281
query73	809	756	431	431
query74	4609	4459	4277	4277
query75	2297	2298	1927	1927
query76	2334	1093	741	741
query77	353	399	302	302
query78	9262	9048	8482	8482
query79	1370	1200	716	716
query80	764	451	368	368
query81	545	327	288	288
query82	631	162	132	132
query83	282	225	194	194
query84	317	146	117	117
query85	982	468	372	372
query86	367	240	233	233
query87	1987	1945	1840	1840
query88	3615	2714	2723	2714
query89	356	284	246	246
query90	1737	186	177	177
query91	173	158	126	126
query92	100	89	87	87
query93	1449	1498	884	884
query94	586	361	291	291
query95	661	372	348	348
query96	996	780	348	348
query97	2448	2416	2325	2325
query98	159	153	162	153
query99	734	769	619	619
Total cold run time: 236607 ms
Total hot run time: 152577 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.09	0.06	0.05
query3	0.26	0.14	0.13
query4	1.61	0.14	0.14
query5	0.25	0.23	0.22
query6	1.15	0.91	0.94
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.40	0.33	0.34
query10	0.55	0.58	0.59
query11	0.21	0.14	0.14
query12	0.18	0.15	0.15
query13	0.47	0.46	0.47
query14	0.95	0.96	0.94
query15	0.60	0.58	0.57
query16	0.32	0.34	0.31
query17	1.08	1.09	1.10
query18	0.22	0.19	0.20
query19	1.99	1.99	1.96
query20	0.02	0.01	0.01
query21	15.48	0.21	0.15
query22	4.83	0.05	0.05
query23	16.10	0.30	0.13
query24	2.99	0.45	0.31
query25	0.11	0.05	0.04
query26	0.74	0.21	0.14
query27	0.05	0.04	0.03
query28	3.58	0.79	0.37
query29	12.53	4.04	3.22
query30	0.28	0.17	0.14
query31	2.77	0.56	0.30
query32	3.22	0.59	0.49
query33	3.12	3.18	3.19
query34	15.64	3.94	3.27
query35	3.23	3.21	3.22
query36	0.55	0.43	0.45
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.02
query40	0.17	0.15	0.15
query41	0.09	0.03	0.03
query42	0.04	0.02	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.2 s
Total hot run time: 24.04 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (2/2) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 64.12% (29859/46565)
Line Coverage 48.76% (311347/638591)
Region Coverage 44.25% (251078/567429)
Branch Coverage 45.81% (116749/254842)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 66.65% (30041/45076)
Line Coverage 51.03% (322105/631261)
Region Coverage 46.80% (264468/565117)
Branch Coverage 47.92% (121730/254035)

@morningman

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: {"type":"error","status":400,"error":{"type":"invalid_request_error","message":"The 'gpt-6-sol' model is not supported when using Codex with a ChatGPT account."}}
Workflow run: https://github.com/apache/doris/actions/runs/36383868797

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

@shuke987

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.

Static review of exact head 0608d7a585c7c523e0243deff76e215cfb403574 found no new distinct inline findings. I request changes because three concerns remain in the current code and are already covered by inline threads: the unbounded wait after SIGKILL, the synchronous handler-contention probes that can hang the shared test binary, and the production startup branches bypassed by BE_TEST. I am not reposting duplicate inline comments.

Critical checkpoints:

  • Goal and correctness: Exact-PID waitpid avoids reaping unrelated BE children. The generation-qualified operation claim, pending-reap bit, and stale-handler retry close the reviewed same- and cross-generation handoffs. Failed-start cleanup can still block the CDC lifecycle indefinitely at the already-threaded post-SIGKILL wait.
  • Scope and clarity: The change is confined to the CDC manager, its header, and tests. The ownership state machine is complex but documented near its operations.
  • Concurrency and lifecycle: The process-wide SIGCHLD handler, RPC and HttpFileReader callers, singleton ExecEnv manager, fork/publication, health inspection, adoption, stop, and destruction were traced. Start and stop serialize on _start_mutex; the handler uses lock-free atomics and exact-generation claims. No additional lost notification, double owner, stale-PID syscall, lock-order defect, or static-initialization hazard was substantiated.
  • Error handling: EINTR, ECHILD, early exit, and ownership revocation were checked. The unbounded wait after a failed-start SIGKILL remains a concrete error-path defect.
  • Memory and resource safety: The handler allocates nothing, the new atomics require no dynamic initialization, and exact-PID collection is intended to release child-process resources. No new cache, tracked-buffer, or ownership-cycle path is introduced.
  • Parallel paths, compatibility, and configuration: Both CDC callers use the same manager. No new configuration, FE/BE variable, protocol, storage format, transaction, persistence, data-write, or rolling-upgrade contract is introduced. No separate performance or observability defect was substantiated; normal-thread lifecycle logs remain and the handler does no allocation or logging.
  • Tests: Direct-child force kill, unrelated-child isolation, stale generations, and pending-reap handoff have BE unit cases. The production-only fork/health/adoption path has no direct test, and three contention checks can hang rather than fail. The relevant details are already inline.
  • Validation: Static inspection only, as required for this review runner. I did not build, run tests, or treat author/CI claims as independent validation.
  • User focus: No additional focus was supplied.

The single main risk scan, both normal full reviews, and the risk-focused review converged with no new valuable findings; every candidate was checked against the existing threads.

@morningman
morningman merged commit a6431d7 into apache:master Sep 28, 2026
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants