| <!DOCTYPE HTML> |
| <html lang="en"> |
| <head> |
| <!-- Generated by javadoc (17) --> |
| <title>Source code</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <meta name="description" content="source: package: org.apache.hadoop.hbase.master.assignment, class: SplitTableRegionProcedure"> |
| <meta name="generator" content="javadoc/SourceToHTMLConverter"> |
| <link rel="stylesheet" type="text/css" href="../../../../../../../stylesheet.css" title="Style"> |
| </head> |
| <body class="source-page"> |
| <main role="main"> |
| <div class="source-container"> |
| <pre><span class="source-line-no">001</span><span id="line-1">/*</span> |
| <span class="source-line-no">002</span><span id="line-2"> * Licensed to the Apache Software Foundation (ASF) under one</span> |
| <span class="source-line-no">003</span><span id="line-3"> * or more contributor license agreements. See the NOTICE file</span> |
| <span class="source-line-no">004</span><span id="line-4"> * distributed with this work for additional information</span> |
| <span class="source-line-no">005</span><span id="line-5"> * regarding copyright ownership. The ASF licenses this file</span> |
| <span class="source-line-no">006</span><span id="line-6"> * to you under the Apache License, Version 2.0 (the</span> |
| <span class="source-line-no">007</span><span id="line-7"> * "License"); you may not use this file except in compliance</span> |
| <span class="source-line-no">008</span><span id="line-8"> * with the License. You may obtain a copy of the License at</span> |
| <span class="source-line-no">009</span><span id="line-9"> *</span> |
| <span class="source-line-no">010</span><span id="line-10"> * http://www.apache.org/licenses/LICENSE-2.0</span> |
| <span class="source-line-no">011</span><span id="line-11"> *</span> |
| <span class="source-line-no">012</span><span id="line-12"> * Unless required by applicable law or agreed to in writing, software</span> |
| <span class="source-line-no">013</span><span id="line-13"> * distributed under the License is distributed on an "AS IS" BASIS,</span> |
| <span class="source-line-no">014</span><span id="line-14"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span> |
| <span class="source-line-no">015</span><span id="line-15"> * See the License for the specific language governing permissions and</span> |
| <span class="source-line-no">016</span><span id="line-16"> * limitations under the License.</span> |
| <span class="source-line-no">017</span><span id="line-17"> */</span> |
| <span class="source-line-no">018</span><span id="line-18">package org.apache.hadoop.hbase.master.assignment;</span> |
| <span class="source-line-no">019</span><span id="line-19"></span> |
| <span class="source-line-no">020</span><span id="line-20">import java.io.IOException;</span> |
| <span class="source-line-no">021</span><span id="line-21">import java.io.InterruptedIOException;</span> |
| <span class="source-line-no">022</span><span id="line-22">import java.util.ArrayList;</span> |
| <span class="source-line-no">023</span><span id="line-23">import java.util.Arrays;</span> |
| <span class="source-line-no">024</span><span id="line-24">import java.util.Collection;</span> |
| <span class="source-line-no">025</span><span id="line-25">import java.util.Collections;</span> |
| <span class="source-line-no">026</span><span id="line-26">import java.util.HashMap;</span> |
| <span class="source-line-no">027</span><span id="line-27">import java.util.List;</span> |
| <span class="source-line-no">028</span><span id="line-28">import java.util.Map;</span> |
| <span class="source-line-no">029</span><span id="line-29">import java.util.concurrent.Callable;</span> |
| <span class="source-line-no">030</span><span id="line-30">import java.util.concurrent.ExecutionException;</span> |
| <span class="source-line-no">031</span><span id="line-31">import java.util.concurrent.ExecutorService;</span> |
| <span class="source-line-no">032</span><span id="line-32">import java.util.concurrent.Executors;</span> |
| <span class="source-line-no">033</span><span id="line-33">import java.util.concurrent.Future;</span> |
| <span class="source-line-no">034</span><span id="line-34">import java.util.concurrent.TimeUnit;</span> |
| <span class="source-line-no">035</span><span id="line-35">import java.util.stream.Stream;</span> |
| <span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.conf.Configuration;</span> |
| <span class="source-line-no">037</span><span id="line-37">import org.apache.hadoop.fs.FileSystem;</span> |
| <span class="source-line-no">038</span><span id="line-38">import org.apache.hadoop.fs.Path;</span> |
| <span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.DoNotRetryIOException;</span> |
| <span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.HConstants;</span> |
| <span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.ServerName;</span> |
| <span class="source-line-no">042</span><span id="line-42">import org.apache.hadoop.hbase.TableName;</span> |
| <span class="source-line-no">043</span><span id="line-43">import org.apache.hadoop.hbase.UnknownRegionException;</span> |
| <span class="source-line-no">044</span><span id="line-44">import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;</span> |
| <span class="source-line-no">045</span><span id="line-45">import org.apache.hadoop.hbase.client.MasterSwitchType;</span> |
| <span class="source-line-no">046</span><span id="line-46">import org.apache.hadoop.hbase.client.Mutation;</span> |
| <span class="source-line-no">047</span><span id="line-47">import org.apache.hadoop.hbase.client.RegionInfo;</span> |
| <span class="source-line-no">048</span><span id="line-48">import org.apache.hadoop.hbase.client.RegionInfoBuilder;</span> |
| <span class="source-line-no">049</span><span id="line-49">import org.apache.hadoop.hbase.client.TableDescriptor;</span> |
| <span class="source-line-no">050</span><span id="line-50">import org.apache.hadoop.hbase.io.hfile.CacheConfig;</span> |
| <span class="source-line-no">051</span><span id="line-51">import org.apache.hadoop.hbase.master.MasterCoprocessorHost;</span> |
| <span class="source-line-no">052</span><span id="line-52">import org.apache.hadoop.hbase.master.MasterFileSystem;</span> |
| <span class="source-line-no">053</span><span id="line-53">import org.apache.hadoop.hbase.master.RegionState.State;</span> |
| <span class="source-line-no">054</span><span id="line-54">import org.apache.hadoop.hbase.master.normalizer.NormalizationPlan;</span> |
| <span class="source-line-no">055</span><span id="line-55">import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineRegionProcedure;</span> |
| <span class="source-line-no">056</span><span id="line-56">import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;</span> |
| <span class="source-line-no">057</span><span id="line-57">import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil;</span> |
| <span class="source-line-no">058</span><span id="line-58">import org.apache.hadoop.hbase.procedure2.ProcedureMetrics;</span> |
| <span class="source-line-no">059</span><span id="line-59">import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;</span> |
| <span class="source-line-no">060</span><span id="line-60">import org.apache.hadoop.hbase.quotas.MasterQuotaManager;</span> |
| <span class="source-line-no">061</span><span id="line-61">import org.apache.hadoop.hbase.quotas.QuotaExceededException;</span> |
| <span class="source-line-no">062</span><span id="line-62">import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;</span> |
| <span class="source-line-no">063</span><span id="line-63">import org.apache.hadoop.hbase.regionserver.HStore;</span> |
| <span class="source-line-no">064</span><span id="line-64">import org.apache.hadoop.hbase.regionserver.HStoreFile;</span> |
| <span class="source-line-no">065</span><span id="line-65">import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy;</span> |
| <span class="source-line-no">066</span><span id="line-66">import org.apache.hadoop.hbase.regionserver.RegionSplitRestriction;</span> |
| <span class="source-line-no">067</span><span id="line-67">import org.apache.hadoop.hbase.regionserver.StoreFileInfo;</span> |
| <span class="source-line-no">068</span><span id="line-68">import org.apache.hadoop.hbase.regionserver.StoreUtils;</span> |
| <span class="source-line-no">069</span><span id="line-69">import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTracker;</span> |
| <span class="source-line-no">070</span><span id="line-70">import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory;</span> |
| <span class="source-line-no">071</span><span id="line-71">import org.apache.hadoop.hbase.util.Bytes;</span> |
| <span class="source-line-no">072</span><span id="line-72">import org.apache.hadoop.hbase.util.CommonFSUtils;</span> |
| <span class="source-line-no">073</span><span id="line-73">import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;</span> |
| <span class="source-line-no">074</span><span id="line-74">import org.apache.hadoop.hbase.util.FSUtils;</span> |
| <span class="source-line-no">075</span><span id="line-75">import org.apache.hadoop.hbase.util.Pair;</span> |
| <span class="source-line-no">076</span><span id="line-76">import org.apache.hadoop.hbase.util.Threads;</span> |
| <span class="source-line-no">077</span><span id="line-77">import org.apache.hadoop.hbase.wal.WALSplitUtil;</span> |
| <span class="source-line-no">078</span><span id="line-78">import org.apache.hadoop.util.ReflectionUtils;</span> |
| <span class="source-line-no">079</span><span id="line-79">import org.apache.yetus.audience.InterfaceAudience;</span> |
| <span class="source-line-no">080</span><span id="line-80">import org.slf4j.Logger;</span> |
| <span class="source-line-no">081</span><span id="line-81">import org.slf4j.LoggerFactory;</span> |
| <span class="source-line-no">082</span><span id="line-82"></span> |
| <span class="source-line-no">083</span><span id="line-83">import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;</span> |
| <span class="source-line-no">084</span><span id="line-84"></span> |
| <span class="source-line-no">085</span><span id="line-85">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span> |
| <span class="source-line-no">086</span><span id="line-86">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse;</span> |
| <span class="source-line-no">087</span><span id="line-87">import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos;</span> |
| <span class="source-line-no">088</span><span id="line-88">import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.SplitTableRegionState;</span> |
| <span class="source-line-no">089</span><span id="line-89"></span> |
| <span class="source-line-no">090</span><span id="line-90">/**</span> |
| <span class="source-line-no">091</span><span id="line-91"> * The procedure to split a region in a table. Takes lock on the parent region. It holds the lock</span> |
| <span class="source-line-no">092</span><span id="line-92"> * for the life of the procedure.</span> |
| <span class="source-line-no">093</span><span id="line-93"> * <p></span> |
| <span class="source-line-no">094</span><span id="line-94"> * Throws exception on construction if determines context hostile to spllt (cluster going down or</span> |
| <span class="source-line-no">095</span><span id="line-95"> * master is shutting down or table is disabled).</span> |
| <span class="source-line-no">096</span><span id="line-96"> * </p></span> |
| <span class="source-line-no">097</span><span id="line-97"> */</span> |
| <span class="source-line-no">098</span><span id="line-98">@InterfaceAudience.Private</span> |
| <span class="source-line-no">099</span><span id="line-99">public class SplitTableRegionProcedure</span> |
| <span class="source-line-no">100</span><span id="line-100"> extends AbstractStateMachineRegionProcedure<SplitTableRegionState> {</span> |
| <span class="source-line-no">101</span><span id="line-101"> private static final Logger LOG = LoggerFactory.getLogger(SplitTableRegionProcedure.class);</span> |
| <span class="source-line-no">102</span><span id="line-102"> private RegionInfo daughterOneRI;</span> |
| <span class="source-line-no">103</span><span id="line-103"> private RegionInfo daughterTwoRI;</span> |
| <span class="source-line-no">104</span><span id="line-104"> private byte[] bestSplitRow;</span> |
| <span class="source-line-no">105</span><span id="line-105"> private RegionSplitPolicy splitPolicy;</span> |
| <span class="source-line-no">106</span><span id="line-106"> // exposed for unit testing</span> |
| <span class="source-line-no">107</span><span id="line-107"> boolean checkTableModifyInProgress = true;</span> |
| <span class="source-line-no">108</span><span id="line-108"></span> |
| <span class="source-line-no">109</span><span id="line-109"> public SplitTableRegionProcedure() {</span> |
| <span class="source-line-no">110</span><span id="line-110"> // Required by the Procedure framework to create the procedure on replay</span> |
| <span class="source-line-no">111</span><span id="line-111"> }</span> |
| <span class="source-line-no">112</span><span id="line-112"></span> |
| <span class="source-line-no">113</span><span id="line-113"> public SplitTableRegionProcedure(final MasterProcedureEnv env, final RegionInfo regionToSplit,</span> |
| <span class="source-line-no">114</span><span id="line-114"> final byte[] splitRow) throws IOException {</span> |
| <span class="source-line-no">115</span><span id="line-115"> super(env, regionToSplit);</span> |
| <span class="source-line-no">116</span><span id="line-116"> preflightChecks(env, true);</span> |
| <span class="source-line-no">117</span><span id="line-117"> // When procedure goes to run in its prepare step, it also does these checkOnline checks. Here</span> |
| <span class="source-line-no">118</span><span id="line-118"> // we fail-fast on construction. There it skips the split with just a warning.</span> |
| <span class="source-line-no">119</span><span id="line-119"> checkOnline(env, regionToSplit);</span> |
| <span class="source-line-no">120</span><span id="line-120"> this.bestSplitRow = splitRow;</span> |
| <span class="source-line-no">121</span><span id="line-121"> TableDescriptor tableDescriptor =</span> |
| <span class="source-line-no">122</span><span id="line-122"> env.getMasterServices().getTableDescriptors().get(getTableName());</span> |
| <span class="source-line-no">123</span><span id="line-123"> Configuration conf = env.getMasterConfiguration();</span> |
| <span class="source-line-no">124</span><span id="line-124"> if (hasBestSplitRow()) {</span> |
| <span class="source-line-no">125</span><span id="line-125"> // Apply the split restriction for the table to the user-specified split point</span> |
| <span class="source-line-no">126</span><span id="line-126"> RegionSplitRestriction splitRestriction =</span> |
| <span class="source-line-no">127</span><span id="line-127"> RegionSplitRestriction.create(tableDescriptor, conf);</span> |
| <span class="source-line-no">128</span><span id="line-128"> byte[] restrictedSplitRow = splitRestriction.getRestrictedSplitPoint(bestSplitRow);</span> |
| <span class="source-line-no">129</span><span id="line-129"> if (!Bytes.equals(bestSplitRow, restrictedSplitRow)) {</span> |
| <span class="source-line-no">130</span><span id="line-130"> LOG.warn(</span> |
| <span class="source-line-no">131</span><span id="line-131"> "The specified split point {} violates the split restriction of the table. "</span> |
| <span class="source-line-no">132</span><span id="line-132"> + "Using {} as a split point.",</span> |
| <span class="source-line-no">133</span><span id="line-133"> Bytes.toStringBinary(bestSplitRow), Bytes.toStringBinary(restrictedSplitRow));</span> |
| <span class="source-line-no">134</span><span id="line-134"> bestSplitRow = restrictedSplitRow;</span> |
| <span class="source-line-no">135</span><span id="line-135"> }</span> |
| <span class="source-line-no">136</span><span id="line-136"> }</span> |
| <span class="source-line-no">137</span><span id="line-137"> checkSplittable(env, regionToSplit);</span> |
| <span class="source-line-no">138</span><span id="line-138"> final TableName table = regionToSplit.getTable();</span> |
| <span class="source-line-no">139</span><span id="line-139"> final long rid = getDaughterRegionIdTimestamp(regionToSplit);</span> |
| <span class="source-line-no">140</span><span id="line-140"> this.daughterOneRI =</span> |
| <span class="source-line-no">141</span><span id="line-141"> RegionInfoBuilder.newBuilder(table).setStartKey(regionToSplit.getStartKey())</span> |
| <span class="source-line-no">142</span><span id="line-142"> .setEndKey(bestSplitRow).setSplit(false).setRegionId(rid).build();</span> |
| <span class="source-line-no">143</span><span id="line-143"> this.daughterTwoRI = RegionInfoBuilder.newBuilder(table).setStartKey(bestSplitRow)</span> |
| <span class="source-line-no">144</span><span id="line-144"> .setEndKey(regionToSplit.getEndKey()).setSplit(false).setRegionId(rid).build();</span> |
| <span class="source-line-no">145</span><span id="line-145"></span> |
| <span class="source-line-no">146</span><span id="line-146"> if (tableDescriptor.getRegionSplitPolicyClassName() != null) {</span> |
| <span class="source-line-no">147</span><span id="line-147"> // Since we don't have region reference here, creating the split policy instance without it.</span> |
| <span class="source-line-no">148</span><span id="line-148"> // This can be used to invoke methods which don't require Region reference. This instantiation</span> |
| <span class="source-line-no">149</span><span id="line-149"> // of a class on Master-side though it only makes sense on the RegionServer-side is</span> |
| <span class="source-line-no">150</span><span id="line-150"> // for Phoenix Local Indexing. Refer HBASE-12583 for more information.</span> |
| <span class="source-line-no">151</span><span id="line-151"> Class<? extends RegionSplitPolicy> clazz =</span> |
| <span class="source-line-no">152</span><span id="line-152"> RegionSplitPolicy.getSplitPolicyClass(tableDescriptor, conf);</span> |
| <span class="source-line-no">153</span><span id="line-153"> this.splitPolicy = ReflectionUtils.newInstance(clazz, conf);</span> |
| <span class="source-line-no">154</span><span id="line-154"> }</span> |
| <span class="source-line-no">155</span><span id="line-155"> }</span> |
| <span class="source-line-no">156</span><span id="line-156"></span> |
| <span class="source-line-no">157</span><span id="line-157"> @Override</span> |
| <span class="source-line-no">158</span><span id="line-158"> protected LockState acquireLock(final MasterProcedureEnv env) {</span> |
| <span class="source-line-no">159</span><span id="line-159"> if (</span> |
| <span class="source-line-no">160</span><span id="line-160"> env.getProcedureScheduler().waitRegions(this, getTableName(), getParentRegion(),</span> |
| <span class="source-line-no">161</span><span id="line-161"> daughterOneRI, daughterTwoRI)</span> |
| <span class="source-line-no">162</span><span id="line-162"> ) {</span> |
| <span class="source-line-no">163</span><span id="line-163"> try {</span> |
| <span class="source-line-no">164</span><span id="line-164"> LOG.debug(LockState.LOCK_EVENT_WAIT + " " + env.getProcedureScheduler().dumpLocks());</span> |
| <span class="source-line-no">165</span><span id="line-165"> } catch (IOException e) {</span> |
| <span class="source-line-no">166</span><span id="line-166"> // Ignore, just for logging</span> |
| <span class="source-line-no">167</span><span id="line-167"> }</span> |
| <span class="source-line-no">168</span><span id="line-168"> return LockState.LOCK_EVENT_WAIT;</span> |
| <span class="source-line-no">169</span><span id="line-169"> }</span> |
| <span class="source-line-no">170</span><span id="line-170"> return LockState.LOCK_ACQUIRED;</span> |
| <span class="source-line-no">171</span><span id="line-171"> }</span> |
| <span class="source-line-no">172</span><span id="line-172"></span> |
| <span class="source-line-no">173</span><span id="line-173"> @Override</span> |
| <span class="source-line-no">174</span><span id="line-174"> protected void releaseLock(final MasterProcedureEnv env) {</span> |
| <span class="source-line-no">175</span><span id="line-175"> env.getProcedureScheduler().wakeRegions(this, getTableName(), getParentRegion(), daughterOneRI,</span> |
| <span class="source-line-no">176</span><span id="line-176"> daughterTwoRI);</span> |
| <span class="source-line-no">177</span><span id="line-177"> }</span> |
| <span class="source-line-no">178</span><span id="line-178"></span> |
| <span class="source-line-no">179</span><span id="line-179"> public RegionInfo getDaughterOneRI() {</span> |
| <span class="source-line-no">180</span><span id="line-180"> return daughterOneRI;</span> |
| <span class="source-line-no">181</span><span id="line-181"> }</span> |
| <span class="source-line-no">182</span><span id="line-182"></span> |
| <span class="source-line-no">183</span><span id="line-183"> public RegionInfo getDaughterTwoRI() {</span> |
| <span class="source-line-no">184</span><span id="line-184"> return daughterTwoRI;</span> |
| <span class="source-line-no">185</span><span id="line-185"> }</span> |
| <span class="source-line-no">186</span><span id="line-186"></span> |
| <span class="source-line-no">187</span><span id="line-187"> private boolean hasBestSplitRow() {</span> |
| <span class="source-line-no">188</span><span id="line-188"> return bestSplitRow != null && bestSplitRow.length > 0;</span> |
| <span class="source-line-no">189</span><span id="line-189"> }</span> |
| <span class="source-line-no">190</span><span id="line-190"></span> |
| <span class="source-line-no">191</span><span id="line-191"> /**</span> |
| <span class="source-line-no">192</span><span id="line-192"> * Check whether the region is splittable</span> |
| <span class="source-line-no">193</span><span id="line-193"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">194</span><span id="line-194"> * @param regionToSplit parent Region to be split</span> |
| <span class="source-line-no">195</span><span id="line-195"> */</span> |
| <span class="source-line-no">196</span><span id="line-196"> private void checkSplittable(final MasterProcedureEnv env, final RegionInfo regionToSplit)</span> |
| <span class="source-line-no">197</span><span id="line-197"> throws IOException {</span> |
| <span class="source-line-no">198</span><span id="line-198"> // Ask the remote RS if this region is splittable.</span> |
| <span class="source-line-no">199</span><span id="line-199"> // If we get an IOE, report it along w/ the failure so can see why we are not splittable at</span> |
| <span class="source-line-no">200</span><span id="line-200"> // this time.</span> |
| <span class="source-line-no">201</span><span id="line-201"> if (regionToSplit.getReplicaId() != RegionInfo.DEFAULT_REPLICA_ID) {</span> |
| <span class="source-line-no">202</span><span id="line-202"> throw new IllegalArgumentException("Can't invoke split on non-default regions directly");</span> |
| <span class="source-line-no">203</span><span id="line-203"> }</span> |
| <span class="source-line-no">204</span><span id="line-204"> RegionStateNode node =</span> |
| <span class="source-line-no">205</span><span id="line-205"> env.getAssignmentManager().getRegionStates().getRegionStateNode(getParentRegion());</span> |
| <span class="source-line-no">206</span><span id="line-206"> IOException splittableCheckIOE = null;</span> |
| <span class="source-line-no">207</span><span id="line-207"> boolean splittable = false;</span> |
| <span class="source-line-no">208</span><span id="line-208"> if (node != null) {</span> |
| <span class="source-line-no">209</span><span id="line-209"> try {</span> |
| <span class="source-line-no">210</span><span id="line-210"> GetRegionInfoResponse response;</span> |
| <span class="source-line-no">211</span><span id="line-211"> if (!hasBestSplitRow()) {</span> |
| <span class="source-line-no">212</span><span id="line-212"> LOG.info(</span> |
| <span class="source-line-no">213</span><span id="line-213"> "{} splitKey isn't explicitly specified, will try to find a best split key from RS {}",</span> |
| <span class="source-line-no">214</span><span id="line-214"> node.getRegionInfo().getRegionNameAsString(), node.getRegionLocation());</span> |
| <span class="source-line-no">215</span><span id="line-215"> response = AssignmentManagerUtil.getRegionInfoResponse(env, node.getRegionLocation(),</span> |
| <span class="source-line-no">216</span><span id="line-216"> node.getRegionInfo(), true);</span> |
| <span class="source-line-no">217</span><span id="line-217"> bestSplitRow =</span> |
| <span class="source-line-no">218</span><span id="line-218"> response.hasBestSplitRow() ? response.getBestSplitRow().toByteArray() : null;</span> |
| <span class="source-line-no">219</span><span id="line-219"> } else {</span> |
| <span class="source-line-no">220</span><span id="line-220"> response = AssignmentManagerUtil.getRegionInfoResponse(env, node.getRegionLocation(),</span> |
| <span class="source-line-no">221</span><span id="line-221"> node.getRegionInfo(), false);</span> |
| <span class="source-line-no">222</span><span id="line-222"> }</span> |
| <span class="source-line-no">223</span><span id="line-223"> splittable = response.hasSplittable() && response.getSplittable();</span> |
| <span class="source-line-no">224</span><span id="line-224"> if (LOG.isDebugEnabled()) {</span> |
| <span class="source-line-no">225</span><span id="line-225"> LOG.debug("Splittable=" + splittable + " " + node.toShortString());</span> |
| <span class="source-line-no">226</span><span id="line-226"> }</span> |
| <span class="source-line-no">227</span><span id="line-227"> } catch (IOException e) {</span> |
| <span class="source-line-no">228</span><span id="line-228"> splittableCheckIOE = e;</span> |
| <span class="source-line-no">229</span><span id="line-229"> }</span> |
| <span class="source-line-no">230</span><span id="line-230"> }</span> |
| <span class="source-line-no">231</span><span id="line-231"></span> |
| <span class="source-line-no">232</span><span id="line-232"> if (!splittable) {</span> |
| <span class="source-line-no">233</span><span id="line-233"> IOException e =</span> |
| <span class="source-line-no">234</span><span id="line-234"> new DoNotRetryIOException(regionToSplit.getShortNameToLog() + " NOT splittable");</span> |
| <span class="source-line-no">235</span><span id="line-235"> if (splittableCheckIOE != null) {</span> |
| <span class="source-line-no">236</span><span id="line-236"> e.initCause(splittableCheckIOE);</span> |
| <span class="source-line-no">237</span><span id="line-237"> }</span> |
| <span class="source-line-no">238</span><span id="line-238"> throw e;</span> |
| <span class="source-line-no">239</span><span id="line-239"> }</span> |
| <span class="source-line-no">240</span><span id="line-240"></span> |
| <span class="source-line-no">241</span><span id="line-241"> if (!hasBestSplitRow()) {</span> |
| <span class="source-line-no">242</span><span id="line-242"> throw new DoNotRetryIOException("Region not splittable because bestSplitPoint = null, "</span> |
| <span class="source-line-no">243</span><span id="line-243"> + "maybe table is too small for auto split. For force split, try specifying split row");</span> |
| <span class="source-line-no">244</span><span id="line-244"> }</span> |
| <span class="source-line-no">245</span><span id="line-245"></span> |
| <span class="source-line-no">246</span><span id="line-246"> if (Bytes.equals(regionToSplit.getStartKey(), bestSplitRow)) {</span> |
| <span class="source-line-no">247</span><span id="line-247"> throw new DoNotRetryIOException(</span> |
| <span class="source-line-no">248</span><span id="line-248"> "Split row is equal to startkey: " + Bytes.toStringBinary(bestSplitRow));</span> |
| <span class="source-line-no">249</span><span id="line-249"> }</span> |
| <span class="source-line-no">250</span><span id="line-250"></span> |
| <span class="source-line-no">251</span><span id="line-251"> if (!regionToSplit.containsRow(bestSplitRow)) {</span> |
| <span class="source-line-no">252</span><span id="line-252"> throw new DoNotRetryIOException("Split row is not inside region key range splitKey:"</span> |
| <span class="source-line-no">253</span><span id="line-253"> + Bytes.toStringBinary(bestSplitRow) + " region: " + regionToSplit);</span> |
| <span class="source-line-no">254</span><span id="line-254"> }</span> |
| <span class="source-line-no">255</span><span id="line-255"> }</span> |
| <span class="source-line-no">256</span><span id="line-256"></span> |
| <span class="source-line-no">257</span><span id="line-257"> /**</span> |
| <span class="source-line-no">258</span><span id="line-258"> * Calculate daughter regionid to use.</span> |
| <span class="source-line-no">259</span><span id="line-259"> * @param hri Parent {@link RegionInfo}</span> |
| <span class="source-line-no">260</span><span id="line-260"> * @return Daughter region id (timestamp) to use.</span> |
| <span class="source-line-no">261</span><span id="line-261"> */</span> |
| <span class="source-line-no">262</span><span id="line-262"> private static long getDaughterRegionIdTimestamp(final RegionInfo hri) {</span> |
| <span class="source-line-no">263</span><span id="line-263"> long rid = EnvironmentEdgeManager.currentTime();</span> |
| <span class="source-line-no">264</span><span id="line-264"> // Regionid is timestamp. Can't be less than that of parent else will insert</span> |
| <span class="source-line-no">265</span><span id="line-265"> // at wrong location in hbase:meta (See HBASE-710).</span> |
| <span class="source-line-no">266</span><span id="line-266"> if (rid < hri.getRegionId()) {</span> |
| <span class="source-line-no">267</span><span id="line-267"> LOG.warn("Clock skew; parent regions id is " + hri.getRegionId()</span> |
| <span class="source-line-no">268</span><span id="line-268"> + " but current time here is " + rid);</span> |
| <span class="source-line-no">269</span><span id="line-269"> rid = hri.getRegionId() + 1;</span> |
| <span class="source-line-no">270</span><span id="line-270"> }</span> |
| <span class="source-line-no">271</span><span id="line-271"> return rid;</span> |
| <span class="source-line-no">272</span><span id="line-272"> }</span> |
| <span class="source-line-no">273</span><span id="line-273"></span> |
| <span class="source-line-no">274</span><span id="line-274"> private void removeNonDefaultReplicas(MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">275</span><span id="line-275"> AssignmentManagerUtil.removeNonDefaultReplicas(env, Stream.of(getParentRegion()),</span> |
| <span class="source-line-no">276</span><span id="line-276"> getRegionReplication(env));</span> |
| <span class="source-line-no">277</span><span id="line-277"> }</span> |
| <span class="source-line-no">278</span><span id="line-278"></span> |
| <span class="source-line-no">279</span><span id="line-279"> private void checkClosedRegions(MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">280</span><span id="line-280"> // theoretically this should not happen any more after we use TRSP, but anyway let's add a check</span> |
| <span class="source-line-no">281</span><span id="line-281"> // here</span> |
| <span class="source-line-no">282</span><span id="line-282"> AssignmentManagerUtil.checkClosedRegion(env, getParentRegion());</span> |
| <span class="source-line-no">283</span><span id="line-283"> }</span> |
| <span class="source-line-no">284</span><span id="line-284"></span> |
| <span class="source-line-no">285</span><span id="line-285"> @Override</span> |
| <span class="source-line-no">286</span><span id="line-286"> protected Flow executeFromState(MasterProcedureEnv env, SplitTableRegionState state)</span> |
| <span class="source-line-no">287</span><span id="line-287"> throws InterruptedException {</span> |
| <span class="source-line-no">288</span><span id="line-288"> LOG.trace("{} execute state={}", this, state);</span> |
| <span class="source-line-no">289</span><span id="line-289"></span> |
| <span class="source-line-no">290</span><span id="line-290"> try {</span> |
| <span class="source-line-no">291</span><span id="line-291"> switch (state) {</span> |
| <span class="source-line-no">292</span><span id="line-292"> case SPLIT_TABLE_REGION_PREPARE:</span> |
| <span class="source-line-no">293</span><span id="line-293"> if (prepareSplitRegion(env)) {</span> |
| <span class="source-line-no">294</span><span id="line-294"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_PRE_OPERATION);</span> |
| <span class="source-line-no">295</span><span id="line-295"> break;</span> |
| <span class="source-line-no">296</span><span id="line-296"> } else {</span> |
| <span class="source-line-no">297</span><span id="line-297"> return Flow.NO_MORE_STATE;</span> |
| <span class="source-line-no">298</span><span id="line-298"> }</span> |
| <span class="source-line-no">299</span><span id="line-299"> case SPLIT_TABLE_REGION_PRE_OPERATION:</span> |
| <span class="source-line-no">300</span><span id="line-300"> preSplitRegion(env);</span> |
| <span class="source-line-no">301</span><span id="line-301"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_CLOSE_PARENT_REGION);</span> |
| <span class="source-line-no">302</span><span id="line-302"> break;</span> |
| <span class="source-line-no">303</span><span id="line-303"> case SPLIT_TABLE_REGION_CLOSE_PARENT_REGION:</span> |
| <span class="source-line-no">304</span><span id="line-304"> addChildProcedure(createUnassignProcedures(env));</span> |
| <span class="source-line-no">305</span><span id="line-305"> // createUnassignProcedures() can throw out IOException. If this happens,</span> |
| <span class="source-line-no">306</span><span id="line-306"> // it wont reach state SPLIT_TABLE_REGIONS_CHECK_CLOSED_REGION and no parent regions</span> |
| <span class="source-line-no">307</span><span id="line-307"> // is closed as all created UnassignProcedures are rolled back. If it rolls back with</span> |
| <span class="source-line-no">308</span><span id="line-308"> // state SPLIT_TABLE_REGION_CLOSE_PARENT_REGION, no need to call openParentRegion(),</span> |
| <span class="source-line-no">309</span><span id="line-309"> // otherwise, it will result in OpenRegionProcedure for an already open region.</span> |
| <span class="source-line-no">310</span><span id="line-310"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGIONS_CHECK_CLOSED_REGIONS);</span> |
| <span class="source-line-no">311</span><span id="line-311"> break;</span> |
| <span class="source-line-no">312</span><span id="line-312"> case SPLIT_TABLE_REGIONS_CHECK_CLOSED_REGIONS:</span> |
| <span class="source-line-no">313</span><span id="line-313"> checkClosedRegions(env);</span> |
| <span class="source-line-no">314</span><span id="line-314"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_CREATE_DAUGHTER_REGIONS);</span> |
| <span class="source-line-no">315</span><span id="line-315"> break;</span> |
| <span class="source-line-no">316</span><span id="line-316"> case SPLIT_TABLE_REGION_CREATE_DAUGHTER_REGIONS:</span> |
| <span class="source-line-no">317</span><span id="line-317"> removeNonDefaultReplicas(env);</span> |
| <span class="source-line-no">318</span><span id="line-318"> createDaughterRegions(env);</span> |
| <span class="source-line-no">319</span><span id="line-319"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_WRITE_MAX_SEQUENCE_ID_FILE);</span> |
| <span class="source-line-no">320</span><span id="line-320"> break;</span> |
| <span class="source-line-no">321</span><span id="line-321"> case SPLIT_TABLE_REGION_WRITE_MAX_SEQUENCE_ID_FILE:</span> |
| <span class="source-line-no">322</span><span id="line-322"> writeMaxSequenceIdFile(env);</span> |
| <span class="source-line-no">323</span><span id="line-323"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_PRE_OPERATION_BEFORE_META);</span> |
| <span class="source-line-no">324</span><span id="line-324"> break;</span> |
| <span class="source-line-no">325</span><span id="line-325"> case SPLIT_TABLE_REGION_PRE_OPERATION_BEFORE_META:</span> |
| <span class="source-line-no">326</span><span id="line-326"> preSplitRegionBeforeMETA(env);</span> |
| <span class="source-line-no">327</span><span id="line-327"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_UPDATE_META);</span> |
| <span class="source-line-no">328</span><span id="line-328"> break;</span> |
| <span class="source-line-no">329</span><span id="line-329"> case SPLIT_TABLE_REGION_UPDATE_META:</span> |
| <span class="source-line-no">330</span><span id="line-330"> updateMeta(env);</span> |
| <span class="source-line-no">331</span><span id="line-331"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_PRE_OPERATION_AFTER_META);</span> |
| <span class="source-line-no">332</span><span id="line-332"> break;</span> |
| <span class="source-line-no">333</span><span id="line-333"> case SPLIT_TABLE_REGION_PRE_OPERATION_AFTER_META:</span> |
| <span class="source-line-no">334</span><span id="line-334"> preSplitRegionAfterMETA(env);</span> |
| <span class="source-line-no">335</span><span id="line-335"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_OPEN_CHILD_REGIONS);</span> |
| <span class="source-line-no">336</span><span id="line-336"> break;</span> |
| <span class="source-line-no">337</span><span id="line-337"> case SPLIT_TABLE_REGION_OPEN_CHILD_REGIONS:</span> |
| <span class="source-line-no">338</span><span id="line-338"> addChildProcedure(createAssignProcedures(env));</span> |
| <span class="source-line-no">339</span><span id="line-339"> setNextState(SplitTableRegionState.SPLIT_TABLE_REGION_POST_OPERATION);</span> |
| <span class="source-line-no">340</span><span id="line-340"> break;</span> |
| <span class="source-line-no">341</span><span id="line-341"> case SPLIT_TABLE_REGION_POST_OPERATION:</span> |
| <span class="source-line-no">342</span><span id="line-342"> postSplitRegion(env);</span> |
| <span class="source-line-no">343</span><span id="line-343"> return Flow.NO_MORE_STATE;</span> |
| <span class="source-line-no">344</span><span id="line-344"> default:</span> |
| <span class="source-line-no">345</span><span id="line-345"> throw new UnsupportedOperationException(this + " unhandled state=" + state);</span> |
| <span class="source-line-no">346</span><span id="line-346"> }</span> |
| <span class="source-line-no">347</span><span id="line-347"> } catch (IOException e) {</span> |
| <span class="source-line-no">348</span><span id="line-348"> String msg = "Splitting " + getParentRegion().getEncodedName() + ", " + this;</span> |
| <span class="source-line-no">349</span><span id="line-349"> if (!isRollbackSupported(state)) {</span> |
| <span class="source-line-no">350</span><span id="line-350"> // We reach a state that cannot be rolled back. We just need to keep retrying.</span> |
| <span class="source-line-no">351</span><span id="line-351"> LOG.warn(msg, e);</span> |
| <span class="source-line-no">352</span><span id="line-352"> } else {</span> |
| <span class="source-line-no">353</span><span id="line-353"> LOG.error(msg, e);</span> |
| <span class="source-line-no">354</span><span id="line-354"> setFailure("master-split-regions", e);</span> |
| <span class="source-line-no">355</span><span id="line-355"> }</span> |
| <span class="source-line-no">356</span><span id="line-356"> }</span> |
| <span class="source-line-no">357</span><span id="line-357"> // if split fails, need to call ((HRegion)parent).clearSplit() when it is a force split</span> |
| <span class="source-line-no">358</span><span id="line-358"> return Flow.HAS_MORE_STATE;</span> |
| <span class="source-line-no">359</span><span id="line-359"> }</span> |
| <span class="source-line-no">360</span><span id="line-360"></span> |
| <span class="source-line-no">361</span><span id="line-361"> /**</span> |
| <span class="source-line-no">362</span><span id="line-362"> * To rollback {@link SplitTableRegionProcedure}, an AssignProcedure is asynchronously submitted</span> |
| <span class="source-line-no">363</span><span id="line-363"> * for parent region to be split (rollback doesn't wait on the completion of the AssignProcedure)</span> |
| <span class="source-line-no">364</span><span id="line-364"> * . This can be improved by changing rollback() to support sub-procedures. See HBASE-19851 for</span> |
| <span class="source-line-no">365</span><span id="line-365"> * details.</span> |
| <span class="source-line-no">366</span><span id="line-366"> */</span> |
| <span class="source-line-no">367</span><span id="line-367"> @Override</span> |
| <span class="source-line-no">368</span><span id="line-368"> protected void rollbackState(final MasterProcedureEnv env, final SplitTableRegionState state)</span> |
| <span class="source-line-no">369</span><span id="line-369"> throws IOException, InterruptedException {</span> |
| <span class="source-line-no">370</span><span id="line-370"> LOG.trace("{} rollback state={}", this, state);</span> |
| <span class="source-line-no">371</span><span id="line-371"></span> |
| <span class="source-line-no">372</span><span id="line-372"> try {</span> |
| <span class="source-line-no">373</span><span id="line-373"> switch (state) {</span> |
| <span class="source-line-no">374</span><span id="line-374"> case SPLIT_TABLE_REGION_POST_OPERATION:</span> |
| <span class="source-line-no">375</span><span id="line-375"> case SPLIT_TABLE_REGION_OPEN_CHILD_REGIONS:</span> |
| <span class="source-line-no">376</span><span id="line-376"> case SPLIT_TABLE_REGION_PRE_OPERATION_AFTER_META:</span> |
| <span class="source-line-no">377</span><span id="line-377"> case SPLIT_TABLE_REGION_UPDATE_META:</span> |
| <span class="source-line-no">378</span><span id="line-378"> // PONR</span> |
| <span class="source-line-no">379</span><span id="line-379"> throw new UnsupportedOperationException(this + " unhandled state=" + state);</span> |
| <span class="source-line-no">380</span><span id="line-380"> case SPLIT_TABLE_REGION_PRE_OPERATION_BEFORE_META:</span> |
| <span class="source-line-no">381</span><span id="line-381"> break;</span> |
| <span class="source-line-no">382</span><span id="line-382"> case SPLIT_TABLE_REGION_CREATE_DAUGHTER_REGIONS:</span> |
| <span class="source-line-no">383</span><span id="line-383"> case SPLIT_TABLE_REGION_WRITE_MAX_SEQUENCE_ID_FILE:</span> |
| <span class="source-line-no">384</span><span id="line-384"> deleteDaughterRegions(env);</span> |
| <span class="source-line-no">385</span><span id="line-385"> break;</span> |
| <span class="source-line-no">386</span><span id="line-386"> case SPLIT_TABLE_REGIONS_CHECK_CLOSED_REGIONS:</span> |
| <span class="source-line-no">387</span><span id="line-387"> openParentRegion(env);</span> |
| <span class="source-line-no">388</span><span id="line-388"> break;</span> |
| <span class="source-line-no">389</span><span id="line-389"> case SPLIT_TABLE_REGION_CLOSE_PARENT_REGION:</span> |
| <span class="source-line-no">390</span><span id="line-390"> // If it rolls back with state SPLIT_TABLE_REGION_CLOSE_PARENT_REGION, no need to call</span> |
| <span class="source-line-no">391</span><span id="line-391"> // openParentRegion(), otherwise, it will result in OpenRegionProcedure for an</span> |
| <span class="source-line-no">392</span><span id="line-392"> // already open region.</span> |
| <span class="source-line-no">393</span><span id="line-393"> break;</span> |
| <span class="source-line-no">394</span><span id="line-394"> case SPLIT_TABLE_REGION_PRE_OPERATION:</span> |
| <span class="source-line-no">395</span><span id="line-395"> postRollBackSplitRegion(env);</span> |
| <span class="source-line-no">396</span><span id="line-396"> break;</span> |
| <span class="source-line-no">397</span><span id="line-397"> case SPLIT_TABLE_REGION_PREPARE:</span> |
| <span class="source-line-no">398</span><span id="line-398"> rollbackPrepareSplit(env);</span> |
| <span class="source-line-no">399</span><span id="line-399"> break;</span> |
| <span class="source-line-no">400</span><span id="line-400"> default:</span> |
| <span class="source-line-no">401</span><span id="line-401"> throw new UnsupportedOperationException(this + " unhandled state=" + state);</span> |
| <span class="source-line-no">402</span><span id="line-402"> }</span> |
| <span class="source-line-no">403</span><span id="line-403"> } catch (IOException e) {</span> |
| <span class="source-line-no">404</span><span id="line-404"> // This will be retried. Unless there is a bug in the code,</span> |
| <span class="source-line-no">405</span><span id="line-405"> // this should be just a "temporary error" (e.g. network down)</span> |
| <span class="source-line-no">406</span><span id="line-406"> LOG.warn("pid=" + getProcId() + " failed rollback attempt step " + state</span> |
| <span class="source-line-no">407</span><span id="line-407"> + " for splitting the region " + getParentRegion().getEncodedName() + " in table "</span> |
| <span class="source-line-no">408</span><span id="line-408"> + getTableName(), e);</span> |
| <span class="source-line-no">409</span><span id="line-409"> throw e;</span> |
| <span class="source-line-no">410</span><span id="line-410"> }</span> |
| <span class="source-line-no">411</span><span id="line-411"> }</span> |
| <span class="source-line-no">412</span><span id="line-412"></span> |
| <span class="source-line-no">413</span><span id="line-413"> /*</span> |
| <span class="source-line-no">414</span><span id="line-414"> * Check whether we are in the state that can be rollback</span> |
| <span class="source-line-no">415</span><span id="line-415"> */</span> |
| <span class="source-line-no">416</span><span id="line-416"> @Override</span> |
| <span class="source-line-no">417</span><span id="line-417"> protected boolean isRollbackSupported(final SplitTableRegionState state) {</span> |
| <span class="source-line-no">418</span><span id="line-418"> switch (state) {</span> |
| <span class="source-line-no">419</span><span id="line-419"> case SPLIT_TABLE_REGION_POST_OPERATION:</span> |
| <span class="source-line-no">420</span><span id="line-420"> case SPLIT_TABLE_REGION_OPEN_CHILD_REGIONS:</span> |
| <span class="source-line-no">421</span><span id="line-421"> case SPLIT_TABLE_REGION_PRE_OPERATION_AFTER_META:</span> |
| <span class="source-line-no">422</span><span id="line-422"> case SPLIT_TABLE_REGION_UPDATE_META:</span> |
| <span class="source-line-no">423</span><span id="line-423"> // It is not safe to rollback if we reach to these states.</span> |
| <span class="source-line-no">424</span><span id="line-424"> return false;</span> |
| <span class="source-line-no">425</span><span id="line-425"> default:</span> |
| <span class="source-line-no">426</span><span id="line-426"> break;</span> |
| <span class="source-line-no">427</span><span id="line-427"> }</span> |
| <span class="source-line-no">428</span><span id="line-428"> return true;</span> |
| <span class="source-line-no">429</span><span id="line-429"> }</span> |
| <span class="source-line-no">430</span><span id="line-430"></span> |
| <span class="source-line-no">431</span><span id="line-431"> @Override</span> |
| <span class="source-line-no">432</span><span id="line-432"> protected SplitTableRegionState getState(final int stateId) {</span> |
| <span class="source-line-no">433</span><span id="line-433"> return SplitTableRegionState.forNumber(stateId);</span> |
| <span class="source-line-no">434</span><span id="line-434"> }</span> |
| <span class="source-line-no">435</span><span id="line-435"></span> |
| <span class="source-line-no">436</span><span id="line-436"> @Override</span> |
| <span class="source-line-no">437</span><span id="line-437"> protected int getStateId(final SplitTableRegionState state) {</span> |
| <span class="source-line-no">438</span><span id="line-438"> return state.getNumber();</span> |
| <span class="source-line-no">439</span><span id="line-439"> }</span> |
| <span class="source-line-no">440</span><span id="line-440"></span> |
| <span class="source-line-no">441</span><span id="line-441"> @Override</span> |
| <span class="source-line-no">442</span><span id="line-442"> protected SplitTableRegionState getInitialState() {</span> |
| <span class="source-line-no">443</span><span id="line-443"> return SplitTableRegionState.SPLIT_TABLE_REGION_PREPARE;</span> |
| <span class="source-line-no">444</span><span id="line-444"> }</span> |
| <span class="source-line-no">445</span><span id="line-445"></span> |
| <span class="source-line-no">446</span><span id="line-446"> @Override</span> |
| <span class="source-line-no">447</span><span id="line-447"> protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {</span> |
| <span class="source-line-no">448</span><span id="line-448"> super.serializeStateData(serializer);</span> |
| <span class="source-line-no">449</span><span id="line-449"></span> |
| <span class="source-line-no">450</span><span id="line-450"> final MasterProcedureProtos.SplitTableRegionStateData.Builder splitTableRegionMsg =</span> |
| <span class="source-line-no">451</span><span id="line-451"> MasterProcedureProtos.SplitTableRegionStateData.newBuilder()</span> |
| <span class="source-line-no">452</span><span id="line-452"> .setUserInfo(MasterProcedureUtil.toProtoUserInfo(getUser()))</span> |
| <span class="source-line-no">453</span><span id="line-453"> .setParentRegionInfo(ProtobufUtil.toRegionInfo(getRegion()))</span> |
| <span class="source-line-no">454</span><span id="line-454"> .addChildRegionInfo(ProtobufUtil.toRegionInfo(daughterOneRI))</span> |
| <span class="source-line-no">455</span><span id="line-455"> .addChildRegionInfo(ProtobufUtil.toRegionInfo(daughterTwoRI));</span> |
| <span class="source-line-no">456</span><span id="line-456"> serializer.serialize(splitTableRegionMsg.build());</span> |
| <span class="source-line-no">457</span><span id="line-457"> }</span> |
| <span class="source-line-no">458</span><span id="line-458"></span> |
| <span class="source-line-no">459</span><span id="line-459"> @Override</span> |
| <span class="source-line-no">460</span><span id="line-460"> protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {</span> |
| <span class="source-line-no">461</span><span id="line-461"> super.deserializeStateData(serializer);</span> |
| <span class="source-line-no">462</span><span id="line-462"></span> |
| <span class="source-line-no">463</span><span id="line-463"> final MasterProcedureProtos.SplitTableRegionStateData splitTableRegionsMsg =</span> |
| <span class="source-line-no">464</span><span id="line-464"> serializer.deserialize(MasterProcedureProtos.SplitTableRegionStateData.class);</span> |
| <span class="source-line-no">465</span><span id="line-465"> setUser(MasterProcedureUtil.toUserInfo(splitTableRegionsMsg.getUserInfo()));</span> |
| <span class="source-line-no">466</span><span id="line-466"> setRegion(ProtobufUtil.toRegionInfo(splitTableRegionsMsg.getParentRegionInfo()));</span> |
| <span class="source-line-no">467</span><span id="line-467"> assert (splitTableRegionsMsg.getChildRegionInfoCount() == 2);</span> |
| <span class="source-line-no">468</span><span id="line-468"> daughterOneRI = ProtobufUtil.toRegionInfo(splitTableRegionsMsg.getChildRegionInfo(0));</span> |
| <span class="source-line-no">469</span><span id="line-469"> daughterTwoRI = ProtobufUtil.toRegionInfo(splitTableRegionsMsg.getChildRegionInfo(1));</span> |
| <span class="source-line-no">470</span><span id="line-470"> }</span> |
| <span class="source-line-no">471</span><span id="line-471"></span> |
| <span class="source-line-no">472</span><span id="line-472"> @Override</span> |
| <span class="source-line-no">473</span><span id="line-473"> public void toStringClassDetails(StringBuilder sb) {</span> |
| <span class="source-line-no">474</span><span id="line-474"> sb.append(getClass().getSimpleName());</span> |
| <span class="source-line-no">475</span><span id="line-475"> sb.append(" table=");</span> |
| <span class="source-line-no">476</span><span id="line-476"> sb.append(getTableName());</span> |
| <span class="source-line-no">477</span><span id="line-477"> sb.append(", parent=");</span> |
| <span class="source-line-no">478</span><span id="line-478"> sb.append(getParentRegion().getShortNameToLog());</span> |
| <span class="source-line-no">479</span><span id="line-479"> sb.append(", daughterA=");</span> |
| <span class="source-line-no">480</span><span id="line-480"> sb.append(daughterOneRI.getShortNameToLog());</span> |
| <span class="source-line-no">481</span><span id="line-481"> sb.append(", daughterB=");</span> |
| <span class="source-line-no">482</span><span id="line-482"> sb.append(daughterTwoRI.getShortNameToLog());</span> |
| <span class="source-line-no">483</span><span id="line-483"> }</span> |
| <span class="source-line-no">484</span><span id="line-484"></span> |
| <span class="source-line-no">485</span><span id="line-485"> private RegionInfo getParentRegion() {</span> |
| <span class="source-line-no">486</span><span id="line-486"> return getRegion();</span> |
| <span class="source-line-no">487</span><span id="line-487"> }</span> |
| <span class="source-line-no">488</span><span id="line-488"></span> |
| <span class="source-line-no">489</span><span id="line-489"> @Override</span> |
| <span class="source-line-no">490</span><span id="line-490"> public TableOperationType getTableOperationType() {</span> |
| <span class="source-line-no">491</span><span id="line-491"> return TableOperationType.REGION_SPLIT;</span> |
| <span class="source-line-no">492</span><span id="line-492"> }</span> |
| <span class="source-line-no">493</span><span id="line-493"></span> |
| <span class="source-line-no">494</span><span id="line-494"> @Override</span> |
| <span class="source-line-no">495</span><span id="line-495"> protected ProcedureMetrics getProcedureMetrics(MasterProcedureEnv env) {</span> |
| <span class="source-line-no">496</span><span id="line-496"> return env.getAssignmentManager().getAssignmentManagerMetrics().getSplitProcMetrics();</span> |
| <span class="source-line-no">497</span><span id="line-497"> }</span> |
| <span class="source-line-no">498</span><span id="line-498"></span> |
| <span class="source-line-no">499</span><span id="line-499"> private byte[] getSplitRow() {</span> |
| <span class="source-line-no">500</span><span id="line-500"> return daughterTwoRI.getStartKey();</span> |
| <span class="source-line-no">501</span><span id="line-501"> }</span> |
| <span class="source-line-no">502</span><span id="line-502"></span> |
| <span class="source-line-no">503</span><span id="line-503"> private static final State[] EXPECTED_SPLIT_STATES = new State[] { State.OPEN, State.CLOSED };</span> |
| <span class="source-line-no">504</span><span id="line-504"></span> |
| <span class="source-line-no">505</span><span id="line-505"> /**</span> |
| <span class="source-line-no">506</span><span id="line-506"> * Prepare to Split region.</span> |
| <span class="source-line-no">507</span><span id="line-507"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">508</span><span id="line-508"> */</span> |
| <span class="source-line-no">509</span><span id="line-509"> public boolean prepareSplitRegion(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">510</span><span id="line-510"> // Fail if we are taking snapshot for the given table</span> |
| <span class="source-line-no">511</span><span id="line-511"> if (</span> |
| <span class="source-line-no">512</span><span id="line-512"> env.getMasterServices().getSnapshotManager()</span> |
| <span class="source-line-no">513</span><span id="line-513"> .isTableTakingAnySnapshot(getParentRegion().getTable())</span> |
| <span class="source-line-no">514</span><span id="line-514"> ) {</span> |
| <span class="source-line-no">515</span><span id="line-515"> setFailure(new IOException("Skip splitting region " + getParentRegion().getShortNameToLog()</span> |
| <span class="source-line-no">516</span><span id="line-516"> + ", because we are taking snapshot for the table " + getParentRegion().getTable()));</span> |
| <span class="source-line-no">517</span><span id="line-517"> return false;</span> |
| <span class="source-line-no">518</span><span id="line-518"> }</span> |
| <span class="source-line-no">519</span><span id="line-519"></span> |
| <span class="source-line-no">520</span><span id="line-520"> /*</span> |
| <span class="source-line-no">521</span><span id="line-521"> * Sometimes a ModifyTableProcedure has edited a table descriptor to change the number of region</span> |
| <span class="source-line-no">522</span><span id="line-522"> * replicas for a table, but it has not yet opened/closed the new replicas. The</span> |
| <span class="source-line-no">523</span><span id="line-523"> * ModifyTableProcedure assumes that nobody else will do the opening/closing of the new</span> |
| <span class="source-line-no">524</span><span id="line-524"> * replicas, but a concurrent SplitTableRegionProcedure would violate that assumption.</span> |
| <span class="source-line-no">525</span><span id="line-525"> */</span> |
| <span class="source-line-no">526</span><span id="line-526"> if (checkTableModifyInProgress && isTableModificationInProgress(env)) {</span> |
| <span class="source-line-no">527</span><span id="line-527"> setFailure(new IOException("Skip splitting region " + getParentRegion().getShortNameToLog()</span> |
| <span class="source-line-no">528</span><span id="line-528"> + ", because there is an active procedure that is modifying the table "</span> |
| <span class="source-line-no">529</span><span id="line-529"> + getParentRegion().getTable()));</span> |
| <span class="source-line-no">530</span><span id="line-530"> return false;</span> |
| <span class="source-line-no">531</span><span id="line-531"> }</span> |
| <span class="source-line-no">532</span><span id="line-532"></span> |
| <span class="source-line-no">533</span><span id="line-533"> // Check whether the region is splittable</span> |
| <span class="source-line-no">534</span><span id="line-534"> RegionStateNode node =</span> |
| <span class="source-line-no">535</span><span id="line-535"> env.getAssignmentManager().getRegionStates().getRegionStateNode(getParentRegion());</span> |
| <span class="source-line-no">536</span><span id="line-536"></span> |
| <span class="source-line-no">537</span><span id="line-537"> if (node == null) {</span> |
| <span class="source-line-no">538</span><span id="line-538"> throw new UnknownRegionException(getParentRegion().getRegionNameAsString());</span> |
| <span class="source-line-no">539</span><span id="line-539"> }</span> |
| <span class="source-line-no">540</span><span id="line-540"></span> |
| <span class="source-line-no">541</span><span id="line-541"> RegionInfo parentHRI = node.getRegionInfo();</span> |
| <span class="source-line-no">542</span><span id="line-542"> if (parentHRI == null) {</span> |
| <span class="source-line-no">543</span><span id="line-543"> LOG.info("Unsplittable; parent region is null; node={}", node);</span> |
| <span class="source-line-no">544</span><span id="line-544"> return false;</span> |
| <span class="source-line-no">545</span><span id="line-545"> }</span> |
| <span class="source-line-no">546</span><span id="line-546"> // Lookup the parent HRI state from the AM, which has the latest updated info.</span> |
| <span class="source-line-no">547</span><span id="line-547"> // Protect against the case where concurrent SPLIT requests came in and succeeded</span> |
| <span class="source-line-no">548</span><span id="line-548"> // just before us.</span> |
| <span class="source-line-no">549</span><span id="line-549"> if (node.isInState(State.SPLIT)) {</span> |
| <span class="source-line-no">550</span><span id="line-550"> LOG.info("Split of " + parentHRI + " skipped; state is already SPLIT");</span> |
| <span class="source-line-no">551</span><span id="line-551"> return false;</span> |
| <span class="source-line-no">552</span><span id="line-552"> }</span> |
| <span class="source-line-no">553</span><span id="line-553"> if (parentHRI.isSplit() || parentHRI.isOffline()) {</span> |
| <span class="source-line-no">554</span><span id="line-554"> LOG.info("Split of " + parentHRI + " skipped because offline/split.");</span> |
| <span class="source-line-no">555</span><span id="line-555"> return false;</span> |
| <span class="source-line-no">556</span><span id="line-556"> }</span> |
| <span class="source-line-no">557</span><span id="line-557"></span> |
| <span class="source-line-no">558</span><span id="line-558"> // expected parent to be online or closed</span> |
| <span class="source-line-no">559</span><span id="line-559"> if (!node.isInState(EXPECTED_SPLIT_STATES)) {</span> |
| <span class="source-line-no">560</span><span id="line-560"> // We may have SPLIT already?</span> |
| <span class="source-line-no">561</span><span id="line-561"> setFailure(</span> |
| <span class="source-line-no">562</span><span id="line-562"> new IOException("Split " + parentHRI.getRegionNameAsString() + " FAILED because state="</span> |
| <span class="source-line-no">563</span><span id="line-563"> + node.getState() + "; expected " + Arrays.toString(EXPECTED_SPLIT_STATES)));</span> |
| <span class="source-line-no">564</span><span id="line-564"> return false;</span> |
| <span class="source-line-no">565</span><span id="line-565"> }</span> |
| <span class="source-line-no">566</span><span id="line-566"></span> |
| <span class="source-line-no">567</span><span id="line-567"> // Mostly the below two checks are not used because we already check the switches before</span> |
| <span class="source-line-no">568</span><span id="line-568"> // submitting the split procedure. Just for safety, we are checking the switch again here.</span> |
| <span class="source-line-no">569</span><span id="line-569"> // Also, in case the switch was set to false after submission, this procedure can be rollbacked,</span> |
| <span class="source-line-no">570</span><span id="line-570"> // thanks to this double check!</span> |
| <span class="source-line-no">571</span><span id="line-571"> // case 1: check for cluster level switch</span> |
| <span class="source-line-no">572</span><span id="line-572"> if (!env.getMasterServices().isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {</span> |
| <span class="source-line-no">573</span><span id="line-573"> LOG.warn("pid=" + getProcId() + " split switch is off! skip split of " + parentHRI);</span> |
| <span class="source-line-no">574</span><span id="line-574"> setFailure(new IOException(</span> |
| <span class="source-line-no">575</span><span id="line-575"> "Split region " + parentHRI.getRegionNameAsString() + " failed due to split switch off"));</span> |
| <span class="source-line-no">576</span><span id="line-576"> return false;</span> |
| <span class="source-line-no">577</span><span id="line-577"> }</span> |
| <span class="source-line-no">578</span><span id="line-578"> // case 2: check for table level switch</span> |
| <span class="source-line-no">579</span><span id="line-579"> if (!env.getMasterServices().getTableDescriptors().get(getTableName()).isSplitEnabled()) {</span> |
| <span class="source-line-no">580</span><span id="line-580"> LOG.warn("pid={}, split is disabled for the table! Skipping split of {}", getProcId(),</span> |
| <span class="source-line-no">581</span><span id="line-581"> parentHRI);</span> |
| <span class="source-line-no">582</span><span id="line-582"> setFailure(new IOException("Split region " + parentHRI.getRegionNameAsString()</span> |
| <span class="source-line-no">583</span><span id="line-583"> + " failed as region split is disabled for the table"));</span> |
| <span class="source-line-no">584</span><span id="line-584"> return false;</span> |
| <span class="source-line-no">585</span><span id="line-585"> }</span> |
| <span class="source-line-no">586</span><span id="line-586"></span> |
| <span class="source-line-no">587</span><span id="line-587"> // set node state as SPLITTING</span> |
| <span class="source-line-no">588</span><span id="line-588"> node.setState(State.SPLITTING);</span> |
| <span class="source-line-no">589</span><span id="line-589"></span> |
| <span class="source-line-no">590</span><span id="line-590"> // Since we have the lock and the master is coordinating the operation</span> |
| <span class="source-line-no">591</span><span id="line-591"> // we are always able to split the region</span> |
| <span class="source-line-no">592</span><span id="line-592"> return true;</span> |
| <span class="source-line-no">593</span><span id="line-593"> }</span> |
| <span class="source-line-no">594</span><span id="line-594"></span> |
| <span class="source-line-no">595</span><span id="line-595"> /**</span> |
| <span class="source-line-no">596</span><span id="line-596"> * Rollback prepare split region</span> |
| <span class="source-line-no">597</span><span id="line-597"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">598</span><span id="line-598"> */</span> |
| <span class="source-line-no">599</span><span id="line-599"> private void rollbackPrepareSplit(final MasterProcedureEnv env) {</span> |
| <span class="source-line-no">600</span><span id="line-600"> RegionStateNode parentRegionStateNode =</span> |
| <span class="source-line-no">601</span><span id="line-601"> env.getAssignmentManager().getRegionStates().getRegionStateNode(getParentRegion());</span> |
| <span class="source-line-no">602</span><span id="line-602"> if (parentRegionStateNode.getState() == State.SPLITTING) {</span> |
| <span class="source-line-no">603</span><span id="line-603"> parentRegionStateNode.setState(State.OPEN);</span> |
| <span class="source-line-no">604</span><span id="line-604"> }</span> |
| <span class="source-line-no">605</span><span id="line-605"> }</span> |
| <span class="source-line-no">606</span><span id="line-606"></span> |
| <span class="source-line-no">607</span><span id="line-607"> /**</span> |
| <span class="source-line-no">608</span><span id="line-608"> * Action before splitting region in a table.</span> |
| <span class="source-line-no">609</span><span id="line-609"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">610</span><span id="line-610"> */</span> |
| <span class="source-line-no">611</span><span id="line-611"> private void preSplitRegion(final MasterProcedureEnv env)</span> |
| <span class="source-line-no">612</span><span id="line-612"> throws IOException, InterruptedException {</span> |
| <span class="source-line-no">613</span><span id="line-613"> final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();</span> |
| <span class="source-line-no">614</span><span id="line-614"> if (cpHost != null) {</span> |
| <span class="source-line-no">615</span><span id="line-615"> cpHost.preSplitRegionAction(getTableName(), getSplitRow(), getUser());</span> |
| <span class="source-line-no">616</span><span id="line-616"> }</span> |
| <span class="source-line-no">617</span><span id="line-617"></span> |
| <span class="source-line-no">618</span><span id="line-618"> // TODO: Clean up split and merge. Currently all over the place.</span> |
| <span class="source-line-no">619</span><span id="line-619"> // Notify QuotaManager and RegionNormalizer</span> |
| <span class="source-line-no">620</span><span id="line-620"> try {</span> |
| <span class="source-line-no">621</span><span id="line-621"> MasterQuotaManager masterQuotaManager = env.getMasterServices().getMasterQuotaManager();</span> |
| <span class="source-line-no">622</span><span id="line-622"> if (masterQuotaManager != null) {</span> |
| <span class="source-line-no">623</span><span id="line-623"> masterQuotaManager.onRegionSplit(this.getParentRegion());</span> |
| <span class="source-line-no">624</span><span id="line-624"> }</span> |
| <span class="source-line-no">625</span><span id="line-625"> } catch (QuotaExceededException e) {</span> |
| <span class="source-line-no">626</span><span id="line-626"> // TODO: why is this here? split requests can be submitted by actors other than the normalizer</span> |
| <span class="source-line-no">627</span><span id="line-627"> env.getMasterServices().getRegionNormalizerManager()</span> |
| <span class="source-line-no">628</span><span id="line-628"> .planSkipped(NormalizationPlan.PlanType.SPLIT);</span> |
| <span class="source-line-no">629</span><span id="line-629"> throw e;</span> |
| <span class="source-line-no">630</span><span id="line-630"> }</span> |
| <span class="source-line-no">631</span><span id="line-631"> }</span> |
| <span class="source-line-no">632</span><span id="line-632"></span> |
| <span class="source-line-no">633</span><span id="line-633"> /**</span> |
| <span class="source-line-no">634</span><span id="line-634"> * Action after rollback a split table region action.</span> |
| <span class="source-line-no">635</span><span id="line-635"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">636</span><span id="line-636"> */</span> |
| <span class="source-line-no">637</span><span id="line-637"> private void postRollBackSplitRegion(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">638</span><span id="line-638"> final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();</span> |
| <span class="source-line-no">639</span><span id="line-639"> if (cpHost != null) {</span> |
| <span class="source-line-no">640</span><span id="line-640"> cpHost.postRollBackSplitRegionAction(getUser());</span> |
| <span class="source-line-no">641</span><span id="line-641"> }</span> |
| <span class="source-line-no">642</span><span id="line-642"> }</span> |
| <span class="source-line-no">643</span><span id="line-643"></span> |
| <span class="source-line-no">644</span><span id="line-644"> /**</span> |
| <span class="source-line-no">645</span><span id="line-645"> * Rollback close parent region</span> |
| <span class="source-line-no">646</span><span id="line-646"> */</span> |
| <span class="source-line-no">647</span><span id="line-647"> private void openParentRegion(MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">648</span><span id="line-648"> AssignmentManagerUtil.reopenRegionsForRollback(env,</span> |
| <span class="source-line-no">649</span><span id="line-649"> Collections.singletonList((getParentRegion())), getRegionReplication(env),</span> |
| <span class="source-line-no">650</span><span id="line-650"> getParentRegionServerName(env));</span> |
| <span class="source-line-no">651</span><span id="line-651"> }</span> |
| <span class="source-line-no">652</span><span id="line-652"></span> |
| <span class="source-line-no">653</span><span id="line-653"> /**</span> |
| <span class="source-line-no">654</span><span id="line-654"> * Create daughter regions</span> |
| <span class="source-line-no">655</span><span id="line-655"> */</span> |
| <span class="source-line-no">656</span><span id="line-656"> public void createDaughterRegions(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">657</span><span id="line-657"> final MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();</span> |
| <span class="source-line-no">658</span><span id="line-658"> final Path tabledir = CommonFSUtils.getTableDir(mfs.getRootDir(), getTableName());</span> |
| <span class="source-line-no">659</span><span id="line-659"> final FileSystem fs = mfs.getFileSystem();</span> |
| <span class="source-line-no">660</span><span id="line-660"> HRegionFileSystem regionFs = HRegionFileSystem.openRegionFromFileSystem(</span> |
| <span class="source-line-no">661</span><span id="line-661"> env.getMasterConfiguration(), fs, tabledir, getParentRegion(), false);</span> |
| <span class="source-line-no">662</span><span id="line-662"> regionFs.createSplitsDir(daughterOneRI, daughterTwoRI);</span> |
| <span class="source-line-no">663</span><span id="line-663"></span> |
| <span class="source-line-no">664</span><span id="line-664"> Pair<List<Path>, List<Path>> expectedReferences = splitStoreFiles(env, regionFs);</span> |
| <span class="source-line-no">665</span><span id="line-665"></span> |
| <span class="source-line-no">666</span><span id="line-666"> assertSplitResultFilesCount(fs, expectedReferences.getFirst().size(),</span> |
| <span class="source-line-no">667</span><span id="line-667"> regionFs.getSplitsDir(daughterOneRI));</span> |
| <span class="source-line-no">668</span><span id="line-668"> regionFs.commitDaughterRegion(daughterOneRI, expectedReferences.getFirst(), env);</span> |
| <span class="source-line-no">669</span><span id="line-669"> assertSplitResultFilesCount(fs, expectedReferences.getFirst().size(),</span> |
| <span class="source-line-no">670</span><span id="line-670"> new Path(tabledir, daughterOneRI.getEncodedName()));</span> |
| <span class="source-line-no">671</span><span id="line-671"></span> |
| <span class="source-line-no">672</span><span id="line-672"> assertSplitResultFilesCount(fs, expectedReferences.getSecond().size(),</span> |
| <span class="source-line-no">673</span><span id="line-673"> regionFs.getSplitsDir(daughterTwoRI));</span> |
| <span class="source-line-no">674</span><span id="line-674"> regionFs.commitDaughterRegion(daughterTwoRI, expectedReferences.getSecond(), env);</span> |
| <span class="source-line-no">675</span><span id="line-675"> assertSplitResultFilesCount(fs, expectedReferences.getSecond().size(),</span> |
| <span class="source-line-no">676</span><span id="line-676"> new Path(tabledir, daughterTwoRI.getEncodedName()));</span> |
| <span class="source-line-no">677</span><span id="line-677"> }</span> |
| <span class="source-line-no">678</span><span id="line-678"></span> |
| <span class="source-line-no">679</span><span id="line-679"> private void deleteDaughterRegions(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">680</span><span id="line-680"> final MasterFileSystem mfs = env.getMasterServices().getMasterFileSystem();</span> |
| <span class="source-line-no">681</span><span id="line-681"> final Path tabledir = CommonFSUtils.getTableDir(mfs.getRootDir(), getTableName());</span> |
| <span class="source-line-no">682</span><span id="line-682"> HRegionFileSystem.deleteRegionFromFileSystem(env.getMasterConfiguration(), mfs.getFileSystem(),</span> |
| <span class="source-line-no">683</span><span id="line-683"> tabledir, daughterOneRI);</span> |
| <span class="source-line-no">684</span><span id="line-684"> HRegionFileSystem.deleteRegionFromFileSystem(env.getMasterConfiguration(), mfs.getFileSystem(),</span> |
| <span class="source-line-no">685</span><span id="line-685"> tabledir, daughterTwoRI);</span> |
| <span class="source-line-no">686</span><span id="line-686"> }</span> |
| <span class="source-line-no">687</span><span id="line-687"></span> |
| <span class="source-line-no">688</span><span id="line-688"> /**</span> |
| <span class="source-line-no">689</span><span id="line-689"> * Create Split directory</span> |
| <span class="source-line-no">690</span><span id="line-690"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">691</span><span id="line-691"> */</span> |
| <span class="source-line-no">692</span><span id="line-692"> private Pair<List<Path>, List<Path>> splitStoreFiles(final MasterProcedureEnv env,</span> |
| <span class="source-line-no">693</span><span id="line-693"> final HRegionFileSystem regionFs) throws IOException {</span> |
| <span class="source-line-no">694</span><span id="line-694"> final Configuration conf = env.getMasterConfiguration();</span> |
| <span class="source-line-no">695</span><span id="line-695"> TableDescriptor htd = env.getMasterServices().getTableDescriptors().get(getTableName());</span> |
| <span class="source-line-no">696</span><span id="line-696"> // The following code sets up a thread pool executor with as many slots as</span> |
| <span class="source-line-no">697</span><span id="line-697"> // there's files to split. It then fires up everything, waits for</span> |
| <span class="source-line-no">698</span><span id="line-698"> // completion and finally checks for any exception</span> |
| <span class="source-line-no">699</span><span id="line-699"> //</span> |
| <span class="source-line-no">700</span><span id="line-700"> // Note: From HBASE-26187, splitStoreFiles now creates daughter region dirs straight under the</span> |
| <span class="source-line-no">701</span><span id="line-701"> // table dir. In case of failure, the proc would go through this again, already existing</span> |
| <span class="source-line-no">702</span><span id="line-702"> // region dirs and split files would just be ignored, new split files should get created.</span> |
| <span class="source-line-no">703</span><span id="line-703"> int nbFiles = 0;</span> |
| <span class="source-line-no">704</span><span id="line-704"> final Map<String, Collection<StoreFileInfo>> files =</span> |
| <span class="source-line-no">705</span><span id="line-705"> new HashMap<String, Collection<StoreFileInfo>>(htd.getColumnFamilyCount());</span> |
| <span class="source-line-no">706</span><span id="line-706"> for (ColumnFamilyDescriptor cfd : htd.getColumnFamilies()) {</span> |
| <span class="source-line-no">707</span><span id="line-707"> String family = cfd.getNameAsString();</span> |
| <span class="source-line-no">708</span><span id="line-708"> StoreFileTracker tracker =</span> |
| <span class="source-line-no">709</span><span id="line-709"> StoreFileTrackerFactory.create(env.getMasterConfiguration(), htd, cfd, regionFs);</span> |
| <span class="source-line-no">710</span><span id="line-710"> Collection<StoreFileInfo> sfis = tracker.load();</span> |
| <span class="source-line-no">711</span><span id="line-711"> if (sfis == null) {</span> |
| <span class="source-line-no">712</span><span id="line-712"> continue;</span> |
| <span class="source-line-no">713</span><span id="line-713"> }</span> |
| <span class="source-line-no">714</span><span id="line-714"> Collection<StoreFileInfo> filteredSfis = null;</span> |
| <span class="source-line-no">715</span><span id="line-715"> for (StoreFileInfo sfi : sfis) {</span> |
| <span class="source-line-no">716</span><span id="line-716"> // Filter. There is a lag cleaning up compacted reference files. They get cleared</span> |
| <span class="source-line-no">717</span><span id="line-717"> // after a delay in case outstanding Scanners still have references. Because of this,</span> |
| <span class="source-line-no">718</span><span id="line-718"> // the listing of the Store content may have straggler reference files. Skip these.</span> |
| <span class="source-line-no">719</span><span id="line-719"> // It should be safe to skip references at this point because we checked above with</span> |
| <span class="source-line-no">720</span><span id="line-720"> // the region if it thinks it is splittable and if we are here, it thinks it is</span> |
| <span class="source-line-no">721</span><span id="line-721"> // splitable.</span> |
| <span class="source-line-no">722</span><span id="line-722"> if (sfi.isReference()) {</span> |
| <span class="source-line-no">723</span><span id="line-723"> LOG.info("Skipping split of " + sfi + "; presuming ready for archiving.");</span> |
| <span class="source-line-no">724</span><span id="line-724"> continue;</span> |
| <span class="source-line-no">725</span><span id="line-725"> }</span> |
| <span class="source-line-no">726</span><span id="line-726"> if (filteredSfis == null) {</span> |
| <span class="source-line-no">727</span><span id="line-727"> filteredSfis = new ArrayList<StoreFileInfo>(sfis.size());</span> |
| <span class="source-line-no">728</span><span id="line-728"> files.put(family, filteredSfis);</span> |
| <span class="source-line-no">729</span><span id="line-729"> }</span> |
| <span class="source-line-no">730</span><span id="line-730"> filteredSfis.add(sfi);</span> |
| <span class="source-line-no">731</span><span id="line-731"> nbFiles++;</span> |
| <span class="source-line-no">732</span><span id="line-732"> }</span> |
| <span class="source-line-no">733</span><span id="line-733"> }</span> |
| <span class="source-line-no">734</span><span id="line-734"> if (nbFiles == 0) {</span> |
| <span class="source-line-no">735</span><span id="line-735"> // no file needs to be splitted.</span> |
| <span class="source-line-no">736</span><span id="line-736"> return new Pair<>(Collections.emptyList(), Collections.emptyList());</span> |
| <span class="source-line-no">737</span><span id="line-737"> }</span> |
| <span class="source-line-no">738</span><span id="line-738"> // Max #threads is the smaller of the number of storefiles or the default max determined above.</span> |
| <span class="source-line-no">739</span><span id="line-739"> int maxThreads = Math.min(</span> |
| <span class="source-line-no">740</span><span id="line-740"> conf.getInt(HConstants.REGION_SPLIT_THREADS_MAX,</span> |
| <span class="source-line-no">741</span><span id="line-741"> conf.getInt(HStore.BLOCKING_STOREFILES_KEY, HStore.DEFAULT_BLOCKING_STOREFILE_COUNT)),</span> |
| <span class="source-line-no">742</span><span id="line-742"> nbFiles);</span> |
| <span class="source-line-no">743</span><span id="line-743"> LOG.info("pid=" + getProcId() + " splitting " + nbFiles + " storefiles, region="</span> |
| <span class="source-line-no">744</span><span id="line-744"> + getParentRegion().getShortNameToLog() + ", threads=" + maxThreads);</span> |
| <span class="source-line-no">745</span><span id="line-745"> final ExecutorService threadPool = Executors.newFixedThreadPool(maxThreads,</span> |
| <span class="source-line-no">746</span><span id="line-746"> new ThreadFactoryBuilder().setNameFormat("StoreFileSplitter-pool-%d").setDaemon(true)</span> |
| <span class="source-line-no">747</span><span id="line-747"> .setUncaughtExceptionHandler(Threads.LOGGING_EXCEPTION_HANDLER).build());</span> |
| <span class="source-line-no">748</span><span id="line-748"> final List<Future<Pair<Path, Path>>> futures = new ArrayList<Future<Pair<Path, Path>>>(nbFiles);</span> |
| <span class="source-line-no">749</span><span id="line-749"></span> |
| <span class="source-line-no">750</span><span id="line-750"> // Split each store file.</span> |
| <span class="source-line-no">751</span><span id="line-751"> for (Map.Entry<String, Collection<StoreFileInfo>> e : files.entrySet()) {</span> |
| <span class="source-line-no">752</span><span id="line-752"> byte[] familyName = Bytes.toBytes(e.getKey());</span> |
| <span class="source-line-no">753</span><span id="line-753"> final ColumnFamilyDescriptor hcd = htd.getColumnFamily(familyName);</span> |
| <span class="source-line-no">754</span><span id="line-754"> Collection<StoreFileInfo> storeFileInfos = e.getValue();</span> |
| <span class="source-line-no">755</span><span id="line-755"> final Collection<StoreFileInfo> storeFiles = storeFileInfos;</span> |
| <span class="source-line-no">756</span><span id="line-756"> if (storeFiles != null && storeFiles.size() > 0) {</span> |
| <span class="source-line-no">757</span><span id="line-757"> final Configuration storeConfiguration =</span> |
| <span class="source-line-no">758</span><span id="line-758"> StoreUtils.createStoreConfiguration(env.getMasterConfiguration(), htd, hcd);</span> |
| <span class="source-line-no">759</span><span id="line-759"> for (StoreFileInfo storeFileInfo : storeFiles) {</span> |
| <span class="source-line-no">760</span><span id="line-760"> // As this procedure is running on master, use CacheConfig.DISABLED means</span> |
| <span class="source-line-no">761</span><span id="line-761"> // don't cache any block.</span> |
| <span class="source-line-no">762</span><span id="line-762"> // We also need to pass through a suitable CompoundConfiguration as if this</span> |
| <span class="source-line-no">763</span><span id="line-763"> // is running in a regionserver's Store context, or we might not be able</span> |
| <span class="source-line-no">764</span><span id="line-764"> // to read the hfiles.</span> |
| <span class="source-line-no">765</span><span id="line-765"> storeFileInfo.setConf(storeConfiguration);</span> |
| <span class="source-line-no">766</span><span id="line-766"> StoreFileSplitter sfs = new StoreFileSplitter(regionFs, htd, hcd,</span> |
| <span class="source-line-no">767</span><span id="line-767"> new HStoreFile(storeFileInfo, hcd.getBloomFilterType(), CacheConfig.DISABLED));</span> |
| <span class="source-line-no">768</span><span id="line-768"> futures.add(threadPool.submit(sfs));</span> |
| <span class="source-line-no">769</span><span id="line-769"> }</span> |
| <span class="source-line-no">770</span><span id="line-770"> }</span> |
| <span class="source-line-no">771</span><span id="line-771"> }</span> |
| <span class="source-line-no">772</span><span id="line-772"> // Shutdown the pool</span> |
| <span class="source-line-no">773</span><span id="line-773"> threadPool.shutdown();</span> |
| <span class="source-line-no">774</span><span id="line-774"></span> |
| <span class="source-line-no">775</span><span id="line-775"> // Wait for all the tasks to finish.</span> |
| <span class="source-line-no">776</span><span id="line-776"> // When splits ran on the RegionServer, how-long-to-wait-configuration was named</span> |
| <span class="source-line-no">777</span><span id="line-777"> // hbase.regionserver.fileSplitTimeout. If set, use its value.</span> |
| <span class="source-line-no">778</span><span id="line-778"> long fileSplitTimeout = conf.getLong("hbase.master.fileSplitTimeout",</span> |
| <span class="source-line-no">779</span><span id="line-779"> conf.getLong("hbase.regionserver.fileSplitTimeout", 600000));</span> |
| <span class="source-line-no">780</span><span id="line-780"> try {</span> |
| <span class="source-line-no">781</span><span id="line-781"> boolean stillRunning = !threadPool.awaitTermination(fileSplitTimeout, TimeUnit.MILLISECONDS);</span> |
| <span class="source-line-no">782</span><span id="line-782"> if (stillRunning) {</span> |
| <span class="source-line-no">783</span><span id="line-783"> threadPool.shutdownNow();</span> |
| <span class="source-line-no">784</span><span id="line-784"> // wait for the thread to shutdown completely.</span> |
| <span class="source-line-no">785</span><span id="line-785"> while (!threadPool.isTerminated()) {</span> |
| <span class="source-line-no">786</span><span id="line-786"> Thread.sleep(50);</span> |
| <span class="source-line-no">787</span><span id="line-787"> }</span> |
| <span class="source-line-no">788</span><span id="line-788"> throw new IOException(</span> |
| <span class="source-line-no">789</span><span id="line-789"> "Took too long to split the" + " files and create the references, aborting split");</span> |
| <span class="source-line-no">790</span><span id="line-790"> }</span> |
| <span class="source-line-no">791</span><span id="line-791"> } catch (InterruptedException e) {</span> |
| <span class="source-line-no">792</span><span id="line-792"> throw (InterruptedIOException) new InterruptedIOException().initCause(e);</span> |
| <span class="source-line-no">793</span><span id="line-793"> }</span> |
| <span class="source-line-no">794</span><span id="line-794"></span> |
| <span class="source-line-no">795</span><span id="line-795"> List<Path> daughterA = new ArrayList<>();</span> |
| <span class="source-line-no">796</span><span id="line-796"> List<Path> daughterB = new ArrayList<>();</span> |
| <span class="source-line-no">797</span><span id="line-797"> // Look for any exception</span> |
| <span class="source-line-no">798</span><span id="line-798"> for (Future<Pair<Path, Path>> future : futures) {</span> |
| <span class="source-line-no">799</span><span id="line-799"> try {</span> |
| <span class="source-line-no">800</span><span id="line-800"> Pair<Path, Path> p = future.get();</span> |
| <span class="source-line-no">801</span><span id="line-801"> if (p.getFirst() != null) {</span> |
| <span class="source-line-no">802</span><span id="line-802"> daughterA.add(p.getFirst());</span> |
| <span class="source-line-no">803</span><span id="line-803"> }</span> |
| <span class="source-line-no">804</span><span id="line-804"> if (p.getSecond() != null) {</span> |
| <span class="source-line-no">805</span><span id="line-805"> daughterB.add(p.getSecond());</span> |
| <span class="source-line-no">806</span><span id="line-806"> }</span> |
| <span class="source-line-no">807</span><span id="line-807"> } catch (InterruptedException e) {</span> |
| <span class="source-line-no">808</span><span id="line-808"> throw (InterruptedIOException) new InterruptedIOException().initCause(e);</span> |
| <span class="source-line-no">809</span><span id="line-809"> } catch (ExecutionException e) {</span> |
| <span class="source-line-no">810</span><span id="line-810"> throw new IOException(e);</span> |
| <span class="source-line-no">811</span><span id="line-811"> }</span> |
| <span class="source-line-no">812</span><span id="line-812"> }</span> |
| <span class="source-line-no">813</span><span id="line-813"></span> |
| <span class="source-line-no">814</span><span id="line-814"> if (LOG.isDebugEnabled()) {</span> |
| <span class="source-line-no">815</span><span id="line-815"> LOG.debug("pid=" + getProcId() + " split storefiles for region "</span> |
| <span class="source-line-no">816</span><span id="line-816"> + getParentRegion().getShortNameToLog() + " Daughter A: " + daughterA</span> |
| <span class="source-line-no">817</span><span id="line-817"> + " storefiles, Daughter B: " + daughterB + " storefiles.");</span> |
| <span class="source-line-no">818</span><span id="line-818"> }</span> |
| <span class="source-line-no">819</span><span id="line-819"> return new Pair<>(daughterA, daughterB);</span> |
| <span class="source-line-no">820</span><span id="line-820"> }</span> |
| <span class="source-line-no">821</span><span id="line-821"></span> |
| <span class="source-line-no">822</span><span id="line-822"> private void assertSplitResultFilesCount(final FileSystem fs,</span> |
| <span class="source-line-no">823</span><span id="line-823"> final int expectedSplitResultFileCount, Path dir) throws IOException {</span> |
| <span class="source-line-no">824</span><span id="line-824"> if (expectedSplitResultFileCount != 0) {</span> |
| <span class="source-line-no">825</span><span id="line-825"> int resultFileCount = FSUtils.getRegionReferenceAndLinkFileCount(fs, dir);</span> |
| <span class="source-line-no">826</span><span id="line-826"> if (expectedSplitResultFileCount != resultFileCount) {</span> |
| <span class="source-line-no">827</span><span id="line-827"> throw new IOException("Failing split. Didn't have expected reference and HFileLink files"</span> |
| <span class="source-line-no">828</span><span id="line-828"> + ", expected=" + expectedSplitResultFileCount + ", actual=" + resultFileCount);</span> |
| <span class="source-line-no">829</span><span id="line-829"> }</span> |
| <span class="source-line-no">830</span><span id="line-830"> }</span> |
| <span class="source-line-no">831</span><span id="line-831"> }</span> |
| <span class="source-line-no">832</span><span id="line-832"></span> |
| <span class="source-line-no">833</span><span id="line-833"> private Pair<Path, Path> splitStoreFile(HRegionFileSystem regionFs, TableDescriptor htd,</span> |
| <span class="source-line-no">834</span><span id="line-834"> ColumnFamilyDescriptor hcd, HStoreFile sf) throws IOException {</span> |
| <span class="source-line-no">835</span><span id="line-835"> if (LOG.isDebugEnabled()) {</span> |
| <span class="source-line-no">836</span><span id="line-836"> LOG.debug("pid=" + getProcId() + " splitting started for store file: " + sf.getPath()</span> |
| <span class="source-line-no">837</span><span id="line-837"> + " for region: " + getParentRegion().getShortNameToLog());</span> |
| <span class="source-line-no">838</span><span id="line-838"> }</span> |
| <span class="source-line-no">839</span><span id="line-839"></span> |
| <span class="source-line-no">840</span><span id="line-840"> final byte[] splitRow = getSplitRow();</span> |
| <span class="source-line-no">841</span><span id="line-841"> final String familyName = hcd.getNameAsString();</span> |
| <span class="source-line-no">842</span><span id="line-842"> StoreFileTracker daughterOneSft =</span> |
| <span class="source-line-no">843</span><span id="line-843"> StoreFileTrackerFactory.create(regionFs.getFileSystem().getConf(), htd, hcd,</span> |
| <span class="source-line-no">844</span><span id="line-844"> HRegionFileSystem.create(regionFs.getFileSystem().getConf(), regionFs.getFileSystem(),</span> |
| <span class="source-line-no">845</span><span id="line-845"> regionFs.getTableDir(), daughterOneRI));</span> |
| <span class="source-line-no">846</span><span id="line-846"> StoreFileTracker daughterTwoSft =</span> |
| <span class="source-line-no">847</span><span id="line-847"> StoreFileTrackerFactory.create(regionFs.getFileSystem().getConf(), htd, hcd,</span> |
| <span class="source-line-no">848</span><span id="line-848"> HRegionFileSystem.create(regionFs.getFileSystem().getConf(), regionFs.getFileSystem(),</span> |
| <span class="source-line-no">849</span><span id="line-849"> regionFs.getTableDir(), daughterTwoRI));</span> |
| <span class="source-line-no">850</span><span id="line-850"> final Path path_first = regionFs.splitStoreFile(this.daughterOneRI, familyName, sf, splitRow,</span> |
| <span class="source-line-no">851</span><span id="line-851"> false, splitPolicy, daughterOneSft);</span> |
| <span class="source-line-no">852</span><span id="line-852"> final Path path_second = regionFs.splitStoreFile(this.daughterTwoRI, familyName, sf, splitRow,</span> |
| <span class="source-line-no">853</span><span id="line-853"> true, splitPolicy, daughterTwoSft);</span> |
| <span class="source-line-no">854</span><span id="line-854"> if (LOG.isDebugEnabled()) {</span> |
| <span class="source-line-no">855</span><span id="line-855"> LOG.debug("pid=" + getProcId() + " splitting complete for store file: " + sf.getPath()</span> |
| <span class="source-line-no">856</span><span id="line-856"> + " for region: " + getParentRegion().getShortNameToLog());</span> |
| <span class="source-line-no">857</span><span id="line-857"> }</span> |
| <span class="source-line-no">858</span><span id="line-858"> return new Pair<Path, Path>(path_first, path_second);</span> |
| <span class="source-line-no">859</span><span id="line-859"> }</span> |
| <span class="source-line-no">860</span><span id="line-860"></span> |
| <span class="source-line-no">861</span><span id="line-861"> /**</span> |
| <span class="source-line-no">862</span><span id="line-862"> * Utility class used to do the file splitting / reference writing in parallel instead of</span> |
| <span class="source-line-no">863</span><span id="line-863"> * sequentially.</span> |
| <span class="source-line-no">864</span><span id="line-864"> */</span> |
| <span class="source-line-no">865</span><span id="line-865"> private class StoreFileSplitter implements Callable<Pair<Path, Path>> {</span> |
| <span class="source-line-no">866</span><span id="line-866"> private final HRegionFileSystem regionFs;</span> |
| <span class="source-line-no">867</span><span id="line-867"> private final ColumnFamilyDescriptor hcd;</span> |
| <span class="source-line-no">868</span><span id="line-868"> private final HStoreFile sf;</span> |
| <span class="source-line-no">869</span><span id="line-869"> private final TableDescriptor htd;</span> |
| <span class="source-line-no">870</span><span id="line-870"></span> |
| <span class="source-line-no">871</span><span id="line-871"> /**</span> |
| <span class="source-line-no">872</span><span id="line-872"> * Constructor that takes what it needs to split</span> |
| <span class="source-line-no">873</span><span id="line-873"> * @param regionFs the file system</span> |
| <span class="source-line-no">874</span><span id="line-874"> * @param hcd Family that contains the store file</span> |
| <span class="source-line-no">875</span><span id="line-875"> * @param sf which file</span> |
| <span class="source-line-no">876</span><span id="line-876"> */</span> |
| <span class="source-line-no">877</span><span id="line-877"> public StoreFileSplitter(HRegionFileSystem regionFs, TableDescriptor htd,</span> |
| <span class="source-line-no">878</span><span id="line-878"> ColumnFamilyDescriptor hcd, HStoreFile sf) {</span> |
| <span class="source-line-no">879</span><span id="line-879"> this.regionFs = regionFs;</span> |
| <span class="source-line-no">880</span><span id="line-880"> this.sf = sf;</span> |
| <span class="source-line-no">881</span><span id="line-881"> this.hcd = hcd;</span> |
| <span class="source-line-no">882</span><span id="line-882"> this.htd = htd;</span> |
| <span class="source-line-no">883</span><span id="line-883"> }</span> |
| <span class="source-line-no">884</span><span id="line-884"></span> |
| <span class="source-line-no">885</span><span id="line-885"> @Override</span> |
| <span class="source-line-no">886</span><span id="line-886"> public Pair<Path, Path> call() throws IOException {</span> |
| <span class="source-line-no">887</span><span id="line-887"> return splitStoreFile(regionFs, htd, hcd, sf);</span> |
| <span class="source-line-no">888</span><span id="line-888"> }</span> |
| <span class="source-line-no">889</span><span id="line-889"> }</span> |
| <span class="source-line-no">890</span><span id="line-890"></span> |
| <span class="source-line-no">891</span><span id="line-891"> /**</span> |
| <span class="source-line-no">892</span><span id="line-892"> * Post split region actions before the Point-of-No-Return step</span> |
| <span class="source-line-no">893</span><span id="line-893"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">894</span><span id="line-894"> **/</span> |
| <span class="source-line-no">895</span><span id="line-895"> private void preSplitRegionBeforeMETA(final MasterProcedureEnv env)</span> |
| <span class="source-line-no">896</span><span id="line-896"> throws IOException, InterruptedException {</span> |
| <span class="source-line-no">897</span><span id="line-897"> final List<Mutation> metaEntries = new ArrayList<Mutation>();</span> |
| <span class="source-line-no">898</span><span id="line-898"> final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();</span> |
| <span class="source-line-no">899</span><span id="line-899"> if (cpHost != null) {</span> |
| <span class="source-line-no">900</span><span id="line-900"> cpHost.preSplitBeforeMETAAction(getSplitRow(), metaEntries, getUser());</span> |
| <span class="source-line-no">901</span><span id="line-901"> try {</span> |
| <span class="source-line-no">902</span><span id="line-902"> for (Mutation p : metaEntries) {</span> |
| <span class="source-line-no">903</span><span id="line-903"> RegionInfo.parseRegionName(p.getRow());</span> |
| <span class="source-line-no">904</span><span id="line-904"> }</span> |
| <span class="source-line-no">905</span><span id="line-905"> } catch (IOException e) {</span> |
| <span class="source-line-no">906</span><span id="line-906"> LOG.error("pid=" + getProcId() + " row key of mutation from coprocessor not parsable as "</span> |
| <span class="source-line-no">907</span><span id="line-907"> + "region name." + "Mutations from coprocessor should only for hbase:meta table.");</span> |
| <span class="source-line-no">908</span><span id="line-908"> throw e;</span> |
| <span class="source-line-no">909</span><span id="line-909"> }</span> |
| <span class="source-line-no">910</span><span id="line-910"> }</span> |
| <span class="source-line-no">911</span><span id="line-911"> }</span> |
| <span class="source-line-no">912</span><span id="line-912"></span> |
| <span class="source-line-no">913</span><span id="line-913"> /**</span> |
| <span class="source-line-no">914</span><span id="line-914"> * Add daughter regions to META</span> |
| <span class="source-line-no">915</span><span id="line-915"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">916</span><span id="line-916"> */</span> |
| <span class="source-line-no">917</span><span id="line-917"> private void updateMeta(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">918</span><span id="line-918"> env.getAssignmentManager().markRegionAsSplit(getParentRegion(), getParentRegionServerName(env),</span> |
| <span class="source-line-no">919</span><span id="line-919"> daughterOneRI, daughterTwoRI);</span> |
| <span class="source-line-no">920</span><span id="line-920"> }</span> |
| <span class="source-line-no">921</span><span id="line-921"></span> |
| <span class="source-line-no">922</span><span id="line-922"> /**</span> |
| <span class="source-line-no">923</span><span id="line-923"> * Pre split region actions after the Point-of-No-Return step</span> |
| <span class="source-line-no">924</span><span id="line-924"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">925</span><span id="line-925"> **/</span> |
| <span class="source-line-no">926</span><span id="line-926"> private void preSplitRegionAfterMETA(final MasterProcedureEnv env)</span> |
| <span class="source-line-no">927</span><span id="line-927"> throws IOException, InterruptedException {</span> |
| <span class="source-line-no">928</span><span id="line-928"> final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();</span> |
| <span class="source-line-no">929</span><span id="line-929"> if (cpHost != null) {</span> |
| <span class="source-line-no">930</span><span id="line-930"> cpHost.preSplitAfterMETAAction(getUser());</span> |
| <span class="source-line-no">931</span><span id="line-931"> }</span> |
| <span class="source-line-no">932</span><span id="line-932"> }</span> |
| <span class="source-line-no">933</span><span id="line-933"></span> |
| <span class="source-line-no">934</span><span id="line-934"> /**</span> |
| <span class="source-line-no">935</span><span id="line-935"> * Post split region actions</span> |
| <span class="source-line-no">936</span><span id="line-936"> * @param env MasterProcedureEnv</span> |
| <span class="source-line-no">937</span><span id="line-937"> **/</span> |
| <span class="source-line-no">938</span><span id="line-938"> private void postSplitRegion(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">939</span><span id="line-939"> final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();</span> |
| <span class="source-line-no">940</span><span id="line-940"> if (cpHost != null) {</span> |
| <span class="source-line-no">941</span><span id="line-941"> cpHost.postCompletedSplitRegionAction(daughterOneRI, daughterTwoRI, getUser());</span> |
| <span class="source-line-no">942</span><span id="line-942"> }</span> |
| <span class="source-line-no">943</span><span id="line-943"> }</span> |
| <span class="source-line-no">944</span><span id="line-944"></span> |
| <span class="source-line-no">945</span><span id="line-945"> private ServerName getParentRegionServerName(final MasterProcedureEnv env) {</span> |
| <span class="source-line-no">946</span><span id="line-946"> return env.getMasterServices().getAssignmentManager().getRegionStates()</span> |
| <span class="source-line-no">947</span><span id="line-947"> .getRegionServerOfRegion(getParentRegion());</span> |
| <span class="source-line-no">948</span><span id="line-948"> }</span> |
| <span class="source-line-no">949</span><span id="line-949"></span> |
| <span class="source-line-no">950</span><span id="line-950"> private TransitRegionStateProcedure[] createUnassignProcedures(MasterProcedureEnv env)</span> |
| <span class="source-line-no">951</span><span id="line-951"> throws IOException {</span> |
| <span class="source-line-no">952</span><span id="line-952"> return AssignmentManagerUtil.createUnassignProceduresForSplitOrMerge(env,</span> |
| <span class="source-line-no">953</span><span id="line-953"> Stream.of(getParentRegion()), getRegionReplication(env));</span> |
| <span class="source-line-no">954</span><span id="line-954"> }</span> |
| <span class="source-line-no">955</span><span id="line-955"></span> |
| <span class="source-line-no">956</span><span id="line-956"> private TransitRegionStateProcedure[] createAssignProcedures(MasterProcedureEnv env)</span> |
| <span class="source-line-no">957</span><span id="line-957"> throws IOException {</span> |
| <span class="source-line-no">958</span><span id="line-958"> List<RegionInfo> hris = new ArrayList<RegionInfo>(2);</span> |
| <span class="source-line-no">959</span><span id="line-959"> hris.add(daughterOneRI);</span> |
| <span class="source-line-no">960</span><span id="line-960"> hris.add(daughterTwoRI);</span> |
| <span class="source-line-no">961</span><span id="line-961"> return AssignmentManagerUtil.createAssignProceduresForSplitDaughters(env, hris,</span> |
| <span class="source-line-no">962</span><span id="line-962"> getRegionReplication(env), getParentRegionServerName(env));</span> |
| <span class="source-line-no">963</span><span id="line-963"> }</span> |
| <span class="source-line-no">964</span><span id="line-964"></span> |
| <span class="source-line-no">965</span><span id="line-965"> private int getRegionReplication(final MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">966</span><span id="line-966"> final TableDescriptor htd = env.getMasterServices().getTableDescriptors().get(getTableName());</span> |
| <span class="source-line-no">967</span><span id="line-967"> return htd.getRegionReplication();</span> |
| <span class="source-line-no">968</span><span id="line-968"> }</span> |
| <span class="source-line-no">969</span><span id="line-969"></span> |
| <span class="source-line-no">970</span><span id="line-970"> private void writeMaxSequenceIdFile(MasterProcedureEnv env) throws IOException {</span> |
| <span class="source-line-no">971</span><span id="line-971"> MasterFileSystem fs = env.getMasterFileSystem();</span> |
| <span class="source-line-no">972</span><span id="line-972"> long maxSequenceId = WALSplitUtil.getMaxRegionSequenceId(env.getMasterConfiguration(),</span> |
| <span class="source-line-no">973</span><span id="line-973"> getParentRegion(), fs::getFileSystem, fs::getWALFileSystem);</span> |
| <span class="source-line-no">974</span><span id="line-974"> if (maxSequenceId > 0) {</span> |
| <span class="source-line-no">975</span><span id="line-975"> WALSplitUtil.writeRegionSequenceIdFile(fs.getWALFileSystem(),</span> |
| <span class="source-line-no">976</span><span id="line-976"> getWALRegionDir(env, daughterOneRI), maxSequenceId);</span> |
| <span class="source-line-no">977</span><span id="line-977"> WALSplitUtil.writeRegionSequenceIdFile(fs.getWALFileSystem(),</span> |
| <span class="source-line-no">978</span><span id="line-978"> getWALRegionDir(env, daughterTwoRI), maxSequenceId);</span> |
| <span class="source-line-no">979</span><span id="line-979"> }</span> |
| <span class="source-line-no">980</span><span id="line-980"> }</span> |
| <span class="source-line-no">981</span><span id="line-981"></span> |
| <span class="source-line-no">982</span><span id="line-982"> @Override</span> |
| <span class="source-line-no">983</span><span id="line-983"> protected boolean abort(MasterProcedureEnv env) {</span> |
| <span class="source-line-no">984</span><span id="line-984"> // Abort means rollback. We can't rollback all steps. HBASE-18018 added abort to all</span> |
| <span class="source-line-no">985</span><span id="line-985"> // Procedures. Here is a Procedure that has a PONR and cannot be aborted wants it enters this</span> |
| <span class="source-line-no">986</span><span id="line-986"> // range of steps; what do we do for these should an operator want to cancel them? HBASE-20022.</span> |
| <span class="source-line-no">987</span><span id="line-987"> return isRollbackSupported(getCurrentState()) ? super.abort(env) : false;</span> |
| <span class="source-line-no">988</span><span id="line-988"> }</span> |
| <span class="source-line-no">989</span><span id="line-989">}</span> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| </pre> |
| </div> |
| </main> |
| </body> |
| </html> |