Skip to content

Commit 7f5befd

Browse files
committed
Add Partial snapshot state
Currently even if some shards of the snapshot are not snapshotted successfully, the snapshot is still marked as "SUCCESS". Users may miss the fact the there are shard failures present in the snapshot and think that snapshot was completed. This change adds a new snapshot state "PARTIAL" that provides a quick indication that the snapshot was only partially successful. Closes elastic#5792
1 parent 9f10547 commit 7f5befd

File tree

7 files changed

+48
-9
lines changed

7 files changed

+48
-9
lines changed

src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java

+3
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ private SnapshotsStatusResponse buildResponse(SnapshotsStatusRequest request, Im
206206
state = SnapshotMetaData.State.FAILED;
207207
break;
208208
case SUCCESS:
209+
case PARTIAL:
210+
// Translating both PARTIAL and SUCCESS to SUCCESS for now
211+
// TODO: add the differentiation on the metadata level in the next major release
209212
state = SnapshotMetaData.State.SUCCESS;
210213
break;
211214
default:

src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,11 @@ public Snapshot finalizeSnapshot(SnapshotId snapshotId, String failure, int tota
312312
String blobName = snapshotBlobName(snapshotId);
313313
BlobStoreSnapshot.Builder updatedSnapshot = BlobStoreSnapshot.builder().snapshot(snapshot);
314314
if (failure == null) {
315-
updatedSnapshot.success();
315+
if (shardFailures.isEmpty()) {
316+
updatedSnapshot.success();
317+
} else {
318+
updatedSnapshot.partial();
319+
}
316320
updatedSnapshot.failures(totalShards, shardFailures);
317321
} else {
318322
updatedSnapshot.failed(failure);

src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreSnapshot.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package org.elasticsearch.repositories.blobstore;
2121

2222
import com.google.common.collect.ImmutableList;
23-
import com.google.common.primitives.Longs;
2423
import org.elasticsearch.Version;
2524
import org.elasticsearch.common.xcontent.ToXContent;
2625
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -290,6 +289,16 @@ public Builder success() {
290289
return this;
291290
}
292291

292+
/**
293+
* Marks snapshot as partially successful
294+
*
295+
* @return this builder
296+
*/
297+
public Builder partial() {
298+
this.state = SnapshotState.PARTIAL;
299+
return this;
300+
}
301+
293302
/**
294303
* Marks snapshot as failed and saves failure reason
295304
*

src/main/java/org/elasticsearch/snapshots/RestoreService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public void restoreSnapshot(final RestoreRequest request, final RestoreSnapshotL
119119
final MetaData metaData = repository.readSnapshotMetaData(snapshotId, filteredIndices);
120120

121121
// Make sure that we can restore from this snapshot
122-
if (snapshot.state() != SnapshotState.SUCCESS) {
122+
if (!snapshot.state().restorable()) {
123123
throw new SnapshotRestoreException(snapshotId, "unsupported snapshot state [" + snapshot.state() + "]");
124124
}
125125
if (Version.CURRENT.before(snapshot.version())) {

src/main/java/org/elasticsearch/snapshots/SnapshotState.java

+27-5
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,30 @@ public enum SnapshotState {
2828
/**
2929
* Snapshot process has started
3030
*/
31-
IN_PROGRESS((byte) 0),
31+
IN_PROGRESS((byte) 0, false, false),
3232
/**
3333
* Snapshot process completed successfully
3434
*/
35-
SUCCESS((byte) 1),
35+
SUCCESS((byte) 1, true, true),
3636
/**
3737
* Snapshot failed
3838
*/
39-
FAILED((byte) 2);
39+
FAILED((byte) 2, true, false),
40+
/**
41+
* Snapshot was partial successful
42+
*/
43+
PARTIAL((byte) 3, true, true);
4044

4145
private byte value;
4246

43-
private SnapshotState(byte value) {
47+
private boolean completed;
48+
49+
private boolean restorable;
50+
51+
private SnapshotState(byte value, boolean completed, boolean restorable) {
4452
this.value = value;
53+
this.completed = completed;
54+
this.restorable = restorable;
4555
}
4656

4757
/**
@@ -59,7 +69,17 @@ public byte value() {
5969
* @return true if snapshot completed, false otherwise
6070
*/
6171
public boolean completed() {
62-
return this == SUCCESS || this == FAILED;
72+
return completed;
73+
}
74+
75+
76+
/**
77+
* Returns true if snapshot can be restored (at least partially)
78+
*
79+
* @return true if snapshot can be restored, false otherwise
80+
*/
81+
public boolean restorable() {
82+
return restorable;
6383
}
6484

6585
/**
@@ -76,6 +96,8 @@ public static SnapshotState fromValue(byte value) {
7696
return SUCCESS;
7797
case 2:
7898
return FAILED;
99+
case 3:
100+
return PARTIAL;
79101
default:
80102
throw new ElasticsearchIllegalArgumentException("No snapshot state for value [" + value + "]");
81103
}

src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public void restoreIndexWithMissingShards() throws Exception {
238238
assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(12));
239239
assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), lessThan(12));
240240
assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), greaterThan(6));
241-
assertThat(client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-2").execute().actionGet().getSnapshots().get(0).state(), equalTo(SnapshotState.SUCCESS));
241+
assertThat(client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-2").execute().actionGet().getSnapshots().get(0).state(), equalTo(SnapshotState.PARTIAL));
242242

243243
assertAcked(client().admin().indices().prepareClose("test-idx-1", "test-idx-2").execute().actionGet());
244244

src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ public void dataFileFailureDuringSnapshotTest() throws Exception {
409409
GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap").get();
410410
assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1));
411411
SnapshotInfo snapshotInfo = getSnapshotsResponse.getSnapshots().get(0);
412+
assertThat(snapshotInfo.state(), equalTo(SnapshotState.PARTIAL));
412413
assertThat(snapshotInfo.shardFailures().size(), greaterThan(0));
413414
assertThat(snapshotInfo.totalShards(), greaterThan(snapshotInfo.successfulShards()));
414415

0 commit comments

Comments
 (0)