Skip to content

Commit

Permalink
SOLR-16871: Fix for duplicated replica added from first coordinator n…
Browse files Browse the repository at this point in the history
…ode (#1794)
  • Loading branch information
patsonluk authored Jul 19, 2023
1 parent 9453534 commit 9cdf0e4
Showing 1 changed file with 39 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,42 +124,48 @@ public static SolrCore getCore(
}
}
}
List<Replica> nodeNameSyntheticReplicas =
syntheticColl.getReplicas(solrCall.cores.getZkController().getNodeName());
if (nodeNameSyntheticReplicas == null || nodeNameSyntheticReplicas.isEmpty()) {
// this node does not have a replica. add one
if (log.isInfoEnabled()) {
log.info(
"this node does not have a replica of the synthetic collection: {} , adding replica ",
syntheticCollectionName);
synchronized (CoordinatorHttpSolrCall.class) {
// get docCollection again to ensure we get the fresh state
syntheticColl =
zkStateReader.getClusterState().getCollectionOrNull(syntheticCollectionName);
List<Replica> nodeNameSyntheticReplicas =
syntheticColl.getReplicas(solrCall.cores.getZkController().getNodeName());
if (nodeNameSyntheticReplicas == null || nodeNameSyntheticReplicas.isEmpty()) {
// this node does not have a replica. add one
if (log.isInfoEnabled()) {
log.info(
"this node does not have a replica of the synthetic collection: {} , adding replica ",
syntheticCollectionName);
}

addReplica(syntheticCollectionName, solrCall.cores);
}

addReplica(syntheticCollectionName, solrCall.cores);
}
// still have to ensure that it's active, otherwise super.getCoreByCollection
// will return null and then CoordinatorHttpSolrCall will call getCore again
// hence creating a calling loop
try {
zkStateReader.waitForState(
syntheticCollectionName,
10,
TimeUnit.SECONDS,
docCollection -> {
for (Replica nodeNameSyntheticReplica :
docCollection.getReplicas(solrCall.cores.getZkController().getNodeName())) {
if (nodeNameSyntheticReplica.getState() == Replica.State.ACTIVE) {
return true;
// still have to ensure that it's active, otherwise super.getCoreByCollection
// will return null and then CoordinatorHttpSolrCall will call getCore again
// hence creating a calling loop
try {
zkStateReader.waitForState(
syntheticCollectionName,
10,
TimeUnit.SECONDS,
docCollection -> {
for (Replica nodeNameSyntheticReplica :
docCollection.getReplicas(solrCall.cores.getZkController().getNodeName())) {
if (nodeNameSyntheticReplica.getState() == Replica.State.ACTIVE) {
return true;
}
}
}
return false;
});
} catch (Exception e) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"Failed to wait for active replica for synthetic collection ["
+ syntheticCollectionName
+ "]",
e);
return false;
});
} catch (Exception e) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"Failed to wait for active replica for synthetic collection ["
+ syntheticCollectionName
+ "]",
e);
}
}

core = solrCall.getCoreByCollection(syntheticCollectionName, isPreferLeader);
Expand Down Expand Up @@ -212,12 +218,9 @@ private static void setMDCLoggingContext(String collectionName) {
private static void addReplica(String syntheticCollectionName, CoreContainer cores) {
SolrQueryResponse rsp = new SolrQueryResponse();
try {
String coreName =
syntheticCollectionName + "_" + cores.getZkController().getNodeName().replace(':', '_');
CollectionAdminRequest.AddReplica addReplicaRequest =
CollectionAdminRequest.addReplicaToShard(syntheticCollectionName, "shard1")
// we are fixing the name, so that no two replicas are created in the same node
.setCoreName(coreName)
.setNode(cores.getZkController().getNodeName());
addReplicaRequest.setWaitForFinalState(true);
cores
Expand All @@ -228,18 +231,6 @@ private static void addReplica(String syntheticCollectionName, CoreContainer cor
SolrException.ErrorCode.SERVER_ERROR,
"Could not auto-create collection: " + Utils.toJSONString(rsp.getValues()));
}
} catch (SolrException e) {
if (e.getMessage().contains("replica with the same core name already exists")) {
// another request has already created a replica for this synthetic collection
if (log.isInfoEnabled()) {
log.info(
"A replica is already created in this node for synthetic collection: {}",
syntheticCollectionName);
}
return;
}
throw e;

} catch (Exception e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
}
Expand Down

0 comments on commit 9cdf0e4

Please sign in to comment.