diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java index 7cc31d0..1c3f01e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -57,12 +58,14 @@ import org.apache.hadoop.hbase.Tag; import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; import org.apache.hadoop.hbase.io.hfile.HFile.FileInfo; +import org.apache.hadoop.hbase.mob.MobUtils; import org.apache.hadoop.hbase.regionserver.TimeRangeTracker; import org.apache.hadoop.hbase.util.BloomFilter; import org.apache.hadoop.hbase.util.BloomFilterUtil; import org.apache.hadoop.hbase.util.BloomFilterFactory; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.FSUtils; +import org.apache.hadoop.hbase.util.HFileArchiveUtil; import org.apache.hadoop.hbase.util.Writables; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; @@ -95,6 +98,8 @@ private boolean checkRow; private boolean checkFamily; private boolean isSeekToRow = false; + private boolean checkMob = false; + private Map> mobFileLocations; /** * The row which the user wants to specify and print all the KeyValues for. @@ -130,6 +135,7 @@ private void init() { options.addOption("w", "seekToRow", true, "Seek to this row and print all the kvs for this row only"); options.addOption("s", "stats", false, "Print statistics"); + options.addOption("i", "checkMob", false, "Print all cells whose mob files are missing"); OptionGroup files = new OptionGroup(); files.addOption(new Option("f", "file", true, @@ -158,6 +164,7 @@ public boolean parseOptions(String args[]) throws ParseException, printStats = cmd.hasOption("s"); checkRow = cmd.hasOption("k"); checkFamily = cmd.hasOption("a"); + checkMob = cmd.hasOption("i"); if (cmd.hasOption("f")) { files.add(new Path(cmd.getOptionValue("f"))); @@ -199,6 +206,12 @@ public boolean parseOptions(String args[]) throws ParseException, files.addAll(regionFiles); } + if(checkMob) { + if (verbose) { + System.out.println("checkMob is enabled"); + } + mobFileLocations = new HashMap>(); + } return true; } @@ -255,7 +268,7 @@ private void processFile(Path file) throws IOException { KeyValueStatsCollector fileStats = null; - if (verbose || printKey || checkRow || checkFamily || printStats) { + if (verbose || printKey || checkRow || checkFamily || printStats || checkMob) { // scan over file and read key/value's and check if requested HFileScanner scanner = reader.getScanner(false, false, false); fileStats = new KeyValueStatsCollector(); @@ -313,6 +326,7 @@ private void processFile(Path file) throws IOException { private void scanKeysValues(Path file, KeyValueStatsCollector fileStats, HFileScanner scanner, byte[] row) throws IOException { Cell pCell = null; + FileSystem fs = FileSystem.get(getConf()); do { Cell cell = scanner.getKeyValue(); if (row != null && row.length != 0) { @@ -369,6 +383,39 @@ private void scanKeysValues(Path file, KeyValueStatsCollector fileStats, + "\n\tcurrent -> " + CellUtil.getCellKeyAsString(cell)); } } + // check if mob files are missing. + if (checkMob && MobUtils.isMobReferenceCell(cell)) { + Tag tnTag = MobUtils.getTableNameTag(cell); + if (tnTag != null) { + TableName tn = TableName.valueOf(tnTag.getValue()); + List locations = mobFileLocations.get(tn.getNameAsString()); + if (locations == null) { + locations = new ArrayList(); + String family = Bytes.toString(CellUtil.cloneFamily(cell)); + locations.add(MobUtils.getMobFamilyPath(getConf(), tn, family)); + locations.add(HFileArchiveUtil.getStoreArchivePath(getConf(), tn, MobUtils + .getMobRegionInfo(tn).getEncodedName(), family)); + mobFileLocations.put(tn.getNameAsString(), locations); + } + String mobFileName = MobUtils.getMobFileName(cell); + boolean exist = false; + for (Path location : locations) { + Path mobFilePath = new Path(location, mobFileName); + if (fs.exists(mobFilePath)) { + exist = true; + break; + } + } + if (!exist) { + // report error + System.err.println("ERROR, the mob file [" + mobFileName + + "] is missing referenced by cell " + CellUtil.getCellKeyAsString(cell)); + } + } else { + System.err.println("ERROR, wrong mob reference cell format " + + CellUtil.getCellKeyAsString(cell)); + } + } pCell = cell; ++count; } while (scanner.next());