commit 75f340a9326e821d2a748d3f4a85b33ade465554 Author: liyintang Date: 67 minutes ago [jira] [HBASE-4698] Let the HFile Pretty Printer print all the key values for a specific row. Summary: HBase-4698 Let the HFile Pretty Printer print all the key values for a specific row. When using HFile Pretty Printer to debug HBase issues, it would very nice to allow the Pretty Printer to seek to a specific row, and only print all the key values for this row. Test Plan: tested this feature on dev cluster and running all the unit tests. Reviewers: mbautin, Kannan, jgray, gqchen, nspiegelberg, JIRA Reviewed By: mbautin CC: HBase Diffs Facebook Group, mbautin, Liyin, nspiegelberg Differential Revision: 111 diff --git a/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java b/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java index 85f9096..faca02d 100644 --- a/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java +++ b/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java @@ -26,15 +26,14 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; @@ -67,7 +66,12 @@ public class HFilePrettyPrinter { private boolean printStats; private boolean checkRow; private boolean checkFamily; + private boolean isSeekToRow = false; + /** + * The row which the user wants to specify and print all the KeyValues for. + */ + private byte[] row = null; private Configuration conf; private List files = new ArrayList(); @@ -87,6 +91,8 @@ public class HFilePrettyPrinter { options.addOption("a", "checkfamily", false, "Enable family check"); options.addOption("f", "file", true, "File to scan. Pass full-path; e.g. hdfs://a:9000/hbase/.META./12/34"); + options.addOption("w", "seekToRow", true, + "Seek to this row and print all the kvs for this row only"); options.addOption("r", "region", true, "Region to scan. Pass region name; e.g. '.META.,,1'"); options.addOption("s", "stats", false, "Print statistics"); @@ -115,6 +121,17 @@ public class HFilePrettyPrinter { files.add(new Path(cmd.getOptionValue("f"))); } + if (cmd.hasOption("w")) { + String key = cmd.getOptionValue("w"); + if (key != null && key.length() != 0) { + row = key.getBytes(); + isSeekToRow = true; + } else { + System.err.println("Invalid row is specified."); + System.exit(-1); + } + } + if (cmd.hasOption("r")) { String regionName = cmd.getOptionValue("r"); byte[] rn = Bytes.toBytes(regionName); @@ -198,8 +215,16 @@ public class HFilePrettyPrinter { // scan over file and read key/value's and check if requested HFileScanner scanner = reader.getScanner(false, false, false); fileStats = new KeyValueStatsCollector(); - if (scanner.seekTo()) - scanKeysValues(file, fileStats, scanner); + boolean shouldScanKeysValues = false; + if (this.isSeekToRow) { + // seek to the first kv on this row + shouldScanKeysValues = + (scanner.seekTo(KeyValue.createFirstOnRow(this.row).getKey()) != -1); + } else { + shouldScanKeysValues = scanner.seekTo(); + } + if (shouldScanKeysValues) + scanKeysValues(file, fileStats, scanner, row); } // print meta data @@ -220,11 +245,19 @@ public class HFilePrettyPrinter { reader.close(); } - private void scanKeysValues(Path file, KeyValueStatsCollector fileStats, HFileScanner scanner) - throws IOException { + private void scanKeysValues(Path file, KeyValueStatsCollector fileStats, + HFileScanner scanner, byte[] row) throws IOException { KeyValue pkv = null; do { KeyValue kv = scanner.getKeyValue(); + if (row != null && row.length != 0) { + int result = Bytes.compareTo(kv.getRow(), row); + if (result > 0) { + break; + } else if (result < 0) { + continue; + } + } // collect stats if (printStats) { fileStats.collect(kv);