@@ -1670,6 +1670,7 @@ public void rollGeneration() throws IOException {
16701670 * required generation
16711671 */
16721672 public void trimUnreferencedReaders () throws IOException {
1673+ List <TranslogReader > toDeleteReaderList = new ArrayList <>();
16731674 try (ReleasableLock ignored = writeLock .acquire ()) {
16741675 if (closed .get ()) {
16751676 // we're shutdown potentially on some tragic event, don't delete anything
@@ -1683,22 +1684,14 @@ public void trimUnreferencedReaders() throws IOException {
16831684 "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] which is higher than the current generation ["
16841685 + currentFileGeneration () + "]" ;
16851686
1686-
16871687 for (Iterator <TranslogReader > iterator = readers .iterator (); iterator .hasNext (); ) {
16881688 TranslogReader reader = iterator .next ();
16891689 if (reader .getGeneration () >= minReferencedGen ) {
16901690 break ;
16911691 }
16921692 iterator .remove ();
1693+ toDeleteReaderList .add (reader );
16931694 IOUtils .closeWhileHandlingException (reader );
1694- final Path translogPath = reader .path ();
1695- logger .trace ("delete translog file [{}], not referenced and not current anymore" , translogPath );
1696- // The checkpoint is used when opening the translog to know which files should be recovered from.
1697- // We now update the checkpoint to ignore the file we are going to remove.
1698- // Note that there is a provision in recoverFromFiles to allow for the case where we synced the checkpoint
1699- // but crashed before we could delete the file.
1700- current .sync ();
1701- deleteReaderFiles (reader );
17021695 }
17031696 assert readers .isEmpty () == false || current .generation == minReferencedGen :
17041697 "all readers were cleaned but the minReferenceGen [" + minReferencedGen + "] is not the current writer's gen [" +
@@ -1707,6 +1700,24 @@ public void trimUnreferencedReaders() throws IOException {
17071700 closeOnTragicEvent (ex );
17081701 throw ex ;
17091702 }
1703+ // Do sync outside the writeLock to avoid blocking all writing thread.
1704+ if (toDeleteReaderList .isEmpty () == false ) {
1705+ try {
1706+ // The checkpoint is used when opening the translog to know which files should be recovered from.
1707+ // We now update the checkpoint to ignore the file we are going to remove.
1708+ // Note that there is a provision in recoverFromFiles to allow for the case where we synced the checkpoint
1709+ // but crashed before we could delete the file.
1710+ sync ();
1711+ for (TranslogReader reader : toDeleteReaderList ) {
1712+ final Path translogPath = reader .path ();
1713+ logger .trace ("delete translog file [{}], not referenced and not current anymore" , translogPath );
1714+ deleteReaderFiles (reader );
1715+ }
1716+ } catch (final Exception ex ) {
1717+ closeOnTragicEvent (ex );
1718+ throw ex ;
1719+ }
1720+ }
17101721 }
17111722
17121723 /**
0 commit comments