Skip to content

Commit 416419e

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 e01ec80 commit 416419e

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
@@ -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

Comments
 (0)