001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import java.security.PrivilegedAction; 021import org.apache.hadoop.hbase.HConstants; 022import org.apache.hadoop.hbase.TableName; 023import org.apache.hadoop.hbase.client.RegionInfo; 024import org.apache.hadoop.hbase.client.RegionInfoBuilder; 025import org.apache.hadoop.hbase.regionserver.RegionServerServices.RegionStateTransitionContext; 026import org.apache.hadoop.hbase.security.User; 027import org.apache.hadoop.hbase.util.Bytes; 028import org.apache.yetus.audience.InterfaceAudience; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 033 034import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode; 035 036/** 037 * Handles processing region splits. Put in a queue, owned by HRegionServer. 038 */ 039@InterfaceAudience.Private 040class SplitRequest implements Runnable { 041 private static final Logger LOG = LoggerFactory.getLogger(SplitRequest.class); 042 private final RegionInfo parent; 043 private final byte[] midKey; 044 private final HRegionServer server; 045 private final User user; 046 047 SplitRequest(Region region, byte[] midKey, HRegionServer hrs, User user) { 048 Preconditions.checkNotNull(hrs); 049 this.parent = region.getRegionInfo(); 050 this.midKey = midKey; 051 this.server = hrs; 052 this.user = user; 053 } 054 055 @Override 056 public String toString() { 057 return "regionName=" + parent + ", midKey=" + Bytes.toStringBinary(midKey); 058 } 059 060 private void doSplitting() { 061 server.getMetrics().incrSplitRequest(); 062 if (user != null && user.getUGI() != null) { 063 user.getUGI().doAs((PrivilegedAction<Void>) () -> { 064 requestRegionSplit(); 065 return null; 066 }); 067 } else { 068 requestRegionSplit(); 069 } 070 } 071 072 private void requestRegionSplit() { 073 final TableName table = parent.getTable(); 074 final RegionInfo hri_a = RegionInfoBuilder.newBuilder(table).setStartKey(parent.getStartKey()) 075 .setEndKey(midKey).build(); 076 final RegionInfo hri_b = 077 RegionInfoBuilder.newBuilder(table).setStartKey(midKey).setEndKey(parent.getEndKey()).build(); 078 // Send the split request to the master. the master will do the validation on the split-key. 079 // The parent region will be unassigned and the two new regions will be assigned. 080 // hri_a and hri_b objects may not reflect the regions that will be created, those objects 081 // are created just to pass the information to the reportRegionStateTransition(). 082 if ( 083 !server.reportRegionStateTransition(new RegionStateTransitionContext( 084 TransitionCode.READY_TO_SPLIT, HConstants.NO_SEQNUM, -1, -1, parent, hri_a, hri_b)) 085 ) { 086 LOG.error("Unable to ask master to split " + parent.getRegionNameAsString()); 087 } 088 } 089 090 @Override 091 public void run() { 092 if (this.server.isStopping() || this.server.isStopped()) { 093 LOG.debug("Skipping split because server is stopping=" + this.server.isStopping() 094 + " or stopped=" + this.server.isStopped()); 095 return; 096 } 097 098 doSplitting(); 099 } 100}