2121
2222import java .io .IOException ;
2323import java .util .ArrayList ;
24- import java .util .Iterator ;
24+ import java .util .HashSet ;
2525import java .util .List ;
2626import java .util .Objects ;
27+ import java .util .Set ;
2728import java .util .function .Consumer ;
2829
2930import static java .util .Collections .unmodifiableList ;
3940 * id, the snapshot name, the repository name and the repository id (if it exists) once, along with the time at which the snapshot was added
4041 * to the pending deletion, in a {@link SnapshotDeletionsPending} entry.
4142 *
42- *
4343 * When cluster state is updated with such entries the {@link org.elasticsearch.snapshots.SnapshotsService} executes corresponding snapshot
4444 * delete requests to effectively delete the snapshot from the repository. It is possible that the deletion of a snapshot failed for various
4545 * reason (ex: conflicting snapshot operation, repository removed etc). In such cases the snapshot pending deletion is kept in the cluster
@@ -51,21 +51,28 @@ public class SnapshotDeletionsPending extends AbstractNamedDiffable<Custom> impl
5151 public static final SnapshotDeletionsPending EMPTY = new SnapshotDeletionsPending (List .of ());
5252 public static final String TYPE = "snapshot_deletions_pending" ;
5353
54+ /**
55+ * Version from which a snapshot can be marked as to be deleted after an index is deleted.
56+ */
57+ public static final Version SNAPSHOT_DELETIONS_PENDING_VERSION = Version .V_8_1_0 ;
58+
5459 /**
5560 * Setting for the maximum number of snapshots pending deletion allowed in the cluster state.
5661 * <p>
5762 * This setting is here to prevent the cluster to grow too large. In the case that the number of snapshots pending deletion exceeds
5863 * the value of this setting the oldest entries are removed from the cluster state. Snapshots that are discarded are removed before
5964 * they can be deleted from their repository and are therefore considered as "leaking" and should be logged as such as warnings.
65+ * <p>
66+ * This setting is a non-dynamic, node-level only setting that is only used on the elected master node.
6067 */
6168 public static final Setting <Integer > MAX_PENDING_DELETIONS_SETTING = Setting .intSetting (
6269 "cluster.snapshot.snapshot_deletions_pending.size" ,
63- 500 ,
70+ 5_000 ,
6471 Setting .Property .NodeScope
6572 );
6673
6774 /**
68- * A list of snapshots to delete, sorted by creation time
75+ * A list of snapshots to delete, in the order deletions were requested.
6976 */
7077 private final List <Entry > entries ;
7178
@@ -111,7 +118,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
111118
112119 @ Override
113120 public Version getMinimalSupportedVersion () {
114- return Version . CURRENT . minimumCompatibilityVersion () ;
121+ return SNAPSHOT_DELETIONS_PENDING_VERSION ;
115122 }
116123
117124 public SnapshotDeletionsPending withRemovedSnapshots (List <SnapshotId > snapshotIds ) {
@@ -120,8 +127,9 @@ public SnapshotDeletionsPending withRemovedSnapshots(List<SnapshotId> snapshotId
120127 }
121128 boolean changed = false ;
122129 final List <Entry > updatedEntries = new ArrayList <>();
130+ final Set <SnapshotId > removedSnapshotIds = new HashSet <>(snapshotIds );
123131 for (Entry entry : entries ) {
124- if (snapshotIds .contains (entry .snapshotId )) {
132+ if (removedSnapshotIds .contains (entry .snapshotId )) {
125133 changed = true ;
126134 continue ;
127135 }
@@ -138,46 +146,35 @@ public SnapshotDeletionsPending withRemovedSnapshots(List<SnapshotId> snapshotId
138146
139147 @ Override
140148 public String toString () {
141- final StringBuilder builder = new StringBuilder ("SnapshotDeletionsPending[" );
142- boolean prepend = true ;
143- final Iterator <Entry > iterator = entries .stream ().iterator ();
144- while (iterator .hasNext ()) {
145- if (prepend == false ) {
146- builder .append (',' );
147- }
148- builder .append (iterator .next ());
149- prepend = false ;
150- }
151- builder .append (']' );
152- return builder .toString ();
149+ return "SnapshotDeletionsPending[" + entries + ']' ;
153150 }
154151
155152 public static class Entry implements Writeable , ToXContentObject {
156153
157154 private final String repositoryName ;
158155 private final String repositoryUuid ;
159156 private final SnapshotId snapshotId ;
160- private final long creationTime ;
157+ private final long indexDeletionTime ;
161158
162- public Entry (String repositoryName , String repositoryUuid , SnapshotId snapshotId , long creationTime ) {
159+ public Entry (String repositoryName , String repositoryUuid , SnapshotId snapshotId , long indexDeletionTime ) {
163160 this .repositoryName = Objects .requireNonNull (repositoryName );
164161 this .repositoryUuid = Objects .requireNonNull (repositoryUuid );
165162 this .snapshotId = Objects .requireNonNull (snapshotId );
166- this .creationTime = creationTime ;
163+ this .indexDeletionTime = indexDeletionTime ;
167164 }
168165
169166 private Entry (StreamInput in ) throws IOException {
170167 this .repositoryName = in .readString ();
171168 this .repositoryUuid = in .readString ();
172- this .creationTime = in .readVLong ();
169+ this .indexDeletionTime = in .readVLong ();
173170 this .snapshotId = new SnapshotId (in );
174171 }
175172
176173 @ Override
177174 public void writeTo (StreamOutput out ) throws IOException {
178175 out .writeString (repositoryName );
179176 out .writeString (repositoryUuid );
180- out .writeVLong (creationTime );
177+ out .writeVLong (indexDeletionTime );
181178 snapshotId .writeTo (out );
182179 }
183180
@@ -193,24 +190,24 @@ public SnapshotId getSnapshotId() {
193190 return snapshotId ;
194191 }
195192
196- public long getCreationTime () {
197- return creationTime ;
193+ public long getIndexDeletionTime () {
194+ return indexDeletionTime ;
198195 }
199196
200197 @ Override
201198 public boolean equals (Object o ) {
202199 if (this == o ) return true ;
203200 if (o == null || getClass () != o .getClass ()) return false ;
204201 Entry entry = (Entry ) o ;
205- return creationTime == entry .creationTime
202+ return indexDeletionTime == entry .indexDeletionTime
206203 && Objects .equals (repositoryName , entry .repositoryName )
207204 && Objects .equals (repositoryUuid , entry .repositoryUuid )
208205 && Objects .equals (snapshotId , entry .snapshotId );
209206 }
210207
211208 @ Override
212209 public int hashCode () {
213- return Objects .hash (repositoryName , repositoryUuid , snapshotId , creationTime );
210+ return Objects .hash (repositoryName , repositoryUuid , snapshotId , indexDeletionTime );
214211 }
215212
216213 @ Override
@@ -219,7 +216,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
219216 {
220217 builder .field ("repository_name" , repositoryName );
221218 builder .field ("repository_uuid" , repositoryUuid );
222- builder .timeField ("creation_time_millis" , "creation_time" , creationTime );
219+ builder .timeField ("creation_time_millis" , "creation_time" , indexDeletionTime );
223220 builder .field ("snapshot" , snapshotId );
224221 }
225222 builder .endObject ();
@@ -228,7 +225,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
228225
229226 @ Override
230227 public String toString () {
231- return '[' + repositoryName + '/' + repositoryUuid + ',' + snapshotId + ',' + creationTime + ']' ;
228+ return '[' + repositoryName + '/' + repositoryUuid + ',' + snapshotId + ',' + indexDeletionTime + ']' ;
232229 }
233230 }
234231
0 commit comments