[Store] delete unallocated shards under a cluster state task
This is to prevent a rare racing condition where the very same shard gets allocated to the node after our sanity check that the cluster state didn't check and the actual deletion of the files. Closes #6902
This commit is contained in:
parent
bb421d7ea3
commit
bdbe86dd2d
|
@ -296,34 +296,42 @@ public class IndicesStore extends AbstractComponent implements ClusterStateListe
|
|||
|
||||
private void allNodesResponded() {
|
||||
if (activeCopies.get() != expectedActiveCopies) {
|
||||
logger.trace("not deleting shard [{}], expected {} active copies, but only {} found active copies", shardId, expectedActiveCopies, activeCopies.get());
|
||||
logger.trace("not deleting shard {}, expected {} active copies, but only {} found active copies", shardId, expectedActiveCopies, activeCopies.get());
|
||||
return;
|
||||
}
|
||||
|
||||
ClusterState latestClusterState = clusterService.state();
|
||||
if (clusterState.getVersion() != latestClusterState.getVersion()) {
|
||||
logger.trace("not deleting shard [{}], the latest cluster state version[{}] is not equal to cluster state before shard active api call [{}]", shardId, latestClusterState.getVersion(), clusterState.getVersion());
|
||||
logger.trace("not deleting shard {}, the latest cluster state version[{}] is not equal to cluster state before shard active api call [{}]", shardId, latestClusterState.getVersion(), clusterState.getVersion());
|
||||
return;
|
||||
}
|
||||
|
||||
clusterService.submitStateUpdateTask("indices_store", new ClusterStateUpdateTask() {
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) throws Exception {
|
||||
if (clusterState.getVersion() != currentState.getVersion()) {
|
||||
logger.trace("not deleting shard {}, the update task state version[{}] is not equal to cluster state before shard active api call [{}]", shardId, currentState.getVersion(), clusterState.getVersion());
|
||||
return currentState;
|
||||
}
|
||||
|
||||
IndexService indexService = indicesService.indexService(shardId.getIndex());
|
||||
if (indexService == null) {
|
||||
// not physical allocation of the index, delete it from the file system if applicable
|
||||
if (nodeEnv.hasNodeFile()) {
|
||||
File[] shardLocations = nodeEnv.shardLocations(shardId);
|
||||
if (FileSystemUtils.exists(shardLocations)) {
|
||||
logger.debug("[{}][{}] deleting shard that is no longer used", shardId.index().name(), shardId.id());
|
||||
logger.debug("[{}][{}] deleting shard that is no longer used", shardId);
|
||||
FileSystemUtils.deleteRecursively(shardLocations);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!indexService.hasShard(shardId.id())) {
|
||||
if (indexService.store().canDeleteUnallocated(shardId)) {
|
||||
logger.debug("[{}][{}] deleting shard that is no longer used", shardId.index().name(), shardId.id());
|
||||
logger.debug("{} deleting shard that is no longer used", shardId);
|
||||
try {
|
||||
indexService.store().deleteUnallocated(shardId);
|
||||
} catch (Exception e) {
|
||||
logger.debug("[{}][{}] failed to delete unallocated shard, ignoring", e, shardId.index().name(), shardId.id());
|
||||
logger.debug("{} failed to delete unallocated shard, ignoring", e, shardId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -333,6 +341,14 @@ public class IndicesStore extends AbstractComponent implements ClusterStateListe
|
|||
// Note, this listener should run after IndicesClusterStateService...
|
||||
}
|
||||
}
|
||||
return currentState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String source, Throwable t) {
|
||||
logger.error("{} unexpected error during deletion of unallocated shard", t, shardId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue