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; 022 023import org.apache.hadoop.hbase.HConstants; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.hadoop.hbase.client.RegionInfo; 026import org.apache.hadoop.hbase.client.RegionInfoBuilder; 027import org.apache.hadoop.hbase.regionserver.RegionServerServices.RegionStateTransitionContext; 028import org.apache.hadoop.hbase.security.User; 029import org.apache.hadoop.hbase.util.Bytes; 030import org.apache.yetus.audience.InterfaceAudience; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 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.metricsRegionServer.incrSplitRequest(); 062 if (user != null && user.getUGI() != null) { 063 user.getUGI().doAs (new PrivilegedAction<Void>() { 064 @Override 065 public Void run() { 066 requestRegionSplit(); 067 return null; 068 } 069 }); 070 } else { 071 requestRegionSplit(); 072 } 073 } 074 075 private void requestRegionSplit() { 076 final TableName table = parent.getTable(); 077 final RegionInfo hri_a = RegionInfoBuilder.newBuilder(table) 078 .setStartKey(parent.getStartKey()) 079 .setEndKey(midKey) 080 .build(); 081 final RegionInfo hri_b = RegionInfoBuilder.newBuilder(table) 082 .setStartKey(midKey) 083 .setEndKey(parent.getEndKey()) 084 .build(); 085 // Send the split request to the master. the master will do the validation on the split-key. 086 // The parent region will be unassigned and the two new regions will be assigned. 087 // hri_a and hri_b objects may not reflect the regions that will be created, those objects 088 // are created just to pass the information to the reportRegionStateTransition(). 089 if (!server.reportRegionStateTransition(new RegionStateTransitionContext( 090 TransitionCode.READY_TO_SPLIT, HConstants.NO_SEQNUM, -1, parent, hri_a, hri_b))) { 091 LOG.error("Unable to ask master to split " + parent.getRegionNameAsString()); 092 } 093 } 094 095 @Override 096 public void run() { 097 if (this.server.isStopping() || this.server.isStopped()) { 098 LOG.debug("Skipping split because server is stopping=" + 099 this.server.isStopping() + " or stopped=" + this.server.isStopped()); 100 return; 101 } 102 103 doSplitting(); 104 } 105}