Skip to content

Commit fd8183e

Browse files
dengweisysudnhatn
authored andcommitted
Sync translog without lock when trim unreferenced readers (#46203)
With this change, we can avoid blocking writing threads when trimming unreferenced readers; hence improving the translog writing performance in async durability mode. Close #46201
1 parent 69abc64 commit fd8183e

File tree

1 file changed

+20
-9
lines changed
  • server/src/main/java/org/elasticsearch/index/translog

1 file changed

+20
-9
lines changed

server/src/main/java/org/elasticsearch/index/translog/Translog.java

+20-9
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)