/** * Merge two regions. Asynchronous operation. * @param encodedNameOfRegionA encoded name of region a * @param encodedNameOfRegionB encoded name of region b * @param forcible true if do a compulsory merge, otherwise we will only merge * two adjacent regions * @throws IOException */ @Override public void mergeRegions(final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB, final boolean forcible) throws IOException { executeCallable(new MasterCallable<Void>(getConnection()) { @Override public Void call(int callTimeout) throws ServiceException { try { DispatchMergingRegionsRequest request = RequestConverter .buildDispatchMergingRegionsRequest(encodedNameOfRegionA, encodedNameOfRegionB, forcible); master.dispatchMergingRegions(null, request); } catch (DeserializationException de) { LOG.error("Could not parse destination server name: " + de); } return null; } }); }
public static DispatchMergingRegionsRequest buildDispatchMergingRegionsRequest( final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB, final boolean forcible) throws DeserializationException { DispatchMergingRegionsRequest.Builder builder = DispatchMergingRegionsRequest.newBuilder(); builder.setRegionA(buildRegionSpecifier( RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionA)); builder.setRegionB(buildRegionSpecifier( RegionSpecifierType.ENCODED_REGION_NAME, encodedNameOfRegionB)); builder.setForcible(forcible); return builder.build(); }
/** * Merge two regions. Asynchronous operation. * @param nameOfRegionA encoded or full name of region a * @param nameOfRegionB encoded or full name of region b * @param forcible true if do a compulsory merge, otherwise we will only merge * two adjacent regions * @throws IOException */ @Override public void mergeRegions(final byte[] nameOfRegionA, final byte[] nameOfRegionB, final boolean forcible) throws IOException { final byte[] encodedNameOfRegionA = isEncodedRegionName(nameOfRegionA) ? nameOfRegionA : HRegionInfo.encodeRegionName(nameOfRegionA).getBytes(); final byte[] encodedNameOfRegionB = isEncodedRegionName(nameOfRegionB) ? nameOfRegionB : HRegionInfo.encodeRegionName(nameOfRegionB).getBytes(); Pair<HRegionInfo, ServerName> pair = getRegion(nameOfRegionA); if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) throw new IllegalArgumentException("Can't invoke merge on non-default regions directly"); pair = getRegion(nameOfRegionB); if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) throw new IllegalArgumentException("Can't invoke merge on non-default regions directly"); executeCallable(new MasterCallable<Void>(getConnection()) { @Override public Void call(int callTimeout) throws ServiceException { PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setCallTimeout(callTimeout); try { DispatchMergingRegionsRequest request = RequestConverter .buildDispatchMergingRegionsRequest(encodedNameOfRegionA, encodedNameOfRegionB, forcible); master.dispatchMergingRegions(controller, request); } catch (DeserializationException de) { LOG.error("Could not parse destination server name: " + de); } return null; } }); }
/** * Merge two regions. Asynchronous operation. * @param encodedNameOfRegionA encoded name of region a * @param encodedNameOfRegionB encoded name of region b * @param forcible true if do a compulsory merge, otherwise we will only merge * two adjacent regions * @throws IOException */ public void mergeRegions(final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB, final boolean forcible) throws IOException { MasterKeepAliveConnection master = connection .getKeepAliveMasterService(); try { DispatchMergingRegionsRequest request = RequestConverter .buildDispatchMergingRegionsRequest(encodedNameOfRegionA, encodedNameOfRegionB, forcible); master.dispatchMergingRegions(null, request); } catch (ServiceException se) { IOException ioe = ProtobufUtil.getRemoteException(se); if (ioe instanceof UnknownRegionException) { throw (UnknownRegionException) ioe; } if (ioe instanceof MergeRegionException) { throw (MergeRegionException) ioe; } LOG.error("Unexpected exception: " + se + " from calling HMaster.dispatchMergingRegions"); } catch (DeserializationException de) { LOG.error("Could not parse destination server name: " + de); } finally { master.close(); } }
@Override public DispatchMergingRegionsResponse dispatchMergingRegions( RpcController controller, DispatchMergingRegionsRequest request) throws ServiceException { final byte[] encodedNameOfRegionA = request.getRegionA().getValue() .toByteArray(); final byte[] encodedNameOfRegionB = request.getRegionB().getValue() .toByteArray(); final boolean forcible = request.getForcible(); if (request.getRegionA().getType() != RegionSpecifierType.ENCODED_REGION_NAME || request.getRegionB().getType() != RegionSpecifierType.ENCODED_REGION_NAME) { LOG.warn("mergeRegions specifier type: expected: " + RegionSpecifierType.ENCODED_REGION_NAME + " actual: region_a=" + request.getRegionA().getType() + ", region_b=" + request.getRegionB().getType()); } RegionState regionStateA = assignmentManager.getRegionStates() .getRegionState(Bytes.toString(encodedNameOfRegionA)); RegionState regionStateB = assignmentManager.getRegionStates() .getRegionState(Bytes.toString(encodedNameOfRegionB)); if (regionStateA == null || regionStateB == null) { throw new ServiceException(new UnknownRegionException( Bytes.toStringBinary(regionStateA == null ? encodedNameOfRegionA : encodedNameOfRegionB))); } if (!regionStateA.isOpened() || !regionStateB.isOpened()) { throw new ServiceException(new MergeRegionException( "Unable to merge regions not online " + regionStateA + ", " + regionStateB)); } HRegionInfo regionInfoA = regionStateA.getRegion(); HRegionInfo regionInfoB = regionStateB.getRegion(); if (regionInfoA.compareTo(regionInfoB) == 0) { throw new ServiceException(new MergeRegionException( "Unable to merge a region to itself " + regionInfoA + ", " + regionInfoB)); } if (!forcible && !HRegionInfo.areAdjacent(regionInfoA, regionInfoB)) { throw new ServiceException(new MergeRegionException( "Unable to merge not adjacent regions " + regionInfoA.getRegionNameAsString() + ", " + regionInfoB.getRegionNameAsString() + " where forcible = " + forcible)); } try { dispatchMergingRegions(regionInfoA, regionInfoB, forcible); } catch (IOException ioe) { throw new ServiceException(ioe); } return DispatchMergingRegionsResponse.newBuilder().build(); }