Skip to content

Commit 6cc80a0

Browse files
authored
SOLR-18096: /admin/cores?action=UPGRADECOREINDEX (#3903)
Provides a /admin/cores api (action=UPGRADECOREINDEX) to upgrade older index segments to the latest version (by targeted reindexing). Calling this endpoint on an index created in version X-1 (assuming you are on Solr version X) would reindex documents in any segments of the older version (X-1) creating new segments, resulting in the old ones getting deleted. This would help prepare the index for when Solr is upgraded to X+1 without having to recreate the index from source (as is the requirement today). Various limitations apply.
1 parent 45adb11 commit 6cc80a0

10 files changed

Lines changed: 1099 additions & 2 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
2+
title: CoreAdmin API (/admin/cores?action=UPGRADECOREINDEX) to upgrade an index in-place
3+
type: added
4+
authors:
5+
- name: Rahul Goswami
6+
links:
7+
- name: SOLR-18096
8+
url: https://issues.apache.org/jira/browse/SOLR-18096
9+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.model;
18+
19+
import com.fasterxml.jackson.annotation.JsonProperty;
20+
import io.swagger.v3.oas.annotations.media.Schema;
21+
22+
public class UpgradeCoreIndexRequestBody {
23+
24+
@Schema(description = "Request ID to track this action which will be processed asynchronously.")
25+
@JsonProperty
26+
public String async;
27+
28+
@Schema(
29+
description =
30+
"updateChain to be used for reindexing during index upgrade if you don't want to use the one used by /update by default")
31+
@JsonProperty
32+
public String updateChain;
33+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.model;
18+
19+
import com.fasterxml.jackson.annotation.JsonProperty;
20+
import io.swagger.v3.oas.annotations.media.Schema;
21+
22+
public class UpgradeCoreIndexResponse extends SolrJerseyResponse {
23+
@Schema(description = "The name of the core.")
24+
@JsonProperty
25+
public String core;
26+
27+
@Schema(description = "The total number of segments eligible for upgrade.")
28+
@JsonProperty
29+
public Integer numSegmentsEligibleForUpgrade;
30+
31+
@Schema(description = "The number of segments successfully upgraded.")
32+
@JsonProperty
33+
public Integer numSegmentsUpgraded;
34+
35+
@Schema(description = "Status of the core index upgrade operation.")
36+
@JsonProperty
37+
public String upgradeStatus;
38+
}

solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import static org.apache.solr.common.params.CoreAdminParams.CoreAdminAction.STATUS;
3939
import static org.apache.solr.common.params.CoreAdminParams.CoreAdminAction.SWAP;
4040
import static org.apache.solr.common.params.CoreAdminParams.CoreAdminAction.UNLOAD;
41+
import static org.apache.solr.common.params.CoreAdminParams.CoreAdminAction.UPGRADECOREINDEX;
4142
import static org.apache.solr.handler.admin.CoreAdminHandler.CallInfo;
4243

4344
import java.lang.invoke.MethodHandles;
@@ -256,7 +257,8 @@ public enum CoreAdminOperation implements CoreAdminOp {
256257
final ListCoreSnapshotsResponse response = coreSnapshotAPI.listSnapshots(coreName);
257258

258259
V2ApiUtils.squashIntoSolrResponseWithoutHeader(it.rsp, response);
259-
});
260+
}),
261+
UPGRADECOREINDEX_OP(UPGRADECOREINDEX, new UpgradeCoreIndexOp());
260262

261263
final CoreAdminParams.CoreAdminAction action;
262264
final CoreAdminOp fun;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.handler.admin;
18+
19+
import org.apache.solr.client.api.model.UpgradeCoreIndexRequestBody;
20+
import org.apache.solr.client.api.model.UpgradeCoreIndexResponse;
21+
import org.apache.solr.common.SolrException;
22+
import org.apache.solr.common.params.CommonAdminParams;
23+
import org.apache.solr.common.params.CoreAdminParams;
24+
import org.apache.solr.common.params.SolrParams;
25+
import org.apache.solr.common.params.UpdateParams;
26+
import org.apache.solr.common.util.NamedList;
27+
import org.apache.solr.core.CoreContainer;
28+
import org.apache.solr.handler.admin.api.UpgradeCoreIndex;
29+
import org.apache.solr.handler.api.V2ApiUtils;
30+
import org.apache.solr.request.SolrQueryRequest;
31+
import org.apache.solr.response.SolrQueryResponse;
32+
33+
class UpgradeCoreIndexOp implements CoreAdminHandler.CoreAdminOp {
34+
@FunctionalInterface
35+
public interface UpgradeCoreIndexFactory {
36+
UpgradeCoreIndex create(
37+
CoreContainer coreContainer,
38+
CoreAdminHandler.CoreAdminAsyncTracker coreAdminAsyncTracker,
39+
SolrQueryRequest req,
40+
SolrQueryResponse rsp);
41+
}
42+
43+
static UpgradeCoreIndexFactory UPGRADE_CORE_INDEX_FACTORY = UpgradeCoreIndex::new;
44+
45+
@Override
46+
public boolean isExpensive() {
47+
return true;
48+
}
49+
50+
@Override
51+
public void execute(CoreAdminHandler.CallInfo it) throws Exception {
52+
53+
assert it.handler.coreContainer != null;
54+
if (it.handler.coreContainer.isZooKeeperAware()) {
55+
throw new SolrException(
56+
SolrException.ErrorCode.BAD_REQUEST,
57+
"action=UPGRADECOREINDEX is not supported in SolrCloud mode. As an alternative, in order to upgrade index, configure LatestVersionMergePolicyFactory in solrconfig.xml and reindex the data in your collection.");
58+
}
59+
60+
SolrParams params = it.req.getParams();
61+
String cname = params.required().get(CoreAdminParams.CORE);
62+
final boolean isAsync = params.get(CommonAdminParams.ASYNC) != null;
63+
final var requestBody = new UpgradeCoreIndexRequestBody();
64+
requestBody.updateChain = params.get(UpdateParams.UPDATE_CHAIN);
65+
66+
UpgradeCoreIndex upgradeCoreIndexApi =
67+
UPGRADE_CORE_INDEX_FACTORY.create(
68+
it.handler.coreContainer, it.handler.coreAdminAsyncTracker, it.req, it.rsp);
69+
final UpgradeCoreIndexResponse response =
70+
upgradeCoreIndexApi.upgradeCoreIndex(cname, requestBody);
71+
V2ApiUtils.squashIntoSolrResponseWithoutHeader(it.rsp, response);
72+
73+
if (isAsync) {
74+
final var opResponse = new NamedList<>();
75+
V2ApiUtils.squashIntoNamedListWithoutHeader(opResponse, response);
76+
// REQUESTSTATUS is returning the inner response NamedList as a positional array
77+
// ([k1,v1,k2,v2...]).
78+
// so converting to a map
79+
it.rsp.addResponse(opResponse.asMap(1));
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)