Skip to content

Commit 2052058

Browse files
saintstackinfraio
authored andcommitted
HBASE-22741 Show catalogjanitor consistency complaints in new 'HBCK Report' page
Signed-off-by: huzheng <openinx@gmail.com> Signed-off-by: Guanghao Zhang <zghao@apache.org>
1 parent 69baeb2 commit 2052058

3 files changed

Lines changed: 210 additions & 48 deletions

File tree

hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@
2222
import java.io.InputStream;
2323
import java.util.ArrayList;
2424
import java.util.Comparator;
25-
import java.util.HashMap;
2625
import java.util.HashSet;
2726
import java.util.List;
2827
import java.util.Map;
2928
import java.util.Properties;
3029
import java.util.TreeMap;
3130
import java.util.concurrent.atomic.AtomicBoolean;
3231

32+
import org.apache.hadoop.conf.Configuration;
3333
import org.apache.hadoop.fs.FileSystem;
3434
import org.apache.hadoop.fs.Path;
3535
import org.apache.hadoop.hbase.HBaseConfiguration;
@@ -43,8 +43,11 @@
4343
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
4444
import org.apache.hadoop.hbase.client.Connection;
4545
import org.apache.hadoop.hbase.client.ConnectionFactory;
46+
import org.apache.hadoop.hbase.client.Get;
47+
import org.apache.hadoop.hbase.client.Put;
4648
import org.apache.hadoop.hbase.client.RegionInfo;
4749
import org.apache.hadoop.hbase.client.Result;
50+
import org.apache.hadoop.hbase.client.Table;
4851
import org.apache.hadoop.hbase.client.TableDescriptor;
4952
import org.apache.hadoop.hbase.client.TableState;
5053
import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
@@ -240,7 +243,7 @@ Report scanForReport() throws IOException {
240243
* @return Returns last published Report that comes of last successful scan
241244
* of hbase:meta.
242245
*/
243-
Report getLastReport() {
246+
public Report getLastReport() {
244247
return this.lastReport;
245248
}
246249

@@ -444,29 +447,49 @@ public boolean cleanMergeQualifier(final RegionInfo region) throws IOException {
444447
}
445448

446449
/**
447-
* Report made by {@link ReportMakingVisitor}.
450+
* Report made by ReportMakingVisitor
448451
*/
449-
static class Report {
452+
public static class Report {
450453
private final long now = EnvironmentEdgeManager.currentTime();
451454

452455
// Keep Map of found split parents. These are candidates for cleanup.
453456
// Use a comparator that has split parents come before its daughters.
454457
final Map<RegionInfo, Result> splitParents = new TreeMap<>(new SplitParentFirstComparator());
455458
final Map<RegionInfo, Result> mergedRegions = new TreeMap<>(RegionInfo.COMPARATOR);
456-
457-
final List<Pair<MetaRow, MetaRow>> holes = new ArrayList<>();
458-
final List<Pair<MetaRow, MetaRow>> overlaps = new ArrayList<>();
459-
final Map<ServerName, RegionInfo> unknownServers = new HashMap<ServerName, RegionInfo>();
460-
final List<byte []> emptyRegionInfo = new ArrayList<>();
461459
int count = 0;
462460

461+
private final List<Pair<MetaRow, MetaRow>> holes = new ArrayList<>();
462+
private final List<Pair<MetaRow, MetaRow>> overlaps = new ArrayList<>();
463+
private final List<Pair<MetaRow, ServerName>> unknownServers = new ArrayList<>();
464+
private final List<byte []> emptyRegionInfo = new ArrayList<>();
465+
463466
@VisibleForTesting
464467
Report() {}
465468

469+
public long getCreateTime() {
470+
return this.now;
471+
}
472+
473+
public List<Pair<MetaRow, MetaRow>> getHoles() {
474+
return this.holes;
475+
}
476+
477+
public List<Pair<MetaRow, MetaRow>> getOverlaps() {
478+
return this.overlaps;
479+
}
480+
481+
public List<Pair<MetaRow, ServerName>> getUnknownServers() {
482+
return unknownServers;
483+
}
484+
485+
public List<byte[]> getEmptyRegionInfo() {
486+
return emptyRegionInfo;
487+
}
488+
466489
/**
467490
* @return True if an 'empty' lastReport -- no problems found.
468491
*/
469-
boolean isEmpty() {
492+
public boolean isEmpty() {
470493
return this.holes.isEmpty() && this.overlaps.isEmpty() && this.unknownServers.isEmpty() &&
471494
this.emptyRegionInfo.isEmpty();
472495
}
@@ -478,28 +501,28 @@ public String toString() {
478501
if (sb.length() > 0) {
479502
sb.append(", ");
480503
}
481-
sb.append("hole=" + Bytes.toString(p.getFirst().metaRow) + "/" +
482-
Bytes.toString(p.getSecond().metaRow));
504+
sb.append("hole=" + Bytes.toStringBinary(p.getFirst().metaRow) + "/" +
505+
Bytes.toStringBinary(p.getSecond().metaRow));
483506
}
484507
for (Pair<MetaRow, MetaRow> p: this.overlaps) {
485508
if (sb.length() > 0) {
486509
sb.append(", ");
487510
}
488-
sb.append("overlap=").append(Bytes.toString(p.getFirst().metaRow)).append("/").
489-
append(Bytes.toString(p.getSecond().metaRow));
511+
sb.append("overlap=").append(Bytes.toStringBinary(p.getFirst().metaRow)).append("/").
512+
append(Bytes.toStringBinary(p.getSecond().metaRow));
490513
}
491514
for (byte [] r: this.emptyRegionInfo) {
492515
if (sb.length() > 0) {
493516
sb.append(", ");
494517
}
495-
sb.append("empty=").append(Bytes.toString(r));
518+
sb.append("empty=").append(Bytes.toStringBinary(r));
496519
}
497-
for (Map.Entry<ServerName, RegionInfo> e: this.unknownServers.entrySet()) {
520+
for (Pair<MetaRow, ServerName> p: this.unknownServers) {
498521
if (sb.length() > 0) {
499522
sb.append(", ");
500523
}
501-
sb.append("unknown_server=").append(e.getKey()).append("/").
502-
append(e.getValue().getRegionNameAsString());
524+
sb.append("unknown_server=").append(p.getSecond()).append("/").
525+
append(Bytes.toStringBinary(p.getFirst().metaRow));
503526
}
504527
return sb.toString();
505528
}
@@ -508,7 +531,7 @@ public String toString() {
508531
/**
509532
* Simple datastructure to hold a MetaRow content.
510533
*/
511-
static class MetaRow {
534+
public static class MetaRow {
512535
/**
513536
* A marker for use in case where there is a hole at the very
514537
* first row in hbase:meta. Should never happen.
@@ -519,17 +542,25 @@ static class MetaRow {
519542
/**
520543
* Row from hbase:meta table.
521544
*/
522-
final byte [] metaRow;
545+
private final byte [] metaRow;
523546

524547
/**
525548
* The decoded RegionInfo gotten from hbase:meta.
526549
*/
527-
final RegionInfo regionInfo;
550+
private final RegionInfo regionInfo;
528551

529552
MetaRow(byte [] metaRow, RegionInfo regionInfo) {
530553
this.metaRow = metaRow;
531554
this.regionInfo = regionInfo;
532555
}
556+
557+
public RegionInfo getRegionInfo() {
558+
return regionInfo;
559+
}
560+
561+
public byte[] getMetaRow() {
562+
return metaRow;
563+
}
533564
}
534565

535566
/**
@@ -608,13 +639,14 @@ private RegionInfo metaTableConsistencyCheck(Result metaTableRow) {
608639
MetaTableAccessor.getRegionInfoColumn());
609640
} else {
610641
ri = locations.getDefaultRegionLocation().getRegion();
611-
checkServer(locations);
642+
checkServer(metaTableRow.getRow(), locations);
612643
}
613644

614645
if (ri == null) {
615646
this.report.emptyRegionInfo.add(metaTableRow.getRow());
616647
return ri;
617648
}
649+
618650
MetaRow mrri = new MetaRow(metaTableRow.getRow(), ri);
619651
// If table is disabled, skip integrity check.
620652
if (!isTableDisabled(ri)) {
@@ -673,7 +705,7 @@ boolean isTableDisabled(RegionInfo ri) {
673705
/**
674706
* Run through referenced servers and save off unknown and the dead.
675707
*/
676-
private void checkServer(RegionLocations locations) {
708+
private void checkServer(byte [] metaTableRow, RegionLocations locations) {
677709
if (this.services == null) {
678710
// Can't do this test if no services.
679711
return;
@@ -691,7 +723,8 @@ private void checkServer(RegionLocations locations) {
691723
isServerKnownAndOnline(sn);
692724
switch (state) {
693725
case UNKNOWN:
694-
this.report.unknownServers.put(sn, location.getRegion());
726+
this.report.unknownServers.add(
727+
new Pair(new MetaRow(metaTableRow, location.getRegion()), sn));
695728
break;
696729

697730
default:
@@ -736,20 +769,22 @@ private static void checkLog4jProperties() {
736769
public static void main(String [] args) throws IOException {
737770
checkLog4jProperties();
738771
ReportMakingVisitor visitor = new ReportMakingVisitor(null);
739-
try (Connection connection = ConnectionFactory.createConnection(HBaseConfiguration.create())) {
772+
Configuration configuration = HBaseConfiguration.create();
773+
configuration.setBoolean("hbase.defaults.for.version.skip", true);
774+
try (Connection connection = ConnectionFactory.createConnection(configuration)) {
740775
/* Used to generate an overlap.
741-
Get g = new Get(Bytes.toBytes("t2,40,1563939166317.5a8be963741d27e9649e5c67a34259d9."));
776+
*/
777+
Get g = new Get(Bytes.toBytes("t2,40,1564119846424.1db8c57d64e0733e0f027aaeae7a0bf0."));
742778
g.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
743779
try (Table t = connection.getTable(TableName.META_TABLE_NAME)) {
744780
Result r = t.get(g);
745781
byte [] row = g.getRow();
746-
row[row.length - 3] <<= ((byte)row[row.length -3]);
782+
row[row.length - 2] <<= ((byte)row[row.length - 2]);
747783
Put p = new Put(g.getRow());
748784
p.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
749785
r.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER));
750786
t.put(p);
751787
}
752-
*/
753788
MetaTableAccessor.scanMetaForTableRegions(connection, visitor, null);
754789
Report report = visitor.getReport();
755790
LOG.info(report != null? report.toString(): "empty");

0 commit comments

Comments
 (0)