/** * Split a region on the region server. * * @param controller the RPC controller * @param request the request * @throws ServiceException */ @Override @QosPriority(priority=HConstants.ADMIN_QOS) public SplitRegionResponse splitRegion(final RpcController controller, final SplitRegionRequest request) throws ServiceException { try { checkOpen(); requestCount.increment(); Region region = getRegion(request.getRegion()); region.startRegionOperation(Operation.SPLIT_REGION); if (region.getRegionInfo().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) { throw new IOException("Can't split replicas directly. " + "Replicas are auto-split when their primary is split."); } LOG.info("Splitting " + region.getRegionInfo().getRegionNameAsString()); long startTime = EnvironmentEdgeManager.currentTime(); FlushResult flushResult = region.flush(true); if (flushResult.isFlushSucceeded()) { long endTime = EnvironmentEdgeManager.currentTime(); regionServer.metricsRegionServer.updateFlushTime(endTime - startTime); } byte[] splitPoint = null; if (request.hasSplitPoint()) { splitPoint = request.getSplitPoint().toByteArray(); } ((HRegion)region).forceSplit(splitPoint); regionServer.compactSplitThread.requestSplit(region, ((HRegion)region).checkSplit(), RpcServer.getRequestUser()); return SplitRegionResponse.newBuilder().build(); } catch (DroppedSnapshotException ex) { regionServer.abort("Replay of WAL required. Forcing server shutdown", ex); throw new ServiceException(ex); } catch (IOException ie) { throw new ServiceException(ie); } }
public void postStartRegionOperation(final Operation op) throws IOException { execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.postStartRegionOperation(ctx, op); } }); }
public void postCloseRegionOperation(final Operation op) throws IOException { execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { @Override public void call(RegionObserver oserver, ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException { oserver.postCloseRegionOperation(ctx, op); } }); }
@Override public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation op) throws IOException { if (ctPostStartRegionOperation.get() > 0) { ctPostCloseRegionOperation.incrementAndGet(); } }
@Override @QosPriority(priority=HConstants.ADMIN_QOS) public GetRegionInfoResponse getRegionInfo(final RpcController controller, final GetRegionInfoRequest request) throws ServiceException { try { checkOpen(); requestCount.increment(); HRegion region = getRegion(request.getRegion()); RegionInfo info = region.getRegionInfo(); byte[] bestSplitRow = null; if (request.hasBestSplitRow() && request.getBestSplitRow()) { HRegion r = region; region.startRegionOperation(Operation.SPLIT_REGION); r.forceSplit(null); bestSplitRow = r.checkSplit(); // when all table data are in memstore, bestSplitRow = null // try to flush region first if(bestSplitRow == null) { r.flush(true); bestSplitRow = r.checkSplit(); } r.clearSplit(); } GetRegionInfoResponse.Builder builder = GetRegionInfoResponse.newBuilder(); builder.setRegionInfo(ProtobufUtil.toRegionInfo(info)); if (request.hasCompactionState() && request.getCompactionState()) { builder.setCompactionState(ProtobufUtil.createCompactionState(region.getCompactionState())); } builder.setSplittable(region.isSplittable()); builder.setMergeable(region.isMergeable()); if (request.hasBestSplitRow() && request.getBestSplitRow() && bestSplitRow != null) { builder.setBestSplitRow(UnsafeByteOperations.unsafeWrap(bestSplitRow)); } return builder.build(); } catch (IOException ie) { throw new ServiceException(ie); } }
public void postStartRegionOperation(final Operation op) throws IOException { execOperation(coprocEnvironments.isEmpty()? null: new RegionObserverOperationWithoutResult() { @Override public void call(RegionObserver observer) throws IOException { observer.postStartRegionOperation(this, op); } }); }
public void postCloseRegionOperation(final Operation op) throws IOException { execOperation(coprocEnvironments.isEmpty()? null: new RegionObserverOperationWithoutResult() { @Override public void call(RegionObserver observer) throws IOException { observer.postCloseRegionOperation(this, op); } }); }
@Override public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation op) throws IOException { }
@Override public void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation op) throws IOException { }
/** * Compact a region on the region server. * * @param controller the RPC controller * @param request the request * @throws ServiceException */ @Override @QosPriority(priority=HConstants.ADMIN_QOS) public CompactRegionResponse compactRegion(final RpcController controller, final CompactRegionRequest request) throws ServiceException { try { checkOpen(); requestCount.increment(); Region region = getRegion(request.getRegion()); region.startRegionOperation(Operation.COMPACT_REGION); LOG.info("Compacting " + region.getRegionInfo().getRegionNameAsString()); boolean major = false; byte [] family = null; Store store = null; if (request.hasFamily()) { family = request.getFamily().toByteArray(); store = region.getStore(family); if (store == null) { throw new ServiceException(new IOException("column family " + Bytes.toString(family) + " does not exist in region " + region.getRegionInfo().getRegionNameAsString())); } } if (request.hasMajor()) { major = request.getMajor(); } if (major) { if (family != null) { store.triggerMajorCompaction(); } else { region.triggerMajorCompaction(); } } String familyLogMsg = (family != null)?" for column family: " + Bytes.toString(family):""; if (LOG.isTraceEnabled()) { LOG.trace("User-triggered compaction requested for region " + region.getRegionInfo().getRegionNameAsString() + familyLogMsg); } String log = "User-triggered " + (major ? "major " : "") + "compaction" + familyLogMsg; if(family != null) { regionServer.compactSplitThread.requestCompaction(region, store, log, Store.PRIORITY_USER, null, RpcServer.getRequestUser()); } else { regionServer.compactSplitThread.requestCompaction(region, log, Store.PRIORITY_USER, null, RpcServer.getRequestUser()); } return CompactRegionResponse.newBuilder().build(); } catch (IOException ie) { throw new ServiceException(ie); } }
@Override public void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation op) throws IOException { ctPostStartRegionOperation.incrementAndGet(); }
@Override public Void call() throws Exception { // Taking the region read lock prevents the individual region from being closed while a // snapshot is in progress. This is helpful but not sufficient for preventing races with // snapshots that involve multiple regions and regionservers. It is still possible to have // an interleaving such that globally regions are missing, so we still need the verification // step. LOG.debug("Starting snapshot operation on " + region); region.startRegionOperation(Operation.SNAPSHOT); try { if (skipFlush) { /* * This is to take an online-snapshot without force a coordinated flush to prevent pause * The snapshot type is defined inside the snapshot description. FlushSnapshotSubprocedure * should be renamed to distributedSnapshotSubprocedure, and the flush() behavior can be * turned on/off based on the flush type. * To minimized the code change, class name is not changed. */ LOG.debug("take snapshot without flush memstore first"); } else { LOG.debug("Flush Snapshotting region " + region.toString() + " started..."); boolean succeeded = false; long readPt = region.getReadPoint(IsolationLevel.READ_COMMITTED); for (int i = 0; i < MAX_RETRIES; i++) { FlushResult res = region.flush(true); if (res.getResult() == FlushResult.Result.CANNOT_FLUSH) { // CANNOT_FLUSH may mean that a flush is already on-going // we need to wait for that flush to complete region.waitForFlushes(); if (region.getMaxFlushedSeqId() >= readPt) { // writes at the start of the snapshot have been persisted succeeded = true; break; } } else { succeeded = true; break; } } if (!succeeded) { throw new IOException("Unable to complete flush after " + MAX_RETRIES + " attempts"); } } region.addRegionToSnapshot(snapshotDesc, monitor); if (skipFlush) { LOG.debug("... SkipFlush Snapshotting region " + region.toString() + " completed."); } else { LOG.debug("... Flush Snapshotting region " + region.toString() + " completed."); } } finally { LOG.debug("Closing snapshot operation on " + region); region.closeRegionOperation(Operation.SNAPSHOT); } return null; }
/** * This will be called for region operations where read lock is acquired in * {@link Region#startRegionOperation()}. * @param ctx * @param operation The operation is about to be taken on the region * @throws IOException */ void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation operation) throws IOException;
/** * Called after releasing read lock in {@link Region#closeRegionOperation()}. * @param ctx * @param operation * @throws IOException */ void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, Operation operation) throws IOException;
/** * This will be called for region operations where read lock is acquired in * {@link Region#startRegionOperation()}. * @param ctx * @param operation The operation is about to be taken on the region */ default void postStartRegionOperation(ObserverContext<RegionCoprocessorEnvironment> ctx, Operation operation) throws IOException {}
/** * Called after releasing read lock in {@link Region#closeRegionOperation()}. * @param ctx * @param operation */ default void postCloseRegionOperation(ObserverContext<RegionCoprocessorEnvironment> ctx, Operation operation) throws IOException {}