Browse Source

Do not reach to the repository to process empty snapshot deletions (#82323)

We can avoid reaching to the repository when processing a queued 
snapshot deletion that overlaps a previous deletion but also aborts 
queued snapshots. For example a snapshot deletion A that deletes 
[snap-0, snap-1], then snapshot [snap-2] is queued and finally 
snapshot deletion B that deletes [snap-0, snap-1, snap-2] is also 
queued. At the time B is processed [snap-2] is successfully aborted 
but the remaining snapshots are now gone and there is no need 
to reach to the repository.

This scenario is tested in testQueuedDeletesWithOverlap().
Tanguy Leroux 3 years ago
parent
commit
e7478980e5

+ 9 - 1
server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java

@@ -2166,7 +2166,7 @@ public class SnapshotsService extends AbstractLifecycleComponent implements Clus
                             return abortedEntry;
                         }
                         return existing;
-                    }).filter(Objects::nonNull).collect(Collectors.toUnmodifiableList())
+                    }).filter(Objects::nonNull).toList()
                 );
                 if (snapshotIdsRequiringCleanup.isEmpty()) {
                     // We only saw snapshots that could be removed from the cluster state right away, no need to update the deletions
@@ -2387,6 +2387,14 @@ public class SnapshotsService extends AbstractLifecycleComponent implements Clus
             assert currentlyFinalizing.contains(deleteEntry.repository());
             final List<SnapshotId> snapshotIds = deleteEntry.getSnapshots();
             assert deleteEntry.state() == SnapshotDeletionsInProgress.State.STARTED : "incorrect state for entry [" + deleteEntry + "]";
+            if (snapshotIds.isEmpty()) {
+                // this deletion overlapped one or more deletions that were successfully processed and there is no remaining snapshot to
+                // delete now, we can avoid reaching to the repository and can complete the deletion.
+                // TODO we should complete the deletion and resolve the listeners of SnapshotDeletionsInProgress with no snapshot sooner,
+                // that would save some cluster state updates.
+                removeSnapshotDeletionFromClusterState(deleteEntry, null, repositoryData);
+                return;
+            }
             repositoriesService.repository(deleteEntry.repository())
                 .deleteSnapshots(
                     snapshotIds,