Index: src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (revision 1499339) +++ src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (working copy) @@ -661,8 +661,8 @@ throws IOException { Path tableDir = HTableDescriptor.getTableDir(rootDir, logEntry.getKey() .getTablename()); - Path regiondir = HRegion.getRegionDir(tableDir, - Bytes.toString(logEntry.getKey().getEncodedRegionName())); + String encodedRegionName = Bytes.toString(logEntry.getKey().getEncodedRegionName()); + Path regiondir = HRegion.getRegionDir(tableDir, encodedRegionName); Path dir = HLog.getRegionDirRecoveredEditsDir(regiondir); if (!fs.exists(regiondir)) { @@ -671,6 +671,20 @@ " already split so it's safe to discard those edits."); return null; } + if (fs.exists(dir) && fs.isFile(dir)) { + Path tmp = new Path("/tmp"); + if (!fs.exists(tmp)) { + fs.mkdirs(tmp); + } + tmp = new Path(tmp, + HLog.RECOVERED_EDITS_DIR + "_" + encodedRegionName); + LOG.warn("Found existing old file: " + dir + ". It could be some " + + "leftover of an old installation. It should be a folder instead. " + + "So moving it to " + tmp); + if (!HBaseFileSystem.renameDirForFileSystem(fs, dir, tmp)) { + LOG.warn("Failed to sideline old file " + dir); + } + } if (isCreate && !fs.exists(dir) && !HBaseFileSystem.makeDirOnFileSystem(fs, dir)) { LOG.warn("mkdir failed on " + dir); Index: src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestHLogSplit.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestHLogSplit.java (revision 1499339) +++ src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestHLogSplit.java (working copy) @@ -200,7 +200,34 @@ } } + /** + * Test old recovered edits file doesn't break HLogSplitter. + * This is useful in upgrading old instances. + */ @Test + public void testOldRecoveredEditsFileSidelined() throws IOException { + FileSystem fs = FileSystem.get(TEST_UTIL.getConfiguration()); + byte [] encoded = HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes(); + Path tdir = new Path(hbaseDir, Bytes.toString(HConstants.META_TABLE_NAME)); + Path regiondir = new Path(tdir, + HRegionInfo.FIRST_META_REGIONINFO.getEncodedName()); + fs.mkdirs(regiondir); + long now = System.currentTimeMillis(); + HLog.Entry entry = + new HLog.Entry(new HLogKey(encoded, + HConstants.META_TABLE_NAME, 1, now, HConstants.DEFAULT_CLUSTER_ID), + new WALEdit()); + Path parent = HLog.getRegionDirRecoveredEditsDir(regiondir); + assertEquals(parent.getName(), HLog.RECOVERED_EDITS_DIR); + fs.createNewFile(parent); // create a recovered.edits file + + Path p = HLogSplitter.getRegionSplitEditsPath(fs, entry, hbaseDir, true); + String parentOfParent = p.getParent().getParent().getName(); + assertEquals(parentOfParent, HRegionInfo.FIRST_META_REGIONINFO.getEncodedName()); + HLog.createWriter(fs, p, conf).close(); + } + + @Test public void testSplitPreservesEdits() throws IOException{ final String REGION = "region__1"; regions.removeAll(regions);