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:
zjushch 2013-12-19 06:25:20 +00:00
parent 3c24b6a24d
commit ce58832621
3 changed files with 90 additions and 0 deletions

View File

@ -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

View File

@ -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>() {

View File

@ -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();
}