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