From 82ab1bc1ff40a2e7041413428bfda810507f94e7 Mon Sep 17 00:00:00 2001 From: Yannick Welsch Date: Thu, 20 Feb 2020 15:55:33 +0100 Subject: [PATCH] Separate translog from index deletion conditions (#52556) Separates the translog from the index deletion conditions (allowing the translog to be cleaned up more eagerly), and avoids taking the write lock on the translog if no clean-up is actually necessary. --- .../index/engine/InternalEngine.java | 2 +- .../index/translog/Translog.java | 38 +++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) 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 b76a23c0141..5fa7bd2c8c2 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java +++ b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java @@ -585,8 +585,8 @@ public class InternalEngine extends Engine { 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 87d22835216..452d65ffcfd 100644 --- a/server/src/main/java/org/elasticsearch/index/translog/Translog.java +++ b/server/src/main/java/org/elasticsearch/index/translog/Translog.java @@ -1646,23 +1646,25 @@ public class Translog extends AbstractIndexShardComponent implements IndexShardC * 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.minTranslogGenRequired(readers, current), - 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) { @@ -1689,6 +1691,20 @@ public class Translog extends AbstractIndexShardComponent implements IndexShardC } } + private long getMinReferencedGen() throws IOException { + assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread(); + long minReferencedGen = Math.min( + deletionPolicy.minTranslogGenRequired(readers, current), + 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 */