SOLR-9566: Don't put replicas into recovery when collections are created

This commit is contained in:
Alan Woodward 2016-09-26 22:51:39 +01:00
parent 927fd51d64
commit 65f55802ee
9 changed files with 41 additions and 32 deletions

View File

@ -195,6 +195,8 @@ Optimizations
reader rather than ask for a global view. In extreme cases, this leads to a 100x speedup.
(Takahiro Ishikawa, yonik)
* SOLR-9566: Don't put replicas into recovery when first creating a Collection
(Alan Woodward)
Other Changes
----------------------

View File

@ -217,6 +217,7 @@ public class CreateCollectionCmd implements Cmd {
params.set(CoreAdminParams.COLLECTION, collectionName);
params.set(CoreAdminParams.SHARD, position.shard);
params.set(ZkStateReader.NUM_SHARDS_PROP, numSlices);
params.set(CoreAdminParams.NEW_COLLECTION, "true");
if (async != null) {
String coreAdminAsyncId = async + Math.abs(System.nanoTime());

View File

@ -231,7 +231,7 @@ public class ZkController {
public Object call() throws Exception {
log.info("Registering core {} afterExpiration? {}", descriptor.getName(), afterExpiration);
register(descriptor.getName(), descriptor, recoverReloadedCores, afterExpiration);
register(descriptor.getName(), descriptor, recoverReloadedCores, afterExpiration, false);
return descriptor;
}
}
@ -354,7 +354,7 @@ public class ZkController {
if (executorService != null) {
executorService.submit(new RegisterCoreAsync(descriptor, true, true));
} else {
register(descriptor.getName(), descriptor, true, true);
register(descriptor.getName(), descriptor, true, true, false);
}
} catch (Exception e) {
SolrException.log(log, "Error registering SolrCore", e);
@ -840,8 +840,8 @@ public class ZkController {
*
* @return the shardId for the SolrCore
*/
public String register(String coreName, final CoreDescriptor desc) throws Exception {
return register(coreName, desc, false, false);
public String register(String coreName, final CoreDescriptor desc, boolean skipRecovery) throws Exception {
return register(coreName, desc, false, false, skipRecovery);
}
@ -850,7 +850,8 @@ public class ZkController {
*
* @return the shardId for the SolrCore
*/
public String register(String coreName, final CoreDescriptor desc, boolean recoverReloadedCores, boolean afterExpiration) throws Exception {
public String register(String coreName, final CoreDescriptor desc, boolean recoverReloadedCores,
boolean afterExpiration, boolean skipRecovery) throws Exception {
try (SolrCore core = cc.getCore(desc.getName())) {
MDCLoggingContext.setCore(core);
}
@ -929,8 +930,8 @@ public class ZkController {
}
}
}
boolean didRecovery = checkRecovery(coreName, desc, recoverReloadedCores, isLeader, cloudDesc, collection,
coreZkNodeName, shardId, leaderProps, core, cc, afterExpiration);
boolean didRecovery
= checkRecovery(recoverReloadedCores, isLeader, skipRecovery, collection, coreZkNodeName, core, cc, afterExpiration);
if (!didRecovery) {
publish(desc, Replica.State.ACTIVE);
}
@ -1080,10 +1081,8 @@ public class ZkController {
/**
* Returns whether or not a recovery was started
*/
private boolean checkRecovery(String coreName, final CoreDescriptor desc,
boolean recoverReloadedCores, final boolean isLeader,
final CloudDescriptor cloudDesc, final String collection,
final String shardZkNodeName, String shardId, ZkNodeProps leaderProps,
private boolean checkRecovery(boolean recoverReloadedCores, final boolean isLeader, boolean skipRecovery,
final String collection, String shardId,
SolrCore core, CoreContainer cc, boolean afterExpiration) {
if (SKIP_AUTO_RECOVERY) {
log.warn("Skipping recovery according to sys prop solrcloud.skip.autorecovery");
@ -1092,7 +1091,7 @@ public class ZkController {
boolean doRecovery = true;
if (!isLeader) {
if (!afterExpiration && core.isReloaded() && !recoverReloadedCores) {
if (skipRecovery || (!afterExpiration && core.isReloaded() && !recoverReloadedCores)) {
doRecovery = false;
}

View File

@ -517,14 +517,14 @@ public class CoreContainer {
zkSys.getZkController().throwErrorIfReplicaReplaced(cd);
}
core = create(cd, false);
core = create(cd, false, false);
} finally {
if (asyncSolrCoreLoad) {
solrCores.markCoreAsNotLoading(cd);
}
}
try {
zkSys.registerInZk(core, true);
zkSys.registerInZk(core, true, false);
} catch (RuntimeException e) {
SolrException.log(log, "Error registering SolrCore", e);
}
@ -706,7 +706,7 @@ public class CoreContainer {
return coresLocator;
}
protected SolrCore registerCore(String name, SolrCore core, boolean registerInZk) {
protected SolrCore registerCore(String name, SolrCore core, boolean registerInZk, boolean skipRecovery) {
if( core == null ) {
throw new RuntimeException( "Can not register a null core." );
}
@ -744,7 +744,7 @@ public class CoreContainer {
if( old == null || old == core) {
log.debug( "registering core: "+name );
if (registerInZk) {
zkSys.registerInZk(core, false);
zkSys.registerInZk(core, false, skipRecovery);
}
return null;
}
@ -752,7 +752,7 @@ public class CoreContainer {
log.debug( "replacing core: "+name );
old.close();
if (registerInZk) {
zkSys.registerInZk(core, false);
zkSys.registerInZk(core, false, skipRecovery);
}
return old;
}
@ -765,7 +765,7 @@ public class CoreContainer {
* @return the newly created core
*/
public SolrCore create(String coreName, Map<String, String> parameters) {
return create(coreName, cfg.getCoreRootDirectory().resolve(coreName), parameters);
return create(coreName, cfg.getCoreRootDirectory().resolve(coreName), parameters, false);
}
/**
@ -775,7 +775,7 @@ public class CoreContainer {
* @param parameters the core parameters
* @return the newly created core
*/
public SolrCore create(String coreName, Path instancePath, Map<String, String> parameters) {
public SolrCore create(String coreName, Path instancePath, Map<String, String> parameters, boolean newCollection) {
CoreDescriptor cd = new CoreDescriptor(this, coreName, instancePath, parameters);
@ -798,7 +798,7 @@ public class CoreContainer {
preExisitingZkEntry = getZkController().checkIfCoreNodeNameAlreadyExists(cd);
}
SolrCore core = create(cd, true);
SolrCore core = create(cd, true, newCollection);
// only write out the descriptor if the core is successfully created
coresLocator.create(this, cd);
@ -845,7 +845,7 @@ public class CoreContainer {
*
* @return the newly created core
*/
private SolrCore create(CoreDescriptor dcore, boolean publishState) {
private SolrCore create(CoreDescriptor dcore, boolean publishState, boolean newCollection) {
if (isShutDown) {
throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Solr has been shutdown.");
@ -868,7 +868,7 @@ public class CoreContainer {
core.getUpdateHandler().getUpdateLog().recoverFromLog();
}
registerCore(dcore.getName(), core, publishState);
registerCore(dcore.getName(), core, publishState, newCollection);
return core;
} catch (Exception e) {
@ -964,7 +964,7 @@ public class CoreContainer {
ConfigSet coreConfig = coreConfigService.getConfig(cd);
log.info("Reloading SolrCore '{}' using configuration from {}", cd.getName(), coreConfig.getName());
SolrCore newCore = core.reload(coreConfig);
registerCore(name, newCore, false);
registerCore(name, newCore, false, false);
} catch (SolrCoreState.CoreIsClosedException e) {
throw e;
} catch (Exception e) {
@ -1061,7 +1061,7 @@ public class CoreContainer {
SolrIdentifierValidator.validateCoreName(toName);
try (SolrCore core = getCore(name)) {
if (core != null) {
registerCore(toName, core, true);
registerCore(toName, core, true, false);
SolrCore old = solrCores.remove(name);
coresLocator.rename(this, old.getCoreDescriptor(), core.getCoreDescriptor());
}
@ -1132,7 +1132,7 @@ public class CoreContainer {
if (zkSys.getZkController() != null) {
zkSys.getZkController().throwErrorIfReplicaReplaced(desc);
}
core = create(desc, true); // This should throw an error if it fails.
core = create(desc, true, false); // This should throw an error if it fails.
}
core.open();
}

View File

@ -173,12 +173,12 @@ public class ZkContainer {
return zkRun.substring(0, zkRun.lastIndexOf('/'));
}
public void registerInZk(final SolrCore core, boolean background) {
public void registerInZk(final SolrCore core, boolean background, boolean skipRecovery) {
Runnable r = () -> {
MDCLoggingContext.setCore(core);
try {
try {
zkController.register(core.getName(), core.getCoreDescriptor());
zkController.register(core.getName(), core.getCoreDescriptor(), skipRecovery);
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();

View File

@ -82,7 +82,9 @@ enum CoreAdminOperation implements CoreAdminOp {
instancePath = coreContainer.getCoreRootDirectory().resolve(instanceDir).normalize();
}
coreContainer.create(coreName, instancePath, coreParams);
boolean newCollection = params.getBool(CoreAdminParams.NEW_COLLECTION, false);
coreContainer.create(coreName, instancePath, coreParams, newCollection);
it.rsp.add("core", coreName);
}),

View File

@ -219,7 +219,7 @@ public class TestCodecSupport extends SolrTestCaseJ4 {
try {
c = new SolrCore(new CoreDescriptor(h.getCoreContainer(), newCoreName, testSolrHome.resolve(newCoreName)),
new ConfigSet("fakeConfigset", config, schema, null));
assertNull(h.getCoreContainer().registerCore(newCoreName, c, false));
assertNull(h.getCoreContainer().registerCore(newCoreName, c, false, false));
h.coreName = newCoreName;
assertEquals("We are not using the correct core", "solrconfig_codec2.xml", h.getCore().getConfigResource());
assertU(add(doc("string_f", "foo")));

View File

@ -230,7 +230,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 {
try {
// Create a new core, this should call all the firstSearcherListeners
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"));
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"), false);
//validate that the new core was created with the correct solrconfig
assertNotNull(newCore.getSearchComponent("mock"));
@ -280,7 +280,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 {
boolean coreCreated = false;
try {
// Create a new core, this should call all the firstSearcherListeners
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"));
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"), false);
coreCreated = true;
//validate that the new core was created with the correct solrconfig
@ -346,7 +346,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 {
try {
System.setProperty("tests.solr.useColdSearcher", "true");
// Create a new core, this should call all the firstSearcherListeners
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"));
newCore = cores.create("core1", cd.getInstanceDir(), ImmutableMap.of("config", "solrconfig-searcher-listeners1.xml"), false);
coreCreated = true;
//validate that the new core was created with the correct solrconfig

View File

@ -123,6 +123,11 @@ public abstract class CoreAdminParams
*/
public static final String COMMIT_NAME = "commitName";
/**
* A boolean parameter specifying if a core is being created as part of a new collection
*/
public static final String NEW_COLLECTION = "newCollection";
public enum CoreAdminAction {
STATUS(true),
UNLOAD,