Snapshot/Restore: fix snapshot of a single closed index
Snapshot of a closed index can leave snapshot hanging in initializing state. Fixes #8046
This commit is contained in:
parent
249a145a5c
commit
e3d379fb08
|
@ -323,6 +323,12 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
@Override
|
||||
public void onFailure(String source, Throwable t) {
|
||||
logger.warn("[{}] failed to create snapshot", t, snapshot.snapshotId());
|
||||
removeSnapshotFromClusterState(snapshot.snapshotId(), null, t);
|
||||
try {
|
||||
repositoriesService.repository(snapshot.snapshotId().getRepository()).finalizeSnapshot(snapshot.snapshotId(), ExceptionsHelper.detailedMessage(t), 0, ImmutableList.<SnapshotShardFailure>of());
|
||||
} catch (Throwable t2) {
|
||||
logger.warn("[{}] failed to close snapshot in repository", snapshot.snapshotId());
|
||||
}
|
||||
userCreateSnapshotListener.onFailure(t);
|
||||
}
|
||||
|
||||
|
@ -345,28 +351,7 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
});
|
||||
} catch (Throwable t) {
|
||||
logger.warn("failed to create snapshot [{}]", t, snapshot.snapshotId());
|
||||
clusterService.submitStateUpdateTask("fail_snapshot [" + snapshot.snapshotId() + "]", new ClusterStateUpdateTask() {
|
||||
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) {
|
||||
MetaData metaData = currentState.metaData();
|
||||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
||||
SnapshotMetaData snapshots = metaData.custom(SnapshotMetaData.TYPE);
|
||||
ImmutableList.Builder<SnapshotMetaData.Entry> entries = ImmutableList.builder();
|
||||
for (SnapshotMetaData.Entry entry : snapshots.entries()) {
|
||||
if (!entry.snapshotId().equals(snapshot.snapshotId())) {
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
mdBuilder.putCustom(SnapshotMetaData.TYPE, new SnapshotMetaData(entries.build()));
|
||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String source, Throwable t) {
|
||||
logger.warn("[{}] failed to delete snapshot", t, snapshot.snapshotId());
|
||||
}
|
||||
});
|
||||
removeSnapshotFromClusterState(snapshot.snapshotId(), null, t);
|
||||
if (snapshotCreated) {
|
||||
try {
|
||||
repositoriesService.repository(snapshot.snapshotId().getRepository()).finalizeSnapshot(snapshot.snapshotId(), ExceptionsHelper.detailedMessage(t), 0, ImmutableList.<SnapshotShardFailure>of());
|
||||
|
@ -1046,7 +1031,7 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
listener.onSnapshotFailure(snapshotId, t);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
logger.warn("failed to refresh settings for [{}]", t, listener);
|
||||
logger.warn("failed to notify listener [{}]", t, listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1127,18 +1112,22 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
logger.trace("adding snapshot completion listener to wait for deleted snapshot to finish");
|
||||
addListener(new SnapshotCompletionListener() {
|
||||
@Override
|
||||
public void onSnapshotCompletion(SnapshotId snapshotId, SnapshotInfo snapshot) {
|
||||
public void onSnapshotCompletion(SnapshotId completedSnapshotId, SnapshotInfo snapshot) {
|
||||
if (completedSnapshotId.equals(snapshotId)) {
|
||||
logger.trace("deleted snapshot completed - deleting files");
|
||||
removeListener(this);
|
||||
deleteSnapshotFromRepository(snapshotId, listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSnapshotFailure(SnapshotId snapshotId, Throwable t) {
|
||||
public void onSnapshotFailure(SnapshotId failedSnapshotId, Throwable t) {
|
||||
if (failedSnapshotId.equals(snapshotId)) {
|
||||
logger.trace("deleted snapshot failed - deleting files", t);
|
||||
removeListener(this);
|
||||
deleteSnapshotFromRepository(snapshotId, listener);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.trace("deleted snapshot is not running - deleting files");
|
||||
|
@ -1203,11 +1192,9 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
for (String index : indices) {
|
||||
IndexMetaData indexMetaData = metaData.index(index);
|
||||
IndexRoutingTable indexRoutingTable = clusterState.getRoutingTable().index(index);
|
||||
if (indexRoutingTable == null) {
|
||||
throw new SnapshotCreationException(snapshotId, "Missing routing table for index [" + index + "]");
|
||||
}
|
||||
for (int i = 0; i < indexMetaData.numberOfShards(); i++) {
|
||||
ShardId shardId = new ShardId(index, i);
|
||||
if (indexRoutingTable != null) {
|
||||
ShardRouting primary = indexRoutingTable.shard(i).primaryShard();
|
||||
if (primary == null || !primary.assignedToNode()) {
|
||||
builder.put(shardId, new SnapshotMetaData.ShardSnapshotStatus(null, State.MISSING, "primary shard is not allocated"));
|
||||
|
@ -1219,6 +1206,9 @@ public class SnapshotsService extends AbstractLifecycleComponent<SnapshotsServic
|
|||
} else {
|
||||
builder.put(shardId, new SnapshotMetaData.ShardSnapshotStatus(primary.currentNodeId()));
|
||||
}
|
||||
} else {
|
||||
builder.put(shardId, new SnapshotMetaData.ShardSnapshotStatus(null, State.MISSING, "missing routing table"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -804,6 +804,27 @@ public class SharedClusterSnapshotRestoreTests extends AbstractSnapshotTests {
|
|||
client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void snapshotSingleClosedIndexTest() throws Exception {
|
||||
Client client = client();
|
||||
|
||||
logger.info("--> creating repository");
|
||||
assertAcked(client.admin().cluster().preparePutRepository("test-repo")
|
||||
.setType("fs").setSettings(ImmutableSettings.settingsBuilder()
|
||||
.put("location", newTempDir(LifecycleScope.SUITE))));
|
||||
|
||||
createIndex("test-idx");
|
||||
ensureGreen();
|
||||
logger.info("--> closing index test-idx");
|
||||
assertAcked(client.admin().indices().prepareClose("test-idx"));
|
||||
|
||||
logger.info("--> snapshot");
|
||||
CreateSnapshotResponse createSnapshotResponse = client.admin().cluster().prepareCreateSnapshot("test-repo", "test-snap-1")
|
||||
.setWaitForCompletion(true).setIndices("test-idx").get();
|
||||
assertThat(createSnapshotResponse.getSnapshotInfo().indices().size(), equalTo(1));
|
||||
assertThat(createSnapshotResponse.getSnapshotInfo().state(), equalTo(SnapshotState.FAILED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renameOnRestoreTest() throws Exception {
|
||||
Client client = client();
|
||||
|
|
Loading…
Reference in New Issue