/** * Refresh all the region locations. * * @return true if user created regions got refreshed. */ private boolean scheduleFullRefresh() { // Protect from anything being null while starting up. if (services == null) { return false; } AssignmentManager am = services.getAssignmentManager(); if (am == null) { return false; } RegionStates regionStates = am.getRegionStates(); if (regionStates == null) { return false; } Set<HRegionInfo> regions = regionStates.getRegionAssignments().keySet(); boolean includesUserTables = false; for (final HRegionInfo hri : regions) { cache.refresh(hri); includesUserTables = includesUserTables || !hri.isSystemTable(); } return includesUserTables; }
public OpenedRegionHandler(Server server, AssignmentManager assignmentManager, HRegionInfo regionInfo, OpenRegionCoordination coordination, OpenRegionCoordination.OpenRegionDetails ord) { super(server, EventType.RS_ZK_REGION_OPENED); this.assignmentManager = assignmentManager; this.regionInfo = regionInfo; this.coordination = coordination; this.ord = ord; if(regionInfo.isMetaRegion()) { priority = OpenedPriority.META; } else if(regionInfo.getTable() .getNamespaceAsString().equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR)) { priority = OpenedPriority.SYSTEM; } else { priority = OpenedPriority.USER; } }
protected static void assignRegions(final MasterProcedureEnv env, final TableName tableName, final List<HRegionInfo> regions) throws HBaseException, IOException { ProcedureSyncWait.waitRegionServers(env); final AssignmentManager assignmentManager = env.getMasterServices().getAssignmentManager(); // Mark the table as Enabling assignmentManager.getTableStateManager().setTableState(tableName, ZooKeeperProtos.Table.State.ENABLING); // Trigger immediate assignment of the regions in round-robin fashion ModifyRegionUtils.assignRegions(assignmentManager, regions); // Enable table assignmentManager.getTableStateManager() .setTableState(tableName, ZooKeeperProtos.Table.State.ENABLED); }
/** * @return True if region cleared RIT, else false if we timed out waiting. * @throws InterruptedIOException */ private boolean waitOnRegionToClearRegionsInTransition(AssignmentManager am, final HRegionInfo hri, final int timeout) throws InterruptedIOException { try { if (!am.waitOnRegionToClearRegionsInTransition(hri, timeout)) { // Wait here is to avoid log replay hits current dead server and incur a RPC timeout // when replay happens before region assignment completes. LOG.warn("Region " + hri.getEncodedName() + " didn't complete assignment in time"); return false; } } catch (InterruptedException ie) { throw new InterruptedIOException("Caught " + ie + " during waitOnRegionToClearRegionsInTransition for " + hri); } return true; }
protected static void waitRegionInTransition(final MasterProcedureEnv env, final List<HRegionInfo> regions) throws IOException, CoordinatedStateException { final AssignmentManager am = env.getMasterServices().getAssignmentManager(); final RegionStates states = am.getRegionStates(); for (final HRegionInfo region : regions) { ProcedureSyncWait.waitFor(env, "regions " + region.getRegionNameAsString() + " in transition", new ProcedureSyncWait.Predicate<Boolean>() { @Override public Boolean evaluate() throws IOException { if (states.isRegionInState(region, State.FAILED_OPEN)) { am.regionOffline(region); } return !states.isRegionInTransition(region); } }); } }
@Test (timeout=300000) public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException { byte[] tableName = Bytes.toBytes("testMoveToPreviouslyAssignedRS"); MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); HMaster master = cluster.getMaster(); HBaseAdmin localAdmin = createTable(tableName); List<HRegionInfo> tableRegions = localAdmin.getTableRegions(tableName); HRegionInfo hri = tableRegions.get(0); AssignmentManager am = master.getAssignmentManager(); assertTrue("Region " + hri.getRegionNameAsString() + " should be assigned properly", am.waitForAssignment(hri)); ServerName server = am.getRegionStates().getRegionServerOfRegion(hri); localAdmin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(server.getServerName())); assertEquals("Current region server and region server before move should be same.", server, am.getRegionStates().getRegionServerOfRegion(hri)); }
public OpenedRegionHandler(Server server, AssignmentManager assignmentManager, HRegionInfo regionInfo, ServerName sn, int expectedVersion) { super(server, EventType.RS_ZK_REGION_OPENED); this.assignmentManager = assignmentManager; this.regionInfo = regionInfo; this.sn = sn; this.expectedVersion = expectedVersion; if(regionInfo.isRootRegion()) { priority = OpenedPriority.ROOT; } else if(regionInfo.isMetaRegion()) { priority = OpenedPriority.META; } else { priority = OpenedPriority.USER; } }
/** * Check individual daughter is up in .META.; fixup if its not. * @param result The contents of the parent row in .META. * @param qualifier Which daughter to check for. * @return 1 if the daughter is missing and fixed. Otherwise 0 * @throws IOException */ static int fixupDaughter(final Result result, final byte [] qualifier, final AssignmentManager assignmentManager, final CatalogTracker catalogTracker) throws IOException { HRegionInfo daughter = MetaReader.parseHRegionInfoFromCatalogResult(result, qualifier); if (daughter == null) return 0; if (isDaughterMissing(catalogTracker, daughter)) { LOG.info("Fixup; missing daughter " + daughter.getRegionNameAsString()); MetaEditor.addDaughter(catalogTracker, daughter, null); // TODO: Log WARN if the regiondir does not exist in the fs. If its not // there then something wonky about the split -- things will keep going // but could be missing references to parent region. // And assign it. assignmentManager.assign(daughter, true); return 1; } else { LOG.debug("Daughter " + daughter.getRegionNameAsString() + " present"); } return 0; }
static void checkAndSetEnablingTable(final AssignmentManager assignmentManager, final TableName tableName) throws IOException { // If we have multiple client threads trying to create the table at the // same time, given the async nature of the operation, the table // could be in a state where hbase:meta table hasn't been updated yet in // the process() function. // Use enabling state to tell if there is already a request for the same // table in progress. This will introduce a new zookeeper call. Given // createTable isn't a frequent operation, that should be ok. // TODO: now that we have table locks, re-evaluate above -- table locks are not enough. // We could have cleared the hbase.rootdir and not zk. How can we detect this case? // Having to clean zk AND hdfs is awkward. try { if (!assignmentManager.getTableStateManager().setTableStateIfNotInStates(tableName, ZooKeeperProtos.Table.State.ENABLING, ZooKeeperProtos.Table.State.ENABLING, ZooKeeperProtos.Table.State.ENABLED)) { throw new TableExistsException(tableName); } } catch (CoordinatedStateException e) { throw new IOException("Unable to ensure that the table will be" + " enabling because of a ZooKeeper issue", e); } }
@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); }
public OpenedRegionHandler(Server server, AssignmentManager assignmentManager, HRegionInfo regionInfo, ServerName sn, int expectedVersion) { super(server, EventType.RS_ZK_REGION_OPENED); this.assignmentManager = assignmentManager; this.regionInfo = regionInfo; this.sn = sn; this.expectedVersion = expectedVersion; if(regionInfo.isMetaRegion()) { priority = OpenedPriority.META; } else if(regionInfo.getTable() .getNamespaceAsString().equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR)) { priority = OpenedPriority.SYSTEM; } else { priority = OpenedPriority.USER; } }
protected OpenRegionHandler(final Server server, final RegionServerServices rsServices, final HRegionInfo regionInfo, final HTableDescriptor htd, EventType eventType, final int versionOfOfflineNode) { super(server, eventType); this.rsServices = rsServices; this.regionInfo = regionInfo; this.htd = htd; this.versionOfOfflineNode = versionOfOfflineNode; tomActivated = this.server.getConfiguration(). getBoolean(AssignmentManager.ASSIGNMENT_TIMEOUT_MANAGEMENT, AssignmentManager.DEFAULT_ASSIGNMENT_TIMEOUT_MANAGEMENT); assignmentTimeout = this.server.getConfiguration(). getInt(AssignmentManager.ASSIGNMENT_TIMEOUT, AssignmentManager.DEFAULT_ASSIGNMENT_TIMEOUT_DEFAULT); }
/** * Process a dead region from a dead RS. Checks if the region is disabled * or if the region has a partially completed split. * @param hri * @param result * @param assignmentManager * @param catalogTracker * @return Returns true if specified region should be assigned, false if not. * @throws IOException */ public static boolean processDeadRegion(HRegionInfo hri, Result result, AssignmentManager assignmentManager, CatalogTracker catalogTracker) throws IOException { // If table is not disabled but the region is offlined, boolean disabled = assignmentManager.getZKTable().isDisabledTable( hri.getTableNameAsString()); if (disabled) return false; if (hri.isOffline() && hri.isSplit()) { LOG.debug("Offlined and split region " + hri.getRegionNameAsString() + "; checking daughter presence"); fixupDaughters(result, assignmentManager, catalogTracker); return false; } return true; }
/** * Check individual daughter is up in .META.; fixup if its not. * @param result The contents of the parent row in .META. - not used * @param daughter Which daughter to check for. * @return 1 if the daughter is missing and fixed. Otherwise 0 * @throws IOException */ static int fixupDaughter(final Result result, HRegionInfo daughter, final AssignmentManager assignmentManager, final CatalogTracker catalogTracker) throws IOException { if (daughter == null) return 0; if (isDaughterMissing(catalogTracker, daughter)) { LOG.info("Fixup; missing daughter " + daughter.getRegionNameAsString()); MetaEditor.addDaughter(catalogTracker, daughter, null); // TODO: Log WARN if the regiondir does not exist in the fs. If its not // there then something wonky about the split -- things will keep going // but could be missing references to parent region. // And assign it. assignmentManager.assign(daughter, true, true); return 1; } else { LOG.debug("Daughter " + daughter.getRegionNameAsString() + " present"); } return 0; }
private boolean checkRegionInTransition(ObserverContext<MasterCoprocessorEnvironment> ctx, HRegionInfo hri) { MasterServices master = ctx.getEnvironment().getMasterServices(); AssignmentManager am = master.getAssignmentManager(); boolean isRegionInTransition = false; String tableName = hri.getTableNameAsString(); if (false == IndexUtils.isIndexTable(tableName)) { NavigableMap<String, RegionState> regionsInTransition = am.getRegionsInTransition(); RegionState regionState = regionsInTransition.get(hri.getEncodedName()); if (regionState != null) { isRegionInTransition = true; } else { String indexTableName = IndexUtils.getIndexTableName(tableName); for (Entry<String, RegionState> region : regionsInTransition.entrySet()) { HRegionInfo regionInfo = region.getValue().getRegion(); if (indexTableName.equals(regionInfo.getTableNameAsString())) { if (Bytes.compareTo(hri.getStartKey(), regionInfo.getStartKey()) == 0) { isRegionInTransition = true; break; } } } } } return isRegionInTransition; }
@Override public boolean commitOpenOnMasterSide(AssignmentManager assignmentManager, HRegionInfo regionInfo, OpenRegionDetails ord) { boolean committedSuccessfully = true; // Code to defend against case where we get SPLIT before region open // processing completes; temporary till we make SPLITs go via zk -- 0.92. RegionState regionState = assignmentManager.getRegionStates() .getRegionTransitionState(regionInfo.getEncodedName()); boolean openedNodeDeleted = false; if (regionState != null && regionState.isOpened()) { openedNodeDeleted = deleteOpenedNode(regionInfo, ord); if (!openedNodeDeleted) { LOG.error("Znode of region " + regionInfo.getShortNameToLog() + " could not be deleted."); } } else { LOG.warn("Skipping the onlining of " + regionInfo.getShortNameToLog() + " because regions is NOT in RIT -- presuming this is because it SPLIT"); } if (!openedNodeDeleted) { if (assignmentManager.getTableStateManager().isTableState(regionInfo.getTable(), ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING)) { debugLog(regionInfo, "Opened region " + regionInfo.getShortNameToLog() + " but " + "this table is disabled, triggering close of region"); committedSuccessfully = false; } } return committedSuccessfully; }
static void checkAndSetEnablingTable(final AssignmentManager assignmentManager, final TableName tableName, boolean skipTableStateCheck) throws IOException { // If we have multiple client threads trying to create the table at the // same time, given the async nature of the operation, the table // could be in a state where hbase:meta table hasn't been updated yet in // the process() function. // Use enabling state to tell if there is already a request for the same // table in progress. This will introduce a new zookeeper call. Given // createTable isn't a frequent operation, that should be ok. // TODO: now that we have table locks, re-evaluate above -- table locks are not enough. // We could have cleared the hbase.rootdir and not zk. How can we detect this case? // Having to clean zk AND hdfs is awkward. try { if (skipTableStateCheck) { assignmentManager.getTableStateManager().setTableState( tableName, ZooKeeperProtos.Table.State.ENABLING); } else if (!assignmentManager.getTableStateManager().setTableStateIfNotInStates( tableName, ZooKeeperProtos.Table.State.ENABLING, ZooKeeperProtos.Table.State.ENABLING, ZooKeeperProtos.Table.State.ENABLED)) { throw new TableExistsException(tableName); } } catch (CoordinatedStateException e) { throw new IOException("Unable to ensure that the table will be" + " enabling because of a ZooKeeper issue", e); } }
static void removeEnablingTable(final AssignmentManager assignmentManager, final TableName tableName) { // Try deleting the enabling node in case of error // If this does not happen then if the client tries to create the table // again with the same Active master // It will block the creation saying TableAlreadyExists. try { assignmentManager.getTableStateManager().checkAndRemoveTableState(tableName, ZooKeeperProtos.Table.State.ENABLING, false); } catch (CoordinatedStateException e) { // Keeper exception should not happen here LOG.error("Got a keeper exception while removing the ENABLING table znode " + tableName, e); } }