Skip to content

[Opt](cloud) Notify BE to make committed rowset visible directly after txn commit without fetching from meta service - #59754

Merged
liaoxin01 merged 7 commits into
apache:masterfrom
bobhan1:notify-be-visible-rs-after-load-txn-commit
Mar 18, 2026
Merged

liaoxin01 merged 7 commits into
apache:masterfrom
bobhan1:notify-be-visible-rs-after-load-txn-commit

Conversation

@bobhan1

@bobhan1 bobhan1 commented Jan 12, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Test

1FE+3BE, 400bucket mow table, 10 concurrency stream load

before:
image
after:
image


Problem Summary

In cloud storage mode, after a load transaction commits rowsets to Meta Service (MS), BE nodes need to fetch the committed rowset metadata from MS during subsequent sync_rowsets() operations. This introduces additional latency and MS query overhead, especially for high-frequency import scenarios.

This PR implements a notification mechanism where FE/BE directly notifies BE nodes about committed rowsets after transaction commit, allowing BE to update tablet metadata immediately without fetching from MS.

Solution

  1. CloudCommittedRSMgr (BE): A new in-memory manager that caches committed temporary rowset metadata after they are committed to MS
    - Stores rowset meta with expiration time
    - Supports efficient lookup by (txn_id, tablet_id)
    - Handles empty rowset markers
    - Background thread for cleaning expired entries
  2. Notification Flow:
    - When FE commits a load transaction to MS, it sends MakeCloudTmpRsVisibleTask to involved BE nodes
    - BE receives the task with final version/visible_ts information
    - BE promotes cached rowset metadata to tablet meta directly
    - BE can forward notification to FE if needed (for tablets not on the original BE)
  3. Configuration:
    - FE: enable_cloud_notify_be_after_load_txn_commit (default: false)
    - BE: enable_cloud_make_rs_visible_on_be (default: false)
    - BE: cloud_make_committed_rs_visible_worker_count (default: 4)
    - BE: cloud_mow_sync_rowsets_when_load_txn_begin (default: true)

Benefits

  • Reduces Meta Service query pressure by avoiding redundant rowset metadata fetches
  • Improves import latency by making rowsets visible faster
  • Optimizes cloud storage mode performance for high-frequency imports

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

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

@Thearas

Thearas commented Jan 12, 2026

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?

@bobhan1
bobhan1 force-pushed the notify-be-visible-rs-after-load-txn-commit branch 7 times, most recently from ed17b16 to 2394c9c Compare January 13, 2026 08:31
@bobhan1 bobhan1 changed the title [Opt](cloud) Notify BE to make committed rowset visible after txn commit directly without fetching from meta service [Opt](cloud) Notify BE to make committed rowset visible directly after txn commit without fetching from meta service Jan 13, 2026
@bobhan1
bobhan1 force-pushed the notify-be-visible-rs-after-load-txn-commit branch 5 times, most recently from 0a3020d to 59a710c Compare January 14, 2026 06:34
@bobhan1

bobhan1 commented Jan 14, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@doris-robot

Copy link
Copy Markdown

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 79.57% (1784/2242)
Line Coverage 64.76% (31732/48997)
Region Coverage 65.44% (15783/24120)
Branch Coverage 55.97% (8377/14968)

@doris-robot

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

------ Round 1 ----------------------------------
q1	17666	4245	4027	4027
q2	2044	349	234	234
q3	10184	1275	716	716
q4	10226	916	317	317
q5	7541	2088	1853	1853
q6	192	174	148	148
q7	918	793	647	647
q8	9252	1507	1159	1159
q9	4889	4607	4598	4598
q10	6767	1813	1411	1411
q11	522	292	287	287
q12	692	734	604	604
q13	17778	3902	3121	3121
q14	293	295	295	295
q15	581	511	502	502
q16	689	680	636	636
q17	663	780	528	528
q18	6538	6534	6525	6525
q19	903	957	593	593
q20	379	361	241	241
q21	2958	2440	2168	2168
q22	1041	1015	984	984
Total cold run time: 102716 ms
Total hot run time: 31594 ms

----- Round 2, with runtime_filter_mode=off -----
q1	4098	4039	4042	4039
q2	335	387	308	308
q3	2070	2607	2256	2256
q4	1312	1753	1364	1364
q5	4135	4094	4166	4094
q6	203	186	130	130
q7	1908	1788	1721	1721
q8	2823	2496	2503	2496
q9	7301	7327	7133	7133
q10	2436	2783	2336	2336
q11	577	493	467	467
q12	730	756	628	628
q13	3630	4016	3463	3463
q14	299	296	288	288
q15	548	509	492	492
q16	643	668	688	668
q17	1172	1365	1417	1365
q18	7862	7834	7661	7661
q19	835	827	852	827
q20	2065	2269	1872	1872
q21	4864	4298	4191	4191
q22	1120	1036	990	990
Total cold run time: 50966 ms
Total hot run time: 48789 ms

@doris-robot

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

query5	4404	607	472	472
query6	328	225	212	212
query7	4225	455	248	248
query8	332	276	235	235
query9	8702	2879	2858	2858
query10	539	379	335	335
query11	15162	15126	14940	14940
query12	170	115	111	111
query13	1260	468	363	363
query14	6250	2965	2748	2748
query14_1	2648	2681	2643	2643
query15	209	197	178	178
query16	1018	499	475	475
query17	1106	679	581	581
query18	2443	441	334	334
query19	229	230	198	198
query20	121	115	114	114
query21	217	137	124	124
query22	4051	4112	3988	3988
query23	16103	15495	15390	15390
query23_1	15711	15390	15547	15390
query24	7168	1536	1148	1148
query24_1	1184	1170	1164	1164
query25	557	477	430	430
query26	1247	280	163	163
query27	2743	485	267	267
query28	4531	2162	2138	2138
query29	764	504	403	403
query30	308	241	210	210
query31	806	620	546	546
query32	81	78	74	74
query33	510	334	296	296
query34	885	891	519	519
query35	718	762	667	667
query36	883	945	872	872
query37	137	101	81	81
query38	2687	2688	2646	2646
query39	784	766	733	733
query39_1	716	730	731	730
query40	218	131	118	118
query41	66	63	60	60
query42	104	100	100	100
query43	467	457	429	429
query44	1297	730	729	729
query45	184	176	176	176
query46	820	926	563	563
query47	1463	1502	1351	1351
query48	288	312	218	218
query49	611	415	340	340
query50	594	268	206	206
query51	3724	3979	3769	3769
query52	100	105	92	92
query53	286	319	266	266
query54	286	275	261	261
query55	78	80	72	72
query56	317	305	315	305
query57	1042	1044	927	927
query58	268	257	256	256
query59	2037	2121	2054	2054
query60	338	335	311	311
query61	163	152	154	152
query62	382	363	313	313
query63	291	256	268	256
query64	4982	1291	951	951
query65	3787	3834	3757	3757
query66	1442	439	327	327
query67	14861	15960	15730	15730
query68	4718	1002	714	714
query69	482	356	315	315
query70	1054	953	942	942
query71	350	313	285	285
query72	5683	3303	3674	3303
query73	746	699	303	303
query74	8732	8825	8545	8545
query75	2784	2805	2462	2462
query76	3415	1061	631	631
query77	511	368	303	303
query78	9824	9791	9292	9292
query79	1659	880	561	561
query80	680	589	493	493
query81	500	264	229	229
query82	215	146	108	108
query83	271	262	243	243
query84	247	111	98	98
query85	883	511	446	446
query86	390	293	330	293
query87	2903	2834	2770	2770
query88	2880	2140	2117	2117
query89	386	359	322	322
query90	2174	167	162	162
query91	174	180	167	167
query92	84	72	71	71
query93	1434	914	522	522
query94	577	333	288	288
query95	591	327	323	323
query96	551	477	203	203
query97	2352	2410	2363	2363
query98	231	205	200	200
query99	622	588	529	529
Total cold run time: 249249 ms
Total hot run time: 173905 ms

@doris-robot

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

query1	0.05	0.04	0.05
query2	0.13	0.07	0.07
query3	0.32	0.08	0.07
query4	1.61	0.10	0.09
query5	0.26	0.25	0.27
query6	1.15	0.65	0.65
query7	0.03	0.02	0.03
query8	0.08	0.06	0.07
query9	0.58	0.50	0.51
query10	0.56	0.56	0.54
query11	0.26	0.13	0.14
query12	0.26	0.14	0.15
query13	0.63	0.62	0.59
query14	0.97	0.97	0.97
query15	0.90	0.83	0.84
query16	0.42	0.37	0.38
query17	1.01	1.02	1.05
query18	0.25	0.21	0.23
query19	1.82	1.81	1.85
query20	0.02	0.01	0.01
query21	15.38	0.29	0.24
query22	5.03	0.10	0.11
query23	15.40	0.40	0.23
query24	2.38	0.52	0.33
query25	0.10	0.10	0.11
query26	0.18	0.17	0.18
query27	0.10	0.10	0.10
query28	3.64	1.11	0.97
query29	12.50	4.08	3.25
query30	0.33	0.13	0.11
query31	2.81	0.69	0.44
query32	3.24	0.63	0.50
query33	2.99	3.04	3.05
query34	16.39	5.22	4.47
query35	4.48	4.48	4.41
query36	0.60	0.49	0.49
query37	0.24	0.09	0.09
query38	0.21	0.05	0.06
query39	0.07	0.04	0.04
query40	0.20	0.17	0.16
query41	0.13	0.06	0.07
query42	0.07	0.06	0.05
query43	0.07	0.05	0.05
Total cold run time: 97.85 s
Total hot run time: 27.82 s

@doris-robot

Copy link
Copy Markdown

BE UT Coverage Report

Increment line coverage 16.82% (73/434) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 52.95% (18984/35856)
Line Coverage 38.98% (175873/451150)
Region Coverage 33.62% (136415/405750)
Branch Coverage 34.63% (58923/170142)

@bobhan1
bobhan1 marked this pull request as ready for review January 15, 2026 04:14
@bobhan1

bobhan1 commented Jan 15, 2026

Copy link
Copy Markdown
Contributor Author

run cloud_p0

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 81.55% (358/439) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.92% (25981/35147)
Line Coverage 61.37% (276548/450625)
Region Coverage 56.29% (230941/410306)
Branch Coverage 58.13% (99354/170914)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 15.60% (17/109) 🎉
Increment coverage report
Complete coverage report

@bobhan1
bobhan1 force-pushed the notify-be-visible-rs-after-load-txn-commit branch from 7bd047b to 728053d Compare January 16, 2026 03:45
@bobhan1

bobhan1 commented Jan 16, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 79.59% (1786/2244)
Line Coverage 64.77% (31787/49075)
Region Coverage 65.45% (15829/24185)
Branch Coverage 56.03% (8413/15014)

@bobhan1
bobhan1 force-pushed the notify-be-visible-rs-after-load-txn-commit branch from e1f8a1b to 2f31af9 Compare March 17, 2026 03:16
@bobhan1
bobhan1 force-pushed the notify-be-visible-rs-after-load-txn-commit branch from 2f31af9 to 1586ff7 Compare March 17, 2026 03:27
@bobhan1

bobhan1 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 79.15% (1796/2269)
Line Coverage 64.46% (32277/50072)
Region Coverage 65.37% (16164/24727)
Branch Coverage 55.76% (8606/15434)

@doris-robot

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

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17656	4483	4363	4363
q2	q3	10729	823	514	514
q4	4735	374	256	256
q5	8241	1239	998	998
q6	242	175	144	144
q7	813	845	666	666
q8	10781	1513	1351	1351
q9	6760	4802	4747	4747
q10	6298	1961	1640	1640
q11	465	247	240	240
q12	755	583	469	469
q13	18046	2992	2194	2194
q14	234	243	215	215
q15	q16	738	748	671	671
q17	745	858	446	446
q18	6166	5417	5326	5326
q19	1126	984	626	626
q20	556	506	376	376
q21	4445	2100	1531	1531
q22	376	330	256	256
Total cold run time: 99907 ms
Total hot run time: 27029 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4676	4558	4622	4558
q2	q3	3979	4437	3964	3964
q4	916	1233	804	804
q5	4080	4428	4352	4352
q6	193	178	145	145
q7	1777	1655	1525	1525
q8	2559	2732	2636	2636
q9	7722	7580	7434	7434
q10	3761	4042	3615	3615
q11	524	477	500	477
q12	481	579	469	469
q13	3053	3221	2376	2376
q14	286	307	285	285
q15	q16	761	755	715	715
q17	1144	1391	1360	1360
q18	7290	6987	6637	6637
q19	880	904	941	904
q20	2088	2168	2027	2027
q21	3980	3512	3311	3311
q22	465	415	378	378
Total cold run time: 50615 ms
Total hot run time: 47972 ms

@doris-robot

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

query5	4328	630	497	497
query6	332	233	206	206
query7	4210	472	269	269
query8	340	239	236	236
query9	8723	2736	2777	2736
query10	516	367	339	339
query11	6987	5088	4852	4852
query12	195	132	126	126
query13	1276	477	376	376
query14	5806	3670	3430	3430
query14_1	2847	2841	2855	2841
query15	210	194	178	178
query16	985	470	483	470
query17	887	693	591	591
query18	2417	448	350	350
query19	225	204	179	179
query20	133	125	122	122
query21	209	136	109	109
query22	13277	14266	14578	14266
query23	16316	15833	15560	15560
query23_1	15713	15616	15588	15588
query24	7149	1640	1247	1247
query24_1	1233	1274	1235	1235
query25	545	462	405	405
query26	1237	264	147	147
query27	2778	481	306	306
query28	4475	1854	1856	1854
query29	872	562	485	485
query30	295	223	188	188
query31	1023	956	875	875
query32	87	73	71	71
query33	520	342	288	288
query34	900	873	526	526
query35	664	686	605	605
query36	1092	1077	991	991
query37	141	99	87	87
query38	2996	2962	2926	2926
query39	864	828	800	800
query39_1	800	790	787	787
query40	231	152	135	135
query41	63	60	59	59
query42	257	261	261	261
query43	252	257	223	223
query44	
query45	196	197	184	184
query46	889	993	616	616
query47	2505	2127	2048	2048
query48	305	323	238	238
query49	639	461	390	390
query50	701	278	230	230
query51	4027	4059	4004	4004
query52	264	268	258	258
query53	291	340	286	286
query54	305	288	264	264
query55	97	97	87	87
query56	342	331	318	318
query57	1937	1792	1602	1602
query58	284	282	276	276
query59	2792	2948	2706	2706
query60	343	344	335	335
query61	158	176	151	151
query62	625	584	542	542
query63	308	274	286	274
query64	5138	1303	1033	1033
query65	
query66	1483	467	409	409
query67	24523	24307	24174	24174
query68	
query69	416	332	307	307
query70	976	1002	962	962
query71	357	315	329	315
query72	3050	2940	2706	2706
query73	571	564	332	332
query74	9641	9572	9391	9391
query75	2905	2801	2514	2514
query76	2269	1046	690	690
query77	368	394	317	317
query78	10929	11257	10450	10450
query79	1085	823	575	575
query80	1344	618	566	566
query81	543	264	229	229
query82	1351	153	120	120
query83	341	271	246	246
query84	299	121	105	105
query85	953	497	450	450
query86	413	338	306	306
query87	3153	3113	3046	3046
query88	3558	2674	2643	2643
query89	425	371	349	349
query90	2045	183	188	183
query91	175	163	147	147
query92	75	77	76	76
query93	911	887	505	505
query94	590	335	286	286
query95	583	424	320	320
query96	651	538	224	224
query97	2443	2451	2397	2397
query98	235	226	227	226
query99	1008	975	907	907
Total cold run time: 250674 ms
Total hot run time: 169021 ms

@bobhan1

bobhan1 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor Author

run p0

@doris-robot

Copy link
Copy Markdown

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 52.70% (19756/37490)
Line Coverage 36.23% (184524/509261)
Region Coverage 32.42% (142481/439490)
Branch Coverage 33.57% (62267/185478)

@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 71.66% (26296/36698)
Line Coverage 54.42% (276201/507559)
Region Coverage 51.46% (228242/443541)
Branch Coverage 53.02% (98591/185960)

@liaoxin01
liaoxin01 merged commit 09f7287 into apache:master Mar 18, 2026
27 of 30 checks passed
bobhan1 added a commit to bobhan1/doris that referenced this pull request Apr 1, 2026
…r txn commit without fetching from meta service (apache#59754)

1FE+3BE, 400bucket mow table, 10 concurrency stream load

before:
<img width="3218" height="1300" alt="image"
src="https://github.com/user-attachments/assets/3d4fe51d-4fae-484b-a257-a6b5ec010970"
/>
after:
<img width="3206" height="1304" alt="image"
src="https://github.com/user-attachments/assets/e7230b3c-999d-407b-aa57-783492995e5b"
/>

---

  Problem Summary

In cloud storage mode, after a load transaction commits rowsets to Meta
Service (MS), BE nodes need to fetch the committed rowset metadata from
MS during subsequent sync_rowsets() operations. This introduces
additional latency and MS query overhead, especially for high-frequency
import scenarios.

This PR implements a notification mechanism where FE/BE directly
notifies BE nodes about committed rowsets after transaction commit,
allowing BE to update tablet metadata immediately without fetching from
MS.

  Solution

1. CloudCommittedRSMgr (BE): A new in-memory manager that caches
committed temporary rowset metadata after they are committed to MS
    - Stores rowset meta with expiration time
    - Supports efficient lookup by (txn_id, tablet_id)
    - Handles empty rowset markers
    - Background thread for cleaning expired entries
  2. Notification Flow:
- When FE commits a load transaction to MS, it sends
MakeCloudTmpRsVisibleTask to involved BE nodes
    - BE receives the task with final version/visible_ts information
    - BE promotes cached rowset metadata to tablet meta directly
- BE can forward notification to FE if needed (for tablets not on the
original BE)
  3. Configuration:
    - FE: enable_cloud_notify_be_after_load_txn_commit (default: false)
    - BE: enable_cloud_make_rs_visible_on_be (default: false)
    - BE: cloud_make_committed_rs_visible_worker_count (default: 4)
    - BE: cloud_mow_sync_rowsets_when_load_txn_begin (default: true)

  Benefits

- Reduces Meta Service query pressure by avoiding redundant rowset
metadata fetches
  - Improves import latency by making rowsets visible faster
  - Optimizes cloud storage mode performance for high-frequency imports
bobhan1 added a commit to bobhan1/doris that referenced this pull request Apr 1, 2026
…r txn commit without fetching from meta service (apache#59754)

1FE+3BE, 400bucket mow table, 10 concurrency stream load

before:
<img width="3218" height="1300" alt="image"
src="https://github.com/user-attachments/assets/3d4fe51d-4fae-484b-a257-a6b5ec010970"
/>
after:
<img width="3206" height="1304" alt="image"
src="https://github.com/user-attachments/assets/e7230b3c-999d-407b-aa57-783492995e5b"
/>

---

  Problem Summary

In cloud storage mode, after a load transaction commits rowsets to Meta
Service (MS), BE nodes need to fetch the committed rowset metadata from
MS during subsequent sync_rowsets() operations. This introduces
additional latency and MS query overhead, especially for high-frequency
import scenarios.

This PR implements a notification mechanism where FE/BE directly
notifies BE nodes about committed rowsets after transaction commit,
allowing BE to update tablet metadata immediately without fetching from
MS.

  Solution

1. CloudCommittedRSMgr (BE): A new in-memory manager that caches
committed temporary rowset metadata after they are committed to MS
    - Stores rowset meta with expiration time
    - Supports efficient lookup by (txn_id, tablet_id)
    - Handles empty rowset markers
    - Background thread for cleaning expired entries
  2. Notification Flow:
- When FE commits a load transaction to MS, it sends
MakeCloudTmpRsVisibleTask to involved BE nodes
    - BE receives the task with final version/visible_ts information
    - BE promotes cached rowset metadata to tablet meta directly
- BE can forward notification to FE if needed (for tablets not on the
original BE)
  3. Configuration:
    - FE: enable_cloud_notify_be_after_load_txn_commit (default: false)
    - BE: enable_cloud_make_rs_visible_on_be (default: false)
    - BE: cloud_make_committed_rs_visible_worker_count (default: 4)
    - BE: cloud_mow_sync_rowsets_when_load_txn_begin (default: true)

  Benefits

- Reduces Meta Service query pressure by avoiding redundant rowset
metadata fetches
  - Improves import latency by making rowsets visible faster
  - Optimizes cloud storage mode performance for high-frequency imports
yiguolei pushed a commit that referenced this pull request Apr 2, 2026
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 4, 2026
### Background

Cloud MoW load initialization can synchronize rowsets from Meta Service before capturing its local rowset snapshot. The existing mutable cloud_mow_sync_rowsets_when_load_txn_begin setting controls this synchronization.

### What problem does this PR solve?

Issue Number: None
Related PR: apache#59754 (introduced the setting), apache#70218 (enables notifications and fixes cleanup), apache#70209 (temporary BE UT build prerequisite)
PR Type: Enhancement

Problem Summary: Make rowset synchronization at the start of a cloud MoW load opt-in by changing cloud_mow_sync_rowsets_when_load_txn_begin from true to false. Adjust the related CloudGroupRowsetBuilderWriterTest fixture to restore the incoming configuration value instead of hard-coding true during teardown.

### Details

- **Before and after:** Cloud MoW loads no longer force sync_rowsets before constructing their initial local rowset snapshot by default.
- **Configs and defaults:** cloud_mow_sync_rowsets_when_load_txn_begin changes from true to false and remains dynamically mutable.
- **Impact on existing users:** An explicit true setting retains synchronization at load initialization. Notification delivery and subsequent metadata synchronization remain relevant to local rowset freshness.
- **Behavior change:** Yes; skip the initial synchronization unless the setting is enabled. The test fixture preserves whichever configuration value it received.

### Testing

- ./run-be-ut.sh --run --filter='CloudGroupRowsetBuilderWriterTest.*:*DeltaWriterCancelIntegrationTest.*' -j100 passed all 12 ASAN tests after this change.
- The unit-test build temporarily applied apache#70209 to fix the unrelated vparquet_writer_test.cpp compilation failure. That prerequisite was removed afterward and is not included in this commit.
- clang-format v16/check-format on both changed files and git diff --check passed.
- The earlier 36 BE and 56 FE passing tests belong to commit 1b4d168, before this default update; they were not rerun for this commit.
- clang-tidy was omitted. The stale-cache partial-update scenario below was not exercised in a running cloud cluster.

### Notes for Reviewers

The stale-rowset partial-update issue identified during source review remains unresolved: if a BE has not received or synchronized a prior committed rowset, constructing the MoW context from its local snapshot can classify an existing key as new and fail a partial update under the ERROR policy or when an omitted column is non-nullable and has no default. This commit changes the default; it does not repair that path.

### Release note

The BE setting cloud_mow_sync_rowsets_when_load_txn_begin now defaults to false. Cloud MoW loads skip forced rowset synchronization at initialization unless this setting is explicitly enabled.

### Check List (For Author)

- Test: Unit Test; 12 BE ASAN tests passed with the prerequisite described above.
- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; include this third default-value change in the configuration reference and release notes alongside the two notification settings.
- Pre-submission status: Partially verified: focused tests passed; the known stale-cache partial-update risk remains unresolved and cloud end-to-end validation is pending.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: Code, test fixture adjustment and this description.
- Human review: Pending.
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 6, 2026
…by default

### Background

After a cloud load transaction commits in Meta Service, FE can notify the participating BEs of its visible versions. BE uses cached committed rowsets or lightweight empty-rowset entries to update local tablet metadata, with normal metadata synchronization as the fallback.

### What problem does this PR solve?

Issue Number: None
Related PR: apache#59754 (introduced the notification path), apache#70209 (temporary prerequisite for local BE unit-test builds)
PR Type: Bugfix

Problem Summary: Completed notification tasks retain their registered signatures, including when the BE feature is disabled. Consumed empty-rowset markers also remain cached because removal only covers the separate non-empty-rowset map. Release signatures on every callback exit and represent both rowset kinds in one cache so removal and expiration share the same lifecycle. Enable the existing FE and BE notification settings by default.

### Details

- **Frequency:** Every accepted notification leaves its signature behind; every consumed empty entry remains until expiration.
- **Root cause:** The callback does not pair task registration with removal, and the split empty/non-empty caches have different removal behavior.
- **Why existing tests missed it:** They cover insertion and expiration but do not check removal of an empty entry or resubmission after a notification callback completes.
- **Fix:** Add a Defer guard before the BE enable check. Store empty rowsets as null metadata in the existing committed-rowset cache, reuse insertion and expiration, and avoid a redundant lookup during cleanup.
- **Other paths and branches:** The guard covers enabled notifications, disabled notifications and cache misses. Non-empty and empty committed rowsets now share cleanup; the independent MoW delete-bitmap cache is unchanged. This change targets master.
- **Behavior change:** enable_notify_be_after_load_txn_commit and enable_cloud_make_rs_visible_on_be now default to true. Both retain their existing dynamic mutability. cloud_mow_sync_rowsets_when_load_txn_begin remains true.
- **Concurrency and lifecycle:** Cache operations retain the existing shared mutex and acquire no new nested locks. Signature cleanup runs after tablet processing has released its locks. Refreshed entries remain protected from older expiration records.
- **Compatibility and data correctness:** No RPC fields, persistent formats, transaction commit rules or partition-version visibility checks change. Missing cached data continues to use the existing metadata synchronization path.
- **Observability and cost:** Move per-rowset insertion logging outside the cache lock and lower it to DEBUG as notifications become enabled by default. Existing notification and expiration logs retain transaction/tablet identifiers.

### Testing

- Before the fix: four new ASAN cases ran; empty-entry removal and both enabled/disabled signature-release cases failed, while the expiration-refresh case passed.
- After the final change: ./run-be-ut.sh --run --filter='CloudCommittedRSMgrTest.*:EnabledAndDisabled/CloudCommittedRowsetTaskTest.*:TaskWorkerPoolTest.*:CloudTabletApplyVisiblePendingTest.*:CloudGroupRowsetBuilderWriterTest.*' -j100 passed all 36 tests.
- ./run-fe-ut.sh --run org.apache.doris.cloud.transaction.CloudGlobalTransactionMgrTest passed all 56 tests.
- clang-format v16/check-format on all six changed C++ files, build-support/check-build-hygiene.sh, FE fe-common Maven validate/Checkstyle, and git diff --check passed.
- BE unit-test builds used the temporary apache#70209 fix for an unrelated master compilation failure in vparquet_writer_test.cpp. The prerequisite was restored afterward and is not part of this commit.
- clang-tidy was not completed. A cloud end-to-end regression and a standalone production BE build were not run.

### Release note

Cloud committed-rowset notifications are enabled by default through enable_notify_be_after_load_txn_commit on FE and enable_cloud_make_rs_visible_on_be on BE. Completed notifications release their task signatures, and consumed empty-rowset entries are removed promptly.

### Check List (For Author)

- Test: Unit Test; 36 BE ASAN tests and 56 FE tests passed with the prerequisite described above.
- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; document the two default-value changes in the configuration reference and release notes.
- Pre-submission status: Partially verified: targeted tests passed; cloud end-to-end regression, standalone production BE build and clang-tidy are not completed. The master BE UT build requires apache#70209.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: Code, tests and this description.
- Human review: Pending.
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 6, 2026
### Background

Cloud MoW load initialization can synchronize rowsets from Meta Service before capturing its local rowset snapshot. The existing mutable cloud_mow_sync_rowsets_when_load_txn_begin setting controls this synchronization.

### What problem does this PR solve?

Issue Number: None
Related PR: apache#59754 (introduced the setting), apache#70218 (enables notifications and fixes cleanup), apache#70209 (temporary BE UT build prerequisite)
PR Type: Enhancement

Problem Summary: Make rowset synchronization at the start of a cloud MoW load opt-in by changing cloud_mow_sync_rowsets_when_load_txn_begin from true to false. Adjust the related CloudGroupRowsetBuilderWriterTest fixture to restore the incoming configuration value instead of hard-coding true during teardown.

### Details

- **Before and after:** Cloud MoW loads no longer force sync_rowsets before constructing their initial local rowset snapshot by default.
- **Configs and defaults:** cloud_mow_sync_rowsets_when_load_txn_begin changes from true to false and remains dynamically mutable.
- **Impact on existing users:** An explicit true setting retains synchronization at load initialization. Notification delivery and subsequent metadata synchronization remain relevant to local rowset freshness.
- **Behavior change:** Yes; skip the initial synchronization unless the setting is enabled. The test fixture preserves whichever configuration value it received.

### Testing

- ./run-be-ut.sh --run --filter='CloudGroupRowsetBuilderWriterTest.*:*DeltaWriterCancelIntegrationTest.*' -j100 passed all 12 ASAN tests after this change.
- The unit-test build temporarily applied apache#70209 to fix the unrelated vparquet_writer_test.cpp compilation failure. That prerequisite was removed afterward and is not included in this commit.
- clang-format v16/check-format on both changed files and git diff --check passed.
- The earlier 36 BE and 56 FE passing tests belong to commit 1b4d168, before this default update; they were not rerun for this commit.
- clang-tidy was omitted. The stale-cache partial-update scenario below was not exercised in a running cloud cluster.

### Notes for Reviewers

The stale-rowset partial-update issue identified during source review remains unresolved: if a BE has not received or synchronized a prior committed rowset, constructing the MoW context from its local snapshot can classify an existing key as new and fail a partial update under the ERROR policy or when an omitted column is non-nullable and has no default. This commit changes the default; it does not repair that path.

### Release note

The BE setting cloud_mow_sync_rowsets_when_load_txn_begin now defaults to false. Cloud MoW loads skip forced rowset synchronization at initialization unless this setting is explicitly enabled.

### Check List (For Author)

- Test: Unit Test; 12 BE ASAN tests passed with the prerequisite described above.
- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; include this third default-value change in the configuration reference and release notes alongside the two notification settings.
- Pre-submission status: Partially verified: focused tests passed; the known stale-cache partial-update risk remains unresolved and cloud end-to-end validation is pending.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: Code, test fixture adjustment and this description.
- Human review: Pending.
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 6, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#59754

Problem Summary: Cloud p0 and p1 still explicitly configure committed-rowset notifications and initial MoW rowset synchronization to the values now provided by the defaults. Remove these six overrides from the four FE/BE pipeline configuration files so the pipelines exercise the defaults while retaining the same effective settings.

### Release note

None

### Check List (For Author)

- Test: Manual check of all removed values against the FE/BE defaults, comparison of the remaining parsed settings, and git diff --check passed. No runtime rerun for this configuration cleanup because the effective values are unchanged.
- Behavior changed: No (the pipeline settings resolve to the same values through defaults)
- Does this need documentation: No
bobhan1 added a commit that referenced this pull request Nov 10, 2026
…faults (#70218)

### Background

After a cloud load transaction commits in Meta Service, FE can notify
the participating BEs of its visible versions. BE uses cached committed
rowsets or lightweight empty-rowset entries to update local tablet
metadata, with normal metadata synchronization as the fallback.

### What problem does this PR solve?

Issue Number: None
Related PR: #59754 (introduced the notification path), #70209 (fixes the
unrelated Parquet unit-test build failure and is now included in master)
PR Type: Bugfix

Problem Summary: Completed notification tasks retain their registered
signatures, including when the BE feature is disabled. Consumed
empty-rowset markers also remain cached because removal only covers the
separate non-empty-rowset map. Release signatures on every callback exit
and represent both rowset kinds in one cache so removal and expiration
share the same lifecycle. Enable the existing FE and BE notification
settings by default, and default
cloud_mow_sync_rowsets_when_load_txn_begin to false so cloud MoW loads
skip forced synchronization when they begin. Remove the six
now-redundant FE/BE overrides from the Cloud p0/p1 pipeline configs so
those pipelines exercise the new defaults with unchanged effective
settings.

### Details

- **Frequency:** Every accepted notification leaves its signature
behind; every consumed empty entry remains until expiration.
- **Root cause:** The callback does not pair task registration with
removal, and the split empty/non-empty caches have different removal
behavior.
- **Why existing tests missed it:** They cover insertion and expiration
but do not check removal of an empty entry or resubmission after a
notification callback completes.
- **Fix:** Add a Defer guard before the BE enable check. Store empty
rowsets as null metadata in the existing committed-rowset cache, reuse
insertion and expiration, and avoid a redundant lookup during cleanup.
- **Other paths and branches:** The guard covers enabled notifications,
disabled notifications and cache misses. Non-empty and empty committed
rowsets now share cleanup; the independent MoW delete-bitmap cache is
unchanged. This change targets master.
- **Behavior change:** `enable_notify_be_after_load_txn_commit` and
`enable_cloud_make_rs_visible_on_be` now default to `true`;
`cloud_mow_sync_rowsets_when_load_txn_begin` now defaults to `false`.
All three settings retain their existing dynamic mutability. The cloud
rowset-builder test fixture now restores the incoming setting rather
than hard-coding `true` at teardown.
- **Concurrency and lifecycle:** Cache operations retain the existing
shared mutex and acquire no new nested locks. Signature cleanup runs
after tablet processing has released its locks. Refreshed entries remain
protected from older expiration records.
- **Compatibility and data correctness:** RPC fields and persistent
formats are unchanged. Cloud MoW loads continue to use a local flush
snapshot. Skipping initialization synchronization enlarges the existing
snapshot freshness window; the partial-update validation and
publish-alignment algorithms are unchanged. The rolling-upgrade caveat
is described below.
- **Observability and cost:** Move per-rowset insertion logging outside
the cache lock and lower it to DEBUG as notifications become enabled by
default. Existing notification and expiration logs retain
transaction/tablet identifiers.

### Testing

- The implementation commits were rebased onto master
`87b462e4f58104140f098f5f4a8b5d58bec70149`. The BE/FE runs below tested
implementation head `17d42f6ef184c7f851920830ad3ce4861fe679aa`. Final
head `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` adds only the
pipeline-configuration cleanup.
- On the rebased head, `./run-be-ut.sh --run
--filter='CloudCommittedRSMgrTest.*:EnabledAndDisabled/CloudCommittedRowsetTaskTest.*:TaskWorkerPoolTest.*:CloudTabletApplyVisiblePendingTest.*:CloudGroupRowsetBuilderWriterTest.*:*DeltaWriterCancelIntegrationTest.*'
-j100` passed all 46 ASAN tests with the requested defaults.
- On the same rebased head, `./run-fe-ut.sh --run
org.apache.doris.cloud.transaction.CloudGlobalTransactionMgrTest` passed
all 56 tests (0 failures, errors or skips); the Maven reactor completed
successfully.
- The BE build compiled both `task_worker_pool_test.cpp` and
`vparquet_writer_test.cpp` successfully. The latter uses the #70209 fix
already merged into master; no temporary source patch was applied.
- Before the original cleanup fix, the empty-entry removal test and both
enabled/disabled signature-release tests failed; the expiration-refresh
test passed.
- `build-support/check-build-hygiene.sh` and `git diff --check` passed
after rebase. The unchanged PR patch previously passed clang-format
v16/check-format and FE fe-common Maven validate/Checkstyle.
- For the final pipeline cleanup, checked all six removed values against
the FE/BE defaults, compared the remaining parsed settings in all four
files, and ran `git diff --check`: all passed. BE/FE tests were not
rerun for this config-only commit because its effective pipeline values
are unchanged.
- clang-tidy was not rerun, as requested. A cloud end-to-end regression
and a standalone production BE build were not run. The snapshot-window
and mixed-version behavior below was assessed from code, without a
running-cluster reproduction.

### Notes for Reviewers

Local review of `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` found no
Blocker or Major issue. One non-blocking P2 remains for rolling
upgrades.

| Existing review finding | Current disposition |
| --- | --- |
|
[MF-001](#70218 (comment)):
FE notification retries | False positive: this notification is not
inserted into `AgentTaskQueue`. |
|
[MF-002](#70218 (comment)):
stale MoW snapshot | Documented behavior tradeoff of the existing mode;
the new-P1 classification is withdrawn under the intended load
semantics. |
|
[MF-003](#70218 (comment)):
old-BE signature leak | P2 remains for a new-FE/old-BE rolling-upgrade
window. |
|
[MF-004](#70218 (comment)):
protected test access | False positive: BE UT uses
`-fno-access-control`, and the tests compiled and passed. |

**Snapshot semantics:** Even with initialization synchronization
enabled, `sync_rowsets`, local snapshot construction and the later flush
are not atomic with other transactions' commits. A key absent from the
captured snapshot can already enter the new-key validation path and fail
under ERROR or for an omitted non-nullable column without a default.
Disabling the initial synchronization can enlarge the freshness window,
including while an earlier MS-committed rowset is still absent locally.
This PR deliberately makes that existing mode the default; master
already configures Cloud p0/p1 to use it. This is an explicit
behavior/cost tradeoff, not a claim that local snapshots always contain
the latest committed keys. For APPEND updates that reach publication,
delete-bitmap calculation synchronizes missing versions and realigns
conflicting rows from historical columns; flush-time default/null fill
alone does not establish final data loss.

**Rolling upgrades:** Enabling the new FE notification default while an
old BE supports this task but lacks the cleanup guard exposes the old BE
signature leak, including when its local notification setting is false.
That process retains the signatures until it is restarted/upgraded. Keep
FE notifications disabled until all receiving BEs include the cleanup
fix.

### Release note

Cloud committed-rowset notifications are enabled by default through
enable_notify_be_after_load_txn_commit on FE and
enable_cloud_make_rs_visible_on_be on BE. Completed notifications
release their task signatures, and consumed empty-rowset entries are
removed promptly. The BE setting
cloud_mow_sync_rowsets_when_load_txn_begin now defaults to false, so
cloud MoW loads skip forced rowset synchronization at initialization
unless it is explicitly enabled.

### Check List (For Author)

- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; document all three default-value
changes in the configuration reference and release notes.
- Pre-submission status: Partially verified: the implementation passed
the targeted BE/FE tests and the final pipeline cleanup passed static
effective-configuration checks. Cloud end-to-end regression and a
standalone production BE build were not run; clang-tidy was excluded as
requested. The local review has no Blocker/Major finding, with the
rolling-upgrade P2 and snapshot behavior documented above.

### AI Disclosure

- Tool: Codex (GPT-6).
- Generated: Code, tests and this description.
- Human review: [@gavinchou previously approved implementation head
`17d42f6ef18`](#70218 (review));
GitHub dismissed that approval after the pipeline cleanup commit. The
final head has been reviewed locally.
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 12, 2026
…faults (apache#70218)

After a cloud load transaction commits in Meta Service, FE can notify
the participating BEs of its visible versions. BE uses cached committed
rowsets or lightweight empty-rowset entries to update local tablet
metadata, with normal metadata synchronization as the fallback.

Issue Number: None
Related PR: apache#59754 (introduced the notification path), apache#70209 (fixes the
unrelated Parquet unit-test build failure and is now included in master)
PR Type: Bugfix

Problem Summary: Completed notification tasks retain their registered
signatures, including when the BE feature is disabled. Consumed
empty-rowset markers also remain cached because removal only covers the
separate non-empty-rowset map. Release signatures on every callback exit
and represent both rowset kinds in one cache so removal and expiration
share the same lifecycle. Enable the existing FE and BE notification
settings by default, and default
cloud_mow_sync_rowsets_when_load_txn_begin to false so cloud MoW loads
skip forced synchronization when they begin. Remove the six
now-redundant FE/BE overrides from the Cloud p0/p1 pipeline configs so
those pipelines exercise the new defaults with unchanged effective
settings.

- **Frequency:** Every accepted notification leaves its signature
behind; every consumed empty entry remains until expiration.
- **Root cause:** The callback does not pair task registration with
removal, and the split empty/non-empty caches have different removal
behavior.
- **Why existing tests missed it:** They cover insertion and expiration
but do not check removal of an empty entry or resubmission after a
notification callback completes.
- **Fix:** Add a Defer guard before the BE enable check. Store empty
rowsets as null metadata in the existing committed-rowset cache, reuse
insertion and expiration, and avoid a redundant lookup during cleanup.
- **Other paths and branches:** The guard covers enabled notifications,
disabled notifications and cache misses. Non-empty and empty committed
rowsets now share cleanup; the independent MoW delete-bitmap cache is
unchanged. This change targets master.
- **Behavior change:** `enable_notify_be_after_load_txn_commit` and
`enable_cloud_make_rs_visible_on_be` now default to `true`;
`cloud_mow_sync_rowsets_when_load_txn_begin` now defaults to `false`.
All three settings retain their existing dynamic mutability. The cloud
rowset-builder test fixture now restores the incoming setting rather
than hard-coding `true` at teardown.
- **Concurrency and lifecycle:** Cache operations retain the existing
shared mutex and acquire no new nested locks. Signature cleanup runs
after tablet processing has released its locks. Refreshed entries remain
protected from older expiration records.
- **Compatibility and data correctness:** RPC fields and persistent
formats are unchanged. Cloud MoW loads continue to use a local flush
snapshot. Skipping initialization synchronization enlarges the existing
snapshot freshness window; the partial-update validation and
publish-alignment algorithms are unchanged. The rolling-upgrade caveat
is described below.
- **Observability and cost:** Move per-rowset insertion logging outside
the cache lock and lower it to DEBUG as notifications become enabled by
default. Existing notification and expiration logs retain
transaction/tablet identifiers.

- The implementation commits were rebased onto master
`87b462e4f58104140f098f5f4a8b5d58bec70149`. The BE/FE runs below tested
implementation head `17d42f6ef184c7f851920830ad3ce4861fe679aa`. Final
head `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` adds only the
pipeline-configuration cleanup.
- On the rebased head, `./run-be-ut.sh --run
--filter='CloudCommittedRSMgrTest.*:EnabledAndDisabled/CloudCommittedRowsetTaskTest.*:TaskWorkerPoolTest.*:CloudTabletApplyVisiblePendingTest.*:CloudGroupRowsetBuilderWriterTest.*:*DeltaWriterCancelIntegrationTest.*'
-j100` passed all 46 ASAN tests with the requested defaults.
- On the same rebased head, `./run-fe-ut.sh --run
org.apache.doris.cloud.transaction.CloudGlobalTransactionMgrTest` passed
all 56 tests (0 failures, errors or skips); the Maven reactor completed
successfully.
- The BE build compiled both `task_worker_pool_test.cpp` and
`vparquet_writer_test.cpp` successfully. The latter uses the apache#70209 fix
already merged into master; no temporary source patch was applied.
- Before the original cleanup fix, the empty-entry removal test and both
enabled/disabled signature-release tests failed; the expiration-refresh
test passed.
- `build-support/check-build-hygiene.sh` and `git diff --check` passed
after rebase. The unchanged PR patch previously passed clang-format
v16/check-format and FE fe-common Maven validate/Checkstyle.
- For the final pipeline cleanup, checked all six removed values against
the FE/BE defaults, compared the remaining parsed settings in all four
files, and ran `git diff --check`: all passed. BE/FE tests were not
rerun for this config-only commit because its effective pipeline values
are unchanged.
- clang-tidy was not rerun, as requested. A cloud end-to-end regression
and a standalone production BE build were not run. The snapshot-window
and mixed-version behavior below was assessed from code, without a
running-cluster reproduction.

Local review of `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` found no
Blocker or Major issue. One non-blocking P2 remains for rolling
upgrades.

| Existing review finding | Current disposition |
| --- | --- |
|
[MF-001](apache#70218 (comment)):
FE notification retries | False positive: this notification is not
inserted into `AgentTaskQueue`. |
|
[MF-002](apache#70218 (comment)):
stale MoW snapshot | Documented behavior tradeoff of the existing mode;
the new-P1 classification is withdrawn under the intended load
semantics. |
|
[MF-003](apache#70218 (comment)):
old-BE signature leak | P2 remains for a new-FE/old-BE rolling-upgrade
window. |
|
[MF-004](apache#70218 (comment)):
protected test access | False positive: BE UT uses
`-fno-access-control`, and the tests compiled and passed. |

**Snapshot semantics:** Even with initialization synchronization
enabled, `sync_rowsets`, local snapshot construction and the later flush
are not atomic with other transactions' commits. A key absent from the
captured snapshot can already enter the new-key validation path and fail
under ERROR or for an omitted non-nullable column without a default.
Disabling the initial synchronization can enlarge the freshness window,
including while an earlier MS-committed rowset is still absent locally.
This PR deliberately makes that existing mode the default; master
already configures Cloud p0/p1 to use it. This is an explicit
behavior/cost tradeoff, not a claim that local snapshots always contain
the latest committed keys. For APPEND updates that reach publication,
delete-bitmap calculation synchronizes missing versions and realigns
conflicting rows from historical columns; flush-time default/null fill
alone does not establish final data loss.

**Rolling upgrades:** Enabling the new FE notification default while an
old BE supports this task but lacks the cleanup guard exposes the old BE
signature leak, including when its local notification setting is false.
That process retains the signatures until it is restarted/upgraded. Keep
FE notifications disabled until all receiving BEs include the cleanup
fix.

Cloud committed-rowset notifications are enabled by default through
enable_notify_be_after_load_txn_commit on FE and
enable_cloud_make_rs_visible_on_be on BE. Completed notifications
release their task signatures, and consumed empty-rowset entries are
removed promptly. The BE setting
cloud_mow_sync_rowsets_when_load_txn_begin now defaults to false, so
cloud MoW loads skip forced rowset synchronization at initialization
unless it is explicitly enabled.

- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; document all three default-value
changes in the configuration reference and release notes.
- Pre-submission status: Partially verified: the implementation passed
the targeted BE/FE tests and the final pipeline cleanup passed static
effective-configuration checks. Cloud end-to-end regression and a
standalone production BE build were not run; clang-tidy was excluded as
requested. The local review has no Blocker/Major finding, with the
rolling-upgrade P2 and snapshot behavior documented above.

- Tool: Codex (GPT-6).
- Generated: Code, tests and this description.
- Human review: [@gavinchou previously approved implementation head
`17d42f6ef18`](apache#70218 (review));
GitHub dismissed that approval after the pipeline cleanup commit. The
final head has been reviewed locally.

(cherry picked from commit 08231e3)
bobhan1 added a commit to bobhan1/doris that referenced this pull request Nov 13, 2026
…faults (apache#70218)

After a cloud load transaction commits in Meta Service, FE can notify
the participating BEs of its visible versions. BE uses cached committed
rowsets or lightweight empty-rowset entries to update local tablet
metadata, with normal metadata synchronization as the fallback.

Issue Number: None
Related PR: apache#59754 (introduced the notification path), apache#70209 (fixes the
unrelated Parquet unit-test build failure and is now included in master)
PR Type: Bugfix

Problem Summary: Completed notification tasks retain their registered
signatures, including when the BE feature is disabled. Consumed
empty-rowset markers also remain cached because removal only covers the
separate non-empty-rowset map. Release signatures on every callback exit
and represent both rowset kinds in one cache so removal and expiration
share the same lifecycle. Enable the existing FE and BE notification
settings by default, and default
cloud_mow_sync_rowsets_when_load_txn_begin to false so cloud MoW loads
skip forced synchronization when they begin. Remove the six
now-redundant FE/BE overrides from the Cloud p0/p1 pipeline configs so
those pipelines exercise the new defaults with unchanged effective
settings.

- **Frequency:** Every accepted notification leaves its signature
behind; every consumed empty entry remains until expiration.
- **Root cause:** The callback does not pair task registration with
removal, and the split empty/non-empty caches have different removal
behavior.
- **Why existing tests missed it:** They cover insertion and expiration
but do not check removal of an empty entry or resubmission after a
notification callback completes.
- **Fix:** Add a Defer guard before the BE enable check. Store empty
rowsets as null metadata in the existing committed-rowset cache, reuse
insertion and expiration, and avoid a redundant lookup during cleanup.
- **Other paths and branches:** The guard covers enabled notifications,
disabled notifications and cache misses. Non-empty and empty committed
rowsets now share cleanup; the independent MoW delete-bitmap cache is
unchanged. This change targets master.
- **Behavior change:** `enable_notify_be_after_load_txn_commit` and
`enable_cloud_make_rs_visible_on_be` now default to `true`;
`cloud_mow_sync_rowsets_when_load_txn_begin` now defaults to `false`.
All three settings retain their existing dynamic mutability. The cloud
rowset-builder test fixture now restores the incoming setting rather
than hard-coding `true` at teardown.
- **Concurrency and lifecycle:** Cache operations retain the existing
shared mutex and acquire no new nested locks. Signature cleanup runs
after tablet processing has released its locks. Refreshed entries remain
protected from older expiration records.
- **Compatibility and data correctness:** RPC fields and persistent
formats are unchanged. Cloud MoW loads continue to use a local flush
snapshot. Skipping initialization synchronization enlarges the existing
snapshot freshness window; the partial-update validation and
publish-alignment algorithms are unchanged. The rolling-upgrade caveat
is described below.
- **Observability and cost:** Move per-rowset insertion logging outside
the cache lock and lower it to DEBUG as notifications become enabled by
default. Existing notification and expiration logs retain
transaction/tablet identifiers.

- The implementation commits were rebased onto master
`87b462e4f58104140f098f5f4a8b5d58bec70149`. The BE/FE runs below tested
implementation head `17d42f6ef184c7f851920830ad3ce4861fe679aa`. Final
head `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` adds only the
pipeline-configuration cleanup.
- On the rebased head, `./run-be-ut.sh --run
--filter='CloudCommittedRSMgrTest.*:EnabledAndDisabled/CloudCommittedRowsetTaskTest.*:TaskWorkerPoolTest.*:CloudTabletApplyVisiblePendingTest.*:CloudGroupRowsetBuilderWriterTest.*:*DeltaWriterCancelIntegrationTest.*'
-j100` passed all 46 ASAN tests with the requested defaults.
- On the same rebased head, `./run-fe-ut.sh --run
org.apache.doris.cloud.transaction.CloudGlobalTransactionMgrTest` passed
all 56 tests (0 failures, errors or skips); the Maven reactor completed
successfully.
- The BE build compiled both `task_worker_pool_test.cpp` and
`vparquet_writer_test.cpp` successfully. The latter uses the apache#70209 fix
already merged into master; no temporary source patch was applied.
- Before the original cleanup fix, the empty-entry removal test and both
enabled/disabled signature-release tests failed; the expiration-refresh
test passed.
- `build-support/check-build-hygiene.sh` and `git diff --check` passed
after rebase. The unchanged PR patch previously passed clang-format
v16/check-format and FE fe-common Maven validate/Checkstyle.
- For the final pipeline cleanup, checked all six removed values against
the FE/BE defaults, compared the remaining parsed settings in all four
files, and ran `git diff --check`: all passed. BE/FE tests were not
rerun for this config-only commit because its effective pipeline values
are unchanged.
- clang-tidy was not rerun, as requested. A cloud end-to-end regression
and a standalone production BE build were not run. The snapshot-window
and mixed-version behavior below was assessed from code, without a
running-cluster reproduction.

Local review of `4ba6d0db1480dd018a2e9353cffbb6137fe1c65d` found no
Blocker or Major issue. One non-blocking P2 remains for rolling
upgrades.

| Existing review finding | Current disposition |
| --- | --- |
|
[MF-001](apache#70218 (comment)):
FE notification retries | False positive: this notification is not
inserted into `AgentTaskQueue`. |
|
[MF-002](apache#70218 (comment)):
stale MoW snapshot | Documented behavior tradeoff of the existing mode;
the new-P1 classification is withdrawn under the intended load
semantics. |
|
[MF-003](apache#70218 (comment)):
old-BE signature leak | P2 remains for a new-FE/old-BE rolling-upgrade
window. |
|
[MF-004](apache#70218 (comment)):
protected test access | False positive: BE UT uses
`-fno-access-control`, and the tests compiled and passed. |

**Snapshot semantics:** Even with initialization synchronization
enabled, `sync_rowsets`, local snapshot construction and the later flush
are not atomic with other transactions' commits. A key absent from the
captured snapshot can already enter the new-key validation path and fail
under ERROR or for an omitted non-nullable column without a default.
Disabling the initial synchronization can enlarge the freshness window,
including while an earlier MS-committed rowset is still absent locally.
This PR deliberately makes that existing mode the default; master
already configures Cloud p0/p1 to use it. This is an explicit
behavior/cost tradeoff, not a claim that local snapshots always contain
the latest committed keys. For APPEND updates that reach publication,
delete-bitmap calculation synchronizes missing versions and realigns
conflicting rows from historical columns; flush-time default/null fill
alone does not establish final data loss.

**Rolling upgrades:** Enabling the new FE notification default while an
old BE supports this task but lacks the cleanup guard exposes the old BE
signature leak, including when its local notification setting is false.
That process retains the signatures until it is restarted/upgraded. Keep
FE notifications disabled until all receiving BEs include the cleanup
fix.

Cloud committed-rowset notifications are enabled by default through
enable_notify_be_after_load_txn_commit on FE and
enable_cloud_make_rs_visible_on_be on BE. Completed notifications
release their task signatures, and consumed empty-rowset entries are
removed promptly. The BE setting
cloud_mow_sync_rowsets_when_load_txn_begin now defaults to false, so
cloud MoW loads skip forced rowset synchronization at initialization
unless it is explicitly enabled.

- Behavior changed: Yes (see Details).
- Does this need documentation: Yes; document all three default-value
changes in the configuration reference and release notes.
- Pre-submission status: Partially verified: the implementation passed
the targeted BE/FE tests and the final pipeline cleanup passed static
effective-configuration checks. Cloud end-to-end regression and a
standalone production BE build were not run; clang-tidy was excluded as
requested. The local review has no Blocker/Major finding, with the
rolling-upgrade P2 and snapshot behavior documented above.

- Tool: Codex (GPT-6).
- Generated: Code, tests and this description.
- Human review: [@gavinchou previously approved implementation head
`17d42f6ef18`](apache#70218 (review));
GitHub dismissed that approval after the pipeline cleanup commit. The
final head has been reviewed locally.

(cherry picked from commit 08231e3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.1.0-merged reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants