@@ -1678,6 +1678,7 @@ public void rollGeneration() throws IOException {
16781678 * required generation
16791679 */
16801680 public void trimUnreferencedReaders () throws IOException {
1681+ List <TranslogReader > toDeleteReaderList = new ArrayList <>();
16811682 try (ReleasableLock ignored = writeLock .acquire ()) {
16821683 if (closed .get ()) {
16831684 // we're shutdown potentially on some tragic event, don't delete anything
@@ -1691,22 +1692,14 @@ public void trimUnreferencedReaders() throws IOException {
16911692 "deletion policy requires a minReferenceGen of [" + minReferencedGen + "] which is higher than the current generation ["
16921693 + currentFileGeneration () + "]" ;
16931694
1694-
16951695 for (Iterator <TranslogReader > iterator = readers .iterator (); iterator .hasNext (); ) {
16961696 TranslogReader reader = iterator .next ();
16971697 if (reader .getGeneration () >= minReferencedGen ) {
16981698 break ;
16991699 }
17001700 iterator .remove ();
1701+ toDeleteReaderList .add (reader );
17011702 IOUtils .closeWhileHandlingException (reader );
1702- final Path translogPath = reader .path ();
1703- logger .trace ("delete translog file [{}], not referenced and not current anymore" , translogPath );
1704- // The checkpoint is used when opening the translog to know which files should be recovered from.
1705- // We now update the checkpoint to ignore the file we are going to remove.
1706- // Note that there is a provision in recoverFromFiles to allow for the case where we synced the checkpoint
1707- // but crashed before we could delete the file.
1708- current .sync ();
1709- deleteReaderFiles (reader );
17101703 }
17111704 assert readers .isEmpty () == false || current .generation == minReferencedGen :
17121705 "all readers were cleaned but the minReferenceGen [" + minReferencedGen + "] is not the current writer's gen [" +
@@ -1715,6 +1708,24 @@ public void trimUnreferencedReaders() throws IOException {
17151708 closeOnTragicEvent (ex );
17161709 throw ex ;
17171710 }
1711+ // Do sync outside the writeLock to avoid blocking all writing thread.
1712+ if (toDeleteReaderList .isEmpty () == false ) {
1713+ try {
1714+ // The checkpoint is used when opening the translog to know which files should be recovered from.
1715+ // We now update the checkpoint to ignore the file we are going to remove.
1716+ // Note that there is a provision in recoverFromFiles to allow for the case where we synced the checkpoint
1717+ // but crashed before we could delete the file.
1718+ sync ();
1719+ for (TranslogReader reader : toDeleteReaderList ) {
1720+ final Path translogPath = reader .path ();
1721+ logger .trace ("delete translog file [{}], not referenced and not current anymore" , translogPath );
1722+ deleteReaderFiles (reader );
1723+ }
1724+ } catch (final Exception ex ) {
1725+ closeOnTragicEvent (ex );
1726+ throw ex ;
1727+ }
1728+ }
17181729 }
17191730
17201731 /**
0 commit comments