|
@@ -97,21 +97,13 @@ public class CombinedDeletionPolicy extends IndexDeletionPolicy {
|
|
|
assert Thread.holdsLock(this) == false : "should not block concurrent acquire or release";
|
|
|
final int keptPosition = indexOfKeptCommits(commits, globalCheckpointSupplier.getAsLong());
|
|
|
final IndexCommit safeCommit = commits.get(keptPosition);
|
|
|
- int totalDocsOfSafeCommit;
|
|
|
- try {
|
|
|
- totalDocsOfSafeCommit = getDocCountOfCommit(safeCommit);
|
|
|
- } catch (IOException ex) {
|
|
|
- logger.info("failed to get the total docs from the safe commit; use the total docs from the previous safe commit", ex);
|
|
|
- totalDocsOfSafeCommit = safeCommitInfo.docCount;
|
|
|
- }
|
|
|
- IndexCommit newCommit = null;
|
|
|
- IndexCommit previousLastCommit = null;
|
|
|
+ final var newSafeCommitInfo = getNewSafeCommitInfo(safeCommit);
|
|
|
+ final IndexCommit newCommit;
|
|
|
+ final IndexCommit previousLastCommit;
|
|
|
List<IndexCommit> deletedCommits = null;
|
|
|
synchronized (this) {
|
|
|
- this.safeCommitInfo = new SafeCommitInfo(
|
|
|
- Long.parseLong(safeCommit.getUserData().get(SequenceNumbers.LOCAL_CHECKPOINT_KEY)),
|
|
|
- totalDocsOfSafeCommit
|
|
|
- );
|
|
|
+ // we are synchronized on the IndexWriter in this method so nothing concurrently changed safeCommitInfo since the previous read
|
|
|
+ this.safeCommitInfo = newSafeCommitInfo;
|
|
|
previousLastCommit = this.lastCommit;
|
|
|
this.lastCommit = commits.get(commits.size() - 1);
|
|
|
this.safeCommit = safeCommit;
|
|
@@ -123,6 +115,8 @@ public class CombinedDeletionPolicy extends IndexDeletionPolicy {
|
|
|
}
|
|
|
if (commitsListener != null && previousLastCommit != this.lastCommit) {
|
|
|
newCommit = acquireIndexCommit(false);
|
|
|
+ } else {
|
|
|
+ newCommit = null;
|
|
|
}
|
|
|
for (int i = 0; i < keptPosition; i++) {
|
|
|
final IndexCommit commit = commits.get(i);
|
|
@@ -149,6 +143,31 @@ public class CombinedDeletionPolicy extends IndexDeletionPolicy {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private SafeCommitInfo getNewSafeCommitInfo(IndexCommit newSafeCommit) {
|
|
|
+ final var currentSafeCommitInfo = this.safeCommitInfo;
|
|
|
+ final long newSafeCommitLocalCheckpoint;
|
|
|
+ try {
|
|
|
+ newSafeCommitLocalCheckpoint = Long.parseLong(newSafeCommit.getUserData().get(SequenceNumbers.LOCAL_CHECKPOINT_KEY));
|
|
|
+ } catch (Exception ex) {
|
|
|
+ logger.info("failed to get the local checkpoint from the safe commit; use the info from the previous safe commit", ex);
|
|
|
+ return currentSafeCommitInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentSafeCommitInfo.localCheckpoint == newSafeCommitLocalCheckpoint) {
|
|
|
+ // the new commit could in principle have the same LCP but a different doc count due to extra operations between its LCP and
|
|
|
+ // MSN, but that is a transient state since we'll eventually advance the LCP. The doc count is only used for heuristics around
|
|
|
+ // expiring excessively-lagging retention leases, so a little inaccuracy is tolerable here.
|
|
|
+ return currentSafeCommitInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return new SafeCommitInfo(newSafeCommitLocalCheckpoint, getDocCountOfCommit(newSafeCommit));
|
|
|
+ } catch (IOException ex) {
|
|
|
+ logger.info("failed to get the total docs from the safe commit; use the total docs from the previous safe commit", ex);
|
|
|
+ return new SafeCommitInfo(newSafeCommitLocalCheckpoint, currentSafeCommitInfo.docCount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private boolean assertSafeCommitUnchanged(IndexCommit safeCommit) {
|
|
|
// This is protected from concurrent calls by a lock on the IndexWriter, but this assertion makes sure that we notice if that ceases
|
|
|
// to be true in future. It is not disastrous if safeCommitInfo refers to an older safeCommit, it just means that we might retain a
|