@Override public void processResult(int rc, String path, Object ctx, Stat stat) { if (rc != 0) { // This is resultcode. If non-zero, need to resubmit. LOG.warn("rc != 0 for " + path + " -- some error, may be connection loss -- " + "FIX see http://wiki.apache.org/hadoop/ZooKeeper/FAQ#A2"); parent.reportCompletion(false); return; } RegionState state = (RegionState)ctx; LOG.debug("rs=" + state); // Transition RegionState to PENDING_OPEN here in master; means we've // sent the open. We're a little ahead of ourselves here since we've not // yet sent out the actual open but putting this state change after the // call to open risks our writing PENDING_OPEN after state has been moved // to OPENING by the regionserver. state.update(RegionState.State.PENDING_OPEN, System.currentTimeMillis(), destination); parent.reportCompletion(true); }
/** * Sets regions {@link RegionState} to {@link RegionState.State#OFFLINE}. * Caller must hold lock on this.regionsInTransition. * @param region * @param hijack * @return Amended RegionState. */ private RegionState forceRegionStateToOffline(final HRegionInfo region, boolean hijack) { String encodedName = region.getEncodedName(); RegionState state = this.regionsInTransition.get(encodedName); if (state == null) { state = new RegionState(region, RegionState.State.OFFLINE); this.regionsInTransition.put(encodedName, state); } else { // If we are reassigning the node do not force in-memory state to OFFLINE. // Based on the znode state we will decide if to change in-memory state to // OFFLINE or not. It will be done before setting znode to OFFLINE state. // We often get here with state == CLOSED because ClosedRegionHandler will // assign on its tail as part of the handling of a region close. if (!hijack) { LOG.debug("Forcing OFFLINE; was=" + state); state.update(RegionState.State.OFFLINE); } } return state; }
/** * Set region as OFFLINED up in zookeeper asynchronously. * @param state * @return True if we succeeded, false otherwise (State was incorrect or failed * updating zk). */ boolean asyncSetOfflineInZooKeeper(final RegionState state, final AsyncCallback.StringCallback cb, final Object ctx) { if (!state.isClosed() && !state.isOffline()) { new RuntimeException("Unexpected state trying to OFFLINE; " + state); this.master.abort("Unexpected state trying to OFFLINE; " + state, new IllegalStateException()); return false; } state.update(RegionState.State.OFFLINE); try { ZKAssign.asyncCreateNodeOffline(master.getZooKeeper(), state.getRegion(), this.master.getServerName(), cb, ctx); } catch (KeeperException e) { // TODO: this error handling will never execute, as the callback is async. if (e instanceof NodeExistsException) { LOG.warn("Node for " + state.getRegion() + " already exists"); } else { master.abort("Unexpected ZK exception creating/setting node OFFLINE", e); } return false; } return true; }
/** * Put the region <code>hri</code> into an offline state up in zk. * @param hri * @param oldData * @throws KeeperException */ private void forceOffline(final HRegionInfo hri, final RegionTransitionData oldData) throws KeeperException { // If was on dead server, its closed now. Force to OFFLINE and then // handle it like a close; this will get it reassigned if appropriate LOG.debug("RIT " + hri.getEncodedName() + " in state=" + oldData.getEventType() + " was on deadserver; forcing offline"); ZKAssign.createOrForceNodeOffline(this.watcher, hri, this.master.getServerName()); addToRITandCallClose(hri, RegionState.State.OFFLINE, oldData); }
/** * If the passed regionState is in PENDING_CLOSE, clean up PENDING_CLOSE * state and convert it to SPLITTING instead. * This can happen in case where master wants to close a region at same time * a regionserver starts a split. The split won. Clean out old PENDING_CLOSE * state. * @param rs * @return True if we converted from PENDING_CLOSE to SPLITTING */ private boolean convertPendingCloseToSplitting(final RegionState rs) { if (!rs.isPendingClose()) return false; LOG.debug("Converting PENDING_CLOSE to SPLITING; rs=" + rs); rs.update(RegionState.State.SPLITTING); // Clean up existing state. Clear from region plans seems all we // have to do here by way of clean up of PENDING_CLOSE. clearRegionPlan(rs.getRegion()); return true; }
/** * @param serverName * @param encodedName * @return The SPLITTING RegionState we added to RIT for the passed region * <code>encodedName</code> */ private RegionState addSplittingToRIT(final ServerName serverName, final String encodedName) { RegionState regionState = null; synchronized (this.regions) { regionState = findHRegionInfoThenAddToRIT(serverName, encodedName); if (regionState != null) { regionState.update(RegionState.State.SPLITTING, System.currentTimeMillis(), serverName); } } return regionState; }
@Override public void readFields(DataInput in) throws IOException { region = new HRegionInfo(); region.readFields(in); state = State.valueOf(in.readUTF()); stamp.set(in.readLong()); }
private void testSSHWhenSourceRSandDestRSInRegionPlanGoneDown(boolean regionInOffline) throws IOException, KeeperException, ServiceException { // We need a mocked catalog tracker. CatalogTracker ct = Mockito.mock(CatalogTracker.class); // Create an AM. AssignmentManagerWithExtrasForTesting am = setUpMockedAssignmentManager(this.server, this.serverManager); // adding region in pending open. if (regionInOffline) { ServerName MASTER_SERVERNAME = new ServerName("example.org", 1111, 1111); am.regionsInTransition.put(REGIONINFO.getEncodedName(), new RegionState(REGIONINFO, State.OFFLINE, System.currentTimeMillis(), MASTER_SERVERNAME)); } else { am.regionsInTransition.put(REGIONINFO.getEncodedName(), new RegionState(REGIONINFO, State.OPENING, System.currentTimeMillis(), SERVERNAME_B)); } // adding region plan am.regionPlans.put(REGIONINFO.getEncodedName(), new RegionPlan(REGIONINFO, SERVERNAME_A, SERVERNAME_B)); am.getZKTable().setEnabledTable(REGIONINFO.getTableNameAsString()); try { processServerShutdownHandler(ct, am, false, SERVERNAME_A); processServerShutdownHandler(ct, am, false, SERVERNAME_B); if(regionInOffline){ assertFalse("Assign should not be invoked.", am.assignInvoked); } else { assertTrue("Assign should be invoked.", am.assignInvoked); } } finally { am.regionsInTransition.remove(REGIONINFO.getEncodedName()); am.regionPlans.remove(REGIONINFO.getEncodedName()); } }