Index: src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (revision 1206051) +++ src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (working copy) @@ -458,6 +458,8 @@ WriterAndPath wap = (WriterAndPath)o; wap.w.close(); LOG.debug("Closed " + wap.p); + Path dst = getCompletedRecoveredEditsFilePath(wap.p); + fs.rename(wap.p, dst); } String msg = ("processed " + editsCount + " edits across " + n + " regions" + " threw away edits for " + (logWriters.size() - n) + " regions" + @@ -624,10 +626,31 @@ if (isCreate && !fs.exists(dir)) { if (!fs.mkdirs(dir)) LOG.warn("mkdir failed on " + dir); } - return new Path(dir, formatRecoveredEditsFileName(logEntry.getKey() - .getLogSeqNum())); + // Append file name ends with RECOVERED_LOG_TMPFILE_SUFFIX to ensure + // region's replayRecoveredEdits will not delete it + String fileName = formatRecoveredEditsFileName(logEntry.getKey() + .getLogSeqNum()); + fileName = getTmpRecoveredEditsFileName(fileName); + return new Path(dir, fileName); } + static String getTmpRecoveredEditsFileName(String fileName) { + return fileName + HLog.RECOVERED_LOG_TMPFILE_SUFFIX; + } + + /** + * Convert path to a file under RECOVERED_EDITS_DIR directory without + * RECOVERED_LOG_TMPFILE_SUFFIX + * @param srcPath + * @return dstPath without RECOVERED_LOG_TMPFILE_SUFFIX + */ + static Path getCompletedRecoveredEditsFilePath(Path srcPath) { + String fileName = srcPath.getName(); + if (fileName.endsWith(HLog.RECOVERED_LOG_TMPFILE_SUFFIX)) + fileName = fileName.split(HLog.RECOVERED_LOG_TMPFILE_SUFFIX)[0]; + return new Path(srcPath.getParent(), fileName); + } + static String formatRecoveredEditsFileName(final long seqid) { return String.format("%019d", seqid); } @@ -1136,9 +1159,17 @@ thrown.add(ioe); continue; } - paths.add(wap.p); LOG.info("Closed path " + wap.p +" (wrote " + wap.editsWritten + " edits in " + (wap.nanosSpent / 1000/ 1000) + "ms)"); + Path dst = getCompletedRecoveredEditsFilePath(wap.p); + try { + fs.rename(wap.p, dst); + } catch (IOException ioe) { + LOG.error("Couldn't rename " + wap.p + " to " + dst, ioe); + thrown.add(ioe); + continue; + } + paths.add(dst); } if (!thrown.isEmpty()) { throw MultipleIOException.createIOException(thrown); Index: src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java (revision 1206051) +++ src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLog.java (working copy) @@ -31,8 +31,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedList; import java.util.List; -import java.util.LinkedList; import java.util.Map; import java.util.NavigableSet; import java.util.SortedMap; @@ -126,6 +126,7 @@ private static final String RECOVERED_EDITS_DIR = "recovered.edits"; private static final Pattern EDITFILES_NAME_PATTERN = Pattern.compile("-?[0-9]+"); + static final String RECOVERED_LOG_TMPFILE_SUFFIX = ".temp"; private final FileSystem fs; private final Path dir; @@ -1726,6 +1727,10 @@ // it a timestamp suffix. See moveAsideBadEditsFile. Matcher m = EDITFILES_NAME_PATTERN.matcher(p.getName()); result = fs.isFile(p) && m.matches(); + // Skip the file whose name ends with RECOVERED_LOG_TMPFILE_SUFFIX, + // because it means splithlog thread is writting this file. + if (p.getName().endsWith(RECOVERED_LOG_TMPFILE_SUFFIX)) + result = false; } catch (IOException e) { LOG.warn("Failed isFile check on " + p); }