SOLR-14128: Improve distributed locking around managed schema upgrade process.

This commit is contained in:
Andrzej Bialecki 2020-03-25 22:19:15 +01:00
parent 4f03ce5899
commit b0728ceca6
2 changed files with 37 additions and 33 deletions

View File

@ -77,6 +77,8 @@ Bug Fixes
* SOLR-14347: Autoscaling placement wrong when concurrent replica placements are calculated. (ab) * SOLR-14347: Autoscaling placement wrong when concurrent replica placements are calculated. (ab)
* SOLR-14128: Improve distributed locking around managed schema upgrade process. (ab)
Other Changes Other Changes
--------------------- ---------------------
* SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid * SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid

View File

@ -321,30 +321,32 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol
* and no exception will be thrown. * and no exception will be thrown.
*/ */
private void zkUgradeToManagedSchema() { private void zkUgradeToManagedSchema() {
schema.persistManagedSchemaToZooKeeper(true); // Only create, don't update it if it already exists
// After successfully persisting the managed schema, rename the non-managed
// schema znode by appending UPGRADED_SCHEMA_EXTENSION to its name.
if (resourceName.equals(managedSchemaResourceName)) { if (resourceName.equals(managedSchemaResourceName)) {
log.info("On upgrading to managed schema, did not rename non-managed schema " log.info("On upgrading to managed schema, did not rename non-managed schema "
+ resourceName + " because it's the same as the managed schema's name."); + resourceName + " because it's the same as the managed schema's name.");
} else { return;
// Rename the non-managed schema znode in ZooKeeper }
ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader)loader; final ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader)loader;
ZkController zkController = zkLoader.getZkController(); final ZkController zkController = zkLoader.getZkController();
SolrZkClient zkClient = zkController.getZkClient(); final SolrZkClient zkClient = zkController.getZkClient();
final String nonManagedSchemaPath = zkLoader.getConfigSetZkPath() + "/" + resourceName; final String lockPath = zkLoader.getConfigSetZkPath() + "/schemaUpgrade.lock";
final String lockPath = nonManagedSchemaPath + ".lock"; boolean locked = false;
boolean locked = false; try {
try {
zkClient.makePath(lockPath, null, CreateMode.EPHEMERAL, null, true, true);
locked = true;
} catch (Exception e) {
// some other node already started the upgrade, or an error occurred - bail out
return;
}
schema.persistManagedSchemaToZooKeeper(true); // Only create, don't update it if it already exists
// After successfully persisting the managed schema, rename the non-managed
// schema znode by appending UPGRADED_SCHEMA_EXTENSION to its name.
// Rename the non-managed schema znode in ZooKeeper
final String nonManagedSchemaPath = zkLoader.getConfigSetZkPath() + "/" + resourceName;
try { try {
try {
zkClient.makePath(lockPath, null, CreateMode.EPHEMERAL, null, true, true);
locked = true;
} catch (Exception e) {
// some other node already started the upgrade, or an error occurred - bail out
return;
}
ZkCmdExecutor zkCmdExecutor = new ZkCmdExecutor(zkController.getClientTimeout()); ZkCmdExecutor zkCmdExecutor = new ZkCmdExecutor(zkController.getClientTimeout());
if (zkController.pathExists(nonManagedSchemaPath)) { if (zkController.pathExists(nonManagedSchemaPath)) {
// First, copy the non-managed schema znode content to the upgraded schema znode // First, copy the non-managed schema znode content to the upgraded schema znode
@ -365,10 +367,10 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol
schema.setResourceName(managedSchemaResourceName); schema.setResourceName(managedSchemaResourceName);
log.info("After upgrading to managed schema in ZooKeeper, renamed the non-managed schema " log.info("After upgrading to managed schema in ZooKeeper, renamed the non-managed schema "
+ nonManagedSchemaPath + " to " + upgradedSchemaPath); + nonManagedSchemaPath + " to " + upgradedSchemaPath);
} else { } else {
log.info("After upgrading to managed schema in ZooKeeper, the non-managed schema " log.info("After upgrading to managed schema in ZooKeeper, the non-managed schema "
+ nonManagedSchemaPath + " no longer exists."); + nonManagedSchemaPath + " no longer exists.");
} }
} catch (Exception e) { } catch (Exception e) {
if (e instanceof InterruptedException) { if (e instanceof InterruptedException) {
@ -376,16 +378,16 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol
} }
final String msg = "Error persisting managed schema resource " + managedSchemaResourceName; final String msg = "Error persisting managed schema resource " + managedSchemaResourceName;
log.warn(msg, e); // Log as warning and suppress the exception log.warn(msg, e); // Log as warning and suppress the exception
} finally { }
if (locked) { } finally {
// unlock if (locked) {
try { // unlock
zkClient.delete(lockPath, -1, true); try {
} catch (KeeperException.NoNodeException nne) { zkClient.delete(lockPath, -1, true);
// ignore - someone else deleted it } catch (KeeperException.NoNodeException nne) {
} catch (Exception e) { // ignore - someone else deleted it
log.warn("Unable to delete schema upgrade lock file " + lockPath, e); } catch (Exception e) {
} log.warn("Unable to delete schema upgrade lock file " + lockPath, e);
} }
} }
} }