Skip to content

Commit 0c80d5b

Browse files
committed
HBASE-22723 Have CatalogJanitor report holes and overlaps; i.e. problems it sees when doing its regular scan of hbase:meta
Refactor of CatalogJanitor so it generates a Report on the state of hbase:meta when it runs. Also refactor so CJ runs even if RIT (previous it would punt on running if RIT) so it can generate a 'Report' on the interval regardless. If RIT, it just doesn't go on to do the merge/split GC as it used to. If report finds an issue, dump as a WARN message to the master log. Follow-on is to make the Report actionable/available for the Master to pull when it goes to draw the hbck UI page (could also consider shipping the Report as part of ClusterMetrics?) Adds new, fatter Visitor to CJ, one that generates Report on each run keeping around more findings as it runs. Moved some methods around so class reads better; previous methods were randomly ordered in the class. M hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java Make a few handy methods public. M hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java Add utility as defaults on the Inteface; i.e. is this the first region in table, is it last, does a passed region come next, or does passed region overlap this region (added tests for this new stuff). M hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java Bugfix... handle case where buffer passed is null. M hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java Lots of change, reorg., but mostly adding consistency checking to the visitor used scanning hbase:meta on a period and the generation of a Report on what the scan has found traversing hbase:meta. Added a main so could try the CatalogJanitor against a running cluster. A hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitorCluster.java Fat ugly test for CatalogJanitor consistency checking. M hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionInfo.java Add tests for new functionality in RI. M hbase-shell/src/main/ruby/hbase/table.rb Bug fix for case where meta has a null regioninfo; scan was aborting. Signed-off-by: Andrew Purtell <[email protected]> Signed-off-by: Wellington Chevreuil <[email protected]>
1 parent f68cda3 commit 0c80d5b

File tree

9 files changed

+751
-178
lines changed

9 files changed

+751
-178
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ private static RegionInfo getClosestRegionInfo(Connection connection,
810810
* Returns the column family used for meta columns.
811811
* @return HConstants.CATALOG_FAMILY.
812812
*/
813-
private static byte[] getCatalogFamily() {
813+
public static byte[] getCatalogFamily() {
814814
return HConstants.CATALOG_FAMILY;
815815
}
816816

@@ -826,7 +826,7 @@ private static byte[] getTableFamily() {
826826
* Returns the column qualifier for serialized region info
827827
* @return HConstants.REGIONINFO_QUALIFIER
828828
*/
829-
private static byte[] getRegionInfoColumn() {
829+
public static byte[] getRegionInfoColumn() {
830830
return HConstants.REGIONINFO_QUALIFIER;
831831
}
832832

@@ -1049,7 +1049,7 @@ public static RegionInfo getRegionInfo(Result data) {
10491049
* @return An RegionInfo instance or null.
10501050
*/
10511051
@Nullable
1052-
private static RegionInfo getRegionInfo(final Result r, byte [] qualifier) {
1052+
public static RegionInfo getRegionInfo(final Result r, byte [] qualifier) {
10531053
Cell cell = r.getColumnLatestCell(getCatalogFamily(), qualifier);
10541054
if (cell == null) return null;
10551055
return RegionInfo.parseFromOrNull(cell.getValueArray(),

hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
*/
7171
@InterfaceAudience.Public
7272
public interface RegionInfo {
73+
public static final RegionInfo UNDEFINED =
74+
RegionInfoBuilder.newBuilder(TableName.valueOf("__UNDEFINED__")).build();
7375
/**
7476
* Separator used to demarcate the encodedName in a region name
7577
* in the new format. See description on new format above.
@@ -775,4 +777,55 @@ static List<RegionInfo> parseDelimitedFrom(final byte[] bytes, final int offset,
775777
}
776778
return ris;
777779
}
780+
781+
782+
/**
783+
* @return True if this is first Region in Table
784+
*/
785+
default boolean isFirst() {
786+
return Bytes.equals(getStartKey(), HConstants.EMPTY_START_ROW);
787+
}
788+
789+
/**
790+
* @return True if this is last Region in Table
791+
*/
792+
default boolean isLast() {
793+
return Bytes.equals(getEndKey(), HConstants.EMPTY_START_ROW);
794+
}
795+
796+
/**
797+
* @return True if regions are adjacent, if 'after' next. Does not do tablename compare.
798+
*/
799+
default boolean isNext(RegionInfo after) {
800+
return Bytes.equals(getEndKey(), after.getStartKey());
801+
}
802+
803+
/**
804+
* @return True if RegionInfo is degenerate... if startKey > endKey.
805+
*/
806+
default boolean isDegenerate() {
807+
return !isLast() && Bytes.compareTo(getStartKey(), getEndKey()) > 0;
808+
}
809+
810+
/**
811+
* @return True if an overlap in region range. Does not do tablename compare.
812+
* Does not check if <code>other</code> has degenerate range.
813+
* @see #isDegenerate()
814+
*/
815+
default boolean isOverlap(RegionInfo other) {
816+
int startKeyCompare = Bytes.compareTo(getStartKey(), other.getStartKey());
817+
if (startKeyCompare == 0) {
818+
return true;
819+
}
820+
if (startKeyCompare < 0) {
821+
if (isLast()) {
822+
return true;
823+
}
824+
return Bytes.compareTo(getEndKey(), other.getStartKey()) > 0;
825+
}
826+
if (other.isLast()) {
827+
return true;
828+
}
829+
return Bytes.compareTo(getStartKey(), other.getEndKey()) < 0;
830+
}
778831
}

hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ public static long readAsVLong(final byte [] buffer, final int offset) {
13591359
*/
13601360
public static int compareTo(final byte [] left, final byte [] right) {
13611361
return LexicographicalComparerHolder.BEST_COMPARER.
1362-
compareTo(left, 0, left.length, right, 0, right.length);
1362+
compareTo(left, 0, left == null? 0: left.length, right, 0, right == null? 0: right.length);
13631363
}
13641364

13651365
/**

0 commit comments

Comments
 (0)