Skip to content

[fix](cloud) Skip empty partition meta RPCs in cloud restore - #67139

Open
felixwluo wants to merge 3 commits into
apache:masterfrom
felixwluo:fix-cloud-restore
Open

[fix](cloud) Skip empty partition meta RPCs in cloud restore#67139
felixwluo wants to merge 3 commits into
apache:masterfrom
felixwluo:fix-cloud-restore

Conversation

@felixwluo

Copy link
Copy Markdown
Member

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:
When restoring a backup from an integrated-storage cluster to a storage-compute separated cluster, cloud restore could fail if the backed-up OLAP table had no restore partitions. CloudRestoreJob still sent prepare/commit/drop partition RPCs to the meta service with an empty partition id list. The meta service correctly rejected the request with "empty partition_ids or index_ids or table_id". During cancellation/cleanup, the original failure could be overwritten by the drop-partition cleanup failure, showing an error like:
cloud restore job failed to drop partitions, table=xxx, partitions=[], errMsg: empty partition_ids or index_ids or table_id.

The fix treats empty restore partition collections as a no-op for cloud partition meta operations, because there is no partition metadata to prepare, commit, or drop. It also resolves the storage vault id from the restore storage vault name when no tablets are created, so empty-table restore does not depend on a createTablets response to fill the vault id.

Release note

Fix cloud restore failure when restoring backup metadata with empty OLAP table partitions.

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

… segments in the rowset reader (apache#35484)

## Proposed changes

pick apache#35432 

## Further comments

If this is a relatively large or complex change, kick off the discussion
at [dev@doris.apache.org](mailto:dev@doris.apache.org) by explaining why
you chose the solution you did and what alternatives you considered,
etc...
@felixwluo
felixwluo requested a review from gavinchou as a code owner August 25, 2026 17:23
@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?

@felixwluo

Copy link
Copy Markdown
Member Author

/review

@felixwluo

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17627	3122	3082	3082
q2	2074	251	226	226
q3	10250	888	515	515
q4	4664	247	207	207
q5	7674	584	374	374
q6	136	114	94	94
q7	528	498	374	374
q8	9226	929	947	929
q9	3544	2405	2394	2394
q10	6515	843	698	698
q11	387	200	180	180
q12	603	259	204	204
q13	18161	1544	1171	1171
q14	153	154	133	133
q15	q16	427	396	369	369
q17	1322	862	790	790
q18	3085	2216	2230	2216
q19	1275	919	793	793
q20	354	276	199	199
q21	5622	1790	1858	1790
q22	335	268	230	230
Total cold run time: 93962 ms
Total hot run time: 16968 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3439	3390	3364	3364
q2	516	408	393	393
q3	2236	2354	2164	2164
q4	1186	1160	897	897
q5	2161	2108	2101	2101
q6	180	121	86	86
q7	1049	920	893	893
q8	1619	1417	1420	1417
q9	3132	3123	3095	3095
q10	1837	1794	1602	1602
q11	355	268	253	253
q12	450	429	349	349
q13	1466	1542	1154	1154
q14	172	171	162	162
q15	q16	402	394	358	358
q17	3596	3326	3309	3309
q18	4796	4432	4713	4432
q19	888	959	882	882
q20	998	967	824	824
q21	3915	3250	3224	3224
q22	404	350	333	333
Total cold run time: 34797 ms
Total hot run time: 31292 ms

@hello-stephen

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

query5	4274	411	315	315
query6	374	133	122	122
query7	4997	428	216	216
query8	297	124	113	113
query9	8675	2917	2938	2917
query10	389	225	201	201
query11	5383	1037	913	913
query12	121	73	72	72
query13	1196	441	334	334
query14	6151	2220	2116	2116
query14_1	1989	1965	1952	1952
query15	172	125	112	112
query16	911	377	366	366
query17	807	473	366	366
query18	2344	332	245	245
query19	166	137	116	116
query20	73	68	72	68
query21	201	102	86	86
query22	5310	5232	5277	5232
query23	6847	6256	5959	5959
query23_1	6092	6013	6033	6013
query24	7302	1128	761	761
query24_1	760	798	804	798
query25	435	316	258	258
query26	1234	234	133	133
query27	2795	416	256	256
query28	4682	1504	1510	1504
query29	938	452	331	331
query30	248	157	125	125
query31	819	389	326	326
query32	124	84	68	68
query33	450	208	166	166
query34	984	816	474	474
query35	403	385	340	340
query36	569	583	513	513
query37	118	86	65	65
query38	994	841	830	830
query39	490	476	484	476
query39_1	445	470	424	424
query40	202	86	75	75
query41	53	52	52	52
query42	72	70	76	70
query43	243	238	209	209
query44	1023	546	553	546
query45	109	104	99	99
query46	775	839	516	516
query47	767	735	691	691
query48	304	311	209	209
query49	531	229	180	180
query50	752	259	189	189
query51	8368	8345	8118	8118
query52	73	66	63	63
query53	196	199	145	145
query54	225	179	251	179
query55	75	59	53	53
query56	193	177	162	162
query57	684	683	646	646
query58	197	160	166	160
query59	1227	1231	1111	1111
query60	242	186	172	172
query61	108	120	118	118
query62	353	210	176	176
query63	181	154	138	138
query64	2746	719	617	617
query65	1605	1619	1573	1573
query66	1802	253	205	205
query67	9628	9699	9393	9393
query68	2742	1191	735	735
query69	343	238	186	186
query70	662	631	599	599
query71	250	168	165	165
query72	2286	1774	1536	1536
query73	639	639	326	326
query74	1568	1208	1129	1129
query75	1153	1087	954	954
query76	2287	729	545	545
query77	251	257	212	212
query78	3946	3550	3153	3153
query79	2225	824	583	583
query80	1585	335	273	273
query81	478	155	131	131
query82	617	117	99	99
query83	313	203	190	190
query84	294	108	90	90
query85	803	349	323	323
query86	386	164	167	164
query87	994	958	891	891
query88	2774	2097	2122	2097
query89	286	195	174	174
query90	1915	132	130	130
query91	132	120	97	97
query92	76	67	69	67
query93	1339	1069	698	698
query94	653	238	228	228
query95	517	242	228	228
query96	857	616	272	272
query97	1056	1101	1027	1027
query98	154	139	133	133
query99	417	341	312	312
Total cold run time: 176723 ms
Total hot run time: 81437 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.07	0.04	0.03
query3	0.24	0.12	0.11
query4	1.60	0.10	0.09
query5	0.18	0.16	0.16
query6	1.29	0.71	0.69
query7	0.03	0.01	0.00
query8	0.04	0.02	0.03
query9	0.29	0.21	0.22
query10	0.36	0.35	0.34
query11	0.16	0.12	0.11
query12	0.15	0.11	0.11
query13	0.30	0.30	0.32
query14	0.45	0.46	0.46
query15	0.36	0.37	0.37
query16	0.22	0.20	0.23
query17	0.71	0.76	0.71
query18	0.18	0.17	0.18
query19	1.24	1.12	1.10
query20	0.01	0.01	0.01
query21	15.45	0.17	0.11
query22	5.07	0.04	0.04
query23	16.18	0.26	0.10
query24	3.03	0.31	0.26
query25	0.10	0.04	0.04
query26	0.77	0.18	0.12
query27	0.04	0.03	0.03
query28	3.61	0.59	0.28
query29	12.45	3.19	2.60
query30	0.25	0.12	0.13
query31	2.82	0.38	0.18
query32	3.52	0.32	0.24
query33	1.57	1.43	1.49
query34	15.37	2.22	1.78
query35	1.81	1.73	1.71
query36	0.45	0.30	0.30
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.03	0.02
query40	0.11	0.08	0.07
query41	0.07	0.03	0.02
query42	0.03	0.03	0.03
query43	0.04	0.03	0.03
Total cold run time: 90.76 s
Total hot run time: 14.77 s

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

Request changes — capped/incomplete after the third permitted review round. Three blocking correctness issues are substantiated and covered inline. The third was newly accepted in the final round, so I cannot truthfully claim convergence even though every currently known candidate has been adjudicated and reported.

Critical checkpoint conclusions:

  • Goal and proof: Supporting a Cloud restore with no selected backup partitions is a valid goal, but the code only avoids the failing partition RPCs; it does not preserve a writable table or complete metadata/vault semantics. The helper-level test does not prove the end-to-end goal.
  • Scope and clarity: The two-file change is small and focused, but the broad empty-collection return conflates valid empty RANGE/LIST tables with invalid zero-partition unpartitioned tables and suppresses non-partition side effects.
  • Concurrency: run/cancel serialize job transitions and the vault map is protected by its read/write lock. No new data race, lock-order, or heavy-under-lock issue was found; the vault defect is initialization ordering and authority, not mutual exclusion.
  • Lifecycle: PENDING/CREATING transitions are unjournaled, so index publication/cleanup must remain replay-safe across failover. BackupHandler can also resume before the asynchronous vault checker has populated its cache.
  • Configuration: No configuration is added. The relevant existing gates were checked: storage-vault enablement, FE compatibility-check mode, and Meta Service multi-version states.
  • Compatibility: No function-symbol, FE/BE protocol, transmitted-variable, or storage-format change is introduced. Legacy and versioned metadata branches were inspected; the concrete MF-1 deletion path is on supported multi-version metadata.
  • Parallel paths: Normal empty-table creation, exclude-all restore, existing-table partition restore, mixed/multi-table jobs, later ADD PARTITION, dynamic/automatic and unpartitioned tables, cancellation, replay, views/resources, and Cloud atomic restore were checked. Cloud atomic restore is rejected upstream; no separate issue remains there.
  • Conditions and error handling: The empty guard is too broad. It turns an invalid unpartitioned terminal shape into success, skips required index work, and the vault fallback turns temporary cache unreadiness into permanent cancellation while accepting stale nonempty IDs.
  • Test coverage and results: The new test directly injects a warm-cache SinglePartitionInfo table and calls hooks; it does not cover filtering, the full state machine, registration, replay, index RPCs, authoritative-vault negative cases, later mutation, or post-restore writes. COMPILE, CheckStyle, BE UT, Cloud UT, and performance currently pass; FE UT currently fails and its TeamCity log requires authentication; several regressions remain pending. No local build/test was run because the review prompt prohibits it.
  • Observability: The bounded INFO log has useful identifiers and creates no separate logging/metrics issue, but it currently describes semantically required lifecycle work as a harmless skip.
  • Persistence, transactions, and data writes: The missing versioned index hierarchy/table version, unjournaled replay window, and registration of an unwritable table violate metadata/data correctness. No independent FE/BE crash, memory-safety, or atomicity issue remained beyond the inline findings.
  • Performance: No material CPU, memory, allocation, or hot-path regression was found.
  • Additional focus: No additional user-provided review focus was supplied.

Please address all three inline findings and add end-to-end coverage for the repaired table types and failure/replay boundaries.

// set storage vault for new restoring table
if (((CloudEnv) Env.getCurrentEnv()).getEnableStorageVault()) {
if (Strings.isNullOrEmpty(storageVaultId)) {
storageVaultId = Env.getCurrentEnv().getStorageVaultMgr().getVaultIdByName(storageVaultName);

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.

[P1] Do not treat the asynchronous vault cache as authoritative

For an empty restore there is no create-tablets response to validate the vault, so this lookup is the only source of the ID. After restart/master promotion, storageVaultId is transient and the vault map starts empty; BackupHandler can resume jobs before CloudInstanceStatusChecker populates it, turning a valid restore into a permanent cancellation. The map can also be stale: the checker leaves old entries when Meta Service reports zero vaults, so deleting the last vault can let this code persist a deleted nonempty ID. Please resolve/revalidate the vault from an authoritative source at empty-table creation time, treating transient unavailability as retry/defer and definitive absence as failure before registration; merely serializing the earlier cached ID would not handle deletion.


private void handleOlapTableMeta(MetaSeriviceOperation operation, OlapTable olapTable,
Collection<Partition> partitions) throws DdlException {
if (partitions.isEmpty()) {

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.

[P1] Preserve the index lifecycle for an empty restored table

This avoids the invalid empty-partition RPCs, but it also skips the index-only lifecycle used by normal empty Cloud table creation. That path still calls prepare/commit materialized-index; commit-index creates the versioned index mappings and initializes the table version. A later ADD PARTITION only commits partition keys, so it does not repair the missing index mappings. The orphan recycler then sees no index-inverted key for the table and can delete the newly added partition and table-version metadata. Please use a replay-safe index PREPARE/COMMIT lifecycle for zero partitions, including cleanup of prepared/committed transient IDs on cancellation or PENDING replay, instead of suppressing all Meta Service work.

if (partitions.isEmpty()) {
LOG.info("cloud restore job skip {} partitions, dbId: {}, tableName: {}, vault name: {}",
operation, dbId, olapTable.getName(), storageVaultName);
return;

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.

[P1] Do not register an unpartitioned table without its implicit partition

The new test exercises a SinglePartitionInfo table, removes its only partition, and this return lets the restore register that zero-partition table successfully. It is then permanently unusable: inserts fail with ERR_EMPTY_PARTITION_IN_TABLE, while ADD PARTITION is rejected for unpartitioned tables. The index-only lifecycle needed for valid empty RANGE/LIST tables does not repair this case. Please either reject exclusion of an unpartitioned table's sole implicit partition, or recreate an empty implicit partition/tablets so the restored table remains writable, and cover that outcome end to end.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/7) 🎉
Increment coverage report
Complete coverage report

@felixwluo

Copy link
Copy Markdown
Member Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17640	3058	3035	3035
q2	2433	259	226	226
q3	10220	847	527	527
q4	4672	254	211	211
q5	7675	539	385	385
q6	136	115	91	91
q7	536	503	391	391
q8	9238	974	946	946
q9	3889	2451	2440	2440
q10	6598	848	722	722
q11	403	195	175	175
q12	623	253	193	193
q13	18204	1547	1158	1158
q14	161	153	139	139
q15	q16	439	399	369	369
q17	1383	873	785	785
q18	3151	2326	2304	2304
q19	1330	948	802	802
q20	380	282	203	203
q21	5281	1744	1837	1744
q22	323	263	226	226
Total cold run time: 94715 ms
Total hot run time: 17072 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3391	3327	3323	3323
q2	530	403	379	379
q3	2207	2361	2312	2312
q4	1219	1218	902	902
q5	2246	2153	2157	2153
q6	175	121	84	84
q7	1022	919	872	872
q8	1607	1429	1424	1424
q9	3247	3224	3192	3192
q10	1883	1829	1654	1654
q11	361	269	258	258
q12	451	431	347	347
q13	1521	1545	1162	1162
q14	179	166	178	166
q15	q16	405	403	357	357
q17	3664	3496	3314	3314
q18	4987	4692	5045	4692
q19	932	837	819	819
q20	996	985	859	859
q21	3612	3003	3278	3003
q22	398	350	334	334
Total cold run time: 35033 ms
Total hot run time: 31606 ms

@hello-stephen

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

query5	4272	412	345	345
query6	392	134	135	134
query7	4929	393	234	234
query8	317	125	117	117
query9	8690	2848	2875	2848
query10	479	219	182	182
query11	5396	1059	917	917
query12	117	70	72	70
query13	1193	485	321	321
query14	6047	2273	2162	2162
query14_1	1998	1991	1978	1978
query15	165	127	109	109
query16	1116	353	345	345
query17	794	434	345	345
query18	2326	313	231	231
query19	167	137	102	102
query20	73	69	70	69
query21	424	96	84	84
query22	5681	5453	5606	5453
query23	6843	6471	6175	6175
query23_1	6283	6291	6221	6221
query24	7349	1132	824	824
query24_1	778	817	795	795
query25	448	321	270	270
query26	1231	255	133	133
query27	2758	437	275	275
query28	4644	1523	1513	1513
query29	960	487	351	351
query30	261	158	131	131
query31	826	409	336	336
query32	126	70	72	70
query33	456	211	176	176
query34	975	838	474	474
query35	415	415	344	344
query36	560	539	531	531
query37	129	78	68	68
query38	1043	871	842	842
query39	523	501	472	472
query39_1	447	448	456	448
query40	200	89	76	76
query41	54	55	54	54
query42	81	74	74	74
query43	242	242	213	213
query44	1027	547	549	547
query45	112	107	103	103
query46	772	852	527	527
query47	779	754	724	724
query48	314	315	234	234
query49	550	256	207	207
query50	782	274	192	192
query51	8038	8013	7869	7869
query52	71	71	57	57
query53	191	200	144	144
query54	218	156	151	151
query55	73	56	52	52
query56	194	169	148	148
query57	790	699	671	671
query58	198	158	152	152
query59	1231	1197	1077	1077
query60	253	179	164	164
query61	116	114	118	114
query62	357	205	166	166
query63	163	134	142	134
query64	2769	713	567	567
query65	1658	1709	1650	1650
query66	1884	272	219	219
query67	10271	10229	10018	10018
query68	2788	1163	753	753
query69	371	220	191	191
query70	661	614	621	614
query71	274	163	169	163
query72	2342	1884	1789	1789
query73	690	609	349	349
query74	1570	1252	1184	1184
query75	1199	1132	982	982
query76	2299	722	549	549
query77	259	270	221	221
query78	4067	3847	3462	3462
query79	1258	855	585	585
query80	1169	354	312	312
query81	471	157	140	140
query82	597	122	97	97
query83	336	217	196	196
query84	313	117	98	98
query85	932	363	304	304
query86	339	183	170	170
query87	1056	974	919	919
query88	2749	2114	2094	2094
query89	290	200	177	177
query90	1816	125	130	125
query91	133	122	98	98
query92	81	70	69	69
query93	1243	1158	748	748
query94	578	268	243	243
query95	522	259	294	259
query96	756	572	258	258
query97	1096	1119	1121	1119
query98	146	147	136	136
query99	466	359	314	314
Total cold run time: 178289 ms
Total hot run time: 83734 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.24	0.04	0.03
query3	0.60	0.11	0.11
query4	1.72	0.10	0.10
query5	0.18	0.16	0.15
query6	1.53	0.70	0.69
query7	0.04	0.01	0.00
query8	0.04	0.03	0.03
query9	0.63	0.22	0.21
query10	0.34	0.35	0.34
query11	0.28	0.12	0.11
query12	0.21	0.12	0.12
query13	0.32	0.31	0.33
query14	0.46	0.46	0.45
query15	0.37	0.34	0.35
query16	0.23	0.23	0.23
query17	0.73	0.69	0.66
query18	0.19	0.17	0.17
query19	1.35	1.14	1.18
query20	0.02	0.02	0.02
query21	16.88	0.15	0.11
query22	4.80	0.04	0.05
query23	16.87	0.25	0.11
query24	16.75	0.32	0.26
query25	0.09	0.04	0.04
query26	0.73	0.16	0.11
query27	0.04	0.02	0.03
query28	3.67	0.56	0.27
query29	12.53	3.13	2.53
query30	0.26	0.13	0.12
query31	2.88	0.36	0.18
query32	3.56	0.33	0.23
query33	1.39	1.44	1.42
query34	15.39	2.24	1.80
query35	1.76	1.72	1.72
query36	0.45	0.29	0.28
query37	0.21	0.04	0.04
query38	0.04	0.03	0.03
query39	0.25	0.03	0.03
query40	0.20	0.08	0.07
query41	0.37	0.02	0.02
query42	0.15	0.02	0.02
query43	0.03	0.03	0.02
Total cold run time: 108.79 s
Total hot run time: 14.68 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 57.14% (4/7) 🎉
Increment coverage report
Complete coverage report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants