diff --git a/server/src/main/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommand.java b/server/src/main/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommand.java
index 92dc44d0d8beb..929e301fd9d5f 100644
--- a/server/src/main/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommand.java
+++ b/server/src/main/java/org/elasticsearch/index/shard/RemoveCorruptedShardDataCommand.java
@@ -160,7 +160,7 @@ protected void findAndProcessShardPath(OptionSet options, Environment environmen
.resolve(Integer.toString(shId.id()));
if (Files.exists(shardPathLocation)) {
final ShardPath shardPath = ShardPath.loadShardPath(logger, shId, indexSettings.customDataPath(),
- shardPathLocation, dataPath);
+ new Path[]{shardPathLocation}, dataPath);
if (shardPath != null) {
consumer.accept(shardPath);
}
diff --git a/server/src/main/java/org/elasticsearch/index/shard/ShardPath.java b/server/src/main/java/org/elasticsearch/index/shard/ShardPath.java
index 12172d09fe0af..ea8203556ccb2 100644
--- a/server/src/main/java/org/elasticsearch/index/shard/ShardPath.java
+++ b/server/src/main/java/org/elasticsearch/index/shard/ShardPath.java
@@ -99,44 +99,59 @@ public boolean isCustomDataPath() {
}
/**
- * This method resolves the node's shard path using the given {@link NodeEnvironment}.
+ * This method walks through the nodes shard paths to find the data and state path for the given shard. If multiple
+ * directories with a valid shard state exist the one with the highest version will be used.
* Note: this method resolves custom data locations for the shard if such a custom data path is provided.
*/
public static ShardPath loadShardPath(Logger logger, NodeEnvironment env,
ShardId shardId, String customDataPath) throws IOException {
final Path shardPath = env.availableShardPath(shardId);
final Path sharedDataPath = env.sharedDataPath();
- return loadShardPath(logger, shardId, customDataPath, shardPath, sharedDataPath);
+ return loadShardPath(logger, shardId, customDataPath, new Path[] { shardPath }, sharedDataPath);
}
/**
- * This method resolves the node's shard path using the given data paths.
+ * This method walks through the nodes shard paths to find the data and state path for the given shard. If multiple
+ * directories with a valid shard state exist the one with the highest version will be used.
* Note: this method resolves custom data locations for the shard.
*/
- public static ShardPath loadShardPath(Logger logger, ShardId shardId, String customDataPath, Path shardPath,
+ public static ShardPath loadShardPath(Logger logger, ShardId shardId, String customDataPath, Path[] availableShardPaths,
Path sharedDataPath) throws IOException {
final String indexUUID = shardId.getIndex().getUUID();
- // EMPTY is safe here because we never call namedObject
- ShardStateMetadata load = ShardStateMetadata.FORMAT.loadLatestState(logger, NamedXContentRegistry.EMPTY, shardPath);
- if (load != null) {
- if (load.indexUUID.equals(indexUUID) == false && IndexMetadata.INDEX_UUID_NA_VALUE.equals(load.indexUUID) == false) {
- logger.warn("{} found shard on path: [{}] with a different index UUID - this "
- + "shard seems to be leftover from a different index with the same name. "
- + "Remove the leftover shard in order to reuse the path with the current index", shardId, shardPath);
- throw new IllegalStateException(shardId + " index UUID in shard state was: " + load.indexUUID
- + " expected: " + indexUUID + " on shard path: " + shardPath);
+ Path loadedPath = null;
+ for (Path path : availableShardPaths) {
+ // EMPTY is safe here because we never call namedObject
+ ShardStateMetadata load = ShardStateMetadata.FORMAT.loadLatestState(logger, NamedXContentRegistry.EMPTY, path);
+ if (load != null) {
+ if (load.indexUUID.equals(indexUUID) == false && IndexMetadata.INDEX_UUID_NA_VALUE.equals(load.indexUUID) == false) {
+ logger.warn("{} found shard on path: [{}] with a different index UUID - this "
+ + "shard seems to be leftover from a different index with the same name. "
+ + "Remove the leftover shard in order to reuse the path with the current index", shardId, path);
+ throw new IllegalStateException(shardId + " index UUID in shard state was: " + load.indexUUID
+ + " expected: " + indexUUID + " on shard path: " + path);
+ }
+ if (loadedPath == null) {
+ loadedPath = path;
+ } else{
+ throw new IllegalStateException(shardId + " more than one shard state found");
+ }
}
+
+ }
+ if (loadedPath == null) {
+ return null;
+ } else {
final Path dataPath;
+ final Path statePath = loadedPath;
final boolean hasCustomDataPath = Strings.isNotEmpty(customDataPath);
if (hasCustomDataPath) {
dataPath = NodeEnvironment.resolveCustomLocation(customDataPath, shardId, sharedDataPath);
} else {
- dataPath = shardPath;
+ dataPath = statePath;
}
- logger.debug("{} loaded data path [{}], state path [{}]", shardId, dataPath, shardPath);
- return new ShardPath(hasCustomDataPath, dataPath, shardPath, shardId);
+ logger.debug("{} loaded data path [{}], state path [{}]", shardId, dataPath, statePath);
+ return new ShardPath(hasCustomDataPath, dataPath, statePath, shardId);
}
- return null;
}
/**