mirror of https://github.com/apache/lucene.git
SOLR-13066: A failure while reloading a SolrCore can result in the SolrCore not being closed.
This commit is contained in:
parent
9728dbc167
commit
7de72c9bc7
|
@ -167,7 +167,9 @@ Bug Fixes
|
|||
|
||||
* SOLR-12933: Fix SolrCloud distributed commit. (Mark Miller)
|
||||
|
||||
* SOLR-13014: URI Too Long with large streaming expressions in SolrJ (janhoy)
|
||||
* SOLR-13014: URI Too Long with large streaming expressions in SolrJ (janhoy)
|
||||
|
||||
* SOLR-13066: A failure while reloading a SolrCore can result in the SolrCore not being closed. (Mark Miller)
|
||||
|
||||
Improvements
|
||||
----------------------
|
||||
|
|
|
@ -32,6 +32,7 @@ import static org.apache.solr.common.params.CommonParams.ZK_STATUS_PATH;
|
|||
import static org.apache.solr.core.CorePropertiesLocator.PROPERTIES_FILENAME;
|
||||
import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGIN_PROP;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.file.Path;
|
||||
|
@ -1432,6 +1433,7 @@ public class CoreContainer {
|
|||
if (isShutDown) {
|
||||
throw new AlreadyClosedException();
|
||||
}
|
||||
SolrCore newCore = null;
|
||||
SolrCore core = solrCores.getCoreFromAnyList(name, false);
|
||||
if (core != null) {
|
||||
|
||||
|
@ -1439,34 +1441,41 @@ public class CoreContainer {
|
|||
// CoreDescriptor and we need to reload it from the disk files
|
||||
CoreDescriptor cd = reloadCoreDescriptor(core.getCoreDescriptor());
|
||||
solrCores.addCoreDescriptor(cd);
|
||||
Closeable oldCore = null;
|
||||
boolean success = false;
|
||||
try {
|
||||
solrCores.waitAddPendingCoreOps(cd.getName());
|
||||
ConfigSet coreConfig = coreConfigService.getConfig(cd);
|
||||
log.info("Reloading SolrCore '{}' using configuration from {}", cd.getName(), coreConfig.getName());
|
||||
SolrCore newCore = core.reload(coreConfig);
|
||||
newCore = core.reload(coreConfig);
|
||||
|
||||
registerCore(cd, newCore, false, false);
|
||||
|
||||
if (getZkController() != null) {
|
||||
DocCollection docCollection = getZkController().getClusterState().getCollection(cd.getCollectionName());
|
||||
Replica replica = docCollection.getReplica(cd.getCloudDescriptor().getCoreNodeName());
|
||||
assert replica != null;
|
||||
if (replica.getType() == Replica.Type.TLOG) { //TODO: needed here?
|
||||
if (replica.getType() == Replica.Type.TLOG) { // TODO: needed here?
|
||||
getZkController().stopReplicationFromLeader(core.getName());
|
||||
if (!cd.getCloudDescriptor().isLeader()) {
|
||||
getZkController().startReplicationFromLeader(newCore.getName(), true);
|
||||
}
|
||||
|
||||
} else if(replica.getType() == Replica.Type.PULL) {
|
||||
} else if (replica.getType() == Replica.Type.PULL) {
|
||||
getZkController().stopReplicationFromLeader(core.getName());
|
||||
getZkController().startReplicationFromLeader(newCore.getName(), false);
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
} catch (SolrCoreState.CoreIsClosedException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
coreInitFailures.put(cd.getName(), new CoreLoadFailure(cd, e));
|
||||
coreInitFailures.put(cd.getName(), new CoreLoadFailure(cd, (Exception) e));
|
||||
throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to reload core [" + cd.getName() + "]", e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if (!success && newCore != null && newCore.getOpenCount() > 0) {
|
||||
IOUtils.closeQuietly(newCore);
|
||||
}
|
||||
solrCores.removeFromPendingOps(cd.getName());
|
||||
}
|
||||
} else {
|
||||
|
@ -1479,7 +1488,7 @@ public class CoreContainer {
|
|||
solrCores.removeFromPendingOps(clf.cd.getName());
|
||||
}
|
||||
} else {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name );
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No such core: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -674,7 +674,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
return core;
|
||||
} finally {
|
||||
// close the new core on any errors that have occurred.
|
||||
if (!success) {
|
||||
if (!success && core != null && core.getOpenCount() > 0) {
|
||||
IOUtils.closeQuietly(core);
|
||||
}
|
||||
}
|
||||
|
@ -896,64 +896,64 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
public SolrCore(CoreContainer coreContainer, String name, String dataDir, SolrConfig config,
|
||||
IndexSchema schema, NamedList configSetProperties,
|
||||
CoreDescriptor coreDescriptor, UpdateHandler updateHandler,
|
||||
IndexDeletionPolicyWrapper delPolicy, SolrCore prev, boolean reload) {
|
||||
IndexDeletionPolicyWrapper delPolicy, SolrCore prev, boolean reload) {
|
||||
|
||||
this.coreContainer = coreContainer;
|
||||
|
||||
assert ObjectReleaseTracker.track(searcherExecutor); // ensure that in unclean shutdown tests we still close this
|
||||
|
||||
CoreDescriptor cd = Objects.requireNonNull(coreDescriptor, "coreDescriptor cannot be null");
|
||||
coreContainer.solrCores.addCoreDescriptor(cd);
|
||||
|
||||
setName(name);
|
||||
MDCLoggingContext.setCore(this);
|
||||
|
||||
resourceLoader = config.getResourceLoader();
|
||||
this.solrConfig = config;
|
||||
this.configSetProperties = configSetProperties;
|
||||
// Initialize the metrics manager
|
||||
this.coreMetricManager = initCoreMetricManager(config);
|
||||
this.coreMetricManager.loadReporters();
|
||||
|
||||
if (updateHandler == null) {
|
||||
directoryFactory = initDirectoryFactory();
|
||||
recoveryStrategyBuilder = initRecoveryStrategyBuilder();
|
||||
solrCoreState = new DefaultSolrCoreState(directoryFactory, recoveryStrategyBuilder);
|
||||
} else {
|
||||
solrCoreState = updateHandler.getSolrCoreState();
|
||||
directoryFactory = solrCoreState.getDirectoryFactory();
|
||||
recoveryStrategyBuilder = solrCoreState.getRecoveryStrategyBuilder();
|
||||
isReloaded = true;
|
||||
}
|
||||
|
||||
this.dataDir = initDataDir(dataDir, config, coreDescriptor);
|
||||
this.ulogDir = initUpdateLogDir(coreDescriptor);
|
||||
|
||||
log.info("[{}] Opening new SolrCore at [{}], dataDir=[{}]", logid, resourceLoader.getInstancePath(), this.dataDir);
|
||||
|
||||
checkVersionFieldExistsInSchema(schema, coreDescriptor);
|
||||
|
||||
SolrMetricManager metricManager = coreContainer.getMetricManager();
|
||||
|
||||
// initialize searcher-related metrics
|
||||
initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, null);
|
||||
|
||||
SolrFieldCacheBean solrFieldCacheBean = new SolrFieldCacheBean();
|
||||
// this is registered at the CONTAINER level because it's not core-specific - for now we
|
||||
// also register it here for back-compat
|
||||
solrFieldCacheBean.initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, "core");
|
||||
infoRegistry.put("fieldCache", solrFieldCacheBean);
|
||||
|
||||
|
||||
initSchema(config, schema);
|
||||
|
||||
this.maxWarmingSearchers = config.maxWarmingSearchers;
|
||||
this.slowQueryThresholdMillis = config.slowQueryThresholdMillis;
|
||||
this.coreContainer = coreContainer;
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
try {
|
||||
|
||||
CoreDescriptor cd = Objects.requireNonNull(coreDescriptor, "coreDescriptor cannot be null");
|
||||
coreContainer.solrCores.addCoreDescriptor(cd);
|
||||
|
||||
setName(name);
|
||||
MDCLoggingContext.setCore(this);
|
||||
|
||||
resourceLoader = config.getResourceLoader();
|
||||
this.solrConfig = config;
|
||||
this.configSetProperties = configSetProperties;
|
||||
// Initialize the metrics manager
|
||||
this.coreMetricManager = initCoreMetricManager(config);
|
||||
this.coreMetricManager.loadReporters();
|
||||
|
||||
if (updateHandler == null) {
|
||||
directoryFactory = initDirectoryFactory();
|
||||
recoveryStrategyBuilder = initRecoveryStrategyBuilder();
|
||||
solrCoreState = new DefaultSolrCoreState(directoryFactory, recoveryStrategyBuilder);
|
||||
} else {
|
||||
solrCoreState = updateHandler.getSolrCoreState();
|
||||
directoryFactory = solrCoreState.getDirectoryFactory();
|
||||
recoveryStrategyBuilder = solrCoreState.getRecoveryStrategyBuilder();
|
||||
isReloaded = true;
|
||||
}
|
||||
|
||||
this.dataDir = initDataDir(dataDir, config, coreDescriptor);
|
||||
this.ulogDir = initUpdateLogDir(coreDescriptor);
|
||||
|
||||
log.info("[{}] Opening new SolrCore at [{}], dataDir=[{}]", logid, resourceLoader.getInstancePath(),
|
||||
this.dataDir);
|
||||
|
||||
checkVersionFieldExistsInSchema(schema, coreDescriptor);
|
||||
|
||||
SolrMetricManager metricManager = coreContainer.getMetricManager();
|
||||
|
||||
// initialize searcher-related metrics
|
||||
initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, null);
|
||||
|
||||
SolrFieldCacheBean solrFieldCacheBean = new SolrFieldCacheBean();
|
||||
// this is registered at the CONTAINER level because it's not core-specific - for now we
|
||||
// also register it here for back-compat
|
||||
solrFieldCacheBean.initializeMetrics(metricManager, coreMetricManager.getRegistryName(), metricTag, "core");
|
||||
infoRegistry.put("fieldCache", solrFieldCacheBean);
|
||||
|
||||
initSchema(config, schema);
|
||||
|
||||
this.maxWarmingSearchers = config.maxWarmingSearchers;
|
||||
this.slowQueryThresholdMillis = config.slowQueryThresholdMillis;
|
||||
|
||||
initListeners();
|
||||
|
||||
this.snapshotMgr = initSnapshotMetaDataManager();
|
||||
|
@ -961,7 +961,9 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
|
||||
this.codec = initCodec(solrConfig, this.schema);
|
||||
|
||||
memClassLoader = new MemClassLoader(PluginBag.RuntimeLib.getLibObjects(this, solrConfig.getPluginInfos(PluginBag.RuntimeLib.class.getName())), getResourceLoader());
|
||||
memClassLoader = new MemClassLoader(
|
||||
PluginBag.RuntimeLib.getLibObjects(this, solrConfig.getPluginInfos(PluginBag.RuntimeLib.class.getName())),
|
||||
getResourceLoader());
|
||||
initIndex(prev != null, reload);
|
||||
|
||||
initWriters();
|
||||
|
@ -987,7 +989,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
});
|
||||
|
||||
this.updateHandler = initUpdateHandler(updateHandler);
|
||||
|
||||
|
||||
initSearcher(prev);
|
||||
|
||||
// Initialize the RestManager
|
||||
|
@ -997,7 +999,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
resourceLoader.inform(resourceLoader);
|
||||
resourceLoader.inform(this); // last call before the latch is released.
|
||||
this.updateHandler.informEventListeners(this);
|
||||
|
||||
|
||||
infoRegistry.put("core", this);
|
||||
|
||||
// register any SolrInfoMBeans SolrResourceLoader initialized
|
||||
|
@ -1029,13 +1031,13 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
// should be fine, since counting down on a latch of 0 is still fine
|
||||
latch.countDown();
|
||||
if (e instanceof OutOfMemoryError) {
|
||||
throw (OutOfMemoryError)e;
|
||||
throw (OutOfMemoryError) e;
|
||||
}
|
||||
|
||||
try {
|
||||
// close down the searcher and any other resources, if it exists, as this
|
||||
// is not recoverable
|
||||
close();
|
||||
close();
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof OutOfMemoryError) {
|
||||
throw (OutOfMemoryError) t;
|
||||
|
@ -1048,7 +1050,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
|
|||
// allow firstSearcher events to fire and make sure it is released
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
|
||||
assert ObjectReleaseTracker.track(this);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue