/** * Checks and sets table state in ZK. Sets no watches. * {@inheritDoc} */ @Override public boolean setTableStateIfInStates(TableName tableName, ZooKeeperProtos.Table.State newState, ZooKeeperProtos.Table.State... states) throws CoordinatedStateException { synchronized (this.cache) { // Transition ENABLED->DISABLING has to be performed with a hack, because // we treat empty state as enabled in this case because 0.92- clusters. if ( (newState == ZooKeeperProtos.Table.State.DISABLING) && this.cache.get(tableName) != null && !isTableState(tableName, states) || (newState != ZooKeeperProtos.Table.State.DISABLING && !isTableState(tableName, states) )) { return false; } try { setTableStateInZK(tableName, newState); } catch (KeeperException e) { throw new CoordinatedStateException(e); } return true; } }
/** * {@inheritDoc} */ @Override public void checkAndRemoveTableState(TableName tableName, ZooKeeperProtos.Table.State states, boolean deletePermanentState) throws CoordinatedStateException { synchronized (this.cache) { if (isTableState(tableName, states)) { this.cache.remove(tableName); if (deletePermanentState) { try { ZKUtil.deleteNodeFailSilent(this.watcher, ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString())); } catch (KeeperException e) { throw new CoordinatedStateException(e); } } } } }
/** * Gets a list of all the tables of specified states in zookeeper. * @return Set of tables of specified states, empty Set if none * @throws KeeperException */ Set<TableName> getAllTables(final ZooKeeperProtos.Table.State... states) throws KeeperException, InterruptedIOException { Set<TableName> allTables = new HashSet<TableName>(); List<String> children = ZKUtil.listChildrenNoWatch(watcher, watcher.tableZNode); if(children == null) return allTables; for (String child: children) { TableName tableName = TableName.valueOf(child); ZooKeeperProtos.Table.State state; try { state = getTableState(watcher, tableName); } catch (InterruptedException e) { throw new InterruptedIOException(); } for (ZooKeeperProtos.Table.State expectedState: states) { if (state == expectedState) { allTables.add(tableName); break; } } } return allTables; }
@Override public void handleMetadata(byte[] ownerMetadata) { if (!LOG.isDebugEnabled()) { return; } ZooKeeperProtos.TableLock data = fromBytes(ownerMetadata); if (data == null) { return; } LOG.debug("Table is locked by " + String.format("[tableName=%s:%s, lockOwner=%s, threadId=%s, " + "purpose=%s, isShared=%s, createTime=%s]", data.getTableName().getNamespace().toStringUtf8(), data.getTableName().getQualifier().toStringUtf8(), ProtobufUtil.toServerName(data.getLockOwner()), data.getThreadId(), data.getPurpose(), data.getIsShared(), data.getCreateTime())); }
private InterProcessLock createTableLock() { String tableLockZNode = ZKUtil.joinZNode(zkWatcher.tableLockZNode, tableName.getNameAsString()); ZooKeeperProtos.TableLock data = ZooKeeperProtos.TableLock.newBuilder() .setTableName(ProtobufUtil.toProtoTableName(tableName)) .setLockOwner(ProtobufUtil.toServerName(serverName)) .setThreadId(Thread.currentThread().getId()) .setPurpose(purpose) .setIsShared(isShared) .setCreateTime(EnvironmentEdgeManager.currentTime()).build(); byte[] lockMetadata = toBytes(data); InterProcessReadWriteLock lock = new ZKInterProcessReadWriteLock(zkWatcher, tableLockZNode, METADATA_HANDLER); return isShared ? lock.readLock(lockMetadata) : lock.writeLock(lockMetadata); }
@Override public void process() { LOG.debug("Handling CLOSED event for " + regionInfo.getEncodedName()); // Check if this table is being disabled or not if (this.assignmentManager.getTableStateManager().isTableState(this.regionInfo.getTable(), ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING) || assignmentManager.getReplicasToClose().contains(regionInfo)) { assignmentManager.offlineDisabledRegion(regionInfo); return; } // ZK Node is in CLOSED state, assign it. assignmentManager.getRegionStates().updateRegionState( regionInfo, RegionState.State.CLOSED); // This below has to do w/ online enable/disable of a table assignmentManager.removeClosedRegion(regionInfo); assignmentManager.assign(regionInfo, true); }
private boolean prepareCreate(final MasterProcedureEnv env) throws IOException { final TableName tableName = getTableName(); if (MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) { setFailure("master-create-table", new TableExistsException(getTableName())); return false; } // During master initialization, the ZK state could be inconsistent from failed DDL // in the past. If we fail here, it would prevent master to start. We should force // setting the system table state regardless the table state. boolean skipTableStateCheck = !(env.getMasterServices().isInitialized()) && tableName.isSystemTable(); if (!skipTableStateCheck) { TableStateManager tsm = env.getMasterServices().getAssignmentManager().getTableStateManager(); if (tsm.isTableState(tableName, true, ZooKeeperProtos.Table.State.ENABLING, ZooKeeperProtos.Table.State.ENABLED)) { LOG.warn("The table " + tableName + " does not exist in meta but has a znode. " + "run hbck to fix inconsistencies."); setFailure("master-create-table", new TableExistsException(getTableName())); return false; } } return true; }
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); }
/** * Rollback of table state change in prepareDisable() * @param env MasterProcedureEnv */ @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION", justification="Intended") private void undoTableStateChange(final MasterProcedureEnv env) { if (!skipTableStateCheck) { try { // If the state was changed, undo it. if (env.getMasterServices().getAssignmentManager().getTableStateManager().isTableState( tableName, ZooKeeperProtos.Table.State.DISABLING)) { EnableTableProcedure.setTableStateToEnabled(env, tableName); } } catch (Exception e) { // Ignore exception. LOG.trace(e.getMessage()); } } }
/** * @param bytes Content of a peer znode. * @return ClusterKey parsed from the passed bytes. * @throws DeserializationException */ private static ReplicationPeerConfig parsePeerFrom(final byte[] bytes) throws DeserializationException { if (ProtobufUtil.isPBMagicPrefix(bytes)) { int pblen = ProtobufUtil.lengthOfPBMagic(); ZooKeeperProtos.ReplicationPeer.Builder builder = ZooKeeperProtos.ReplicationPeer.newBuilder(); ZooKeeperProtos.ReplicationPeer peer; try { ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen); peer = builder.build(); } catch (IOException e) { throw new DeserializationException(e); } return convert(peer); } else { if (bytes.length > 0) { return new ReplicationPeerConfig().setClusterKey(Bytes.toString(bytes)); } return new ReplicationPeerConfig().setClusterKey(""); } }
/** * Recover the tables that were not fully moved to DISABLED state. These * tables are in DISABLING state when the master restarted/switched. * * @throws KeeperException * @throws TableNotFoundException * @throws IOException */ private void recoverTableInDisablingState() throws KeeperException, IOException, CoordinatedStateException { Set<TableName> disablingTables = tableStateManager.getTablesInStates(ZooKeeperProtos.Table.State.DISABLING); if (disablingTables.size() != 0) { for (TableName tableName : disablingTables) { // Recover by calling DisableTableHandler LOG.info("The table " + tableName + " is in DISABLING state. Hence recovering by moving the table" + " to DISABLED state."); new DisableTableHandler(this.server, tableName, this, tableLockManager, true).prepare().process(); } } }
/** * Recover the tables that are not fully moved to ENABLED state. These tables * are in ENABLING state when the master restarted/switched * * @throws KeeperException * @throws org.apache.hadoop.hbase.TableNotFoundException * @throws IOException */ private void recoverTableInEnablingState() throws KeeperException, IOException, CoordinatedStateException { Set<TableName> enablingTables = tableStateManager. getTablesInStates(ZooKeeperProtos.Table.State.ENABLING); if (enablingTables.size() != 0) { for (TableName tableName : enablingTables) { // Recover by calling EnableTableHandler LOG.info("The table " + tableName + " is in ENABLING state. Hence recovering by moving the table" + " to ENABLED state."); // enableTable in sync way during master startup, // no need to invoke coprocessor EnableTableHandler eth = new EnableTableHandler(this.server, tableName, this, tableLockManager, true); try { eth.prepare(); } catch (TableNotFoundException e) { LOG.warn("Table " + tableName + " not found in hbase:meta to recover."); continue; } eth.process(); } } }
/** * @param bytes - Content of a WAL position znode. * @return long - The current WAL position. * @throws DeserializationException */ public static long parseWALPositionFrom(final byte[] bytes) throws DeserializationException { if (bytes == null) { throw new DeserializationException("Unable to parse null WAL position."); } if (ProtobufUtil.isPBMagicPrefix(bytes)) { int pblen = ProtobufUtil.lengthOfPBMagic(); ZooKeeperProtos.ReplicationHLogPosition.Builder builder = ZooKeeperProtos.ReplicationHLogPosition.newBuilder(); ZooKeeperProtos.ReplicationHLogPosition position; try { ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen); position = builder.build(); } catch (IOException e) { throw new DeserializationException(e); } return position.getPosition(); } else { if (bytes.length > 0) { return Bytes.toLong(bytes); } return 0; } }
private void onRegionOpen(final HRegionInfo hri, final ServerName sn, long openSeqNum) { regionOnline(hri, sn, openSeqNum); if (useZKForAssignment) { try { // Delete the ZNode if exists ZKAssign.deleteNodeFailSilent(watcher, hri); } catch (KeeperException ke) { server.abort("Unexpected ZK exception deleting node " + hri, ke); } } // reset the count, if any failedOpenTracker.remove(hri.getEncodedName()); if (getTableStateManager().isTableState(hri.getTable(), ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING)) { invokeUnAssign(hri); } }
private static void appendPeerState(ZooKeeperWatcher zkw, String znodeToProcess, StringBuilder sb) throws KeeperException, InvalidProtocolBufferException { String peerState = zkw.getConfiguration().get("zookeeper.znode.replication.peers.state", "peer-state"); int pblen = ProtobufUtil.lengthOfPBMagic(); for (String child : ZKUtil.listChildrenNoWatch(zkw, znodeToProcess)) { if (!child.equals(peerState)) continue; String peerStateZnode = ZKUtil.joinZNode(znodeToProcess, child); sb.append("\n").append(peerStateZnode).append(": "); byte[] peerStateData; try { peerStateData = ZKUtil.getData(zkw, peerStateZnode); ZooKeeperProtos.ReplicationState.Builder builder = ZooKeeperProtos.ReplicationState.newBuilder(); ProtobufUtil.mergeFrom(builder, peerStateData, pblen, peerStateData.length - pblen); sb.append(builder.getState().name()); } catch (IOException ipbe) { LOG.warn("Got Exception while parsing peer: " + znodeToProcess, ipbe); } catch (InterruptedException e) { zkw.interruptedException(e); return; } } }
private void checkAndMigrateTableStatesToPB(ZooKeeperWatcher zkw) throws KeeperException, InterruptedException { List<String> tables = ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); if (tables == null) { LOG.info("No table present to migrate table state to PB. returning.."); return; } for (String table : tables) { String znode = ZKUtil.joinZNode(zkw.tableZNode, table); // Delete -ROOT- table state znode since its no longer present in 0.95.0 // onwards. if (table.equals("-ROOT-") || table.equals(".META.")) { ZKUtil.deleteNode(zkw, znode); continue; } byte[] data = ZKUtil.getData(zkw, znode); if (ProtobufUtil.isPBMagicPrefix(data)) continue; ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder(); builder.setState(ZooKeeperProtos.Table.State.valueOf(Bytes.toString(data))); data = ProtobufUtil.prependPBMagic(builder.build().toByteArray()); ZKUtil.setData(zkw, znode, data); } }
/** * Gets a list of tables that are set as one of the passing in states in zookeeper. * @param zkw ZooKeeperWatcher instance to use * @param states the list of states that a table could be in * @return Set of tables in one of the states, empty Set if none * @throws KeeperException * @throws InterruptedException */ private static Set<TableName> getTablesInStates( ZooKeeperWatcher zkw, ZooKeeperProtos.Table.State... states) throws KeeperException, InterruptedException { Set<TableName> tableNameSet = new HashSet<TableName>(); List<String> children = ZKUtil.listChildrenNoWatch(zkw, zkw.tableZNode); TableName tableName; ZooKeeperProtos.Table.State tableState; for (String child: children) { tableName = TableName.valueOf(child); tableState = getTableState(zkw, tableName); for (ZooKeeperProtos.Table.State state : states) { if (tableState == state) { tableNameSet.add(tableName); break; } } } return tableNameSet; }
/** * Sets znodes used in 0.94 version. Only table and replication znodes will be upgraded to PB, * others would be deleted. * @throws KeeperException */ private static void setUp94Znodes() throws IOException, KeeperException { // add some old znodes, which would be deleted after upgrade. String rootRegionServerZnode = ZKUtil.joinZNode(zkw.baseZNode, "root-region-server"); ZKUtil.createWithParents(zkw, rootRegionServerZnode); ZKUtil.createWithParents(zkw, zkw.backupMasterAddressesZNode); // add table znode, data of its children would be protobuffized tableAZnode = ZKUtil.joinZNode(zkw.tableZNode, "a"); ZKUtil.createWithParents(zkw, tableAZnode, Bytes.toBytes(ZooKeeperProtos.Table.State.ENABLED.toString())); // add replication znodes, data of its children would be protobuffized String replicationZnode = ZKUtil.joinZNode(zkw.baseZNode, "replication"); replicationPeerZnode = ZKUtil.joinZNode(replicationZnode, "peers"); peer1Znode = ZKUtil.joinZNode(replicationPeerZnode, "1"); peer1 = ReplicationPeer.newBuilder().setClusterkey("abc:123:/hbase").build(); ZKUtil.createWithParents(zkw, peer1Znode, Bytes.toBytes(peer1.getClusterkey())); }
@Test public void testMasterRestartAfterNameSpaceEnablingNodeIsCreated() throws Exception { // Step 1: start mini zk cluster. MiniZooKeeperCluster zkCluster; zkCluster = TEST_UTIL.startMiniZKCluster(); // Step 2: add an orphaned system table ZNODE TableName tableName = TableName.valueOf("hbase:namespace"); ZooKeeperWatcher zkw = TEST_UTIL.getZooKeeperWatcher(); String znode = ZKUtil.joinZNode(zkw.tableZNode, tableName.getNameAsString()); ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder(); builder.setState(ZooKeeperProtos.Table.State.ENABLED); byte [] data = ProtobufUtil.prependPBMagic(builder.build().toByteArray()); ZKUtil.createSetData(zkw, znode, data); LOG.info("Create an orphaned Znode " + znode + " with data " + data); // Step 3: link the zk cluster to hbase cluster TEST_UTIL.setZkCluster(zkCluster); // Step 4: start hbase cluster and expect master to start successfully. TEST_UTIL.startMiniCluster(); assertTrue(TEST_UTIL.getHBaseCluster().getLiveMasterThreads().size() == 1); }
/** * Update the state znode of a peer cluster. * @param id * @param state */ private void changePeerState(String id, ZooKeeperProtos.ReplicationState.State state) throws ReplicationException { try { if (!peerExists(id)) { throw new IllegalArgumentException("Cannot enable/disable peer because id=" + id + " does not exist."); } String peerStateZNode = getPeerStateNode(id); byte[] stateBytes = (state == ZooKeeperProtos.ReplicationState.State.ENABLED) ? ENABLED_ZNODE_BYTES : DISABLED_ZNODE_BYTES; if (ZKUtil.checkExists(this.zookeeper, peerStateZNode) != -1) { ZKUtil.setData(this.zookeeper, peerStateZNode, stateBytes); } else { ZKUtil.createAndWatch(this.zookeeper, peerStateZNode, stateBytes); } LOG.info("Peer with id= " + id + " is now " + state.name()); } catch (KeeperException e) { throw new ReplicationException("Unable to change state of the peer with id=" + id, e); } }
@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; }
/** * Gets a list of all the tables set as disabled in zookeeper. * @throws KeeperException, InterruptedException */ private void populateTableStates() throws KeeperException, InterruptedException { synchronized (this.cache) { List<String> children = ZKUtil.listChildrenNoWatch(this.watcher, this.watcher.tableZNode); if (children == null) return; for (String child: children) { TableName tableName = TableName.valueOf(child); ZooKeeperProtos.Table.State state = getTableState(this.watcher, tableName); if (state != null) this.cache.put(tableName, state); } } }
private void setTableStateInZK(final TableName tableName, final ZooKeeperProtos.Table.State state) throws KeeperException { String znode = ZKUtil.joinZNode(this.watcher.tableZNode, tableName.getNameAsString()); if (ZKUtil.checkExists(this.watcher, znode) == -1) { ZKUtil.createAndFailSilent(this.watcher, znode); } synchronized (this.cache) { ZooKeeperProtos.Table.Builder builder = ZooKeeperProtos.Table.newBuilder(); builder.setState(state); byte [] data = ProtobufUtil.prependPBMagic(builder.build().toByteArray()); ZKUtil.setData(this.watcher, znode, data); this.cache.put(tableName, state); } }
/** * Checks if table is marked in specified state in ZK. {@inheritDoc} */ @Override public boolean isTableState(final TableName tableName, final boolean checkSource, final ZooKeeperProtos.Table.State... states) { boolean isTableInSpecifiedState; synchronized (this.cache) { ZooKeeperProtos.Table.State currentState = this.cache.get(tableName); if (checkSource) { // The cache might be out-of-date, try to find it out from the master source (zookeeper // server) and update the cache. try { ZooKeeperProtos.Table.State stateInZK = getTableState(watcher, tableName); if (currentState != stateInZK) { if (stateInZK != null) { this.cache.put(tableName, stateInZK); } else { this.cache.remove(tableName); } currentState = stateInZK; } } catch (KeeperException | InterruptedException e) { // Contacting zookeeper failed. Let us just trust the value in cache. } } return isTableInState(Arrays.asList(states), currentState); } }
/** * check if table is present. * * @param tableName table we're working on * @return true if the table is present */ @Override public boolean isTablePresent(final TableName tableName) { synchronized (this.cache) { ZooKeeperProtos.Table.State state = this.cache.get(tableName); return !(state == null); } }
/** * Gets a list of all the tables set as disabling in zookeeper. * @return Set of disabling tables, empty Set if none * @throws CoordinatedStateException if error happened in underlying coordination engine */ @Override public Set<TableName> getTablesInStates(ZooKeeperProtos.Table.State... states) throws InterruptedIOException, CoordinatedStateException { try { return getAllTables(states); } catch (KeeperException e) { throw new CoordinatedStateException(e); } }
/** * @return Content of the clusterup znode as a serialized pb with the pb * magic as prefix. */ static byte [] toByteArray() { ZooKeeperProtos.ClusterUp.Builder builder = ZooKeeperProtos.ClusterUp.newBuilder(); builder.setStartDate(new java.util.Date().toString()); return ProtobufUtil.prependPBMagic(builder.build().toByteArray()); }
/** * @param data Serialized date to parse. * @return A RegionTransition instance made of the passed <code>data</code> * @throws DeserializationException * @see #toByteArray() */ public static RegionTransition parseFrom(final byte [] data) throws DeserializationException { ProtobufUtil.expectPBMagicPrefix(data); try { int prefixLen = ProtobufUtil.lengthOfPBMagic(); ZooKeeperProtos.RegionTransition.Builder builder = ZooKeeperProtos.RegionTransition.newBuilder(); ProtobufUtil.mergeFrom(builder, data, prefixLen, data.length - prefixLen); return new RegionTransition(builder.build()); } catch (IOException e) { throw new DeserializationException(e); } }
/** * @param data Serialized date to parse. * @return An SplitLogTaskState instance made of the passed <code>data</code> * @throws DeserializationException * @see #toByteArray() */ public static SplitLogTask parseFrom(final byte [] data) throws DeserializationException { ProtobufUtil.expectPBMagicPrefix(data); try { int prefixLen = ProtobufUtil.lengthOfPBMagic(); ZooKeeperProtos.SplitLogTask.Builder builder = ZooKeeperProtos.SplitLogTask.newBuilder(); ProtobufUtil.mergeFrom(builder, data, prefixLen, data.length - prefixLen); return new SplitLogTask(builder.build()); } catch (IOException e) { throw new DeserializationException(Bytes.toStringBinary(data, 0, 64), e); } }
/** * @return This instance serialized into a byte array * @see #parseFrom(byte[]) */ public byte [] toByteArray() { // First create a pb ServerName. Then create a ByteString w/ the TaskState // bytes in it. Finally create a SplitLogTaskState passing in the two // pbs just created. HBaseProtos.ServerName snpb = ProtobufUtil.toServerName(this.originServer); ZooKeeperProtos.SplitLogTask slts = ZooKeeperProtos.SplitLogTask.newBuilder().setServerName(snpb).setState(this.state). setMode(this.mode).build(); return ProtobufUtil.prependPBMagic(slts.toByteArray()); }
/** * A region is offline, won't be in transition any more. Its state * should be the specified expected state, which can only be * Split/Merged/Offline/null(=Offline)/SplittingNew/MergingNew. */ public void regionOffline( final HRegionInfo hri, final State expectedState) { Preconditions.checkArgument(expectedState == null || RegionState.isUnassignable(expectedState), "Offlined region should not be " + expectedState); if (isRegionInState(hri, State.SPLITTING_NEW, State.MERGING_NEW)) { // Remove it from all region maps deleteRegion(hri); return; } State newState = expectedState == null ? State.OFFLINE : expectedState; updateRegionState(hri, newState); String encodedName = hri.getEncodedName(); synchronized (this) { regionsInTransition.remove(encodedName); ServerName oldServerName = regionAssignments.remove(hri); if (oldServerName != null && serverHoldings.containsKey(oldServerName)) { if (newState == State.MERGED || newState == State.SPLIT || hri.isMetaRegion() || tableStateManager.isTableState(hri.getTable(), ZooKeeperProtos.Table.State.DISABLED, ZooKeeperProtos.Table.State.DISABLING)) { // Offline the region only if it's merged/split, or the table is disabled/disabling. // Otherwise, offline it from this server only when it is online on a different server. LOG.info("Offlined " + hri.getShortNameToLog() + " from " + oldServerName); removeFromServerHoldings(oldServerName, hri); removeFromReplicaMapping(hri); } else { // Need to remember it so that we can offline it from this // server when it is online on a different server. oldAssignments.put(encodedName, oldServerName); } } } }
/** Public for hbck */ public static ZooKeeperProtos.TableLock fromBytes(byte[] bytes) { int pblen = ProtobufUtil.lengthOfPBMagic(); if (bytes == null || bytes.length < pblen) { return null; } try { ZooKeeperProtos.TableLock.Builder builder = ZooKeeperProtos.TableLock.newBuilder(); ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen); return builder.build(); } catch (IOException ex) { LOG.warn("Exception in deserialization", ex); } return null; }
/** * @param sn must not be null * @return Content of the master znode as a serialized pb with the pb * magic as prefix. */ static byte[] toByteArray(final ServerName sn, int infoPort) { ZooKeeperProtos.Master.Builder mbuilder = ZooKeeperProtos.Master.newBuilder(); HBaseProtos.ServerName.Builder snbuilder = HBaseProtos.ServerName.newBuilder(); snbuilder.setHostName(sn.getHostname()); snbuilder.setPort(sn.getPort()); snbuilder.setStartCode(sn.getStartcode()); mbuilder.setMaster(snbuilder.build()); mbuilder.setRpcVersion(HConstants.RPC_CURRENT_VERSION); mbuilder.setInfoPort(infoPort); return ProtobufUtil.prependPBMagic(mbuilder.build().toByteArray()); }
private void handleDisableTable() throws IOException, CoordinatedStateException { // Set table disabling flag up in zk. this.assignmentManager.getTableStateManager().setTableState(this.tableName, ZooKeeperProtos.Table.State.DISABLING); boolean done = false; while (true) { // Get list of online regions that are of this table. Regions that are // already closed will not be included in this list; i.e. the returned // list is not ALL regions in a table, its all online regions according // to the in-memory state on this master. final List<HRegionInfo> regions = this.assignmentManager .getRegionStates().getRegionsOfTable(tableName); if (regions.size() == 0) { done = true; break; } LOG.info("Offlining " + regions.size() + " regions."); BulkDisabler bd = new BulkDisabler(this.server, regions); try { if (bd.bulkAssign()) { done = true; break; } } catch (InterruptedException e) { LOG.warn("Disable was interrupted"); // Preserve the interrupt. Thread.currentThread().interrupt(); break; } } // Flip the table to disabled if success. if (done) this.assignmentManager.getTableStateManager().setTableState(this.tableName, ZooKeeperProtos.Table.State.DISABLED); LOG.info("Disabled table, " + this.tableName + ", is done=" + done); }
/** * @param data zookeeper data. may be null * @return pb object of master, null if no active master * @throws DeserializationException */ public static ZooKeeperProtos.Master parse(byte[] data) throws DeserializationException { if (data == null) { return null; } int prefixLen = ProtobufUtil.lengthOfPBMagic(); try { return ZooKeeperProtos.Master.PARSER.parseFrom(data, prefixLen, data.length - prefixLen); } catch (InvalidProtocolBufferException e) { throw new DeserializationException(e); } }
@Override public void checkTableModifiable(final TableName tableName) throws IOException, TableNotFoundException, TableNotDisabledException { if (isCatalogTable(tableName)) { throw new IOException("Can't modify catalog tables"); } if (!MetaTableAccessor.tableExists(getConnection(), tableName)) { throw new TableNotFoundException(tableName); } if (!getAssignmentManager().getTableStateManager(). isTableState(tableName, ZooKeeperProtos.Table.State.DISABLED)) { throw new TableNotDisabledException(tableName); } }
/** * Last action from the procedure - executed when online schema change is supported. * @param env MasterProcedureEnv * @throws IOException */ private void reOpenAllRegionsIfTableIsOnline(final MasterProcedureEnv env) throws IOException { // This operation only run when the table is enabled. if (!env.getMasterServices().getAssignmentManager().getTableStateManager() .isTableState(getTableName(), ZooKeeperProtos.Table.State.ENABLED)) { return; } List<HRegionInfo> regionInfoList = ProcedureSyncWait.getRegionsFromMeta(env, getTableName()); if (MasterDDLOperationHelper.reOpenAllRegions(env, getTableName(), regionInfoList)) { LOG.info("Completed add column family operation on table " + getTableName()); } else { LOG.warn("Error on reopening the regions on table " + getTableName()); } }
/** * Action before any real action of disabling table. Set the exception in the procedure instead * of throwing it. This approach is to deal with backward compatible with 1.0. * @param env MasterProcedureEnv * @throws HBaseException * @throws IOException */ private boolean prepareDisable(final MasterProcedureEnv env) throws HBaseException, IOException { boolean canTableBeDisabled = true; if (tableName.equals(TableName.META_TABLE_NAME)) { setFailure("master-disable-table", new ConstraintException("Cannot disable catalog table")); canTableBeDisabled = false; } else if (!MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) { setFailure("master-disable-table", new TableNotFoundException(tableName)); canTableBeDisabled = false; } else if (!skipTableStateCheck) { // There could be multiple client requests trying to disable or enable // the table at the same time. Ensure only the first request is honored // After that, no other requests can be accepted until the table reaches // DISABLED or ENABLED. // // Note: A quick state check should be enough for us to move forward. However, instead of // calling TableStateManager.isTableState() to just check the state, we called // TableStateManager.setTableStateIfInStates() to set the state to DISABLING from ENABLED. // This is because we treat empty state as enabled from 0.92-clusters. See // ZKTableStateManager.setTableStateIfInStates() that has a hack solution to work around // this issue. TableStateManager tsm = env.getMasterServices().getAssignmentManager().getTableStateManager(); if (!tsm.setTableStateIfInStates(tableName, ZooKeeperProtos.Table.State.DISABLING, ZooKeeperProtos.Table.State.DISABLING, ZooKeeperProtos.Table.State.ENABLED)) { LOG.info("Table " + tableName + " isn't enabled; skipping disable"); setFailure("master-disable-table", new TableNotEnabledException(tableName)); canTableBeDisabled = false; } } // We are done the check. Future actions in this procedure could be done asynchronously. ProcedurePrepareLatch.releaseLatch(syncLatch, this); return canTableBeDisabled; }
/** * Mark table state to Disabling * @param env MasterProcedureEnv * @throws IOException */ protected static void setTableStateToDisabling( final MasterProcedureEnv env, final TableName tableName) throws HBaseException, IOException { // Set table disabling flag up in zk. env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( tableName, ZooKeeperProtos.Table.State.DISABLING); }
/** * Mark table state to Disabled * @param env MasterProcedureEnv * @throws IOException */ protected static void setTableStateToDisabled( final MasterProcedureEnv env, final TableName tableName) throws HBaseException, IOException { // Flip the table to disabled env.getMasterServices().getAssignmentManager().getTableStateManager().setTableState( tableName, ZooKeeperProtos.Table.State.DISABLED); LOG.info("Disabled table, " + tableName + ", is completed."); }