diff --git a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java index a3f53b069e7df..0fc0e522999e2 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java +++ b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java @@ -539,8 +539,8 @@ public Translog.Location getTranslogLastWriteLocation() { private void revisitIndexDeletionPolicyOnTranslogSynced() throws IOException { if (combinedDeletionPolicy.hasUnreferencedCommits()) { indexWriter.deleteUnusedFiles(); - translog.trimUnreferencedReaders(); } + translog.trimUnreferencedReaders(); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/translog/Translog.java b/server/src/main/java/org/elasticsearch/index/translog/Translog.java index 1427b070b9d43..f0e2b04673a71 100644 --- a/server/src/main/java/org/elasticsearch/index/translog/Translog.java +++ b/server/src/main/java/org/elasticsearch/index/translog/Translog.java @@ -1646,24 +1646,25 @@ public void rollGeneration() throws IOException { * required generation */ public void trimUnreferencedReaders() throws IOException { - // move most of the data to disk to reduce the time the lock is held + // first check under read lock if any readers can be trimmed + try (ReleasableLock ignored = readLock.acquire()) { + if (closed.get()) { + // we're shutdown potentially on some tragic event, don't delete anything + return; + } + if (getMinReferencedGen() == getMinFileGeneration()) { + return; + } + } + + // move most of the data to disk to reduce the time the write lock is held sync(); try (ReleasableLock ignored = writeLock.acquire()) { if (closed.get()) { // we're shutdown potentially on some tragic event, don't delete anything return; } - long minReferencedGen = Math.min( - deletionPolicy.getMinTranslogGenRequiredByLocks(), - minGenerationForSeqNo(deletionPolicy.getLocalCheckpointOfSafeCommit() + 1, current, readers)); - assert minReferencedGen >= getMinFileGeneration() : - "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] but the lowest gen available is [" - + getMinFileGeneration() + "]"; - assert minReferencedGen <= currentFileGeneration() : - "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] which is higher than the current generation [" - + currentFileGeneration() + "]"; - - + final long minReferencedGen = getMinReferencedGen(); for (Iterator iterator = readers.iterator(); iterator.hasNext(); ) { TranslogReader reader = iterator.next(); if (reader.getGeneration() >= minReferencedGen) { @@ -1690,6 +1691,20 @@ public void trimUnreferencedReaders() throws IOException { } } + private long getMinReferencedGen() { + assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread(); + long minReferencedGen = Math.min( + deletionPolicy.getMinTranslogGenRequiredByLocks(), + minGenerationForSeqNo(deletionPolicy.getLocalCheckpointOfSafeCommit() + 1, current, readers)); + assert minReferencedGen >= getMinFileGeneration() : + "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] but the lowest gen available is [" + + getMinFileGeneration() + "]"; + assert minReferencedGen <= currentFileGeneration() : + "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] which is higher than the current generation [" + + currentFileGeneration() + "]"; + return minReferencedGen; + } + /** * deletes all files associated with a reader. package-private to be able to simulate node failures at this point */