From 6a9f0b13841d1192125a6f6d67a63d01f7738bc9 Mon Sep 17 00:00:00 2001 From: chenheng Date: Wed, 18 Nov 2015 12:14:19 +0800 Subject: [PATCH] HBASE-14820 --- .../TestSplitTransactionOnCluster.java | 109 ++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java index af3e541..b84e818 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -40,6 +41,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.Abortable; import org.apache.hadoop.hbase.Coprocessor; import org.apache.hadoop.hbase.CoprocessorEnvironment; +import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.HBaseIOException; import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HColumnDescriptor; @@ -53,6 +55,7 @@ import org.apache.hadoop.hbase.Server; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.UnknownRegionException; +import org.apache.hadoop.hbase.NotServingRegionException; import org.apache.hadoop.hbase.Waiter; import org.apache.hadoop.hbase.ZooKeeperConnectionException; import org.apache.hadoop.hbase.catalog.MetaEditor; @@ -76,7 +79,6 @@ import org.apache.hadoop.hbase.master.RegionState; import org.apache.hadoop.hbase.master.RegionState.State; import org.apache.hadoop.hbase.master.RegionStates; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; -import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; @@ -316,6 +318,111 @@ public class TestSplitTransactionOnCluster { } } + + @Test(timeout = 60000) + public void testHBase14820() throws Exception { + final TableName tableName = + TableName.valueOf("testHBase14820"); + try { + // Create table then get the single region for our new table. + HTable t = createTableAndWait(tableName.getName(), Bytes.toBytes("cf")); + final List regions = cluster.getRegions(tableName); + final HRegionInfo hri = getAndCheckSingleTableRegion(regions); + insertData(tableName.getName(), admin, t); + t.close(); + + // Turn off balancer so it doesn't cut in and mess up our placements. + this.admin.setBalancerRunning(false, true); + // Turn off the meta scanner so it don't remove parent on us. + cluster.getMaster().setCatalogJanitorEnabled(false); + + // find a splittable region + final HRegion region = findSplittableRegion(regions); + assertTrue("not able to find a splittable region", region != null); + int rowNumber = countRows(region); + // install region co-processor to fail splits + region.getCoprocessorHost().load(WaitSplitRegionObserver.class, + Coprocessor.PRIORITY_USER, region.getBaseConf()); + + HRegionServer regionServer = null; + for (RegionServerThread rsThread : cluster.getRegionServerThreads()) { + HRegion hRegion = rsThread.getRegionServer().getOnlineRegion(region.getRegionName()); + if (hRegion != null) { + regionServer = rsThread.getRegionServer(); + } + } + regionServer.getConfiguration().setLong("hbase.regionserver.fileSplitTimeout", 1); + + // split async + this.admin.split(region.getRegionName(), new byte[] {42}); + + + // we have to wait until split complete. + WaitSplitRegionObserver observer = (WaitSplitRegionObserver) region + .getCoprocessorHost().findCoprocessor(WaitSplitRegionObserver.class.getName()); + assertNotNull(observer); + observer.postSplit.await(); + + int result = countRows(region); + assertEquals(rowNumber, result); + + regionServer.getConfiguration().setLong("hbase.regionserver.fileSplitTimeout", 30000); + // split async + observer.reset(); + this.admin.split(region.getRegionName(), new byte[] {42}); + // we have to wait until split complete. + + observer.postSplit.await(); + try { + countRows(region); + fail("region has been splitted, it should be failed!"); + } catch (NotServingRegionException e) { + + } + } finally { + admin.setBalancerRunning(true, false); + cluster.getMaster().setCatalogJanitorEnabled(true); + TESTING_UTIL.deleteTable(tableName); + } + } + + private int countRows(final HRegion r) throws IOException { + int rowcount = 0; + InternalScanner scanner = r.getScanner(new Scan()); + try { + List kvs = new ArrayList(); + boolean hasNext = true; + while (hasNext) { + hasNext = scanner.next(kvs); + if (!kvs.isEmpty()) rowcount++; + } + } finally { + scanner.close(); + } + return rowcount; + } + + public static class WaitSplitRegionObserver extends BaseRegionObserver { + volatile CountDownLatch postSplit; + @Override + public void start(CoprocessorEnvironment e) throws IOException { + reset(); + } + + public void reset() { + postSplit = new CountDownLatch(1); + } + + @Override + public void postCompleteSplit(ObserverContext ctx) + throws IOException { + postSplit.countDown(); + LOG.info("postCompleteSplit called"); + } + } + + + public static class FailingSplitRegionObserver extends BaseRegionObserver { volatile CountDownLatch latch; volatile CountDownLatch postSplit; -- 1.9.3 (Apple Git-50)