Skip to content

[fix](be) Guard Segment::_footer_pb against concurrent re-assignment - #69811

Closed
airborne12 wants to merge 2 commits into
apache:masterfrom
airborne12:segment-footer-weak-ptr-race
Closed

airborne12 wants to merge 2 commits into
apache:masterfrom
airborne12:segment-footer-weak-ptr-race

Conversation

@airborne12

@airborne12 airborne12 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Segment::_footer_pb is a std::weak_ptr to the footer owned by the storage page
cache. _get_segment_footer() calls lock() on it and, once the cache entry has been evicted,
parses the footer again and assigns the weak_ptr; get_metadata_size() calls lock() as well. A
Segment is shared by every reader of its rowset (queries, compaction, statistics), so lock() and
the assignment run on the same weak_ptr object concurrently. That is a data race: the standard
only allows concurrent use of distinct weak_ptr objects, and the control block counts can be
corrupted so that a footer still held through a shared_ptr gets destroyed.

_footer_pb is now an atomic_weak_ptr, loaded with acquire and stored with release.
atomic_weak_ptr is new in common/atomic_shared_ptr.h, next to atomic_shared_ptr. With libstdc++ it
is the C++20 std::atomic<std::weak_ptr>. libc++, which the macOS build uses, has no
std::atomic<std::weak_ptr> (libc++ 20 rejects it), so there it is a weak_ptr guarded by a
mutex, the same way atomic_shared_ptr falls back for shared_ptr. With libstdc++ the member keeps
the 16 bytes of the plain weak_ptr, so Segment does not grow.

The new test fetches the footer from 8 threads while half of them keep evicting its cache page.
On master's segment.cpp, ASAN reported a heap-use-after-free within 20 runs: a thread read the
footer it had just obtained (SegmentFooterPB::ByteSizeLong) after another thread had freed it in
std::weak_ptr assignment (__weak_count::operator= -> _M_weak_release -> _M_destroy). With the
change, rebased on the current master, all six SegmentFooterCacheTest cases passed 20 of 20
repeats without an ASAN report.

The race was found while investigating BE crashes on large VARIANT tables under heavy
compaction; those crashes had a different cause (the host kernel with jemalloc MADV_FREE).

Release note

Fix a data race on the cached segment footer that could free a footer still in use.

Check List (For Author)

  • Test: Unit Test (SegmentFooterCacheTest.ConcurrentGetSegmentFooterWithEviction; ASAN
    heap-use-after-free without the change within 20 runs; with it all SegmentFooterCacheTest
    cases pass 20 of 20 repeats under ASAN).
    atomic_weak_ptr was also stress-tested on its own (8 threads storing and locking) with
    libstdc++ and with libc++ 20 (-DUSE_LIBCPP), each with and without ASAN.
  • Behavior changed: No
  • Does this need documentation: No

🤖 Generated with Claude Code

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

@airborne12

Copy link
Copy Markdown
Member Author

/review

@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@airborne12
airborne12 marked this pull request as ready for review October 29, 2026 05:39

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed all three changed files at ce706bb and traced Segment loading, column-reader callbacks, page-cache eviction/replacement, metadata accounting, and the test fixture. No actionable new findings. There are no existing inline findings to retain, and no additional user focus was supplied.

  • Goal and regression: the two accessors serialize every production access to the same footer weak_ptr, including metadata sizing. The new eviction stress test exercises retrieval and metadata reads; its execution was not verified here.
  • Scope and reuse: the mutex, two private helpers, three call-site substitutions, and one existing-fixture test form a focused change consistent with adjacent locking patterns.
  • Concurrency: cached Segment instances can be shared among readers. The new per-instance mutex protects weak_ptr promotion and reassignment independently of callers' locks.
  • Work inside locks: only weak-pointer operations run under the new mutex; file reads, parsing, protobuf sizing, and page-cache operations remain outside it.
  • Lock order: column-reader cache locking can precede the footer mutex, but neither footer accessor acquires another application lock or invokes a callback. No new lock cycle was identified.
  • Lifecycle and memory: cache handles pin entries during extraction, and copied shared_ptrs keep returned footers alive across eviction and replacement. Weak ownership adds no cycle; sizeof(Segment) accounting includes the mutex. No new static initialization dependency or payload allocation is introduced.
  • Configuration: no new configuration or dynamic-update behavior.
  • Compatibility: no storage format, wire contract, persisted layout, dependency, or linker changes. The synchronization primitive is already used by Segment.
  • Thrift/protobuf definitions: none changed; field-ID comparisons are inapplicable.
  • Parallel paths: metadata sizing and both footer retrieval paths use the helpers. Local and cloud/remote consumers share this Segment implementation; no separate footer access requires the fix.
  • Conditions and comments: no production branch changes. The ownership comment explains the race; duplicate concurrent misses may return separate equivalent footer objects safely.
  • Test coverage: eight workers attach thread contexts, check status/footer content/metadata sizing, and join before fixture teardown. Existing cache and I/O-context tests remain. Test discovery and private access follow the existing BE-UT configuration, with no new source .cpp inclusion.
  • Test results: no expected-result files changed. No builds, tests, sanitizers, or benchmarks were run during this static review; the author's reported runs were not independently reproduced.
  • Observability: existing cache-hit/miss diagnostics and parse-error context remain adequate for this synchronization change; no new noisy logging.
  • Transactions and persistence: no changes to version visibility, delete bitmaps, EditLog, replay, or failover behavior.
  • Data writes and crash atomicity: no persistent-data mutation or new write protocol; footer parsing and error propagation remain unchanged.
  • FE/BE variables: none added; no propagation changes required.
  • Performance: short constant-time locking and one per-Segment mutex are the added costs; parsing stays outside the mutex. No new redundant scan or copying of footer payloads was found. Performance was not measured.
  • Other checks: no new ignored Status, nullable handling, header dependency, explicit-instantiation pairing, or unity-build concern was identified.

The review converged in round 1: both independent reviewers returned NO_NEW_VALUABLE_FINDINGS, all changed code and applicable checkpoints were covered, and both initial risk focuses were dismissed with ownership/lock/test evidence. No unresolved correctness candidate remains. Validation limits: the stress test is scheduling-dependent because active readers can keep a footer alive after erasure; it does not guarantee reload/reassignment overlap on every run. Runtime, sanitizer, and end-to-end remote/variant validation were outside this static-only review.

Review converged after 1 round(s).

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

Yes—C++20 provides std::atomic<std::weak_ptr>, which could replace the explicit mutex here:
std::atomic<std::weak_ptr> _footer_pb;

// Read
auto footer = _footer_pb.load(std::memory_order_acquire).lock();

// Write
_footer_pb.store(std::weak_ptr{footer},
std::memory_order_release);

martin.foo838 and others added 2 commits October 29, 2026 06:14
### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Segment::_footer_pb is a std::weak_ptr to the footer owned by the storage page
cache. _get_segment_footer() calls lock() on it and, once the cache entry has been evicted,
parses the footer again and assigns the weak_ptr; get_metadata_size() calls lock() as well. A
Segment is shared by every reader of its rowset (queries, compaction, statistics), so lock() and
the assignment run on the same weak_ptr object concurrently. That is a data race: the standard
only allows concurrent use of distinct weak_ptr objects, and the control block counts can be
corrupted so that a footer still held through a shared_ptr gets destroyed.

Every access to _footer_pb now goes through two small accessors that take a mutex.

The new test fetches the footer from 8 threads while half of them keep evicting its cache page.
On master's segment.cpp, ASAN reported a heap-use-after-free within 20 runs: a thread read the
footer it had just obtained (SegmentFooterPB::ByteSizeLong) after another thread had freed it in
std::weak_ptr assignment (__weak_count::operator= -> _M_weak_release -> _M_destroy). With the
change, 20 of 20 runs passed without an ASAN report.

The race was found while investigating BE crashes on large VARIANT tables under heavy
compaction; those crashes had a different cause (the host kernel with jemalloc MADV_FREE).

### Release note

Fix a data race on the cached segment footer that could free a footer still in use.

### Check List (For Author)

- Test: Unit Test (SegmentFooterCacheTest.ConcurrentGetSegmentFooterWithEviction; ASAN
  heap-use-after-free without the change within 20 runs, 20/20 clean with it; the other
  SegmentFooterCacheTest cases pass)
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… mutex

Review suggestion: the C++20 std::atomic<std::weak_ptr<T>> serializes lock() against the
re-assignment just as the mutex did, without the two accessors.

The macOS build uses libc++, which has no std::atomic<std::weak_ptr<T>> (libc++ 20 rejects it:
std::atomic<T> requires a trivially copyable T), and std::atomic_load has no weak_ptr overload.
So common/atomic_shared_ptr.h gets an atomic_weak_ptr next to atomic_shared_ptr: the standard
type with libstdc++, a weak_ptr behind a mutex with libc++. With libstdc++ the member is 16 bytes
like the plain weak_ptr, so Segment no longer grows by the 40-byte mutex that
get_metadata_size() counts through sizeof(Segment).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airborne12
airborne12 force-pushed the segment-footer-weak-ptr-race branch from ce706bb to 36327d6 Compare October 29, 2026 06:35
@airborne12

Copy link
Copy Markdown
Member Author

C++20 provides std::atomic<std::weak_ptr>, which could replace the explicit mutex here

Thanks, done in 36327d6: _footer_pb is now atomic_weak_ptr<SegmentFooterPB>, loaded with acquire and stored with release, and the two accessors and the mutex are gone.

atomic_weak_ptr is new in common/atomic_shared_ptr.h, next to atomic_shared_ptr. With libstdc++ it is exactly std::atomic<std::weak_ptr<T>>. The macOS build uses libc++, which rejects std::atomic<std::weak_ptr<T>> (libc++ 20.1: "std::atomic requires that 'T' be a trivially copyable type") and has no std::atomic_load overload for weak_ptr, so there it falls back to a weak_ptr behind a mutex, as atomic_shared_ptr does for shared_ptr. With libstdc++ the member is back to the 16 bytes of a plain weak_ptr, so Segment no longer carries a 40-byte mutex.

The branch is rebased on the current master, and all six SegmentFooterCacheTest cases pass 20 of 20 repeats under ASAN with no report.

@airborne12

Copy link
Copy Markdown
Member Author

/review

@airborne12

Copy link
Copy Markdown
Member Author

run buildall

1 similar comment
@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

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

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

@airborne12

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17622	5203	5066	5066
q2	2168	316	259	259
q3	10217	1386	855	855
q4	4684	461	336	336
q5	7442	799	526	526
q6	186	186	154	154
q7	760	805	606	606
q8	9278	1383	1062	1062
q9	5684	4207	4167	4167
q10	6839	1301	1033	1033
q11	433	246	222	222
q12	636	395	279	279
q13	18123	3574	3031	3031
q14	279	271	243	243
q15	q16	709	711	649	649
q17	1201	751	574	574
q18	7033	6185	6147	6147
q19	1102	962	590	590
q20	382	334	225	225
q21	4792	2128	2288	2128
q22	349	297	257	257
Total cold run time: 99919 ms
Total hot run time: 28409 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5611	5614	5732	5614
q2	685	598	543	543
q3	5177	5422	4933	4933
q4	2166	2143	1572	1572
q5	5234	5161	5719	5161
q6	260	196	160	160
q7	2353	2017	1861	1861
q8	3016	2665	2655	2655
q9	8129	7972	8008	7972
q10	3991	3690	3303	3303
q11	633	447	411	411
q12	715	706	520	520
q13	3480	3925	3242	3242
q14	338	318	269	269
q15	q16	692	737	643	643
q17	8069	7007	6883	6883
q18	13080	12208	12886	12208
q19	922	799	809	799
q20	2166	2135	1914	1914
q21	5629	4589	5230	4589
q22	529	480	399	399
Total cold run time: 72875 ms
Total hot run time: 65651 ms

@hello-stephen

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

query5	4305	603	445	445
query6	419	210	189	189
query7	4795	454	232	232
query8	315	164	151	151
query9	8780	3252	3243	3243
query10	476	300	255	255
query11	5976	3876	3559	3559
query12	148	91	89	89
query13	1245	450	331	331
query14	6138	3941	3658	3658
query14_1	3397	3406	3382	3382
query15	207	204	185	185
query16	947	420	399	399
query17	886	649	516	516
query18	2423	409	301	301
query19	190	156	137	137
query20	81	81	79	79
query21	206	125	103	103
query22	12918	12983	12691	12691
query23	13582	12838	12438	12438
query23_1	12627	12575	12566	12566
query24	7363	817	472	472
query24_1	508	487	501	487
query25	513	398	341	341
query26	1258	257	140	140
query27	2771	441	274	274
query28	4635	2083	2048	2048
query29	1549	572	432	432
query30	305	223	180	180
query31	1005	926	839	839
query32	138	89	91	89
query33	510	286	232	232
query34	922	855	499	499
query35	728	753	646	646
query36	808	809	743	743
query37	123	96	86	86
query38	1765	1743	1694	1694
query39	788	797	749	749
query39_1	732	736	739	736
query40	216	122	100	100
query41	90	68	69	68
query42	90	91	86	86
query43	346	371	310	310
query44	1339	710	722	710
query45	180	172	170	170
query46	842	973	563	563
query47	2881	2955	2770	2770
query48	312	318	231	231
query49	581	402	299	299
query50	699	274	229	229
query51	10540	10476	10117	10117
query52	83	79	69	69
query53	194	214	154	154
query54	269	199	186	186
query55	70	67	65	65
query56	246	217	233	217
query57	1669	1643	1558	1558
query58	295	275	259	259
query59	2186	2121	1986	1986
query60	297	255	237	237
query61	171	162	203	162
query62	393	331	281	281
query63	189	156	157	156
query64	2742	964	791	791
query65	3330	3279	3304	3279
query66	1782	417	293	293
query67	20367	20237	20076	20076
query68	3211	1008	616	616
query69	399	300	259	259
query70	851	802	777	777
query71	300	223	213	213
query72	2830	2709	2374	2374
query73	527	529	294	294
query74	4668	4485	4353	4353
query75	2348	2304	1886	1886
query76	2403	1013	643	643
query77	363	381	272	272
query78	9941	9656	9261	9261
query79	1078	862	535	535
query80	555	430	370	370
query81	535	322	269	269
query82	578	130	103	103
query83	303	198	178	178
query84	313	125	101	101
query85	810	428	368	368
query86	324	237	227	227
query87	2001	1948	1808	1808
query88	3764	2757	2751	2751
query89	329	282	233	233
query90	1893	176	168	168
query91	203	151	129	129
query92	102	94	89	89
query93	1032	1024	578	578
query94	440	320	283	283
query95	596	404	301	301
query96	677	490	236	236
query97	2447	2427	2347	2347
query98	165	149	146	146
query99	774	754	651	651
Total cold run time: 235402 ms
Total hot run time: 151262 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.10	0.05	0.04
query3	0.26	0.09	0.09
query4	1.61	0.10	0.10
query5	0.23	0.23	0.24
query6	1.18	0.69	0.67
query7	0.04	0.00	0.00
query8	0.06	0.03	0.03
query9	0.41	0.34	0.35
query10	0.61	0.58	0.58
query11	0.20	0.14	0.14
query12	0.18	0.14	0.15
query13	0.49	0.49	0.50
query14	1.03	1.02	1.01
query15	0.63	0.61	0.61
query16	0.35	0.34	0.34
query17	1.15	1.09	1.14
query18	0.21	0.19	0.20
query19	2.10	1.98	1.93
query20	0.02	0.01	0.01
query21	15.41	0.20	0.13
query22	4.82	0.06	0.05
query23	16.32	0.31	0.12
query24	3.20	0.62	0.37
query25	0.11	0.07	0.05
query26	1.19	0.21	0.14
query27	0.04	0.03	0.05
query28	3.35	0.78	0.36
query29	12.51	4.16	3.29
query30	0.30	0.13	0.10
query31	2.77	0.56	0.33
query32	3.23	0.60	0.50
query33	3.28	3.21	3.19
query34	15.30	3.99	3.38
query35	3.35	3.35	3.35
query36	0.56	0.48	0.43
query37	0.09	0.07	0.06
query38	0.06	0.03	0.04
query39	0.04	0.03	0.03
query40	0.18	0.15	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.04	0.03
Total cold run time: 97.15 s
Total hot run time: 24.21 s

@airborne12

Copy link
Copy Markdown
Member Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

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

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

@airborne12

Copy link
Copy Markdown
Member Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17596	5215	5160	5160
q2	2168	317	251	251
q3	10236	1432	850	850
q4	4686	465	348	348
q5	7460	810	542	542
q6	180	181	152	152
q7	753	845	620	620
q8	9270	1398	1128	1128
q9	5599	4230	4240	4230
q10	6841	1285	1011	1011
q11	434	249	231	231
q12	640	405	292	292
q13	18087	3630	3050	3050
q14	280	277	241	241
q15	q16	734	712	672	672
q17	1210	760	590	590
q18	7148	6183	6122	6122
q19	1251	960	600	600
q20	400	347	221	221
q21	5777	2373	2433	2373
q22	376	326	263	263
Total cold run time: 101126 ms
Total hot run time: 28947 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5986	5864	5992	5864
q2	754	619	601	601
q3	5712	5900	5342	5342
q4	2039	2184	1776	1776
q5	5666	5852	5566	5566
q6	241	184	148	148
q7	2233	2087	1815	1815
q8	3006	2695	2702	2695
q9	7920	7460	7487	7460
q10	3612	3629	3124	3124
q11	585	412	383	383
q12	683	661	506	506
q13	3397	3682	3081	3081
q14	298	301	262	262
q15	q16	660	682	633	633
q17	7815	7045	6973	6973
q18	12972	12182	12885	12182
q19	924	795	789	789
q20	2133	2140	1920	1920
q21	5689	4706	4716	4706
q22	492	441	408	408
Total cold run time: 72817 ms
Total hot run time: 66234 ms

@hello-stephen

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

query5	4311	605	460	460
query6	435	208	196	196
query7	4802	455	237	237
query8	326	186	150	150
query9	8758	3249	3288	3249
query10	470	317	263	263
query11	6015	3880	3568	3568
query12	153	95	89	89
query13	1266	477	341	341
query14	6146	3947	3647	3647
query14_1	3410	3454	3436	3436
query15	212	199	187	187
query16	952	428	403	403
query17	869	652	538	538
query18	2442	423	310	310
query19	203	170	143	143
query20	90	84	85	84
query21	212	129	109	109
query22	13001	13014	12791	12791
query23	13399	12953	12497	12497
query23_1	12628	12504	12651	12504
query24	7351	855	485	485
query24_1	489	485	489	485
query25	550	426	362	362
query26	1267	264	142	142
query27	2755	444	279	279
query28	4613	2097	2073	2073
query29	1577	607	454	454
query30	310	229	192	192
query31	1006	936	817	817
query32	162	97	91	91
query33	529	315	250	250
query34	912	873	507	507
query35	751	759	662	662
query36	821	817	784	784
query37	130	107	104	104
query38	1778	1744	1663	1663
query39	811	787	741	741
query39_1	737	725	740	725
query40	230	125	98	98
query41	73	68	68	68
query42	94	85	92	85
query43	352	368	312	312
query44	1344	719	750	719
query45	177	178	170	170
query46	835	1025	574	574
query47	2816	2873	2919	2873
query48	293	316	221	221
query49	574	398	297	297
query50	703	279	206	206
query51	10513	10554	10402	10402
query52	79	78	75	75
query53	189	204	151	151
query54	255	212	170	170
query55	75	69	65	65
query56	232	210	203	203
query57	1663	1603	1581	1581
query58	285	259	252	252
query59	2140	2161	2069	2069
query60	282	240	224	224
query61	150	143	146	143
query62	393	329	281	281
query63	198	154	170	154
query64	2783	955	767	767
query65	3336	3275	3284	3275
query66	1778	421	304	304
query67	20351	20087	20029	20029
query68	2927	1030	632	632
query69	388	290	258	258
query70	860	799	765	765
query71	307	247	210	210
query72	2705	2614	2254	2254
query73	524	535	300	300
query74	4665	4494	4353	4353
query75	2356	2313	1929	1929
query76	2336	1017	620	620
query77	347	375	277	277
query78	9774	9725	9148	9148
query79	1040	869	543	543
query80	1252	425	359	359
query81	578	330	272	272
query82	926	132	109	109
query83	307	195	180	180
query84	315	122	102	102
query85	867	424	361	361
query86	410	243	225	225
query87	1992	1933	1788	1788
query88	3924	2799	2766	2766
query89	339	288	241	241
query90	1880	179	172	172
query91	168	168	139	139
query92	101	88	87	87
query93	1083	1025	590	590
query94	652	305	236	236
query95	579	337	314	314
query96	683	500	245	245
query97	2429	2442	2290	2290
query98	166	154	147	147
query99	789	767	633	633
Total cold run time: 236337 ms
Total hot run time: 151697 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.09	0.05	0.05
query3	0.26	0.09	0.09
query4	1.61	0.10	0.10
query5	0.24	0.25	0.25
query6	1.17	0.69	0.68
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.41	0.34	0.34
query10	0.57	0.58	0.63
query11	0.20	0.15	0.14
query12	0.18	0.16	0.13
query13	0.49	0.50	0.50
query14	1.05	1.03	1.00
query15	0.63	0.61	0.62
query16	0.35	0.35	0.32
query17	1.16	1.10	1.11
query18	0.20	0.19	0.20
query19	2.09	1.96	1.93
query20	0.01	0.01	0.01
query21	15.52	0.20	0.14
query22	4.80	0.06	0.05
query23	16.26	0.32	0.13
query24	3.17	0.54	0.34
query25	0.12	0.05	0.05
query26	1.02	0.23	0.15
query27	0.05	0.04	0.05
query28	3.41	0.71	0.40
query29	12.50	4.12	3.29
query30	0.28	0.14	0.10
query31	2.77	0.56	0.32
query32	3.23	0.61	0.49
query33	3.11	3.18	3.18
query34	15.49	3.99	3.37
query35	3.34	3.32	3.34
query36	0.58	0.47	0.42
query37	0.11	0.06	0.07
query38	0.04	0.04	0.03
query39	0.03	0.03	0.03
query40	0.18	0.15	0.15
query41	0.09	0.03	0.04
query42	0.04	0.03	0.03
query43	0.05	0.04	0.03
Total cold run time: 97.01 s
Total hot run time: 24.22 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 67.20% (32527/48404)
Line Coverage 52.07% (344489/661591)
Region Coverage 47.51% (280031/589402)
Branch Coverage 49.20% (132218/268740)

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

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

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

@airborne12

Copy link
Copy Markdown
Member Author

/review

@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 77.30% (36273/46928)
Line Coverage 62.51% (409379/654926)
Region Coverage 58.93% (346360/587703)
Branch Coverage 59.83% (160555/268367)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the complete exact-head diff for PR 69811 (36327d6) across atomic_shared_ptr.h, Segment footer access, and the SegmentFooterCacheTest. No actionable new finding was verified, and there are no existing P0/P1 inline findings to retain.

The change meets the stated goal: C++20 uses atomic weak-pointer load/store, libc++ uses a mutex-backed equivalent, and all production _footer_pb accesses are covered. Segment is explicitly non-copyable; footer cache handles keep erased entries alive until release; parsed SegmentFooterPB values are finalized before publication and consumed read-only. The stress test attaches thread memory context, exercises concurrent eviction and footer reads, checks status/content/metadata, joins workers, and leaves fixture teardown ordered. No configuration, protocol, persistence, transaction, nullable, or FE/BE propagation changes apply.

The review is static-only: no build, test, sanitizer, benchmark, or runtime execution was performed. The stress test is scheduling-dependent and may not force a reload overlap on every run. No additional user focus was supplied. Independent child review workers repeatedly failed before returning due model-capacity errors, so the required independent-subagent convergence condition could not be proven even after the three bounded rounds; the verified main-agent sweep and all candidate dispositions are recorded in the shared ledger.

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

The three-round cap was reached without independent subagent returns: every replacement child review failed with the same model-capacity error before producing a ledger section. Main-agent coverage completed all four changed files, upstream/downstream cache and lifecycle paths, test paths, and risk dispositions; no unresolved candidate or uncovered changed-file scope remains, but the contract requires converged=false when the independent-subagent condition is unproven.

@gavinchou

Copy link
Copy Markdown
Contributor

similar PR #67720

@airborne12

Copy link
Copy Markdown
Member Author

Thanks, I missed #67720. It fixes the same race and also removes the LRU bypass, as suggested there, so I'm closing this one in favor of it. I left two notes on #67720 (#67720 (comment)): the existing GetSegmentFooterPropagatesIoContext test still calls _footer_pb.reset(), which breaks its BE UT build, and the concurrency test from this PR can go along with it.

@airborne12 airborne12 closed this Oct 29, 2026
stinger1206 added a commit to stinger1206/doris that referenced this pull request Oct 29, 2026
… test

### What problem does this PR solve?

Issue Number: close apache#67719

Related PR: apache#67720

Problem Summary: PR apache#67720 removed Segment::_footer_pb, but
be/test/storage/segment/segment_footer_cache_test.cpp still called
segment_ptr->_footer_pb.reset() in GetSegmentFooterPropagatesIoContext,
so the BE UT build failed to compile. Per review feedback in apache#67720
(apache#67720 (comment)),
drop the stale line: the cache erase() right before it already forces
the reload through the cache-only path, so the SyncPoint on
Segment::_parse_footer::io_ctx still fires.

Also port SegmentFooterCacheTest.ConcurrentGetSegmentFooterWithEviction
from apache#69811 (thanks to @airborne12 for the original reproducer): 8
threads call _get_segment_footer() on a segment while half of them keep
erasing the footer's cache page; every caller must get a valid,
identical footer regardless of concurrent evictions. Adapted to this
PR's cache-only design: the get_metadata_size() check is dropped because
that method no longer reads the footer.

### Release note

None

### Check List (For Author)

- Test: Unit Test (this change itself is a test; BE UT run deferred to CI)
- Behavior changed: No
- Does this need documentation: No
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants