From 9cfae9f15fa698dc3a1ad9d1a9b0f24387411813 Mon Sep 17 00:00:00 2001 From: Zhihong Yu Date: Sat, 23 Jun 2012 04:25:58 +0000 Subject: [PATCH] HBASE-6236 Offline meta repair fails if the HBase base mount point is on a different cluster/volume than its parent in a ViewFS or sim ilar FS (Aditya) git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1353065 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/hadoop/hbase/HConstants.java | 6 ++- .../apache/hadoop/hbase/util/HBaseFsck.java | 41 ++++++++++++++----- .../hbase/util/hbck/OfflineMetaRepair.java | 28 +++++++++---- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java index eb1ac795809..9dac3884c0b 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -229,6 +229,9 @@ public final class HConstants { /** Like the previous, but for old logs that are about to be deleted */ public static final String HREGION_OLDLOGDIR_NAME = ".oldlogs"; + /** Used by HBCK to sideline backup data */ + public static final String HBCK_SIDELINEDIR_NAME = ".hbck"; + /** Used to construct the name of the compaction directory during compaction */ public static final String HREGION_COMPACTIONDIR_NAME = "compaction.dir"; @@ -594,7 +597,8 @@ public final class HConstants { public static final List HBASE_NON_USER_TABLE_DIRS = new ArrayList( Arrays.asList(new String[]{ HREGION_LOGDIR_NAME, HREGION_OLDLOGDIR_NAME, CORRUPT_DIR_NAME, Bytes.toString(META_TABLE_NAME), - Bytes.toString(ROOT_TABLE_NAME), SPLIT_LOGDIR_NAME })); + Bytes.toString(ROOT_TABLE_NAME), SPLIT_LOGDIR_NAME, + HBCK_SIDELINEDIR_NAME })); public static final Pattern CP_HTD_ATTR_KEY_PATTERN = Pattern.compile ("^coprocessor\\$([0-9]+)$", Pattern.CASE_INSENSITIVE); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java index fe916c20d9b..640a3127ead 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java @@ -181,6 +181,7 @@ public class HBaseFsck { private int maxMerge = DEFAULT_MAX_MERGE; // maximum number of overlapping regions to merge private int maxOverlapsToSideline = DEFAULT_OVERLAPS_TO_SIDELINE; // maximum number of overlapping regions to sideline private boolean sidelineBigOverlaps = false; // sideline overlaps with >maxMerge regions + private Path sidelineDir = null; private boolean rerun = false; // if we tried to fix something, rerun hbck private static boolean summary = false; // if we want to print less output @@ -817,7 +818,7 @@ public class HBaseFsck { // we can rebuild, move old root and meta out of the way and start LOG.info("HDFS regioninfo's seems good. Sidelining old .META."); - sidelineOldRootAndMeta(); + Path backupDir = sidelineOldRootAndMeta(); LOG.info("Creating new .META."); HRegion meta = createNewRootAndMeta(); @@ -832,6 +833,7 @@ public class HBaseFsck { meta.put(puts.toArray(new Put[0])); HRegion.closeHRegion(meta); LOG.info("Success! .META. table rebuilt."); + LOG.info("Old -ROOT- and .META. are moved into " + backupDir); return true; } @@ -855,11 +857,13 @@ public class HBaseFsck { } private Path getSidelineDir() throws IOException { - Path hbaseDir = FSUtils.getRootDir(conf); - Path hbckDir = new Path(hbaseDir.getParent(), "hbck"); - Path backupDir = new Path(hbckDir, hbaseDir.getName() + "-" - + startMillis); - return backupDir; + if (sidelineDir == null) { + Path hbaseDir = FSUtils.getRootDir(conf); + Path hbckDir = new Path(hbaseDir, HConstants.HBCK_SIDELINEDIR_NAME); + sidelineDir = new Path(hbckDir, hbaseDir.getName() + "-" + + startMillis); + } + return sidelineDir; } /** @@ -957,8 +961,7 @@ public class HBaseFsck { // put current -ROOT- and .META. aside. Path hbaseDir = new Path(conf.get(HConstants.HBASE_DIR)); FileSystem fs = hbaseDir.getFileSystem(conf); - Path backupDir = new Path(hbaseDir.getParent(), hbaseDir.getName() + "-" - + startMillis); + Path backupDir = getSidelineDir(); fs.mkdirs(backupDir); sidelineTable(fs, HConstants.ROOT_TABLE_NAME, hbaseDir, backupDir); @@ -2986,18 +2989,27 @@ public class HBaseFsck { timelag = seconds * 1000; // convert to milliseconds } + /** + * + * @param sidelineDir - HDFS path to sideline data + */ + public void setSidelineDir(String sidelineDir) { + this.sidelineDir = new Path(sidelineDir); + } + protected static void printUsageAndExit() { System.err.println("Usage: fsck [opts] {only tables}"); System.err.println(" where [opts] are:"); System.err.println(" -help Display help options (this)"); System.err.println(" -details Display full report of all regions."); - System.err.println(" -timelag {timeInSeconds} Process only regions that " + + System.err.println(" -timelag Process only regions that " + " have not experienced any metadata updates in the last " + - " {{timeInSeconds} seconds."); - System.err.println(" -sleepBeforeRerun {timeInSeconds} Sleep this many seconds" + + " seconds."); + System.err.println(" -sleepBeforeRerun Sleep this many seconds" + " before checking if the fix worked if run with -fix"); System.err.println(" -summary Print only summary of the tables and status."); System.err.println(" -metaonly Only check the state of ROOT and META tables."); + System.err.println(" -sidelineDir HDFS path to backup existing meta and root."); System.err.println(" Repair options: (expert features, use with caution!)"); System.err.println(" -fix Try to fix region assignments. This is for backwards compatiblity"); @@ -3067,6 +3079,13 @@ public class HBaseFsck { printUsageAndExit(); } i++; + } else if (cmd.equals("-sidelineDir")) { + if (i == args.length - 1) { + System.err.println("HBaseFsck: -sidelineDir needs a value."); + printUsageAndExit(); + } + i++; + fsck.setSidelineDir(args[i]); } else if (cmd.equals("-fix")) { System.err.println("This option is deprecated, please use " + "-fixAssignments instead."); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/hbck/OfflineMetaRepair.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/hbck/OfflineMetaRepair.java index 8dc72f3ae2b..ae2c9f75fbf 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/hbck/OfflineMetaRepair.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/hbck/OfflineMetaRepair.java @@ -46,13 +46,15 @@ public class OfflineMetaRepair { private static final Log LOG = LogFactory.getLog(HBaseFsck.class.getName()); protected static void printUsageAndExit() { - System.err.println("Usage: OfflineMetaRepair [opts] "); - System.err.println(" where [opts] are:"); - System.err - .println(" -details Display full report of all regions."); - System.err.println(" -base Base Hbase Data directory"); - System.err.println(" -fix Auto fix as many problems as possible"); - System.err.println(" -fixHoles Auto fix as region holes"); + StringBuilder sb = new StringBuilder(); + sb.append("Usage: OfflineMetaRepair [opts]\n"). + append(" where [opts] are:\n"). + append(" -details Display full report of all regions.\n"). + append(" -base Base Hbase Data directory.\n"). + append(" -sidelineDir HDFS path to backup existing meta and root.\n"). + append(" -fix Auto fix as many problems as possible.\n"). + append(" -fixHoles Auto fix as region holes."); + System.err.println(sb.toString()); Runtime.getRuntime().exit(-2); } @@ -79,12 +81,24 @@ public class OfflineMetaRepair { if (cmd.equals("-details")) { fsck.setDisplayFullReport(); } else if (cmd.equals("-base")) { + if (i == args.length - 1) { + System.err.println("OfflineMetaRepair: -base needs an HDFS path."); + printUsageAndExit(); + } // update hbase root dir to user-specified base i++; String path = args[i]; conf.set(HConstants.HBASE_DIR, path); conf.set("fs.defaultFS", conf.get(HConstants.HBASE_DIR)); conf.set("fs.default.name", conf.get(HConstants.HBASE_DIR)); + } else if (cmd.equals("-sidelineDir")) { + if (i == args.length - 1) { + System.err.println("OfflineMetaRepair: -sidelineDir needs an HDFS path."); + printUsageAndExit(); + } + // set the hbck sideline dir to user-specified one + i++; + fsck.setSidelineDir(args[i]); } else if (cmd.equals("-fixHoles")) { fixHoles = true; } else if (cmd.equals("-fix")) {