21
21
22
22
import org .apache .logging .log4j .LogManager ;
23
23
import org .apache .logging .log4j .Logger ;
24
+ import org .apache .lucene .util .SetOnce ;
24
25
import org .elasticsearch .ExceptionsHelper ;
25
26
import org .elasticsearch .Version ;
26
27
import org .elasticsearch .action .ActionListener ;
143
144
import org .elasticsearch .env .TestEnvironment ;
144
145
import org .elasticsearch .gateway .MetaStateService ;
145
146
import org .elasticsearch .gateway .TransportNodesListGatewayStartedShards ;
147
+ import org .elasticsearch .index .Index ;
146
148
import org .elasticsearch .index .analysis .AnalysisRegistry ;
147
149
import org .elasticsearch .index .seqno .GlobalCheckpointSyncAction ;
148
150
import org .elasticsearch .index .seqno .RetentionLeaseSyncer ;
@@ -504,7 +506,7 @@ public void testConcurrentSnapshotCreateAndDeleteOther() {
504
506
}
505
507
}
506
508
507
- public void testConcurrentSnapshotDeleteAndDeleteIndex () {
509
+ public void testConcurrentSnapshotDeleteAndDeleteIndex () throws IOException {
508
510
setupTestCluster (randomFrom (1 , 3 , 5 ), randomIntBetween (2 , 10 ));
509
511
510
512
String repoName = "repo" ;
@@ -517,7 +519,9 @@ public void testConcurrentSnapshotDeleteAndDeleteIndex() {
517
519
final StepListener <Collection <CreateIndexResponse >> createIndicesListener = new StepListener <>();
518
520
final int indices = randomIntBetween (5 , 20 );
519
521
522
+ final SetOnce <Index > firstIndex = new SetOnce <>();
520
523
continueOrDie (createRepoAndIndex (repoName , index , 1 ), createIndexResponse -> {
524
+ firstIndex .set (masterNode .clusterService .state ().metaData ().index (index ).getIndex ());
521
525
// create a few more indices to make it more likely that the subsequent index delete operation happens before snapshot
522
526
// finalization
523
527
final GroupedActionListener <CreateIndexResponse > listener = new GroupedActionListener <>(createIndicesListener , indices );
@@ -535,21 +539,43 @@ public void testConcurrentSnapshotDeleteAndDeleteIndex() {
535
539
.setPartial (partialSnapshot ).execute (createSnapshotResponseStepListener ));
536
540
537
541
continueOrDie (createSnapshotResponseStepListener ,
538
- createSnapshotResponse -> client ().admin ().indices ().delete (new DeleteIndexRequest (index ), noopListener ()));
542
+ createSnapshotResponse -> client ().admin ().indices ().delete (new DeleteIndexRequest (index ), new ActionListener <>() {
543
+ @ Override
544
+ public void onResponse (AcknowledgedResponse acknowledgedResponse ) {
545
+ if (partialSnapshot ) {
546
+ // Recreate index by the same name to test that we don't snapshot conflicting metadata in this scenario
547
+ client ().admin ().indices ().create (new CreateIndexRequest (index ), noopListener ());
548
+ }
549
+ }
550
+
551
+ @ Override
552
+ public void onFailure (Exception e ) {
553
+ if (partialSnapshot ) {
554
+ throw new AssertionError ("Delete index should always work during partial snapshots" , e );
555
+ }
556
+ }
557
+ }));
539
558
540
559
deterministicTaskQueue .runAllRunnableTasks ();
541
560
542
561
SnapshotsInProgress finalSnapshotsInProgress = masterNode .clusterService .state ().custom (SnapshotsInProgress .TYPE );
543
562
assertFalse (finalSnapshotsInProgress .entries ().stream ().anyMatch (entry -> entry .state ().completed () == false ));
544
563
final Repository repository = masterNode .repositoriesService .repository (repoName );
545
- Collection <SnapshotId > snapshotIds = getRepositoryData (repository ).getSnapshotIds ();
564
+ final RepositoryData repositoryData = getRepositoryData (repository );
565
+ Collection <SnapshotId > snapshotIds = repositoryData .getSnapshotIds ();
546
566
assertThat (snapshotIds , hasSize (1 ));
547
567
548
568
final SnapshotInfo snapshotInfo = repository .getSnapshotInfo (snapshotIds .iterator ().next ());
549
569
assertEquals (SnapshotState .SUCCESS , snapshotInfo .state ());
550
570
if (partialSnapshot ) {
551
571
// Single shard for each index so we either get all indices or all except for the deleted index
552
572
assertThat (snapshotInfo .successfulShards (), either (is (indices + 1 )).or (is (indices )));
573
+ if (snapshotInfo .successfulShards () == indices + 1 ) {
574
+ final IndexMetaData indexMetaData =
575
+ repository .getSnapshotIndexMetaData (snapshotInfo .snapshotId (), repositoryData .resolveIndexId (index ));
576
+ // Make sure we snapshotted the metadata of this index and not the recreated version
577
+ assertEquals (indexMetaData .getIndex (), firstIndex .get ());
578
+ }
553
579
} else {
554
580
// Index delete must be blocked for non-partial snapshots and we get a snapshot for every index
555
581
assertEquals (snapshotInfo .successfulShards (), indices + 1 );
0 commit comments