Skip to content

Commit 247f587

Browse files
committed
[GATEWAY] copy translog file if rename fails after retries.
Today we ignore a translog file if the rename operation fails. This can be problematic on windows if another process hodls on to the translog file. If we can't rename it we should at least try to copy it since otherwise its content will just be lost. This is a workaround for an already fixed issue in 2.0 since all translog files are write once in 2.0 and renaming / copying is not needed anymore. Conflicts: src/main/java/org/elasticsearch/index/gateway/local/LocalIndexShardGateway.java
1 parent a9b2dee commit 247f587

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

src/main/java/org/elasticsearch/index/gateway/local/LocalIndexShardGateway.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.io.EOFException;
5252
import java.io.File;
5353
import java.io.IOException;
54+
import java.nio.file.Files;
5455
import java.util.Arrays;
5556
import java.util.Set;
5657
import java.util.concurrent.CountDownLatch;
@@ -204,12 +205,30 @@ public void recover(boolean indexShouldExists, RecoveryState recoveryState) thro
204205
if (!tmpRecoveringFile.exists()) {
205206
File tmpTranslogFile = new File(translogLocation, translogName);
206207
if (tmpTranslogFile.exists()) {
208+
logger.trace("Translog file found in {} - renaming", translogLocation);
209+
boolean success = false;
207210
for (int i = 0; i < RECOVERY_TRANSLOG_RENAME_RETRIES; i++) {
208211
if (tmpTranslogFile.renameTo(tmpRecoveringFile)) {
212+
209213
recoveringTranslogFile = tmpRecoveringFile;
214+
logger.trace("Renamed translog from {} to {}", tmpTranslogFile.getName(), recoveringTranslogFile.getName());
215+
success = true;
210216
break;
211217
}
212218
}
219+
if (success == false) {
220+
try {
221+
// this is a fallback logic that to ensure we can recover from the file.
222+
// on windows a virus-scanner etc can hold on to the file and after retrying
223+
// we just skip the recovery and the engine will reuse the file and truncate it.
224+
// in 2.0 this is all not needed since translog files are write once.
225+
Files.copy(tmpTranslogFile.toPath(), tmpRecoveringFile.toPath());
226+
recoveringTranslogFile = tmpRecoveringFile;
227+
logger.trace("Copied translog from {} to {}", tmpTranslogFile.getName(), recoveringTranslogFile.getName());
228+
} catch (IOException ex) {
229+
throw new ElasticsearchException("failed to copy recovery file", ex);
230+
}
231+
}
213232
}
214233
} else {
215234
recoveringTranslogFile = tmpRecoveringFile;

0 commit comments

Comments
 (0)