HBASE-10196 Enhance HBCK to understand the case after online region merge
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1552238 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3c24b6a24d
commit
ce58832621
|
@ -1012,6 +1012,20 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
|
|||
|
||||
return new PairOfSameType<HRegionInfo>(splitA, splitB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the merge regions by reading the corresponding columns of the catalog table
|
||||
* Result.
|
||||
* @param data a Result object from the catalog table scan
|
||||
* @return a pair of HRegionInfo or PairOfSameType(null, null) if the region is not a split
|
||||
* parent
|
||||
*/
|
||||
public static PairOfSameType<HRegionInfo> getMergeRegions(Result data) throws IOException {
|
||||
HRegionInfo mergeA = getHRegionInfo(data, HConstants.MERGEA_QUALIFIER);
|
||||
HRegionInfo mergeB = getHRegionInfo(data, HConstants.MERGEB_QUALIFIER);
|
||||
|
||||
return new PairOfSameType<HRegionInfo>(mergeA, mergeB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HRegionInfo object from the column {@link HConstants#CATALOG_FAMILY} and
|
||||
|
|
|
@ -1668,6 +1668,14 @@ public class HBaseFsck extends Configured {
|
|||
}
|
||||
|
||||
} else if (!inMeta && inHdfs && !isDeployed) {
|
||||
if (hbi.isMerged()) {
|
||||
// This region has already been merged, the remaining hdfs file will be
|
||||
// cleaned by CatalogJanitor later
|
||||
hbi.setSkipChecks(true);
|
||||
LOG.info("Region " + descriptiveName
|
||||
+ " got merge recently, its file will be cleaned by CatalogJanitor later");
|
||||
return;
|
||||
}
|
||||
errors.reportError(ERROR_CODE.NOT_IN_META_OR_DEPLOYED, "Region "
|
||||
+ descriptiveName + " on HDFS, but not listed in hbase:meta " +
|
||||
"or deployed on any region server");
|
||||
|
@ -2646,6 +2654,16 @@ public class HBaseFsck extends Configured {
|
|||
} else {
|
||||
throw new IOException("Two entries in hbase:meta are same " + previous);
|
||||
}
|
||||
|
||||
PairOfSameType<HRegionInfo> mergeRegions = HRegionInfo.getMergeRegions(result);
|
||||
for (HRegionInfo mergeRegion : new HRegionInfo[] {
|
||||
mergeRegions.getFirst(), mergeRegions.getSecond() }) {
|
||||
if (mergeRegion != null) {
|
||||
// This region is already been merged
|
||||
HbckInfo hbInfo = getOrCreateInfo(mergeRegion.getEncodedName());
|
||||
hbInfo.setMerged(true);
|
||||
}
|
||||
}
|
||||
|
||||
// show proof of progress to the user, once for every 100 records.
|
||||
if (countRecord % 100 == 0) {
|
||||
|
@ -2753,6 +2771,7 @@ public class HBaseFsck extends Configured {
|
|||
private List<OnlineEntry> deployedEntries = Lists.newArrayList(); // on Region Server
|
||||
private List<ServerName> deployedOn = Lists.newArrayList(); // info on RS's
|
||||
private boolean skipChecks = false; // whether to skip further checks to this region info.
|
||||
private boolean isMerged = false;// whether this region has already been merged into another one
|
||||
|
||||
HbckInfo(MetaEntry metaEntry) {
|
||||
this.metaEntry = metaEntry;
|
||||
|
@ -2879,6 +2898,14 @@ public class HBaseFsck extends Configured {
|
|||
public boolean isSkipChecks() {
|
||||
return skipChecks;
|
||||
}
|
||||
|
||||
public void setMerged(boolean isMerged) {
|
||||
this.isMerged = isMerged;
|
||||
}
|
||||
|
||||
public boolean isMerged() {
|
||||
return this.isMerged;
|
||||
}
|
||||
}
|
||||
|
||||
final static Comparator<HbckInfo> cmp = new Comparator<HbckInfo>() {
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.assertNoErrors;
|
|||
import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.doFsck;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -2177,6 +2178,54 @@ public class TestHBaseFsck {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHbckAfterRegionMerge() throws Exception {
|
||||
TableName table = TableName.valueOf("testMergeRegionFilesInHdfs");
|
||||
HTable meta = null;
|
||||
try {
|
||||
// disable CatalogJanitor
|
||||
TEST_UTIL.getHBaseCluster().getMaster().setCatalogJanitorEnabled(false);
|
||||
setupTable(table);
|
||||
assertEquals(ROWKEYS.length, countRows());
|
||||
|
||||
// make sure data in regions, if in hlog only there is no data loss
|
||||
TEST_UTIL.getHBaseAdmin().flush(table.getName());
|
||||
HRegionInfo region1 = tbl.getRegionLocation("A").getRegionInfo();
|
||||
HRegionInfo region2 = tbl.getRegionLocation("B").getRegionInfo();
|
||||
|
||||
int regionCountBeforeMerge = tbl.getRegionLocations().size();
|
||||
|
||||
assertNotEquals(region1, region2);
|
||||
|
||||
// do a region merge
|
||||
HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
|
||||
admin.mergeRegions(region1.getEncodedNameAsBytes(),
|
||||
region2.getEncodedNameAsBytes(), false);
|
||||
|
||||
// wait until region merged
|
||||
long timeout = System.currentTimeMillis() + 30 * 1000;
|
||||
while (true) {
|
||||
if (tbl.getRegionLocations().size() < regionCountBeforeMerge) {
|
||||
break;
|
||||
} else if (System.currentTimeMillis() > timeout) {
|
||||
fail("Time out waiting on region " + region1.getEncodedName()
|
||||
+ " and " + region2.getEncodedName() + " be merged");
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
|
||||
assertEquals(ROWKEYS.length, countRows());
|
||||
|
||||
HBaseFsck hbck = doFsck(conf, false);
|
||||
assertNoErrors(hbck); // no errors
|
||||
|
||||
} finally {
|
||||
TEST_UTIL.getHBaseCluster().getMaster().setCatalogJanitorEnabled(true);
|
||||
deleteTable(table);
|
||||
IOUtils.closeQuietly(meta);
|
||||
}
|
||||
}
|
||||
|
||||
@org.junit.Rule
|
||||
public TestName name = new TestName();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue