@@ -2963,6 +2963,108 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception {
2963
2963
assertAcked (client ().admin ().cluster ().prepareDeleteSnapshot ("test-repo" , snapshotInfo .snapshotId ().getName ()).get ());
2964
2964
}
2965
2965
2966
+ /**
2967
+ * Tests that a shard snapshot with a corrupted shard index file can still be used for restore and incremental snapshots.
2968
+ */
2969
+ public void testSnapshotWithCorruptedShardIndexFile () throws Exception {
2970
+ final Client client = client ();
2971
+ final Path repo = randomRepoPath ();
2972
+ final String indexName = "test-idx" ;
2973
+ final int nDocs = randomIntBetween (1 , 10 );
2974
+
2975
+ logger .info ("--> creating index [{}] with [{}] documents in it" , indexName , nDocs );
2976
+ assertAcked (prepareCreate (indexName ).setSettings (Settings .builder ()
2977
+ .put (SETTING_NUMBER_OF_SHARDS , 1 ).put (SETTING_NUMBER_OF_REPLICAS , 0 )));
2978
+
2979
+ final IndexRequestBuilder [] documents = new IndexRequestBuilder [nDocs ];
2980
+ for (int j = 0 ; j < nDocs ; j ++) {
2981
+ documents [j ] = client .prepareIndex (indexName , "_doc" ).setSource ("foo" , "bar" );
2982
+ }
2983
+ indexRandom (true , documents );
2984
+ flushAndRefresh ();
2985
+
2986
+ logger .info ("--> creating repository" );
2987
+ assertAcked (client ().admin ().cluster ().preparePutRepository ("test-repo" )
2988
+ .setType ("fs" )
2989
+ .setSettings (Settings .builder ()
2990
+ .put ("location" , repo )));
2991
+
2992
+ final String snapshot1 = "test-snap-1" ;
2993
+ logger .info ("--> creating snapshot [{}]" , snapshot1 );
2994
+ final SnapshotInfo snapshotInfo = client ().admin ().cluster ().prepareCreateSnapshot ("test-repo" , snapshot1 )
2995
+ .setWaitForCompletion (true )
2996
+ .get ()
2997
+ .getSnapshotInfo ();
2998
+ assertThat (snapshotInfo .failedShards (), equalTo (0 ));
2999
+ assertThat (snapshotInfo .successfulShards (), equalTo (snapshotInfo .totalShards ()));
3000
+ assertThat (snapshotInfo .indices (), hasSize (1 ));
3001
+
3002
+ RepositoriesService service = internalCluster ().getInstance (RepositoriesService .class , internalCluster ().getMasterName ());
3003
+ Repository repository = service .repository ("test-repo" );
3004
+
3005
+ final RepositoryData repositoryData = getRepositoryData (repository );
3006
+ final Map <String , IndexId > indexIds = repositoryData .getIndices ();
3007
+ assertThat (indexIds .size (), equalTo (1 ));
3008
+
3009
+ final IndexId corruptedIndex = indexIds .get (indexName );
3010
+ final Path shardIndexFile = repo .resolve ("indices" )
3011
+ .resolve (corruptedIndex .getId ()).resolve ("0" )
3012
+ .resolve ("index-0" );
3013
+
3014
+ logger .info ("--> truncating shard index file [{}]" , shardIndexFile );
3015
+ try (SeekableByteChannel outChan = Files .newByteChannel (shardIndexFile , StandardOpenOption .WRITE )) {
3016
+ outChan .truncate (randomInt (10 ));
3017
+ }
3018
+
3019
+ logger .info ("--> verifying snapshot state for [{}]" , snapshot1 );
3020
+ List <SnapshotInfo > snapshotInfos = client ().admin ().cluster ().prepareGetSnapshots ("test-repo" ).get ().getSnapshots ();
3021
+ assertThat (snapshotInfos .size (), equalTo (1 ));
3022
+ assertThat (snapshotInfos .get (0 ).state (), equalTo (SnapshotState .SUCCESS ));
3023
+ assertThat (snapshotInfos .get (0 ).snapshotId ().getName (), equalTo (snapshot1 ));
3024
+
3025
+ logger .info ("--> deleting index [{}]" , indexName );
3026
+ assertAcked (client ().admin ().indices ().prepareDelete (indexName ));
3027
+
3028
+ logger .info ("--> restoring snapshot [{}]" , snapshot1 );
3029
+ client ().admin ().cluster ().prepareRestoreSnapshot ("test-repo" , snapshot1 )
3030
+ .setRestoreGlobalState (randomBoolean ())
3031
+ .setWaitForCompletion (true )
3032
+ .get ();
3033
+ ensureGreen ();
3034
+
3035
+ assertHitCount (client ().prepareSearch (indexName ).setSize (0 ).get (), nDocs );
3036
+
3037
+ logger .info ("--> indexing [{}] more documents into [{}]" , nDocs , indexName );
3038
+ for (int j = 0 ; j < nDocs ; j ++) {
3039
+ documents [j ] = client .prepareIndex (indexName , "_doc" ).setSource ("foo2" , "bar2" );
3040
+ }
3041
+ indexRandom (true , documents );
3042
+
3043
+ final String snapshot2 = "test-snap-2" ;
3044
+ logger .info ("--> creating snapshot [{}]" , snapshot2 );
3045
+ final SnapshotInfo snapshotInfo2 = client ().admin ().cluster ().prepareCreateSnapshot ("test-repo" , snapshot2 )
3046
+ .setWaitForCompletion (true )
3047
+ .get ()
3048
+ .getSnapshotInfo ();
3049
+ assertThat (snapshotInfo2 .state (), equalTo (SnapshotState .SUCCESS ));
3050
+ assertThat (snapshotInfo2 .failedShards (), equalTo (0 ));
3051
+ assertThat (snapshotInfo2 .successfulShards (), equalTo (snapshotInfo .totalShards ()));
3052
+ assertThat (snapshotInfo2 .indices (), hasSize (1 ));
3053
+
3054
+ logger .info ("--> deleting index [{}]" , indexName );
3055
+ assertAcked (client ().admin ().indices ().prepareDelete (indexName ));
3056
+
3057
+ logger .info ("--> restoring snapshot [{}]" , snapshot2 );
3058
+ client ().admin ().cluster ().prepareRestoreSnapshot ("test-repo" , snapshot2 )
3059
+ .setRestoreGlobalState (randomBoolean ())
3060
+ .setWaitForCompletion (true )
3061
+ .get ();
3062
+
3063
+ ensureGreen ();
3064
+
3065
+ assertHitCount (client ().prepareSearch (indexName ).setSize (0 ).get (), 2 * nDocs );
3066
+ }
3067
+
2966
3068
public void testCannotCreateSnapshotsWithSameName () throws Exception {
2967
3069
final String repositoryName = "test-repo" ;
2968
3070
final String snapshotName = "test-snap" ;
0 commit comments