@Test public void testWholesomeSplit() throws IOException { final int rowcount = TEST_UTIL.loadRegion(this.parent, CF, true); assertTrue(rowcount > 0); int parentRowCount = TEST_UTIL.countRows(this.parent); assertEquals(rowcount, parentRowCount); // Pretend region's blocks are not in the cache, used for // testWholesomeSplitWithHFileV1 CacheConfig cacheConf = new CacheConfig(TEST_UTIL.getConfiguration()); ((LruBlockCache) cacheConf.getBlockCache()).clearCache(); // Start transaction. SplitTransactionImpl st = prepareGOOD_SPLIT_ROW(); // Run the execute. Look at what it returns. Server mockServer = Mockito.mock(Server.class); when(mockServer.getConfiguration()).thenReturn(TEST_UTIL.getConfiguration()); PairOfSameType<Region> daughters = st.execute(mockServer, null); // Do some assertions about execution. assertTrue(this.fs.exists(this.parent.getRegionFileSystem().getSplitsDir())); // Assert the parent region is closed. assertTrue(this.parent.isClosed()); // Assert splitdir is empty -- because its content will have been moved out // to be under the daughter region dirs. assertEquals(0, this.fs.listStatus(this.parent.getRegionFileSystem().getSplitsDir()).length); // Check daughters have correct key span. assertTrue( Bytes.equals( parent.getRegionInfo().getStartKey(), daughters.getFirst().getRegionInfo().getStartKey())); assertTrue(Bytes.equals(GOOD_SPLIT_ROW, daughters.getFirst().getRegionInfo().getEndKey())); assertTrue(Bytes.equals(daughters.getSecond().getRegionInfo().getStartKey(), GOOD_SPLIT_ROW)); assertTrue( Bytes.equals( parent.getRegionInfo().getEndKey(), daughters.getSecond().getRegionInfo().getEndKey())); // Count rows. daughters are already open int daughtersRowCount = 0; for (Region openRegion : daughters) { try { int count = TEST_UTIL.countRows(openRegion); assertTrue(count > 0 && count != rowcount); daughtersRowCount += count; } finally { HBaseTestingUtility.closeRegionAndWAL(openRegion); } } assertEquals(rowcount, daughtersRowCount); // Assert the write lock is no longer held on parent assertTrue(!this.parent.lock.writeLock().isHeldByCurrentThread()); }
@Test public void testMergeWithReplicas() throws Exception { final TableName tableName = TableName.valueOf("testMergeWithReplicas"); // Create table and load data. createTableAndLoadData(master, tableName, 5, 2); List<Pair<HRegionInfo, ServerName>> initialRegionToServers = MetaTableAccessor.getTableRegionsAndLocations(master.getConnection(), tableName); // Merge 1st and 2nd region PairOfSameType<HRegionInfo> mergedRegions = mergeRegionsAndVerifyRegionNum(master, tableName, 0, 2, 5 * 2 - 2); List<Pair<HRegionInfo, ServerName>> currentRegionToServers = MetaTableAccessor.getTableRegionsAndLocations(master.getConnection(), tableName); List<HRegionInfo> initialRegions = new ArrayList<HRegionInfo>(); for (Pair<HRegionInfo, ServerName> p : initialRegionToServers) { initialRegions.add(p.getFirst()); } List<HRegionInfo> currentRegions = new ArrayList<HRegionInfo>(); for (Pair<HRegionInfo, ServerName> p : currentRegionToServers) { currentRegions.add(p.getFirst()); } assertTrue(initialRegions.contains(mergedRegions.getFirst())); // this is the first region assertTrue( initialRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( mergedRegions.getFirst(), 1))); // this is the replica of the first region assertTrue(initialRegions.contains(mergedRegions.getSecond())); // this is the second region assertTrue( initialRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( mergedRegions.getSecond(), 1))); // this is the replica of the second region assertTrue(!initialRegions.contains(currentRegions.get(0))); // this is the new region assertTrue( !initialRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( currentRegions.get(0), 1))); // replica of the new region assertTrue( currentRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( currentRegions.get(0), 1))); // replica of the new region assertTrue( !currentRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( mergedRegions.getFirst(), 1))); // replica of the merged region assertTrue( !currentRegions.contains( RegionReplicaUtil.getRegionInfoForReplica( mergedRegions.getSecond(), 1))); // replica of the merged region }
@VisibleForTesting void stepsAfterPONR( final Server server, final RegionServerServices services, final PairOfSameType<Region> regions, User user) throws IOException { if (this.parent.getCoprocessorHost() != null) { parent.getCoprocessorHost().preSplitAfterPONR(user); } openDaughters(server, services, regions.getFirst(), regions.getSecond()); transition(SplitTransactionPhase.BEFORE_POST_SPLIT_HOOK); // Coprocessor callback if (parent.getCoprocessorHost() != null) { this.parent.getCoprocessorHost().postSplit(regions.getFirst(), regions.getSecond(), user); } transition(SplitTransactionPhase.AFTER_POST_SPLIT_HOOK); }
@Test public void testWholesomeMerge() throws Exception { LOG.info("Starting testWholesomeMerge"); final TableName tableName = TableName.valueOf("testWholesomeMerge"); // Create table and load data. Table table = createTableAndLoadData(master, tableName); // Merge 1st and 2nd region mergeRegionsAndVerifyRegionNum(master, tableName, 0, 1, INITIAL_REGION_NUM - 1); // Merge 2nd and 3th region PairOfSameType<HRegionInfo> mergedRegions = mergeRegionsAndVerifyRegionNum(master, tableName, 1, 2, INITIAL_REGION_NUM - 2); verifyRowCount(table, ROWSIZE); // Randomly choose one of the two merged regions HRegionInfo hri = RandomUtils.nextBoolean() ? mergedRegions.getFirst() : mergedRegions.getSecond(); MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); AssignmentManager am = cluster.getMaster().getAssignmentManager(); RegionStates regionStates = am.getRegionStates(); long start = EnvironmentEdgeManager.currentTime(); while (!regionStates.isRegionInState(hri, State.MERGED)) { assertFalse( "Timed out in waiting one merged region to be in state MERGED", EnvironmentEdgeManager.currentTime() - start > 60000); Thread.sleep(500); } // We should not be able to assign it again am.assign(hri, true); assertFalse("Merged region can't be assigned", regionStates.isRegionInTransition(hri)); assertTrue(regionStates.isRegionInState(hri, State.MERGED)); // We should not be able to unassign it either am.unassign(hri, null); assertFalse("Merged region can't be unassigned", regionStates.isRegionInTransition(hri)); assertTrue(regionStates.isRegionInState(hri, State.MERGED)); table.close(); }
@SuppressWarnings("deprecation") @Test public void testCleanMergeReference() throws Exception { LOG.info("Starting testCleanMergeReference"); admin.enableCatalogJanitor(false); try { final TableName tableName = TableName.valueOf("testCleanMergeReference"); // Create table and load data. Table table = createTableAndLoadData(master, tableName); // Merge 1st and 2nd region mergeRegionsAndVerifyRegionNum(master, tableName, 0, 1, INITIAL_REGION_NUM - 1); verifyRowCount(table, ROWSIZE); table.close(); List<Pair<HRegionInfo, ServerName>> tableRegions = MetaTableAccessor.getTableRegionsAndLocations(master.getConnection(), tableName); HRegionInfo mergedRegionInfo = tableRegions.get(0).getFirst(); HTableDescriptor tableDescritor = master.getTableDescriptors().get(tableName); Result mergedRegionResult = MetaTableAccessor.getRegionResult( master.getConnection(), mergedRegionInfo.getRegionName()); // contains merge reference in META assertTrue( mergedRegionResult.getValue(HConstants.CATALOG_FAMILY, HConstants.MERGEA_QUALIFIER) != null); assertTrue( mergedRegionResult.getValue(HConstants.CATALOG_FAMILY, HConstants.MERGEB_QUALIFIER) != null); // merging regions' directory are in the file system all the same PairOfSameType<HRegionInfo> p = MetaTableAccessor.getMergeRegions(mergedRegionResult); HRegionInfo regionA = p.getFirst(); HRegionInfo regionB = p.getSecond(); FileSystem fs = master.getMasterFileSystem().getFileSystem(); Path rootDir = master.getMasterFileSystem().getRootDir(); Path tabledir = FSUtils.getTableDir(rootDir, mergedRegionInfo.getTable()); Path regionAdir = new Path(tabledir, regionA.getEncodedName()); Path regionBdir = new Path(tabledir, regionB.getEncodedName()); assertTrue(fs.exists(regionAdir)); assertTrue(fs.exists(regionBdir)); admin.compactRegion(mergedRegionInfo.getRegionName()); // wait until merged region doesn't have reference file long timeout = System.currentTimeMillis() + waitTime; HRegionFileSystem hrfs = new HRegionFileSystem(TEST_UTIL.getConfiguration(), fs, tabledir, mergedRegionInfo); while (System.currentTimeMillis() < timeout) { if (!hrfs.hasReferences(tableDescritor)) { break; } Thread.sleep(50); } assertFalse(hrfs.hasReferences(tableDescritor)); // run CatalogJanitor to clean merge references in hbase:meta and archive the // files of merging regions int cleaned = admin.runCatalogScan(); assertTrue(cleaned > 0); assertFalse(fs.exists(regionAdir)); assertFalse(fs.exists(regionBdir)); mergedRegionResult = MetaTableAccessor.getRegionResult( master.getConnection(), mergedRegionInfo.getRegionName()); assertFalse( mergedRegionResult.getValue(HConstants.CATALOG_FAMILY, HConstants.MERGEA_QUALIFIER) != null); assertFalse( mergedRegionResult.getValue(HConstants.CATALOG_FAMILY, HConstants.MERGEB_QUALIFIER) != null); } finally { admin.enableCatalogJanitor(true); } }