Skip to content

Commit d15ac48

Browse files
committed
MAX_PENDING_DELETIONS_SETTING
1 parent 579c21f commit d15ac48

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

server/src/main/java/org/elasticsearch/cluster/SnapshotDeletionsPending.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import org.elasticsearch.common.io.stream.StreamInput;
1414
import org.elasticsearch.common.io.stream.StreamOutput;
1515
import org.elasticsearch.common.io.stream.Writeable;
16+
import org.elasticsearch.common.settings.Setting;
17+
import org.elasticsearch.common.settings.Settings;
1618
import org.elasticsearch.snapshots.SnapshotId;
1719
import org.elasticsearch.xcontent.ToXContentObject;
1820
import org.elasticsearch.xcontent.XContentBuilder;
@@ -31,13 +33,39 @@
3133

3234
/**
3335
* Represents snapshots marked as to be deleted and pending deletion.
36+
*
37+
* Snapshots pending deletion are added to the cluster state when searchable snapshots indices with a specific setting are deleted (see
38+
* MetadataDeleteIndexService#updateSnapshotDeletionsPending()). Because deleting snapshots requires a consistent view of the repository
39+
* they belong to it is not possible to delete searchable snapshots indices and their backing snapshots in the same cluster state update.
40+
*
41+
* Hence we keep in cluster state the snapshot that should be deleted from repositories. To be able to delete them we capture the snapshot
42+
* 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
43+
* to the pending deletion, in a {@link SnapshotDeletionsPending} entry.
44+
*
45+
*
46+
* When cluster state is updated with such entries the {@link org.elasticsearch.snapshots.SnapshotsService} executes corresponding snapshot
47+
* delete requests to effectively delete the snapshot from the repository. It is possible that the deletion of a snapshot failed for various
48+
* reason (ex: conflicting snapshot operation, repository removed etc). In such cases the snapshot pending deletion is kept in the cluster
49+
* state and the deletion will be retried on the next cluster state update. To avoid too many snapshots pending deletion stored in cluster
50+
* state the number is limited to 500 and configurable through the {@link #MAX_PENDING_DELETIONS_SETTING} setting.
3451
*/
3552
public class SnapshotDeletionsPending extends AbstractNamedDiffable<Custom> implements Custom {
3653

3754
public static final SnapshotDeletionsPending EMPTY = new SnapshotDeletionsPending(Collections.emptySortedSet());
3855
public static final String TYPE = "snapshot_deletions_pending";
3956

40-
public static final int MAX_PENDING_DELETIONS = 500;
57+
/**
58+
* Setting for the maximum number of snapshots pending deletion allowed in the cluster state.
59+
* <p>
60+
* This setting is here to prevent the cluster to grow too large. In the case that the number of snapshots pending deletion exceeds
61+
* the value of this setting the oldest entries are removed from the cluster state. Snapshots that are discarded are removed before
62+
* they can be deleted from their repository and are therefore considered as "leaking" and should be logged as such as warnings.
63+
*/
64+
public static final Setting<Integer> MAX_PENDING_DELETIONS_SETTING = Setting.intSetting(
65+
"cluster.snapshot.snapshot_deletions_pending.size",
66+
500,
67+
Setting.Property.NodeScope
68+
);
4169

4270
/**
4371
* A list of snapshots to delete, sorted by creation time
@@ -46,7 +74,6 @@ public class SnapshotDeletionsPending extends AbstractNamedDiffable<Custom> impl
4674

4775
private SnapshotDeletionsPending(SortedSet<Entry> entries) {
4876
this.entries = unmodifiableSortedSet(Objects.requireNonNull(entries));
49-
assert entries.size() <= MAX_PENDING_DELETIONS : entries.size() + " > " + MAX_PENDING_DELETIONS;
5077
}
5178

5279
public SnapshotDeletionsPending(StreamInput in) throws IOException {
@@ -221,8 +248,8 @@ public Builder(SnapshotDeletionsPending snapshotDeletionsPending, Consumer<Entry
221248
this.consumer = onLimitExceeded;
222249
}
223250

224-
private void ensureLimit() {
225-
while (entries.size() >= MAX_PENDING_DELETIONS) {
251+
private void ensureLimit(final int maxPendingDeletions) {
252+
while (entries.size() >= maxPendingDeletions) {
226253
final Entry removed = entries.last();
227254
entries.remove(removed);
228255
if (consumer != null) {
@@ -232,13 +259,14 @@ private void ensureLimit() {
232259
}
233260

234261
public Builder add(String repositoryName, String repositoryUuid, SnapshotId snapshotId, long creationTime) {
235-
ensureLimit();
236262
entries.add(new Entry(repositoryName, repositoryUuid, snapshotId, creationTime));
237263
return this;
238264
}
239265

240-
public SnapshotDeletionsPending build() {
241-
ensureLimit();
266+
public SnapshotDeletionsPending build(Settings settings) {
267+
final int maxPendingDeletions = MAX_PENDING_DELETIONS_SETTING.get(settings);
268+
ensureLimit(maxPendingDeletions);
269+
assert entries.size() <= maxPendingDeletions : entries.size() + " > " + maxPendingDeletions;
242270
return entries.isEmpty() == false ? new SnapshotDeletionsPending(entries) : EMPTY;
243271
}
244272
}

server/src/main/java/org/elasticsearch/cluster/metadata/MetadataDeleteIndexService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,14 @@ private SnapshotDeletionsPending updateSnapshotDeletionsPending(
215215
}
216216
if (canDeleteSnapshot) {
217217
if (builder == null) {
218+
final int maxPendingDeletions = SnapshotDeletionsPending.MAX_PENDING_DELETIONS_SETTING.get(settings);
218219
builder = new SnapshotDeletionsPending.Builder(
219220
pendingDeletions,
220221
evicted -> logger.warn(
221222
() -> new ParameterizedMessage(
222223
"maximum number of snapshots [{}] awaiting deletion has been reached in "
223224
+ "cluster state before snapshot [{}] deleted on [{}] in repository [{}/{}] could be deleted",
224-
SnapshotDeletionsPending.MAX_PENDING_DELETIONS,
225+
maxPendingDeletions,
225226
evicted.getSnapshotId(),
226227
Instant.ofEpochMilli(evicted.getCreationTime()).atZone(ZoneOffset.UTC),
227228
evicted.getRepositoryName(),
@@ -240,7 +241,7 @@ private SnapshotDeletionsPending updateSnapshotDeletionsPending(
240241
}
241242
}
242243
if (changed) {
243-
return builder.build();
244+
return builder.build(settings);
244245
}
245246
}
246247
return pendingDeletions;

0 commit comments

Comments
 (0)