In SLM retention, when a minimum number of snapshots is required for retention, we prefer to remove the oldest snapshots first. To perform this, we limit one of the streams, in a rare case this can cause: ``` [mynode] error during snapshot retention task java.lang.IllegalArgumentException: -5 at java.util.stream.ReferencePipeline.limit(ReferencePipeline.java:469) ~[?:?] at org.elasticsearch.xpack.core.slm.SnapshotRetentionConfiguration.lambda$getSnapshotDeletionPredicate$6(SnapshotRetentionConfiguration.java:195) ~[?:?] at org.elasticsearch.xpack.slm.SnapshotRetentionTask.snapshotEligibleForDeletion(SnapshotRetentionTask.java:245) ~[?:?] at org.elasticsearch.xpack.slm.SnapshotRetentionTask$1.lambda$onResponse$0(SnapshotRetentionTask.java:163) ~[?:?] at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:176) ~[?:?] at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1624) ~[?:?] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[?:?] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[?:?] at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[?:?] ``` When certain criteria are met. This commit fixes the negative limiting with `Math.max(0, ...)` and adds a unit test for the behavior. Resolves #58515
This commit is contained in:
parent
5f52bc4c9f
commit
f732003370
|
@ -186,7 +186,7 @@ public class SnapshotRetentionConfiguration implements ToXContentObject, Writeab
|
|||
final TimeValue snapshotAge = new TimeValue(nowSupplier.getAsLong() - si.startTime());
|
||||
|
||||
if (this.minimumSnapshotCount != null) {
|
||||
final long eligibleForExpiration = successfulSnapshotCount - minimumSnapshotCount;
|
||||
final long eligibleForExpiration = Math.max(0, successfulSnapshotCount - minimumSnapshotCount);
|
||||
|
||||
// Only the oldest N snapshots are actually eligible, since if we went below this we
|
||||
// would fall below the configured minimum number of snapshots to keep
|
||||
|
|
|
@ -227,7 +227,6 @@ public class SnapshotRetentionConfigurationTests extends ESTestCase {
|
|||
assertThat(conf.getSnapshotDeletionPredicate(infos).test(oldInfo), equalTo(true));
|
||||
}
|
||||
|
||||
|
||||
public void testMostRecentSuccessfulTimestampIsUsed() {
|
||||
boolean failureBeforePartial = randomBoolean();
|
||||
SnapshotRetentionConfiguration conf = new SnapshotRetentionConfiguration(() -> 1, null, 2, 2);
|
||||
|
@ -243,6 +242,18 @@ public class SnapshotRetentionConfigurationTests extends ESTestCase {
|
|||
assertThat(conf.getSnapshotDeletionPredicate(infos).test(s4), equalTo(false));
|
||||
}
|
||||
|
||||
public void testFewerSuccessesThanMinWithPartial() {
|
||||
SnapshotRetentionConfiguration conf = new SnapshotRetentionConfiguration(() -> 1, TimeValue.timeValueSeconds(5), 10, 20);
|
||||
SnapshotInfo s1 = makeInfo(1);
|
||||
SnapshotInfo sP = makePartialInfo(2);
|
||||
SnapshotInfo s2 = makeInfo(3);
|
||||
|
||||
List<SnapshotInfo> infos = Arrays.asList(s1 , sP, s2);
|
||||
assertThat(conf.getSnapshotDeletionPredicate(infos).test(s1), equalTo(false));
|
||||
assertThat(conf.getSnapshotDeletionPredicate(infos).test(sP), equalTo(false));
|
||||
assertThat(conf.getSnapshotDeletionPredicate(infos).test(s2), equalTo(false));
|
||||
}
|
||||
|
||||
private SnapshotInfo makeInfo(long startTime) {
|
||||
final Map<String, Object> meta = new HashMap<>();
|
||||
meta.put(SnapshotLifecyclePolicy.POLICY_ID_METADATA_FIELD, REPO);
|
||||
|
|
Loading…
Reference in New Issue