private void testTruncateTable(final TableName tableName, boolean preserveSplits) throws IOException { byte[][] splitKeys = new byte[2][]; splitKeys[0] = Bytes.toBytes(4); splitKeys[1] = Bytes.toBytes(8); // Create & Fill the table HTable table = TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY, splitKeys); try { TEST_UTIL.loadNumericRows(table, HConstants.CATALOG_FAMILY, 0, 10); assertEquals(10, TEST_UTIL.countRows(table)); } finally { table.close(); } assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); // Truncate & Verify this.admin.disableTable(tableName); this.admin.truncateTable(tableName, preserveSplits); table = new HTable(TEST_UTIL.getConfiguration(), tableName); try { assertEquals(0, TEST_UTIL.countRows(table)); } finally { table.close(); } if (preserveSplits) { assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); } else { assertEquals(1, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); } }
@Ignore("Hangs on occasion waiting on countdown latch") @Test public void testRegionOperations() throws Exception { String nsp1 = prefix + "_regiontest"; NamespaceDescriptor nspDesc = NamespaceDescriptor.create(nsp1) .addConfiguration(TableNamespaceManager.KEY_MAX_REGIONS, "2") .addConfiguration(TableNamespaceManager.KEY_MAX_TABLES, "2") .build(); ADMIN.createNamespace(nspDesc); boolean constraintViolated = false; final TableName tableOne = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table1"); byte[] columnFamily = Bytes.toBytes("info"); HTableDescriptor tableDescOne = new HTableDescriptor(tableOne); tableDescOne.addFamily(new HColumnDescriptor(columnFamily)); NamespaceTableAndRegionInfo stateInfo; try { ADMIN.createTable(tableDescOne, Bytes.toBytes("1"), Bytes.toBytes("1000"), 7); } catch (Exception exp) { assertTrue(exp instanceof DoNotRetryIOException); LOG.info(exp); constraintViolated = true; } finally { assertTrue(constraintViolated); } assertFalse(ADMIN.tableExists(tableOne)); // This call will pass. ADMIN.createTable(tableDescOne); Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration()); Table htable = connection.getTable(tableOne); UTIL.loadNumericRows(htable, Bytes.toBytes("info"), 1, 1000); ADMIN.flush(tableOne); stateInfo = getNamespaceState(nsp1); assertEquals(1, stateInfo.getTables().size()); assertEquals(1, stateInfo.getRegionCount()); restartMaster(); ADMIN.split(tableOne, Bytes.toBytes("500")); HRegion actualRegion = UTIL.getHBaseCluster().getRegions(tableOne).get(0); CustomObserver observer = (CustomObserver) actualRegion.getCoprocessorHost().findCoprocessor(CustomObserver.class.getName()); assertNotNull(observer); observer.postSplit.await(); assertEquals(2, ADMIN.getTableRegions(tableOne).size()); actualRegion = UTIL.getHBaseCluster().getRegions(tableOne).get(0); observer = (CustomObserver) actualRegion.getCoprocessorHost().findCoprocessor(CustomObserver.class.getName()); assertNotNull(observer); ADMIN.split( tableOne, getSplitKey( actualRegion.getRegionInfo().getStartKey(), actualRegion.getRegionInfo().getEndKey())); observer.postSplit.await(); // Make sure no regions have been added. List<HRegionInfo> hris = ADMIN.getTableRegions(tableOne); assertEquals(2, hris.size()); assertTrue("split completed", observer.preSplitBeforePONR.getCount() == 1); htable.close(); }
@Test public void testRegionMerge() throws Exception { String nsp1 = prefix + "_regiontest"; NamespaceDescriptor nspDesc = NamespaceDescriptor.create(nsp1) .addConfiguration(TableNamespaceManager.KEY_MAX_REGIONS, "3") .addConfiguration(TableNamespaceManager.KEY_MAX_TABLES, "2") .build(); ADMIN.createNamespace(nspDesc); final TableName tableTwo = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table2"); byte[] columnFamily = Bytes.toBytes("info"); HTableDescriptor tableDescOne = new HTableDescriptor(tableTwo); tableDescOne.addFamily(new HColumnDescriptor(columnFamily)); final int initialRegions = 3; ADMIN.createTable(tableDescOne, Bytes.toBytes("1"), Bytes.toBytes("2000"), initialRegions); Connection connection = ConnectionFactory.createConnection(UTIL.getConfiguration()); try (Table table = connection.getTable(tableTwo)) { UTIL.loadNumericRows(table, Bytes.toBytes("info"), 1000, 1999); } ADMIN.flush(tableTwo); List<HRegionInfo> hris = ADMIN.getTableRegions(tableTwo); Collections.sort(hris); // merge the two regions final Set<String> encodedRegionNamesToMerge = Sets.newHashSet(hris.get(0).getEncodedName(), hris.get(1).getEncodedName()); ADMIN.mergeRegions( hris.get(0).getEncodedNameAsBytes(), hris.get(1).getEncodedNameAsBytes(), false); UTIL.waitFor( 10000, 100, new Waiter.ExplainingPredicate<Exception>() { @Override public boolean evaluate() throws Exception { RegionStates regionStates = UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().getRegionStates(); for (HRegionInfo hri : ADMIN.getTableRegions(tableTwo)) { if (encodedRegionNamesToMerge.contains(hri.getEncodedName())) { return false; } if (!regionStates.isRegionInState(hri, RegionState.State.OPEN)) { return false; } } return true; } @Override public String explainFailure() throws Exception { RegionStates regionStates = UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().getRegionStates(); for (HRegionInfo hri : ADMIN.getTableRegions(tableTwo)) { if (encodedRegionNamesToMerge.contains(hri.getEncodedName())) { return hri + " which is expected to be merged is still online"; } if (!regionStates.isRegionInState(hri, RegionState.State.OPEN)) { return hri + " is still in not opened"; } } return "Unknown"; } }); hris = ADMIN.getTableRegions(tableTwo); assertEquals(initialRegions - 1, hris.size()); Collections.sort(hris); final HRegionInfo hriToSplit = hris.get(1); ADMIN.split(tableTwo, Bytes.toBytes("500")); UTIL.waitFor( 10000, 100, new Waiter.ExplainingPredicate<Exception>() { @Override public boolean evaluate() throws Exception { RegionStates regionStates = UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().getRegionStates(); for (HRegionInfo hri : ADMIN.getTableRegions(tableTwo)) { if (hri.getEncodedName().equals(hriToSplit.getEncodedName())) { return false; } if (!regionStates.isRegionInState(hri, RegionState.State.OPEN)) { return false; } } return true; } @Override public String explainFailure() throws Exception { RegionStates regionStates = UTIL.getMiniHBaseCluster().getMaster().getAssignmentManager().getRegionStates(); for (HRegionInfo hri : ADMIN.getTableRegions(tableTwo)) { if (hri.getEncodedName().equals(hriToSplit.getEncodedName())) { return hriToSplit + " which is expected to be split is still online"; } if (!regionStates.isRegionInState(hri, RegionState.State.OPEN)) { return hri + " is still in not opened"; } } return "Unknown"; } }); hris = ADMIN.getTableRegions(tableTwo); assertEquals(initialRegions, hris.size()); Collections.sort(hris); // fail region merge through Coprocessor hook MiniHBaseCluster cluster = UTIL.getHBaseCluster(); HRegionServer regionServer = cluster.getRegionServer(0); RegionServerCoprocessorHost cpHost = regionServer.getRegionServerCoprocessorHost(); Coprocessor coprocessor = cpHost.findCoprocessor(CPRegionServerObserver.class.getName()); CPRegionServerObserver regionServerObserver = (CPRegionServerObserver) coprocessor; regionServerObserver.failMerge(true); regionServerObserver.triggered = false; ADMIN.mergeRegions( hris.get(1).getEncodedNameAsBytes(), hris.get(2).getEncodedNameAsBytes(), false); regionServerObserver.waitUtilTriggered(); hris = ADMIN.getTableRegions(tableTwo); assertEquals(initialRegions, hris.size()); Collections.sort(hris); // verify that we cannot split HRegionInfo hriToSplit2 = hris.get(1); ADMIN.split( tableTwo, TableInputFormatBase.getSplitKey(hriToSplit2.getStartKey(), hriToSplit2.getEndKey(), true)); Thread.sleep(2000); assertEquals(initialRegions, ADMIN.getTableRegions(tableTwo).size()); }