public RegionReplicaOutputSink(PipelineController controller, TableDescriptors tableDescriptors, EntryBuffers entryBuffers, ClusterConnection connection, ExecutorService pool, int numWriters, int operationTimeout) { super(controller, entryBuffers, numWriters); this.sinkWriter = new RegionReplicaSinkWriter(this, connection, pool, operationTimeout); this.tableDescriptors = tableDescriptors; // A cache for the table "memstore replication enabled" flag. // It has a default expiry of 5 sec. This means that if the table is altered // with a different flag value, we might miss to replicate for that amount of // time. But this cache avoid the slow lookup and parsing of the TableDescriptor. int memstoreReplicationEnabledCacheExpiryMs = connection.getConfiguration() .getInt("hbase.region.replica.replication.cache.memstoreReplicationEnabled.expiryMs", 5000); this.memstoreReplicationEnabled = CacheBuilder.newBuilder() .expireAfterWrite(memstoreReplicationEnabledCacheExpiryMs, TimeUnit.MILLISECONDS) .initialCapacity(10) .maximumSize(1000) .build(); }
public RegionReplicaSinkWriter(RegionReplicaOutputSink sink, ClusterConnection connection, ExecutorService pool, int operationTimeout) { this.sink = sink; this.connection = connection; this.operationTimeout = operationTimeout; this.rpcRetryingCallerFactory = RpcRetryingCallerFactory.instantiate(connection.getConfiguration()); this.rpcControllerFactory = RpcControllerFactory.instantiate(connection.getConfiguration()); this.pool = pool; int nonExistentTableCacheExpiryMs = connection.getConfiguration() .getInt("hbase.region.replica.replication.cache.disabledAndDroppedTables.expiryMs", 5000); // A cache for non existing tables that have a default expiry of 5 sec. This means that if the // table is created again with the same name, we might miss to replicate for that amount of // time. But this cache prevents overloading meta requests for every edit from a deleted file. disabledAndDroppedTables = CacheBuilder.newBuilder() .expireAfterWrite(nonExistentTableCacheExpiryMs, TimeUnit.MILLISECONDS) .initialCapacity(10) .maximumSize(1000) .build(); }
ServerManager(final Server master, final MasterServices services, final boolean connect) throws IOException { this.master = master; this.services = services; Configuration c = master.getConfiguration(); maxSkew = c.getLong("hbase.master.maxclockskew", 30000); warningSkew = c.getLong("hbase.master.warningclockskew", 10000); this.connection = connect ? (ClusterConnection)ConnectionFactory.createConnection(c) : null; int pingMaxAttempts = Math.max(1, master.getConfiguration().getInt( "hbase.master.maximum.ping.server.attempts", 10)); int pingSleepInterval = Math.max(1, master.getConfiguration().getInt( "hbase.master.ping.server.retry.sleep.interval", 100)); this.pingRetryCounterFactory = new RetryCounterFactory(pingMaxAttempts, pingSleepInterval); this.rpcControllerFactory = this.connection == null ? null : connection.getRpcControllerFactory(); }
/** * A quick test that hbase:meta is assigned; blocks for short time only. * @return True if hbase:meta location is available and verified as good. * @throws InterruptedException * @throws IOException */ private boolean isMetaAssignedQuickTest(final MasterProcedureEnv env) throws InterruptedException, IOException { ZooKeeperWatcher zkw = env.getMasterServices().getZooKeeper(); MetaTableLocator mtl = env.getMasterServices().getMetaTableLocator(); boolean metaAssigned = false; // Is hbase:meta location available yet? if (mtl.isLocationAvailable(zkw)) { ClusterConnection connection = env.getMasterServices().getConnection(); // Is hbase:meta location good yet? long timeout = env.getMasterConfiguration().getLong(KEY_SHORT_WAIT_ON_META, DEFAULT_SHORT_WAIT_ON_META); if (mtl.verifyMetaRegionLocation(connection, zkw, timeout)) { metaAssigned = true; } } return metaAssigned; }
/** * There may be items for this table still up in hbase:meta in the case where the * info:regioninfo column was empty because of some write error. Remove ALL rows from hbase:meta * that have to do with this table. See HBASE-12980. * @throws IOException */ private static void cleanAnyRemainingRows(final MasterProcedureEnv env, final TableName tableName) throws IOException { ClusterConnection connection = env.getMasterServices().getConnection(); Scan tableScan = MetaTableAccessor.getScanForTableName(tableName); try (Table metaTable = connection.getTable(TableName.META_TABLE_NAME)) { List<Delete> deletes = new ArrayList<Delete>(); try (ResultScanner resScanner = metaTable.getScanner(tableScan)) { for (Result result : resScanner) { deletes.add(new Delete(result.getRow())); } } if (!deletes.isEmpty()) { LOG.warn("Deleting some vestigal " + deletes.size() + " rows of " + tableName + " from " + TableName.META_TABLE_NAME); metaTable.delete(deletes); } } }
@Test (timeout = 240000) public void testReplayCallable() throws Exception { // tests replaying the edits to a secondary region replica using the Callable directly openRegion(HTU, rs0, hriSecondary); ClusterConnection connection = (ClusterConnection) ConnectionFactory.createConnection(HTU.getConfiguration()); //load some data to primary HTU.loadNumericRows(table, f, 0, 1000); Assert.assertEquals(1000, entries.size()); // replay the edits to the secondary using replay callable replicateUsingCallable(connection, entries); Region region = rs0.getFromOnlineRegions(hriSecondary.getEncodedName()); HTU.verifyNumericRows(region, f, 0, 1000); HTU.deleteNumericRows(table, f, 0, 1000); closeRegion(HTU, rs0, hriSecondary); connection.close(); }
private void replicateUsingCallable(ClusterConnection connection, Queue<Entry> entries) throws IOException, RuntimeException { Entry entry; while ((entry = entries.poll()) != null) { byte[] row = entry.getEdit().getCells().get(0).getRow(); RegionLocations locations = connection.locateRegion(tableName, row, true, true); RegionReplicaReplayCallable callable = new RegionReplicaReplayCallable(connection, RpcControllerFactory.instantiate(connection.getConfiguration()), table.getName(), locations.getRegionLocation(1), locations.getRegionLocation(1).getRegionInfo(), row, Lists.newArrayList(entry), new AtomicLong()); RpcRetryingCallerFactory factory = RpcRetryingCallerFactory.instantiate( connection.getConfiguration()); factory.<ReplicateWALEntryResponse> newCaller().callWithRetries(callable, 10000); } }
private void testVerifyMetaRegionLocationWithException(Exception ex) throws IOException, InterruptedException, KeeperException, ServiceException { // Mock an ClientProtocol. final ClientProtos.ClientService.BlockingInterface implementation = Mockito.mock(ClientProtos.ClientService.BlockingInterface.class); ClusterConnection connection = mockConnection(null, implementation); // If a 'get' is called on mocked interface, throw connection refused. Mockito.when(implementation.get((RpcController) Mockito.any(), (GetRequest) Mockito.any())). thenThrow(new ServiceException(ex)); long timeout = UTIL.getConfiguration(). getLong("hbase.catalog.verification.timeout", 1000); MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation( connection, watcher, timeout)); MetaTableLocator.setMetaLocation(this.watcher, SN, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation( connection, watcher, timeout)); }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { ClusterConnection connection = Mockito.mock(ClusterConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))). thenReturn(implementation); RpcControllerFactory controllerFactory = Mockito.mock(RpcControllerFactory.class); Mockito.when(controllerFactory.newController()).thenReturn( Mockito.mock(PayloadCarryingRpcController.class)); Mockito.when(connection.getRpcControllerFactory()).thenReturn(controllerFactory); ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis()); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); }
private void printLocations(Result r) { RegionLocations rl = null; if (r == null) { LOG.info("FAILED FOR null Result"); return; } LOG.info("FAILED FOR " + resultToString(r) + " Stale " + r.isStale()); if (r.getRow() == null) { return; } try { rl = ((ClusterConnection)connection).locateRegion(tableName, r.getRow(), true, true); } catch (IOException e) { LOG.warn("Couldn't get locations for row " + Bytes.toString(r.getRow())); } HRegionLocation locations[] = rl.getRegionLocations(); for (HRegionLocation h : locations) { LOG.info("LOCATION " + h); } }
@Override public ServerName getServerHoldingRegion(TableName tn, byte[] regionName) throws IOException { HRegionLocation regionLoc = null; try (RegionLocator locator = connection.getRegionLocator(tn)) { regionLoc = locator.getRegionLocation(regionName); } if (regionLoc == null) { LOG.warn("Cannot find region server holding region " + Bytes.toString(regionName) + ", start key [" + Bytes.toString(HRegionInfo.getStartKey(regionName)) + "]"); return null; } AdminProtos.AdminService.BlockingInterface client = ((ClusterConnection)this.connection).getAdmin(regionLoc.getServerName()); ServerInfo info = ProtobufUtil.getServerInfo(null, client); return ProtobufUtil.toServerName(info.getServerName()); }
/** * Callers should call close on the returned {@link Table} instance. * @param connection connection we're using to access Meta * @return An {@link Table} for <code>hbase:meta</code> * @throws IOException */ static Table getMetaHTable(final Connection connection) throws IOException { // We used to pass whole CatalogTracker in here, now we just pass in Connection if (connection == null) { throw new NullPointerException("No connection"); } else if (connection.isClosed()) { throw new IOException("connection is closed"); } // If the passed in 'connection' is 'managed' -- i.e. every second test uses // a Table or an HBaseAdmin with managed connections -- then doing // connection.getTable will throw an exception saying you are NOT to use // managed connections getting tables. Leaving this as it is for now. Will // revisit when inclined to change all tests. User code probaby makes use of // managed connections too so don't change it till post hbase 1.0. // // There should still be a way to use this method with an unmanaged connection. if (connection instanceof ClusterConnection) { if (((ClusterConnection) connection).isManaged()) { return new HTable(TableName.META_TABLE_NAME, (ClusterConnection) connection); } } return connection.getTable(TableName.META_TABLE_NAME); }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { ClusterConnection connection = Mockito.mock(ClusterConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class))). thenReturn(implementation); ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis()); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); }
@BeforeClass public static void setUpBeforeClass() throws Exception { conf.setInt("hbase.regionserver.handler.count", 2); conf.setInt("hbase.regionserver.metahandler.count", 2); conf.setInt("hbase.htable.threads.max", POOL_SIZE); conf.setInt("hbase.hconnection.threads.max", 2 * POOL_SIZE); conf.setInt("hbase.hconnection.threads.core", POOL_SIZE); conf.setInt("hbase.hbck.close.timeout", 2 * REGION_ONLINE_TIMEOUT); TEST_UTIL.startMiniCluster(3); tableExecutorService = new ThreadPoolExecutor(1, POOL_SIZE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), Threads.newDaemonThreadFactory("testhbck")); hbfsckExecutorService = new ScheduledThreadPoolExecutor(POOL_SIZE); AssignmentManager assignmentManager = TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager(); regionStates = assignmentManager.getRegionStates(); connection = (ClusterConnection) TEST_UTIL.getConnection(); admin = connection.getAdmin(); admin.setBalancerRunning(false, true); }
/** * Callers should call close on the returned {@link Table} instance. * @param connection connection we're using to access Meta * @return An {@link Table} for <code>hbase:meta</code> * @throws IOException */ static Table getMetaHTable(final Connection connection) throws IOException { // We used to pass whole CatalogTracker in here, now we just pass in Connection if (connection == null || connection.isClosed()) { throw new NullPointerException("No connection"); } // If the passed in 'connection' is 'managed' -- i.e. every second test uses // a Table or an HBaseAdmin with managed connections -- then doing // connection.getTable will throw an exception saying you are NOT to use // managed connections getting tables. Leaving this as it is for now. Will // revisit when inclined to change all tests. User code probaby makes use of // managed connections too so don't change it till post hbase 1.0. // // There should still be a way to use this method with an unmanaged connection. if (connection instanceof ClusterConnection) { if (((ClusterConnection) connection).isManaged()) { return new HTable(TableName.META_TABLE_NAME, (ClusterConnection) connection); } } return connection.getTable(TableName.META_TABLE_NAME); }
@Test (timeout = 240000) public void testReplayCallable() throws Exception { // tests replaying the edits to a secondary region replica using the Callable directly openRegion(HTU, rs0, hriSecondary); ClusterConnection connection = (ClusterConnection) ConnectionFactory.createConnection(HTU.getConfiguration()); //load some data to primary HTU.loadNumericRows(table, f, 0, 1000); Assert.assertEquals(1000, entries.size()); // replay the edits to the secondary using replay callable replicateUsingCallable(connection, entries); Region region = rs0.getRegion(hriSecondary.getEncodedName()); HTU.verifyNumericRows(region, f, 0, 1000); HTU.deleteNumericRows(table, f, 0, 1000); closeRegion(HTU, rs0, hriSecondary); connection.close(); }
private void replicateUsingCallable(ClusterConnection connection, Queue<Entry> entries) throws IOException, RuntimeException { Entry entry; while ((entry = entries.poll()) != null) { byte[] row = CellUtil.cloneRow(entry.getEdit().getCells().get(0)); RegionLocations locations = connection.locateRegion(tableName, row, true, true); RegionReplicaReplayCallable callable = new RegionReplicaReplayCallable(connection, RpcControllerFactory.instantiate(connection.getConfiguration()), table.getName(), locations.getRegionLocation(1), locations.getRegionLocation(1).getRegionInfo(), row, Lists.newArrayList(entry), new AtomicLong()); RpcRetryingCallerFactory factory = RpcRetryingCallerFactory.instantiate( connection.getConfiguration()); factory.<ReplicateWALEntryResponse> newCaller().callWithRetries(callable, 10000); } }
private ClusterConnection getMockedConnection(final Configuration conf) throws IOException, org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { ClusterConnection c = Mockito.mock(ClusterConnection.class); Mockito.when(c.getConfiguration()).thenReturn(conf); Mockito.doNothing().when(c).close(); // Make it so we return a particular location when asked. final HRegionLocation loc = new HRegionLocation(RegionInfoBuilder.FIRST_META_REGIONINFO, ServerName.valueOf("example.org", 1234, 0)); Mockito.when( c.getRegionLocation((TableName) Mockito.any(), (byte[]) Mockito.any(), Mockito.anyBoolean())) .thenReturn(loc); Mockito.when(c.locateRegion((TableName) Mockito.any(), (byte[]) Mockito.any())).thenReturn(loc); ClientProtos.ClientService.BlockingInterface hri = Mockito.mock(ClientProtos.ClientService.BlockingInterface.class); Mockito .when( hri.bulkLoadHFile((RpcController) Mockito.any(), (BulkLoadHFileRequest) Mockito.any())) .thenThrow(new ServiceException(new IOException("injecting bulk load error"))); Mockito.when(c.getClient(Mockito.any())).thenReturn(hri); return c; }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { ClusterConnection connection = Mockito.mock(ClusterConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any())). thenReturn(implementation); RpcControllerFactory controllerFactory = Mockito.mock(RpcControllerFactory.class); Mockito.when(controllerFactory.newController()).thenReturn( Mockito.mock(HBaseRpcController.class)); Mockito.when(connection.getRpcControllerFactory()).thenReturn(controllerFactory); ServerName sn = ServerName.valueOf("example.com", 1234, System.currentTimeMillis()); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPENING); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); MetaTableLocator.setMetaLocation(this.watcher, sn, RegionState.State.OPEN); assertFalse(new MetaTableLocator().verifyMetaRegionLocation(connection, watcher, 100)); }
@Test public void testNamespaceCreateAndAssign() throws Exception { LOG.info("testNamespaceCreateAndAssign"); String nsName = tablePrefix+"_foo"; final TableName tableName = TableName.valueOf(nsName, tablePrefix + "_testCreateAndAssign"); RSGroupInfo appInfo = addGroup("appInfo", 1); admin.createNamespace(NamespaceDescriptor.create(nsName) .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "appInfo").build()); final HTableDescriptor desc = new HTableDescriptor(tableName); desc.addFamily(new HColumnDescriptor("f")); admin.createTable(desc); //wait for created table to be assigned TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() { @Override public boolean evaluate() throws Exception { return getTableRegionMap().get(desc.getTableName()) != null; } }); ServerName targetServer = ServerName.parseServerName(appInfo.getServers().iterator().next().toString()); AdminProtos.AdminService.BlockingInterface rs = ((ClusterConnection) admin.getConnection()).getAdmin(targetServer); //verify it was assigned to the right group Assert.assertEquals(1, ProtobufUtil.getOnlineRegions(rs).size()); }
@Override public ServerName getServerHoldingRegion(TableName tn, byte[] regionName) throws IOException { HRegionLocation regionLoc = null; try (RegionLocator locator = connection.getRegionLocator(tn)) { regionLoc = locator.getRegionLocation(regionName, true); } if (regionLoc == null) { LOG.warn("Cannot find region server holding region " + Bytes.toString(regionName) + ", start key [" + Bytes.toString(HRegionInfo.getStartKey(regionName)) + "]"); return null; } AdminProtos.AdminService.BlockingInterface client = ((ClusterConnection)this.connection).getAdmin(regionLoc.getServerName()); ServerInfo info = ProtobufUtil.getServerInfo(null, client); return ProtobufUtil.toServerName(info.getServerName()); }
/** * Fetches the table sizes on the filesystem as tracked by the HBase Master. */ public static Map<TableName,Long> getMasterReportedTableSizes( Connection conn) throws IOException { if (!(conn instanceof ClusterConnection)) { throw new IllegalArgumentException("Expected a ClusterConnection"); } ClusterConnection clusterConn = (ClusterConnection) conn; GetSpaceQuotaRegionSizesResponse response = QuotaStatusCalls.getMasterRegionSizes( clusterConn, 0); Map<TableName,Long> tableSizes = new HashMap<>(); for (RegionSizes sizes : response.getSizesList()) { TableName tn = ProtobufUtil.toTableName(sizes.getTableName()); tableSizes.put(tn, sizes.getSize()); } return tableSizes; }
/** * Fetches the observed {@link SpaceQuotaSnapshot}s observed by a RegionServer. */ public static Map<TableName,SpaceQuotaSnapshot> getRegionServerQuotaSnapshots( Connection conn, ServerName regionServer) throws IOException { if (!(conn instanceof ClusterConnection)) { throw new IllegalArgumentException("Expected a ClusterConnection"); } ClusterConnection clusterConn = (ClusterConnection) conn; GetSpaceQuotaSnapshotsResponse response = QuotaStatusCalls.getRegionServerQuotaSnapshot( clusterConn, 0, regionServer); Map<TableName,SpaceQuotaSnapshot> snapshots = new HashMap<>(); for (TableQuotaSnapshot snapshot : response.getSnapshotsList()) { snapshots.put( ProtobufUtil.toTableName(snapshot.getTableName()), SpaceQuotaSnapshot.toSpaceQuotaSnapshot(snapshot.getSnapshot())); } return snapshots; }
/** * Returns the Master's view of a quota on the given {@code tableName} or null if the * Master has no quota information on that table. */ public static SpaceQuotaSnapshot getCurrentSnapshot( Connection conn, TableName tn) throws IOException { if (!(conn instanceof ClusterConnection)) { throw new IllegalArgumentException("Expected a ClusterConnection"); } ClusterConnection clusterConn = (ClusterConnection) conn; GetQuotaStatesResponse resp = QuotaStatusCalls.getMasterQuotaStates(clusterConn, 0); HBaseProtos.TableName protoTableName = ProtobufUtil.toProtoTableName(tn); for (GetQuotaStatesResponse.TableQuotaSnapshot tableSnapshot : resp.getTableSnapshotsList()) { if (protoTableName.equals(tableSnapshot.getTableName())) { return SpaceQuotaSnapshot.toSpaceQuotaSnapshot(tableSnapshot.getSnapshot()); } } return null; }
@Override protected void doStart() { try { connection = (ClusterConnection) ConnectionFactory.createConnection(this.conf); this.pool = getDefaultThreadPool(conf); outputSink = new RegionReplicaOutputSink(controller, tableDescriptors, entryBuffers, connection, pool, numWriterThreads, operationTimeout); outputSink.startWriterThreads(); super.doStart(); } catch (IOException ex) { LOG.warn("Received exception while creating connection :" + ex); notifyFailed(ex); } }
public RegionReplicaReplayCallable(ClusterConnection connection, RpcControllerFactory rpcControllerFactory, TableName tableName, HRegionLocation location, HRegionInfo regionInfo, byte[] row,List<Entry> entries, AtomicLong skippedEntries) { super(connection, rpcControllerFactory, location, tableName, row, regionInfo.getReplicaId()); this.entries = entries; this.skippedEntries = skippedEntries; this.initialEncodedRegionName = regionInfo.getEncodedNameAsBytes(); }
/** * Contacts a region server and waits up to timeout ms * to close the region. This bypasses the active hmaster. */ public static void closeRegionSilentlyAndWait(ClusterConnection connection, ServerName server, HRegionInfo region, long timeout) throws IOException, InterruptedException { AdminService.BlockingInterface rs = connection.getAdmin(server); PayloadCarryingRpcController controller = connection.getRpcControllerFactory().newController(); try { ProtobufUtil.closeRegion(controller, rs, server, region.getRegionName(), false); } catch (IOException e) { LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e); } long expiration = timeout + System.currentTimeMillis(); while (System.currentTimeMillis() < expiration) { try { HRegionInfo rsRegion = ProtobufUtil.getRegionInfo(controller, rs, region.getRegionName()); if (rsRegion == null) return; } catch (IOException ioe) { if (ioe instanceof NotServingRegionException) // no need to retry again return; LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(), ioe); } Thread.sleep(1000); } throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout); }
/** * Perform a bulk load of the given directory into the given * pre-existing table. This method is not threadsafe. * * @param hfofDir the directory that was provided as the output path * of a job using HFileOutputFormat * @param table the table to load into * @throws TableNotFoundException if table does not yet exist */ @SuppressWarnings("deprecation") public void doBulkLoad(Path hfofDir, final HTable table) throws TableNotFoundException, IOException { Admin admin = null; Table t = table; Connection conn = table.getConnection(); boolean closeConnWhenFinished = false; try { if (conn instanceof ClusterConnection && ((ClusterConnection) conn).isManaged()) { LOG.warn("managed connection cannot be used for bulkload. Creating unmanaged connection."); // can only use unmanaged connections from here on out. conn = ConnectionFactory.createConnection(table.getConfiguration()); t = conn.getTable(table.getName()); closeConnWhenFinished = true; if (conn instanceof ClusterConnection && ((ClusterConnection) conn).isManaged()) { throw new RuntimeException("Failed to create unmanaged connection."); } admin = conn.getAdmin(); } else { admin = conn.getAdmin(); } try (RegionLocator rl = conn.getRegionLocator(t.getName())) { doBulkLoad(hfofDir, admin, t, rl); } } finally { if (admin != null) admin.close(); if (closeConnWhenFinished) { t.close(); conn.close(); } } }
/** * To repair region consistency, one must call connect() in order to repair * online state. */ public void connect() throws IOException { if (isExclusive()) { // Grab the lock hbckOutFd = checkAndMarkRunningHbck(); if (hbckOutFd == null) { setRetCode(-1); LOG.error("Another instance of hbck is fixing HBase, exiting this instance. " + "[If you are sure no other instance is running, delete the lock file " + HBCK_LOCK_PATH + " and rerun the tool]"); throw new IOException("Duplicate hbck - Abort"); } // Make sure to cleanup the lock hbckLockCleanup.set(true); } // Add a shutdown hook to this thread, in case user tries to // kill the hbck with a ctrl-c, we want to cleanup the lock so that // it is available for further calls Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { IOUtils.closeQuietly(HBaseFsck.this); unlockHbck(); } }); LOG.info("Launching hbck"); connection = (ClusterConnection)ConnectionFactory.createConnection(getConf()); admin = connection.getAdmin(); meta = connection.getTable(TableName.META_TABLE_NAME); status = admin.getClusterStatus(); }
/** * Record the location of the hbase:meta region as found in ZooKeeper. */ private boolean recordMetaRegion() throws IOException { RegionLocations rl = ((ClusterConnection)connection).locateRegion(TableName.META_TABLE_NAME, HConstants.EMPTY_START_ROW, false, false); if (rl == null) { errors.reportError(ERROR_CODE.NULL_META_REGION, "META region or some of its attributes are null."); return false; } for (HRegionLocation metaLocation : rl.getRegionLocations()) { // Check if Meta region is valid and existing if (metaLocation == null || metaLocation.getRegionInfo() == null || metaLocation.getHostname() == null) { errors.reportError(ERROR_CODE.NULL_META_REGION, "META region or some of its attributes are null."); return false; } ServerName sn = metaLocation.getServerName(); MetaEntry m = new MetaEntry(metaLocation.getRegionInfo(), sn, EnvironmentEdgeManager.currentTime()); HbckInfo hbckInfo = regionInfoMap.get(metaLocation.getRegionInfo().getEncodedName()); if (hbckInfo == null) { regionInfoMap.put(metaLocation.getRegionInfo().getEncodedName(), new HbckInfo(m)); } else { hbckInfo.metaEntry = m; } } return true; }
/** * Contacts a region server and waits up to hbase.hbck.close.timeout ms * (default 120s) to close the region. This bypasses the active hmaster. */ @SuppressWarnings("deprecation") public static void closeRegionSilentlyAndWait(HConnection connection, ServerName server, HRegionInfo region) throws IOException, InterruptedException { long timeout = connection.getConfiguration() .getLong("hbase.hbck.close.timeout", 120000); ServerManager.closeRegionSilentlyAndWait((ClusterConnection)connection, server, region, timeout); }
/** * Create a 'smarter' HConnection, one that is capable of by-passing RPC if the request is to * the local server. Safe to use going to local or remote server. * Create this instance in a method can be intercepted and mocked in tests. * * @throws IOException */ @VisibleForTesting protected ClusterConnection createClusterConnection() throws IOException { // Create a cluster connection that when appropriate, can short-circuit and go directly to the // local server if the request is to the local server bypassing RPC. Can be used for both local // and remote invocations. return ConnectionUtils .createShortCircuitConnection(conf, null, userProvider.getCurrent(), serverName, rpcServices, rpcServices); }
public RegionReplicaFlushHandler(Server server, ClusterConnection connection, RpcRetryingCallerFactory rpcRetryingCallerFactory, RpcControllerFactory rpcControllerFactory, int operationTimeout, HRegion region) { super(server, EventType.RS_REGION_REPLICA_FLUSH); this.connection = connection; this.rpcRetryingCallerFactory = rpcRetryingCallerFactory; this.rpcControllerFactory = rpcControllerFactory; this.operationTimeout = operationTimeout; this.region = region; }
@Test (timeout = 240000) public void testReplayCallableWithRegionMove() throws Exception { // tests replaying the edits to a secondary region replica using the Callable directly while // the region is moved to another location.It tests handling of RME. openRegion(HTU, rs0, hriSecondary); ClusterConnection connection = (ClusterConnection) ConnectionFactory.createConnection(HTU.getConfiguration()); //load some data to primary HTU.loadNumericRows(table, f, 0, 1000); Assert.assertEquals(1000, entries.size()); // replay the edits to the secondary using replay callable replicateUsingCallable(connection, entries); Region region = rs0.getFromOnlineRegions(hriSecondary.getEncodedName()); HTU.verifyNumericRows(region, f, 0, 1000); HTU.loadNumericRows(table, f, 1000, 2000); // load some more data to primary // move the secondary region from RS0 to RS1 closeRegion(HTU, rs0, hriSecondary); openRegion(HTU, rs1, hriSecondary); // replicate the new data replicateUsingCallable(connection, entries); region = rs1.getFromOnlineRegions(hriSecondary.getEncodedName()); // verify the new data. old data may or may not be there HTU.verifyNumericRows(region, f, 1000, 2000); HTU.deleteNumericRows(table, f, 0, 2000); closeRegion(HTU, rs1, hriSecondary); connection.close(); }
@Test (timeout = 240000) public void testRegionReplicaReplicationEndpointReplicate() throws Exception { // tests replaying the edits to a secondary region replica using the RRRE.replicate() openRegion(HTU, rs0, hriSecondary); ClusterConnection connection = (ClusterConnection) ConnectionFactory.createConnection(HTU.getConfiguration()); RegionReplicaReplicationEndpoint replicator = new RegionReplicaReplicationEndpoint(); ReplicationEndpoint.Context context = mock(ReplicationEndpoint.Context.class); when(context.getConfiguration()).thenReturn(HTU.getConfiguration()); when(context.getMetrics()).thenReturn(mock(MetricsSource.class)); replicator.init(context); replicator.start(); //load some data to primary HTU.loadNumericRows(table, f, 0, 1000); Assert.assertEquals(1000, entries.size()); // replay the edits to the secondary using replay callable final String fakeWalGroupId = "fakeWALGroup"; replicator.replicate(new ReplicateContext().setEntries(Lists.newArrayList(entries)) .setWalGroupId(fakeWalGroupId)); Region region = rs0.getFromOnlineRegions(hriSecondary.getEncodedName()); HTU.verifyNumericRows(region, f, 0, 1000); HTU.deleteNumericRows(table, f, 0, 1000); closeRegion(HTU, rs0, hriSecondary); connection.close(); }