diff --git a/CHANGES.txt b/CHANGES.txt index 4fa58f8e4d4..e6b71c927ce 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -375,6 +375,8 @@ Release 0.92.0 - Unreleased HBASE-4620 I broke the build when I submitted HBASE-3581 (Send length of the rpc response) HBASE-4621 TestAvroServer fails quite often intermittently (Akash Ashok) + HBASE-4378 [hbck] Does not complain about regions with startkey==endkey. + (Jonathan Hsieh) TESTS HBASE-4450 test for number of blocks read: to serve as baseline for expected diff --git a/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java b/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java index 7409c9c1c1c..9e9e07be383 100644 --- a/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java +++ b/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java @@ -653,6 +653,17 @@ public class HBaseFsck { } } + // check for degenerate ranges + for (HbckInfo rng : ranges) { + // special endkey case converts '' to null + byte[] endKey = rng.getEndKey(); + endKey = (endKey.length == 0) ? null : endKey; + if (Bytes.equals(rng.getStartKey(),endKey)) { + errors.reportError(ERROR_CODE.DEGENERATE_REGION, + "Region has the same start and end key.", this, rng); + } + } + if (ranges.size() == 1) { // this split key is ok -- no overlap, not a hole. if (problemKey != null) { @@ -676,12 +687,12 @@ public class HBaseFsck { subRange.remove(r1); for (HbckInfo r2 : subRange) { if (Bytes.compareTo(r1.getStartKey(), r2.getStartKey())==0) { - // dup start key - errors.reportError(ERROR_CODE.DUPE_STARTKEYS, - "Multiple regions have the same startkey: " - + Bytes.toStringBinary(key), this, r1); - errors.reportError(ERROR_CODE.DUPE_STARTKEYS, - "Multiple regions have the same startkey: " + // dup start key + errors.reportError(ERROR_CODE.DUPE_STARTKEYS, + "Multiple regions have the same startkey: " + + Bytes.toStringBinary(key), this, r1); + errors.reportError(ERROR_CODE.DUPE_STARTKEYS, + "Multiple regions have the same startkey: " + Bytes.toStringBinary(key), this, r2); } else { // overlap @@ -1047,7 +1058,7 @@ public class HBaseFsck { NOT_IN_META_OR_DEPLOYED, NOT_IN_HDFS_OR_DEPLOYED, NOT_IN_HDFS, SERVER_DOES_NOT_MATCH_META, NOT_DEPLOYED, MULTI_DEPLOYED, SHOULD_NOT_BE_DEPLOYED, MULTI_META_REGION, RS_CONNECT_FAILURE, FIRST_REGION_STARTKEY_NOT_EMPTY, DUPE_STARTKEYS, - HOLE_IN_REGION_CHAIN, OVERLAP_IN_REGION_CHAIN, REGION_CYCLE + HOLE_IN_REGION_CHAIN, OVERLAP_IN_REGION_CHAIN, REGION_CYCLE, DEGENERATE_REGION } public void clear(); public void report(String message); diff --git a/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java b/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java index f5be448735f..ca6dd4bc72b 100644 --- a/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java +++ b/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java @@ -278,6 +278,32 @@ public class TestHBaseFsck { deleteTable(table); } } + + /** + * This creates a bad table with regions that has startkey == endkey + */ + @Test + public void testDegenerateRegions() throws Exception { + String table = "tableDegenerateRegions"; + try { + setupTable(table); + assertNoErrors(doFsck(false)); + + // Now let's mess it up, by adding a region with a duplicate startkey + HRegionInfo hriDupe = createRegion(conf, tbl.getTableDescriptor(), + Bytes.toBytes("B"), Bytes.toBytes("B")); + TEST_UTIL.getHBaseCluster().getMaster().assignRegion(hriDupe); + TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager() + .waitForAssignment(hriDupe); + + HBaseFsck hbck = doFsck(false); + assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.DEGENERATE_REGION, + ERROR_CODE.DUPE_STARTKEYS, ERROR_CODE.DUPE_STARTKEYS}); + assertEquals(2, hbck.getOverlapGroups(table).size()); + } finally { + deleteTable(table); + } + } /** * This creates a bad table where a start key contained in another region.