You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2025/03/27 14:51:59 UTC

(hbase-site) branch asf-site updated: Published site at d98c63a2eef81a41394485bb9f2012423ae09f1a.

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 3f092f353a7 Published site at d98c63a2eef81a41394485bb9f2012423ae09f1a.
3f092f353a7 is described below

commit 3f092f353a7214d9509192c5d33662f86027d578
Author: jenkins <bu...@apache.org>
AuthorDate: Thu Mar 27 14:51:17 2025 +0000

    Published site at d98c63a2eef81a41394485bb9f2012423ae09f1a.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 apidocs/index-all.html                             |   36 +-
 apidocs/member-search-index.js                     |    2 +-
 .../hadoop/hbase/master/class-use/RegionPlan.html  |    3 +
 .../master/HMaster.TableDescriptorGetter.html      | 4568 ++++++++++----------
 .../org/apache/hadoop/hbase/master/HMaster.html    | 4568 ++++++++++----------
 .../apache/hadoop/hbase/master/LoadBalancer.html   |  285 +-
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          | 2319 +++++-----
 checkstyle.rss                                     |  648 +--
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/constant-values.html                    |   17 +
 devapidocs/index-all.html                          |   24 +
 devapidocs/member-search-index.js                  |    2 +-
 .../apache/hadoop/hbase/class-use/ServerName.html  |  188 +-
 .../apache/hadoop/hbase/class-use/TableName.html   |   54 +-
 .../hadoop/hbase/client/class-use/RegionInfo.html  |  196 +-
 .../hbase/favored/FavoredNodeLoadBalancer.html     |    4 +-
 .../hfile/bucket/BucketCache.BucketEntryGroup.html |   18 +-
 .../io/hfile/bucket/BucketCache.RAMCache.html      |   22 +-
 .../io/hfile/bucket/BucketCache.RAMQueueEntry.html |   24 +-
 .../hfile/bucket/BucketCache.StatisticsThread.html |    8 +-
 .../io/hfile/bucket/BucketCache.WriterThread.html  |   14 +-
 .../hadoop/hbase/io/hfile/bucket/BucketCache.html  |  160 +-
 .../master/HMaster.TableDescriptorGetter.html      |    4 +-
 .../org/apache/hadoop/hbase/master/HMaster.html    |  310 +-
 .../apache/hadoop/hbase/master/LoadBalancer.html   |   96 +-
 .../hbase/master/balancer/BaseLoadBalancer.html    |    4 +-
 ...eLoadBalancer.CacheAwareCandidateGenerator.html |   10 +-
 ...heAwareLoadBalancer.CacheAwareCostFunction.html |   22 +-
 ...ancer.CacheAwareRegionSkewnessCostFunction.html |   18 +-
 ...ancer.CacheAwareSkewnessCandidateGenerator.html |    8 +-
 ...cheAwareLoadBalancer.GeneratorFunctionType.html |   12 +-
 .../master/balancer/CacheAwareLoadBalancer.html    |  128 +-
 .../master/balancer/FavoredStochasticBalancer.html |    5 +-
 .../master/balancer/MaintenanceLoadBalancer.html   |    4 +-
 .../hbase/master/balancer/SimpleLoadBalancer.html  |    4 +-
 .../master/balancer/StochasticLoadBalancer.html    |    5 +-
 .../hadoop/hbase/master/class-use/RegionPlan.html  |   56 +-
 .../hbase/rsgroup/RSGroupBasedLoadBalancer.html    |    5 +-
 .../hfile/bucket/BucketCache.BucketEntryGroup.html | 3567 +++++++--------
 .../io/hfile/bucket/BucketCache.CacheState.html    | 3567 +++++++--------
 .../io/hfile/bucket/BucketCache.RAMCache.html      | 3567 +++++++--------
 .../io/hfile/bucket/BucketCache.RAMQueueEntry.html | 3567 +++++++--------
 .../hfile/bucket/BucketCache.StatisticsThread.html | 3567 +++++++--------
 .../io/hfile/bucket/BucketCache.WriterThread.html  | 3567 +++++++--------
 .../hadoop/hbase/io/hfile/bucket/BucketCache.html  | 3567 +++++++--------
 .../master/HMaster.TableDescriptorGetter.html      | 4568 ++++++++++----------
 .../org/apache/hadoop/hbase/master/HMaster.html    | 4568 ++++++++++----------
 .../apache/hadoop/hbase/master/LoadBalancer.html   |  285 +-
 ...eLoadBalancer.CacheAwareCandidateGenerator.html |  917 ++--
 ...heAwareLoadBalancer.CacheAwareCostFunction.html |  917 ++--
 ...ancer.CacheAwareRegionSkewnessCostFunction.html |  917 ++--
 ...ancer.CacheAwareSkewnessCandidateGenerator.html |  917 ++--
 ...cheAwareLoadBalancer.GeneratorFunctionType.html |  917 ++--
 .../master/balancer/CacheAwareLoadBalancer.html    |  917 ++--
 downloads.html                                     |    2 +-
 export_control.html                                |    2 +-
 index.html                                         |    2 +-
 issue-management.html                              |    2 +-
 licenses.html                                      |    2 +-
 mailing-lists.html                                 |    2 +-
 metrics.html                                       |    2 +-
 old_news.html                                      |    2 +-
 plugin-management.html                             |    2 +-
 plugins.html                                       |    2 +-
 poweredbyhbase.html                                |    2 +-
 project-info.html                                  |    2 +-
 project-reports.html                               |    2 +-
 pseudo-distributed.html                            |    2 +-
 replication.html                                   |    2 +-
 resources.html                                     |    2 +-
 scm.html                                           |    2 +-
 sponsors.html                                      |    2 +-
 summary.html                                       |    2 +-
 supportingprojects.html                            |    2 +-
 team.html                                          |    2 +-
 testapidocs/index-all.html                         |   92 +-
 testapidocs/member-search-index.js                 |    2 +-
 .../hfile/TestBlockEvictionOnRegionMovement.html   |  320 +-
 testdevapidocs/index-all.html                      |   82 +-
 testdevapidocs/member-search-index.js              |    2 +-
 .../hbase/TestZooKeeper.MockLoadBalancer.html      |    4 +-
 .../hfile/TestBlockEvictionOnRegionMovement.html   |   30 +-
 .../bucket/TestBucketCache.MockedBucketCache.html  |    8 +-
 .../hbase/io/hfile/bucket/TestBucketCache.html     |  120 +-
 .../LoadOnlyFavoredStochasticBalancer.html         |    5 +-
 .../TestBaseLoadBalancer.MockBalancer.html         |    4 +-
 .../balancer/TestCacheAwareLoadBalancer.html       |  116 +-
 ...terogeneousCost.StochasticLoadTestBalancer.html |    5 +-
 .../hfile/TestBlockEvictionOnRegionMovement.html   |  320 +-
 .../bucket/TestBucketCache.MockedBucketCache.html  | 2045 ++++-----
 .../hbase/io/hfile/bucket/TestBucketCache.html     | 2045 ++++-----
 .../balancer/TestCacheAwareLoadBalancer.html       |  900 ++--
 100 files changed, 30392 insertions(+), 29513 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 80c05727883..f4e181fefd3 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -469,7 +469,7 @@
         All other marks mentioned may be trademarks or registered trademarks of their respective owners.
       </div>
       <div style="float: right">
-        Last Published: 2025-03-26
+        Last Published: 2025-03-27
       </div>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index 0afaa02b513..0e47b4b0369 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 2.0.6, based on Prawn 2.4.0)
 /Producer (Apache HBase Team)
-/ModDate (D:20250326143037+00'00')
-/CreationDate (D:20250326144427+00'00')
+/ModDate (D:20250327143126+00'00')
+/CreationDate (D:20250327144733+00'00')
 >>
 endobj
 2 0 obj
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index 8e08f52f61c..98e76074069 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -5118,7 +5118,7 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>call(O) - Method in class org.apache.hadoop.hbase.coprocessor.CoprocessorHost.ObserverOperationWithResult</dt>
 <dd>&nbsp;</dd>
-<dt>call(AbstractRpcBasedConnectionRegistry.Callable&lt;T&gt;, Predicate&lt;T&gt;, String) - Method in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>call(AbstractRpcBasedConnectionRegistry.Callable&lt;T&gt;, Predicate&lt;T&gt;, String) - Method in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>&nbsp;</dd>
 <dt>call(HBaseRpcController, AdminProtos.AdminService.Interface) - Method in interface org.apache.hadoop.hbase.client.AsyncAdminRequestRetryingCaller.Callable</dt>
 <dd>&nbsp;</dd>
@@ -7172,7 +7172,7 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>close() - Method in class org.apache.hadoop.hbase.chaos.ChaosAgent</dt>
 <dd>&nbsp;</dd>
-<dt>close() - Method in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>close() - Method in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>&nbsp;</dd>
 <dt>close() - Method in interface org.apache.hadoop.hbase.client.Admin</dt>
 <dd>&nbsp;</dd>
@@ -9236,7 +9236,7 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>conf - Variable in class org.apache.hadoop.hbase.regionserver.StoreFileReader</dt>
 <dd>&nbsp;</dd>
-<dt>conf - Variable in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>conf - Variable in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>&nbsp;</dd>
 <dt>conf - Variable in class org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL</dt>
 <dd>
@@ -11906,7 +11906,7 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Create a new Scan with a cursor.</div>
 </dd>
-<dt>createScanner(List&lt;KeyValueScanner&gt;, FlushLifeCycleTracker) - Method in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>createScanner(List&lt;KeyValueScanner&gt;, FlushLifeCycleTracker) - Method in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>
 <div class="block">Creates the scanner for flushing snapshot.</div>
 </dd>
@@ -12442,7 +12442,7 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Create a writer for writing new store files.</div>
 </dd>
-<dt>createWriter(MemStoreSnapshot, boolean, Consumer&lt;Path&gt;) - Method in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>createWriter(MemStoreSnapshot, boolean, Consumer&lt;Path&gt;) - Method in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>&nbsp;</dd>
 <dt>createWriterInstance(FileSystem, Path) - Method in class org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL</dt>
 <dd>&nbsp;</dd>
@@ -18473,7 +18473,7 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>finalizeWriter(StoreFileWriter, long, MonitoredTask) - Method in class org.apache.hadoop.hbase.mob.DefaultMobStoreFlusher</dt>
 <dd>&nbsp;</dd>
-<dt>finalizeWriter(StoreFileWriter, long, MonitoredTask) - Method in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>finalizeWriter(StoreFileWriter, long, MonitoredTask) - Method in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>&nbsp;</dd>
 <dt>findArchivedLog(Path, Configuration) - Static method in class org.apache.hadoop.hbase.wal.AbstractFSWALProvider</dt>
 <dd>
@@ -19982,7 +19982,7 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>getActiveLogFiles() - Static method in class org.apache.hadoop.hbase.logging.Log4jUtils</dt>
 <dd>&nbsp;</dd>
-<dt>getActiveMaster() - Method in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>getActiveMaster() - Method in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>&nbsp;</dd>
 <dt>getActiveMaster() - Method in interface org.apache.hadoop.hbase.client.ConnectionRegistry</dt>
 <dd>
@@ -21780,7 +21780,7 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Returns the cluster definition</div>
 </dd>
-<dt>getClusterId() - Method in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>getClusterId() - Method in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>&nbsp;</dd>
 <dt>getClusterId() - Method in interface org.apache.hadoop.hbase.client.Connection</dt>
 <dd>
@@ -26952,7 +26952,7 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>getMetaRegionLocationCache() - Method in class org.apache.hadoop.hbase.HBaseServerBase</dt>
 <dd>&nbsp;</dd>
-<dt>getMetaRegionLocations() - Method in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>getMetaRegionLocations() - Method in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>&nbsp;</dd>
 <dt>getMetaRegionLocations() - Method in interface org.apache.hadoop.hbase.client.ConnectionRegistry</dt>
 <dd>
@@ -37431,7 +37431,7 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>HEDGED_READS_DESC - Static variable in interface org.apache.hadoop.hbase.regionserver.MetricsRegionServerSource</dt>
 <dd>&nbsp;</dd>
-<dt>HEDGED_REQS_FANOUT_DEFAULT - Static variable in class org.apache.hadoop.hbase.client.RpcConnectionRegistry</dt>
+<dt>HEDGED_REQS_FANOUT_DEFAULT - Static variable in class org.apache.hadoop.hbase.client.MasterRegistry</dt>
 <dd>
 <div class="block">Default value for the fan out of hedged requests.</div>
 </dd>
@@ -48007,6 +48007,16 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>MOVE_RETRIES_MAX_KEY - Static variable in class org.apache.hadoop.hbase.util.RegionMover</dt>
 <dd>&nbsp;</dd>
+<dt>MOVE_THROTTLING - Static variable in interface org.apache.hadoop.hbase.master.LoadBalancer</dt>
+<dd>
+<div class="block">Configuration to determine the time to sleep when throttling (if throttling is implemented by
+ the underlying implementation).</div>
+</dd>
+<dt>MOVE_THROTTLING_DEFAULT - Static variable in interface org.apache.hadoop.hbase.master.LoadBalancer</dt>
+<dd>
+<div class="block">The default value, in milliseconds, for the hbase.master.balancer.move.throttlingMillis if
+ throttling is implemented.</div>
+</dd>
 <dt>MOVE_WAIT_MAX_KEY - Static variable in class org.apache.hadoop.hbase.util.RegionMover</dt>
 <dd>&nbsp;</dd>
 <dt>moveAsideBadEditsFile(FileSystem, Path) - Static method in class org.apache.hadoop.hbase.wal.WALSplitUtil</dt>
@@ -51928,7 +51938,7 @@ service.</div>
 <dd>
 <div class="block">Performs compaction on a column family with the mob flag enabled.</div>
 </dd>
-<dt>performFlush(InternalScanner, CellSink, ThroughputController) - Method in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>performFlush(InternalScanner, CellSink, ThroughputController) - Method in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>
 <div class="block">Performs memstore flush, writing data from scanner into sink.</div>
 </dd>
@@ -68175,7 +68185,7 @@ service.</div>
 </dd>
 <dt>store - Variable in class org.apache.hadoop.hbase.io.crypto.KeyStoreKeyProvider</dt>
 <dd>&nbsp;</dd>
-<dt>store - Variable in class org.apache.hadoop.hbase.regionserver.DefaultStoreFlusher</dt>
+<dt>store - Variable in class org.apache.hadoop.hbase.regionserver.StripeStoreFlusher</dt>
 <dd>&nbsp;</dd>
 <dt>store - Variable in class org.apache.hadoop.hbase.regionserver.StoreScanner</dt>
 <dd>&nbsp;</dd>
@@ -69814,6 +69824,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.thrift.ThriftUtilities - Class in <a href="org/apache/hadoop/hbase/thrift/package-summary.html">org.apache.hadoop.hbase.thrift</a></dt>
 <dd>&nbsp;</dd>
+<dt>throttle(RegionPlan) - Method in interface org.apache.hadoop.hbase.master.LoadBalancer</dt>
+<dd>&nbsp;</dd>
 <dt>THROTTLE - Enum constant in enum class org.apache.hadoop.hbase.quotas.QuotaType</dt>
 <dd>&nbsp;</dd>
 <dt>throttleCompaction(long) - Method in class org.apache.hadoop.hbase.regionserver.HStore</dt>
diff --git a/apidocs/member-search-index.js b/apidocs/member-search-index.js
index 7b74cd0ba56..b64a0e451dd 100644
--- a/apidocs/member-search-index.js
+++ b/apidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
diff --git a/apidocs/org/apache/hadoop/hbase/master/class-use/RegionPlan.html b/apidocs/org/apache/hadoop/hbase/master/class-use/RegionPlan.html
index faf2a5814cd..03c38250e2b 100644
--- a/apidocs/org/apache/hadoop/hbase/master/class-use/RegionPlan.html
+++ b/apidocs/org/apache/hadoop/hbase/master/class-use/RegionPlan.html
@@ -139,6 +139,9 @@ loadScripts(document, 'script');</script>
 <div class="col-last odd-row-color">
 <div class="block">Compare the region info.</div>
 </div>
+<div class="col-first even-row-color"><code>default void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">LoadBalancer.</span><code>throttle<wbr>(org.apache.hadoop.hbase.master.RegionPlan&nbsp;plan)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
 </div>
 <div class="caption"><span>Method parameters in <a href="../package-summary.html">org.apache.hadoop.hbase.master</a> with type arguments of type org.apache.hadoop.hbase.master.RegionPlan in  in </span></div>
 <div class="summary-table three-column-summary">
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.TableDescriptorGetter.html b/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.TableDescriptorGetter.html
index 346fea5a935..bc4a8f93c95 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.TableDescriptorGetter.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.TableDescriptorGetter.html
@@ -2201,2349 +2201,2353 @@
 <span class="source-line-no">2188</span><span id="line-2188">        // TODO: bulk assign</span>
 <span class="source-line-no">2189</span><span id="line-2189">        try {</span>
 <span class="source-line-no">2190</span><span id="line-2190">          this.assignmentManager.balance(plan);</span>
-<span class="source-line-no">2191</span><span id="line-2191">        } catch (HBaseIOException hioe) {</span>
-<span class="source-line-no">2192</span><span id="line-2192">          // should ignore failed plans here, avoiding the whole balance plans be aborted</span>
-<span class="source-line-no">2193</span><span id="line-2193">          // later calls of balance() can fetch up the failed and skipped plans</span>
-<span class="source-line-no">2194</span><span id="line-2194">          LOG.warn("Failed balance plan {}, skipping...", plan, hioe);</span>
-<span class="source-line-no">2195</span><span id="line-2195">        }</span>
-<span class="source-line-no">2196</span><span id="line-2196">        // rpCount records balance plans processed, does not care if a plan succeeds</span>
-<span class="source-line-no">2197</span><span id="line-2197">        rpCount++;</span>
-<span class="source-line-no">2198</span><span id="line-2198">        successRegionPlans.add(plan);</span>
-<span class="source-line-no">2199</span><span id="line-2199"></span>
-<span class="source-line-no">2200</span><span id="line-2200">        if (this.maxBalancingTime &gt; 0) {</span>
-<span class="source-line-no">2201</span><span id="line-2201">          balanceThrottling(balanceStartTime + rpCount * balanceInterval, maxRegionsInTransition,</span>
-<span class="source-line-no">2202</span><span id="line-2202">            cutoffTime);</span>
-<span class="source-line-no">2203</span><span id="line-2203">        }</span>
-<span class="source-line-no">2204</span><span id="line-2204"></span>
-<span class="source-line-no">2205</span><span id="line-2205">        // if performing next balance exceeds cutoff time, exit the loop</span>
-<span class="source-line-no">2206</span><span id="line-2206">        if (</span>
-<span class="source-line-no">2207</span><span id="line-2207">          this.maxBalancingTime &gt; 0 &amp;&amp; rpCount &lt; plans.size()</span>
-<span class="source-line-no">2208</span><span id="line-2208">            &amp;&amp; EnvironmentEdgeManager.currentTime() &gt; cutoffTime</span>
-<span class="source-line-no">2209</span><span id="line-2209">        ) {</span>
-<span class="source-line-no">2210</span><span id="line-2210">          // TODO: After balance, there should not be a cutoff time (keeping it as</span>
-<span class="source-line-no">2211</span><span id="line-2211">          // a security net for now)</span>
-<span class="source-line-no">2212</span><span id="line-2212">          LOG.debug(</span>
-<span class="source-line-no">2213</span><span id="line-2213">            "No more balancing till next balance run; maxBalanceTime=" + this.maxBalancingTime);</span>
-<span class="source-line-no">2214</span><span id="line-2214">          break;</span>
-<span class="source-line-no">2215</span><span id="line-2215">        }</span>
-<span class="source-line-no">2216</span><span id="line-2216">      }</span>
-<span class="source-line-no">2217</span><span id="line-2217">    }</span>
-<span class="source-line-no">2218</span><span id="line-2218">    LOG.debug("Balancer is going into sleep until next period in {}ms", getConfiguration()</span>
-<span class="source-line-no">2219</span><span id="line-2219">      .getInt(HConstants.HBASE_BALANCER_PERIOD, HConstants.DEFAULT_HBASE_BALANCER_PERIOD));</span>
-<span class="source-line-no">2220</span><span id="line-2220">    return successRegionPlans;</span>
-<span class="source-line-no">2221</span><span id="line-2221">  }</span>
-<span class="source-line-no">2222</span><span id="line-2222"></span>
-<span class="source-line-no">2223</span><span id="line-2223">  @Override</span>
-<span class="source-line-no">2224</span><span id="line-2224">  public RegionNormalizerManager getRegionNormalizerManager() {</span>
-<span class="source-line-no">2225</span><span id="line-2225">    return regionNormalizerManager;</span>
-<span class="source-line-no">2226</span><span id="line-2226">  }</span>
-<span class="source-line-no">2227</span><span id="line-2227"></span>
-<span class="source-line-no">2228</span><span id="line-2228">  @Override</span>
-<span class="source-line-no">2229</span><span id="line-2229">  public boolean normalizeRegions(final NormalizeTableFilterParams ntfp,</span>
-<span class="source-line-no">2230</span><span id="line-2230">    final boolean isHighPriority) throws IOException {</span>
-<span class="source-line-no">2231</span><span id="line-2231">    if (regionNormalizerManager == null || !regionNormalizerManager.isNormalizerOn()) {</span>
-<span class="source-line-no">2232</span><span id="line-2232">      LOG.debug("Region normalization is disabled, don't run region normalizer.");</span>
-<span class="source-line-no">2233</span><span id="line-2233">      return false;</span>
-<span class="source-line-no">2234</span><span id="line-2234">    }</span>
-<span class="source-line-no">2235</span><span id="line-2235">    if (skipRegionManagementAction("region normalizer")) {</span>
-<span class="source-line-no">2236</span><span id="line-2236">      return false;</span>
-<span class="source-line-no">2237</span><span id="line-2237">    }</span>
-<span class="source-line-no">2238</span><span id="line-2238">    if (assignmentManager.hasRegionsInTransition()) {</span>
-<span class="source-line-no">2239</span><span id="line-2239">      return false;</span>
-<span class="source-line-no">2240</span><span id="line-2240">    }</span>
-<span class="source-line-no">2241</span><span id="line-2241"></span>
-<span class="source-line-no">2242</span><span id="line-2242">    final Set&lt;TableName&gt; matchingTables = getTableDescriptors(new LinkedList&lt;&gt;(),</span>
-<span class="source-line-no">2243</span><span id="line-2243">      ntfp.getNamespace(), ntfp.getRegex(), ntfp.getTableNames(), false).stream()</span>
-<span class="source-line-no">2244</span><span id="line-2244">        .map(TableDescriptor::getTableName).collect(Collectors.toSet());</span>
-<span class="source-line-no">2245</span><span id="line-2245">    final Set&lt;TableName&gt; allEnabledTables =</span>
-<span class="source-line-no">2246</span><span id="line-2246">      tableStateManager.getTablesInStates(TableState.State.ENABLED);</span>
-<span class="source-line-no">2247</span><span id="line-2247">    final List&lt;TableName&gt; targetTables =</span>
-<span class="source-line-no">2248</span><span id="line-2248">      new ArrayList&lt;&gt;(Sets.intersection(matchingTables, allEnabledTables));</span>
-<span class="source-line-no">2249</span><span id="line-2249">    Collections.shuffle(targetTables);</span>
-<span class="source-line-no">2250</span><span id="line-2250">    return regionNormalizerManager.normalizeRegions(targetTables, isHighPriority);</span>
-<span class="source-line-no">2251</span><span id="line-2251">  }</span>
-<span class="source-line-no">2252</span><span id="line-2252"></span>
-<span class="source-line-no">2253</span><span id="line-2253">  /** Returns Client info for use as prefix on an audit log string; who did an action */</span>
-<span class="source-line-no">2254</span><span id="line-2254">  @Override</span>
-<span class="source-line-no">2255</span><span id="line-2255">  public String getClientIdAuditPrefix() {</span>
-<span class="source-line-no">2256</span><span id="line-2256">    return "Client=" + RpcServer.getRequestUserName().orElse(null) + "/"</span>
-<span class="source-line-no">2257</span><span id="line-2257">      + RpcServer.getRemoteAddress().orElse(null);</span>
-<span class="source-line-no">2258</span><span id="line-2258">  }</span>
-<span class="source-line-no">2259</span><span id="line-2259"></span>
-<span class="source-line-no">2260</span><span id="line-2260">  /**</span>
-<span class="source-line-no">2261</span><span id="line-2261">   * Switch for the background CatalogJanitor thread. Used for testing. The thread will continue to</span>
-<span class="source-line-no">2262</span><span id="line-2262">   * run. It will just be a noop if disabled.</span>
-<span class="source-line-no">2263</span><span id="line-2263">   * @param b If false, the catalog janitor won't do anything.</span>
-<span class="source-line-no">2264</span><span id="line-2264">   */</span>
-<span class="source-line-no">2265</span><span id="line-2265">  public void setCatalogJanitorEnabled(final boolean b) {</span>
-<span class="source-line-no">2266</span><span id="line-2266">    this.catalogJanitorChore.setEnabled(b);</span>
-<span class="source-line-no">2267</span><span id="line-2267">  }</span>
-<span class="source-line-no">2268</span><span id="line-2268"></span>
-<span class="source-line-no">2269</span><span id="line-2269">  @Override</span>
-<span class="source-line-no">2270</span><span id="line-2270">  public long mergeRegions(final RegionInfo[] regionsToMerge, final boolean forcible, final long ng,</span>
-<span class="source-line-no">2271</span><span id="line-2271">    final long nonce) throws IOException {</span>
-<span class="source-line-no">2272</span><span id="line-2272">    checkInitialized();</span>
-<span class="source-line-no">2273</span><span id="line-2273"></span>
-<span class="source-line-no">2274</span><span id="line-2274">    final String regionNamesToLog = RegionInfo.getShortNameToLog(regionsToMerge);</span>
-<span class="source-line-no">2275</span><span id="line-2275"></span>
-<span class="source-line-no">2276</span><span id="line-2276">    if (!isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {</span>
-<span class="source-line-no">2277</span><span id="line-2277">      LOG.warn("Merge switch is off! skip merge of " + regionNamesToLog);</span>
-<span class="source-line-no">2278</span><span id="line-2278">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2279</span><span id="line-2279">        "Merge of " + regionNamesToLog + " failed because merge switch is off");</span>
-<span class="source-line-no">2280</span><span id="line-2280">    }</span>
-<span class="source-line-no">2281</span><span id="line-2281"></span>
-<span class="source-line-no">2282</span><span id="line-2282">    if (!getTableDescriptors().get(regionsToMerge[0].getTable()).isMergeEnabled()) {</span>
-<span class="source-line-no">2283</span><span id="line-2283">      LOG.warn("Merge is disabled for the table! Skipping merge of {}", regionNamesToLog);</span>
-<span class="source-line-no">2284</span><span id="line-2284">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2285</span><span id="line-2285">        "Merge of " + regionNamesToLog + " failed as region merge is disabled for the table");</span>
-<span class="source-line-no">2286</span><span id="line-2286">    }</span>
-<span class="source-line-no">2287</span><span id="line-2287"></span>
-<span class="source-line-no">2288</span><span id="line-2288">    return MasterProcedureUtil.submitProcedure(new NonceProcedureRunnable(this, ng, nonce) {</span>
-<span class="source-line-no">2289</span><span id="line-2289">      @Override</span>
-<span class="source-line-no">2290</span><span id="line-2290">      protected void run() throws IOException {</span>
-<span class="source-line-no">2291</span><span id="line-2291">        getMaster().getMasterCoprocessorHost().preMergeRegions(regionsToMerge);</span>
-<span class="source-line-no">2292</span><span id="line-2292">        String aid = getClientIdAuditPrefix();</span>
-<span class="source-line-no">2293</span><span id="line-2293">        LOG.info("{} merge regions {}", aid, regionNamesToLog);</span>
-<span class="source-line-no">2294</span><span id="line-2294">        submitProcedure(new MergeTableRegionsProcedure(procedureExecutor.getEnvironment(),</span>
-<span class="source-line-no">2295</span><span id="line-2295">          regionsToMerge, forcible));</span>
-<span class="source-line-no">2296</span><span id="line-2296">        getMaster().getMasterCoprocessorHost().postMergeRegions(regionsToMerge);</span>
-<span class="source-line-no">2297</span><span id="line-2297">      }</span>
-<span class="source-line-no">2298</span><span id="line-2298"></span>
-<span class="source-line-no">2299</span><span id="line-2299">      @Override</span>
-<span class="source-line-no">2300</span><span id="line-2300">      protected String getDescription() {</span>
-<span class="source-line-no">2301</span><span id="line-2301">        return "MergeTableProcedure";</span>
-<span class="source-line-no">2302</span><span id="line-2302">      }</span>
-<span class="source-line-no">2303</span><span id="line-2303">    });</span>
-<span class="source-line-no">2304</span><span id="line-2304">  }</span>
-<span class="source-line-no">2305</span><span id="line-2305"></span>
-<span class="source-line-no">2306</span><span id="line-2306">  @Override</span>
-<span class="source-line-no">2307</span><span id="line-2307">  public long splitRegion(final RegionInfo regionInfo, final byte[] splitRow, final long nonceGroup,</span>
-<span class="source-line-no">2308</span><span id="line-2308">    final long nonce) throws IOException {</span>
-<span class="source-line-no">2309</span><span id="line-2309">    checkInitialized();</span>
-<span class="source-line-no">2310</span><span id="line-2310"></span>
-<span class="source-line-no">2311</span><span id="line-2311">    if (!isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {</span>
-<span class="source-line-no">2312</span><span id="line-2312">      LOG.warn("Split switch is off! skip split of " + regionInfo);</span>
-<span class="source-line-no">2313</span><span id="line-2313">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2314</span><span id="line-2314">        "Split region " + regionInfo.getRegionNameAsString() + " failed due to split switch off");</span>
-<span class="source-line-no">2315</span><span id="line-2315">    }</span>
-<span class="source-line-no">2316</span><span id="line-2316"></span>
-<span class="source-line-no">2317</span><span id="line-2317">    if (!getTableDescriptors().get(regionInfo.getTable()).isSplitEnabled()) {</span>
-<span class="source-line-no">2318</span><span id="line-2318">      LOG.warn("Split is disabled for the table! Skipping split of {}", regionInfo);</span>
-<span class="source-line-no">2319</span><span id="line-2319">      throw new DoNotRetryIOException("Split region " + regionInfo.getRegionNameAsString()</span>
-<span class="source-line-no">2320</span><span id="line-2320">        + " failed as region split is disabled for the table");</span>
-<span class="source-line-no">2321</span><span id="line-2321">    }</span>
-<span class="source-line-no">2322</span><span id="line-2322"></span>
-<span class="source-line-no">2323</span><span id="line-2323">    return MasterProcedureUtil</span>
-<span class="source-line-no">2324</span><span id="line-2324">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2325</span><span id="line-2325">        @Override</span>
-<span class="source-line-no">2326</span><span id="line-2326">        protected void run() throws IOException {</span>
-<span class="source-line-no">2327</span><span id="line-2327">          getMaster().getMasterCoprocessorHost().preSplitRegion(regionInfo.getTable(), splitRow);</span>
-<span class="source-line-no">2328</span><span id="line-2328">          LOG.info(getClientIdAuditPrefix() + " split " + regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">2329</span><span id="line-2329"></span>
-<span class="source-line-no">2330</span><span id="line-2330">          // Execute the operation asynchronously</span>
-<span class="source-line-no">2331</span><span id="line-2331">          submitProcedure(getAssignmentManager().createSplitProcedure(regionInfo, splitRow));</span>
-<span class="source-line-no">2332</span><span id="line-2332">        }</span>
+<span class="source-line-no">2191</span><span id="line-2191">          this.balancer.updateClusterMetrics(getClusterMetricsWithoutCoprocessor());</span>
+<span class="source-line-no">2192</span><span id="line-2192">          this.balancer.throttle(plan);</span>
+<span class="source-line-no">2193</span><span id="line-2193">        } catch (HBaseIOException hioe) {</span>
+<span class="source-line-no">2194</span><span id="line-2194">          // should ignore failed plans here, avoiding the whole balance plans be aborted</span>
+<span class="source-line-no">2195</span><span id="line-2195">          // later calls of balance() can fetch up the failed and skipped plans</span>
+<span class="source-line-no">2196</span><span id="line-2196">          LOG.warn("Failed balance plan {}, skipping...", plan, hioe);</span>
+<span class="source-line-no">2197</span><span id="line-2197">        } catch (Exception e) {</span>
+<span class="source-line-no">2198</span><span id="line-2198">          LOG.warn("Failed throttling assigning a new plan.", e);</span>
+<span class="source-line-no">2199</span><span id="line-2199">        }</span>
+<span class="source-line-no">2200</span><span id="line-2200">        // rpCount records balance plans processed, does not care if a plan succeeds</span>
+<span class="source-line-no">2201</span><span id="line-2201">        rpCount++;</span>
+<span class="source-line-no">2202</span><span id="line-2202">        successRegionPlans.add(plan);</span>
+<span class="source-line-no">2203</span><span id="line-2203"></span>
+<span class="source-line-no">2204</span><span id="line-2204">        if (this.maxBalancingTime &gt; 0) {</span>
+<span class="source-line-no">2205</span><span id="line-2205">          balanceThrottling(balanceStartTime + rpCount * balanceInterval, maxRegionsInTransition,</span>
+<span class="source-line-no">2206</span><span id="line-2206">            cutoffTime);</span>
+<span class="source-line-no">2207</span><span id="line-2207">        }</span>
+<span class="source-line-no">2208</span><span id="line-2208"></span>
+<span class="source-line-no">2209</span><span id="line-2209">        // if performing next balance exceeds cutoff time, exit the loop</span>
+<span class="source-line-no">2210</span><span id="line-2210">        if (</span>
+<span class="source-line-no">2211</span><span id="line-2211">          this.maxBalancingTime &gt; 0 &amp;&amp; rpCount &lt; plans.size()</span>
+<span class="source-line-no">2212</span><span id="line-2212">            &amp;&amp; EnvironmentEdgeManager.currentTime() &gt; cutoffTime</span>
+<span class="source-line-no">2213</span><span id="line-2213">        ) {</span>
+<span class="source-line-no">2214</span><span id="line-2214">          // TODO: After balance, there should not be a cutoff time (keeping it as</span>
+<span class="source-line-no">2215</span><span id="line-2215">          // a security net for now)</span>
+<span class="source-line-no">2216</span><span id="line-2216">          LOG.debug(</span>
+<span class="source-line-no">2217</span><span id="line-2217">            "No more balancing till next balance run; maxBalanceTime=" + this.maxBalancingTime);</span>
+<span class="source-line-no">2218</span><span id="line-2218">          break;</span>
+<span class="source-line-no">2219</span><span id="line-2219">        }</span>
+<span class="source-line-no">2220</span><span id="line-2220">      }</span>
+<span class="source-line-no">2221</span><span id="line-2221">    }</span>
+<span class="source-line-no">2222</span><span id="line-2222">    LOG.debug("Balancer is going into sleep until next period in {}ms", getConfiguration()</span>
+<span class="source-line-no">2223</span><span id="line-2223">      .getInt(HConstants.HBASE_BALANCER_PERIOD, HConstants.DEFAULT_HBASE_BALANCER_PERIOD));</span>
+<span class="source-line-no">2224</span><span id="line-2224">    return successRegionPlans;</span>
+<span class="source-line-no">2225</span><span id="line-2225">  }</span>
+<span class="source-line-no">2226</span><span id="line-2226"></span>
+<span class="source-line-no">2227</span><span id="line-2227">  @Override</span>
+<span class="source-line-no">2228</span><span id="line-2228">  public RegionNormalizerManager getRegionNormalizerManager() {</span>
+<span class="source-line-no">2229</span><span id="line-2229">    return regionNormalizerManager;</span>
+<span class="source-line-no">2230</span><span id="line-2230">  }</span>
+<span class="source-line-no">2231</span><span id="line-2231"></span>
+<span class="source-line-no">2232</span><span id="line-2232">  @Override</span>
+<span class="source-line-no">2233</span><span id="line-2233">  public boolean normalizeRegions(final NormalizeTableFilterParams ntfp,</span>
+<span class="source-line-no">2234</span><span id="line-2234">    final boolean isHighPriority) throws IOException {</span>
+<span class="source-line-no">2235</span><span id="line-2235">    if (regionNormalizerManager == null || !regionNormalizerManager.isNormalizerOn()) {</span>
+<span class="source-line-no">2236</span><span id="line-2236">      LOG.debug("Region normalization is disabled, don't run region normalizer.");</span>
+<span class="source-line-no">2237</span><span id="line-2237">      return false;</span>
+<span class="source-line-no">2238</span><span id="line-2238">    }</span>
+<span class="source-line-no">2239</span><span id="line-2239">    if (skipRegionManagementAction("region normalizer")) {</span>
+<span class="source-line-no">2240</span><span id="line-2240">      return false;</span>
+<span class="source-line-no">2241</span><span id="line-2241">    }</span>
+<span class="source-line-no">2242</span><span id="line-2242">    if (assignmentManager.hasRegionsInTransition()) {</span>
+<span class="source-line-no">2243</span><span id="line-2243">      return false;</span>
+<span class="source-line-no">2244</span><span id="line-2244">    }</span>
+<span class="source-line-no">2245</span><span id="line-2245"></span>
+<span class="source-line-no">2246</span><span id="line-2246">    final Set&lt;TableName&gt; matchingTables = getTableDescriptors(new LinkedList&lt;&gt;(),</span>
+<span class="source-line-no">2247</span><span id="line-2247">      ntfp.getNamespace(), ntfp.getRegex(), ntfp.getTableNames(), false).stream()</span>
+<span class="source-line-no">2248</span><span id="line-2248">        .map(TableDescriptor::getTableName).collect(Collectors.toSet());</span>
+<span class="source-line-no">2249</span><span id="line-2249">    final Set&lt;TableName&gt; allEnabledTables =</span>
+<span class="source-line-no">2250</span><span id="line-2250">      tableStateManager.getTablesInStates(TableState.State.ENABLED);</span>
+<span class="source-line-no">2251</span><span id="line-2251">    final List&lt;TableName&gt; targetTables =</span>
+<span class="source-line-no">2252</span><span id="line-2252">      new ArrayList&lt;&gt;(Sets.intersection(matchingTables, allEnabledTables));</span>
+<span class="source-line-no">2253</span><span id="line-2253">    Collections.shuffle(targetTables);</span>
+<span class="source-line-no">2254</span><span id="line-2254">    return regionNormalizerManager.normalizeRegions(targetTables, isHighPriority);</span>
+<span class="source-line-no">2255</span><span id="line-2255">  }</span>
+<span class="source-line-no">2256</span><span id="line-2256"></span>
+<span class="source-line-no">2257</span><span id="line-2257">  /** Returns Client info for use as prefix on an audit log string; who did an action */</span>
+<span class="source-line-no">2258</span><span id="line-2258">  @Override</span>
+<span class="source-line-no">2259</span><span id="line-2259">  public String getClientIdAuditPrefix() {</span>
+<span class="source-line-no">2260</span><span id="line-2260">    return "Client=" + RpcServer.getRequestUserName().orElse(null) + "/"</span>
+<span class="source-line-no">2261</span><span id="line-2261">      + RpcServer.getRemoteAddress().orElse(null);</span>
+<span class="source-line-no">2262</span><span id="line-2262">  }</span>
+<span class="source-line-no">2263</span><span id="line-2263"></span>
+<span class="source-line-no">2264</span><span id="line-2264">  /**</span>
+<span class="source-line-no">2265</span><span id="line-2265">   * Switch for the background CatalogJanitor thread. Used for testing. The thread will continue to</span>
+<span class="source-line-no">2266</span><span id="line-2266">   * run. It will just be a noop if disabled.</span>
+<span class="source-line-no">2267</span><span id="line-2267">   * @param b If false, the catalog janitor won't do anything.</span>
+<span class="source-line-no">2268</span><span id="line-2268">   */</span>
+<span class="source-line-no">2269</span><span id="line-2269">  public void setCatalogJanitorEnabled(final boolean b) {</span>
+<span class="source-line-no">2270</span><span id="line-2270">    this.catalogJanitorChore.setEnabled(b);</span>
+<span class="source-line-no">2271</span><span id="line-2271">  }</span>
+<span class="source-line-no">2272</span><span id="line-2272"></span>
+<span class="source-line-no">2273</span><span id="line-2273">  @Override</span>
+<span class="source-line-no">2274</span><span id="line-2274">  public long mergeRegions(final RegionInfo[] regionsToMerge, final boolean forcible, final long ng,</span>
+<span class="source-line-no">2275</span><span id="line-2275">    final long nonce) throws IOException {</span>
+<span class="source-line-no">2276</span><span id="line-2276">    checkInitialized();</span>
+<span class="source-line-no">2277</span><span id="line-2277"></span>
+<span class="source-line-no">2278</span><span id="line-2278">    final String regionNamesToLog = RegionInfo.getShortNameToLog(regionsToMerge);</span>
+<span class="source-line-no">2279</span><span id="line-2279"></span>
+<span class="source-line-no">2280</span><span id="line-2280">    if (!isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {</span>
+<span class="source-line-no">2281</span><span id="line-2281">      LOG.warn("Merge switch is off! skip merge of " + regionNamesToLog);</span>
+<span class="source-line-no">2282</span><span id="line-2282">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2283</span><span id="line-2283">        "Merge of " + regionNamesToLog + " failed because merge switch is off");</span>
+<span class="source-line-no">2284</span><span id="line-2284">    }</span>
+<span class="source-line-no">2285</span><span id="line-2285"></span>
+<span class="source-line-no">2286</span><span id="line-2286">    if (!getTableDescriptors().get(regionsToMerge[0].getTable()).isMergeEnabled()) {</span>
+<span class="source-line-no">2287</span><span id="line-2287">      LOG.warn("Merge is disabled for the table! Skipping merge of {}", regionNamesToLog);</span>
+<span class="source-line-no">2288</span><span id="line-2288">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2289</span><span id="line-2289">        "Merge of " + regionNamesToLog + " failed as region merge is disabled for the table");</span>
+<span class="source-line-no">2290</span><span id="line-2290">    }</span>
+<span class="source-line-no">2291</span><span id="line-2291"></span>
+<span class="source-line-no">2292</span><span id="line-2292">    return MasterProcedureUtil.submitProcedure(new NonceProcedureRunnable(this, ng, nonce) {</span>
+<span class="source-line-no">2293</span><span id="line-2293">      @Override</span>
+<span class="source-line-no">2294</span><span id="line-2294">      protected void run() throws IOException {</span>
+<span class="source-line-no">2295</span><span id="line-2295">        getMaster().getMasterCoprocessorHost().preMergeRegions(regionsToMerge);</span>
+<span class="source-line-no">2296</span><span id="line-2296">        String aid = getClientIdAuditPrefix();</span>
+<span class="source-line-no">2297</span><span id="line-2297">        LOG.info("{} merge regions {}", aid, regionNamesToLog);</span>
+<span class="source-line-no">2298</span><span id="line-2298">        submitProcedure(new MergeTableRegionsProcedure(procedureExecutor.getEnvironment(),</span>
+<span class="source-line-no">2299</span><span id="line-2299">          regionsToMerge, forcible));</span>
+<span class="source-line-no">2300</span><span id="line-2300">        getMaster().getMasterCoprocessorHost().postMergeRegions(regionsToMerge);</span>
+<span class="source-line-no">2301</span><span id="line-2301">      }</span>
+<span class="source-line-no">2302</span><span id="line-2302"></span>
+<span class="source-line-no">2303</span><span id="line-2303">      @Override</span>
+<span class="source-line-no">2304</span><span id="line-2304">      protected String getDescription() {</span>
+<span class="source-line-no">2305</span><span id="line-2305">        return "MergeTableProcedure";</span>
+<span class="source-line-no">2306</span><span id="line-2306">      }</span>
+<span class="source-line-no">2307</span><span id="line-2307">    });</span>
+<span class="source-line-no">2308</span><span id="line-2308">  }</span>
+<span class="source-line-no">2309</span><span id="line-2309"></span>
+<span class="source-line-no">2310</span><span id="line-2310">  @Override</span>
+<span class="source-line-no">2311</span><span id="line-2311">  public long splitRegion(final RegionInfo regionInfo, final byte[] splitRow, final long nonceGroup,</span>
+<span class="source-line-no">2312</span><span id="line-2312">    final long nonce) throws IOException {</span>
+<span class="source-line-no">2313</span><span id="line-2313">    checkInitialized();</span>
+<span class="source-line-no">2314</span><span id="line-2314"></span>
+<span class="source-line-no">2315</span><span id="line-2315">    if (!isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {</span>
+<span class="source-line-no">2316</span><span id="line-2316">      LOG.warn("Split switch is off! skip split of " + regionInfo);</span>
+<span class="source-line-no">2317</span><span id="line-2317">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2318</span><span id="line-2318">        "Split region " + regionInfo.getRegionNameAsString() + " failed due to split switch off");</span>
+<span class="source-line-no">2319</span><span id="line-2319">    }</span>
+<span class="source-line-no">2320</span><span id="line-2320"></span>
+<span class="source-line-no">2321</span><span id="line-2321">    if (!getTableDescriptors().get(regionInfo.getTable()).isSplitEnabled()) {</span>
+<span class="source-line-no">2322</span><span id="line-2322">      LOG.warn("Split is disabled for the table! Skipping split of {}", regionInfo);</span>
+<span class="source-line-no">2323</span><span id="line-2323">      throw new DoNotRetryIOException("Split region " + regionInfo.getRegionNameAsString()</span>
+<span class="source-line-no">2324</span><span id="line-2324">        + " failed as region split is disabled for the table");</span>
+<span class="source-line-no">2325</span><span id="line-2325">    }</span>
+<span class="source-line-no">2326</span><span id="line-2326"></span>
+<span class="source-line-no">2327</span><span id="line-2327">    return MasterProcedureUtil</span>
+<span class="source-line-no">2328</span><span id="line-2328">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2329</span><span id="line-2329">        @Override</span>
+<span class="source-line-no">2330</span><span id="line-2330">        protected void run() throws IOException {</span>
+<span class="source-line-no">2331</span><span id="line-2331">          getMaster().getMasterCoprocessorHost().preSplitRegion(regionInfo.getTable(), splitRow);</span>
+<span class="source-line-no">2332</span><span id="line-2332">          LOG.info(getClientIdAuditPrefix() + " split " + regionInfo.getRegionNameAsString());</span>
 <span class="source-line-no">2333</span><span id="line-2333"></span>
-<span class="source-line-no">2334</span><span id="line-2334">        @Override</span>
-<span class="source-line-no">2335</span><span id="line-2335">        protected String getDescription() {</span>
-<span class="source-line-no">2336</span><span id="line-2336">          return "SplitTableProcedure";</span>
-<span class="source-line-no">2337</span><span id="line-2337">        }</span>
-<span class="source-line-no">2338</span><span id="line-2338">      });</span>
-<span class="source-line-no">2339</span><span id="line-2339">  }</span>
-<span class="source-line-no">2340</span><span id="line-2340"></span>
-<span class="source-line-no">2341</span><span id="line-2341">  private void warmUpRegion(ServerName server, RegionInfo region) {</span>
-<span class="source-line-no">2342</span><span id="line-2342">    FutureUtils.addListener(asyncClusterConnection.getRegionServerAdmin(server)</span>
-<span class="source-line-no">2343</span><span id="line-2343">      .warmupRegion(RequestConverter.buildWarmupRegionRequest(region)), (r, e) -&gt; {</span>
-<span class="source-line-no">2344</span><span id="line-2344">        if (e != null) {</span>
-<span class="source-line-no">2345</span><span id="line-2345">          LOG.warn("Failed to warm up region {} on server {}", region, server, e);</span>
-<span class="source-line-no">2346</span><span id="line-2346">        }</span>
-<span class="source-line-no">2347</span><span id="line-2347">      });</span>
-<span class="source-line-no">2348</span><span id="line-2348">  }</span>
-<span class="source-line-no">2349</span><span id="line-2349"></span>
-<span class="source-line-no">2350</span><span id="line-2350">  // Public so can be accessed by tests. Blocks until move is done.</span>
-<span class="source-line-no">2351</span><span id="line-2351">  // Replace with an async implementation from which you can get</span>
-<span class="source-line-no">2352</span><span id="line-2352">  // a success/failure result.</span>
-<span class="source-line-no">2353</span><span id="line-2353">  @InterfaceAudience.Private</span>
-<span class="source-line-no">2354</span><span id="line-2354">  public void move(final byte[] encodedRegionName, byte[] destServerName) throws IOException {</span>
-<span class="source-line-no">2355</span><span id="line-2355">    RegionState regionState =</span>
-<span class="source-line-no">2356</span><span id="line-2356">      assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
-<span class="source-line-no">2357</span><span id="line-2357"></span>
-<span class="source-line-no">2358</span><span id="line-2358">    RegionInfo hri;</span>
-<span class="source-line-no">2359</span><span id="line-2359">    if (regionState != null) {</span>
-<span class="source-line-no">2360</span><span id="line-2360">      hri = regionState.getRegion();</span>
-<span class="source-line-no">2361</span><span id="line-2361">    } else {</span>
-<span class="source-line-no">2362</span><span id="line-2362">      throw new UnknownRegionException(Bytes.toStringBinary(encodedRegionName));</span>
-<span class="source-line-no">2363</span><span id="line-2363">    }</span>
-<span class="source-line-no">2364</span><span id="line-2364"></span>
-<span class="source-line-no">2365</span><span id="line-2365">    ServerName dest;</span>
-<span class="source-line-no">2366</span><span id="line-2366">    List&lt;ServerName&gt; exclude = hri.getTable().isSystemTable()</span>
-<span class="source-line-no">2367</span><span id="line-2367">      ? assignmentManager.getExcludedServersForSystemTable()</span>
-<span class="source-line-no">2368</span><span id="line-2368">      : new ArrayList&lt;&gt;(1);</span>
-<span class="source-line-no">2369</span><span id="line-2369">    if (</span>
-<span class="source-line-no">2370</span><span id="line-2370">      destServerName != null &amp;&amp; exclude.contains(ServerName.valueOf(Bytes.toString(destServerName)))</span>
-<span class="source-line-no">2371</span><span id="line-2371">    ) {</span>
-<span class="source-line-no">2372</span><span id="line-2372">      LOG.info(Bytes.toString(encodedRegionName) + " can not move to "</span>
-<span class="source-line-no">2373</span><span id="line-2373">        + Bytes.toString(destServerName) + " because the server is in exclude list");</span>
-<span class="source-line-no">2374</span><span id="line-2374">      destServerName = null;</span>
-<span class="source-line-no">2375</span><span id="line-2375">    }</span>
-<span class="source-line-no">2376</span><span id="line-2376">    if (destServerName == null || destServerName.length == 0) {</span>
-<span class="source-line-no">2377</span><span id="line-2377">      LOG.info("Passed destination servername is null/empty so " + "choosing a server at random");</span>
-<span class="source-line-no">2378</span><span id="line-2378">      exclude.add(regionState.getServerName());</span>
-<span class="source-line-no">2379</span><span id="line-2379">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList(exclude);</span>
-<span class="source-line-no">2380</span><span id="line-2380">      dest = balancer.randomAssignment(hri, destServers);</span>
-<span class="source-line-no">2381</span><span id="line-2381">      if (dest == null) {</span>
-<span class="source-line-no">2382</span><span id="line-2382">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
-<span class="source-line-no">2383</span><span id="line-2383">        return;</span>
-<span class="source-line-no">2384</span><span id="line-2384">      }</span>
-<span class="source-line-no">2385</span><span id="line-2385">    } else {</span>
-<span class="source-line-no">2386</span><span id="line-2386">      ServerName candidate = ServerName.valueOf(Bytes.toString(destServerName));</span>
-<span class="source-line-no">2387</span><span id="line-2387">      dest = balancer.randomAssignment(hri, Lists.newArrayList(candidate));</span>
-<span class="source-line-no">2388</span><span id="line-2388">      if (dest == null) {</span>
-<span class="source-line-no">2389</span><span id="line-2389">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
-<span class="source-line-no">2390</span><span id="line-2390">        return;</span>
-<span class="source-line-no">2391</span><span id="line-2391">      }</span>
-<span class="source-line-no">2392</span><span id="line-2392">      // TODO: deal with table on master for rs group.</span>
-<span class="source-line-no">2393</span><span id="line-2393">      if (dest.equals(serverName)) {</span>
-<span class="source-line-no">2394</span><span id="line-2394">        // To avoid unnecessary region moving later by balancer. Don't put user</span>
-<span class="source-line-no">2395</span><span id="line-2395">        // regions on master.</span>
-<span class="source-line-no">2396</span><span id="line-2396">        LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">2397</span><span id="line-2397">          + " to avoid unnecessary region moving later by load balancer,"</span>
-<span class="source-line-no">2398</span><span id="line-2398">          + " because it should not be on master");</span>
-<span class="source-line-no">2399</span><span id="line-2399">        return;</span>
-<span class="source-line-no">2400</span><span id="line-2400">      }</span>
-<span class="source-line-no">2401</span><span id="line-2401">    }</span>
-<span class="source-line-no">2402</span><span id="line-2402"></span>
-<span class="source-line-no">2403</span><span id="line-2403">    if (dest.equals(regionState.getServerName())) {</span>
-<span class="source-line-no">2404</span><span id="line-2404">      LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">2405</span><span id="line-2405">        + " because region already assigned to the same server " + dest + ".");</span>
-<span class="source-line-no">2406</span><span id="line-2406">      return;</span>
-<span class="source-line-no">2407</span><span id="line-2407">    }</span>
-<span class="source-line-no">2408</span><span id="line-2408"></span>
-<span class="source-line-no">2409</span><span id="line-2409">    // Now we can do the move</span>
-<span class="source-line-no">2410</span><span id="line-2410">    RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest);</span>
-<span class="source-line-no">2411</span><span id="line-2411">    assert rp.getDestination() != null : rp.toString() + " " + dest;</span>
+<span class="source-line-no">2334</span><span id="line-2334">          // Execute the operation asynchronously</span>
+<span class="source-line-no">2335</span><span id="line-2335">          submitProcedure(getAssignmentManager().createSplitProcedure(regionInfo, splitRow));</span>
+<span class="source-line-no">2336</span><span id="line-2336">        }</span>
+<span class="source-line-no">2337</span><span id="line-2337"></span>
+<span class="source-line-no">2338</span><span id="line-2338">        @Override</span>
+<span class="source-line-no">2339</span><span id="line-2339">        protected String getDescription() {</span>
+<span class="source-line-no">2340</span><span id="line-2340">          return "SplitTableProcedure";</span>
+<span class="source-line-no">2341</span><span id="line-2341">        }</span>
+<span class="source-line-no">2342</span><span id="line-2342">      });</span>
+<span class="source-line-no">2343</span><span id="line-2343">  }</span>
+<span class="source-line-no">2344</span><span id="line-2344"></span>
+<span class="source-line-no">2345</span><span id="line-2345">  private void warmUpRegion(ServerName server, RegionInfo region) {</span>
+<span class="source-line-no">2346</span><span id="line-2346">    FutureUtils.addListener(asyncClusterConnection.getRegionServerAdmin(server)</span>
+<span class="source-line-no">2347</span><span id="line-2347">      .warmupRegion(RequestConverter.buildWarmupRegionRequest(region)), (r, e) -&gt; {</span>
+<span class="source-line-no">2348</span><span id="line-2348">        if (e != null) {</span>
+<span class="source-line-no">2349</span><span id="line-2349">          LOG.warn("Failed to warm up region {} on server {}", region, server, e);</span>
+<span class="source-line-no">2350</span><span id="line-2350">        }</span>
+<span class="source-line-no">2351</span><span id="line-2351">      });</span>
+<span class="source-line-no">2352</span><span id="line-2352">  }</span>
+<span class="source-line-no">2353</span><span id="line-2353"></span>
+<span class="source-line-no">2354</span><span id="line-2354">  // Public so can be accessed by tests. Blocks until move is done.</span>
+<span class="source-line-no">2355</span><span id="line-2355">  // Replace with an async implementation from which you can get</span>
+<span class="source-line-no">2356</span><span id="line-2356">  // a success/failure result.</span>
+<span class="source-line-no">2357</span><span id="line-2357">  @InterfaceAudience.Private</span>
+<span class="source-line-no">2358</span><span id="line-2358">  public void move(final byte[] encodedRegionName, byte[] destServerName) throws IOException {</span>
+<span class="source-line-no">2359</span><span id="line-2359">    RegionState regionState =</span>
+<span class="source-line-no">2360</span><span id="line-2360">      assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
+<span class="source-line-no">2361</span><span id="line-2361"></span>
+<span class="source-line-no">2362</span><span id="line-2362">    RegionInfo hri;</span>
+<span class="source-line-no">2363</span><span id="line-2363">    if (regionState != null) {</span>
+<span class="source-line-no">2364</span><span id="line-2364">      hri = regionState.getRegion();</span>
+<span class="source-line-no">2365</span><span id="line-2365">    } else {</span>
+<span class="source-line-no">2366</span><span id="line-2366">      throw new UnknownRegionException(Bytes.toStringBinary(encodedRegionName));</span>
+<span class="source-line-no">2367</span><span id="line-2367">    }</span>
+<span class="source-line-no">2368</span><span id="line-2368"></span>
+<span class="source-line-no">2369</span><span id="line-2369">    ServerName dest;</span>
+<span class="source-line-no">2370</span><span id="line-2370">    List&lt;ServerName&gt; exclude = hri.getTable().isSystemTable()</span>
+<span class="source-line-no">2371</span><span id="line-2371">      ? assignmentManager.getExcludedServersForSystemTable()</span>
+<span class="source-line-no">2372</span><span id="line-2372">      : new ArrayList&lt;&gt;(1);</span>
+<span class="source-line-no">2373</span><span id="line-2373">    if (</span>
+<span class="source-line-no">2374</span><span id="line-2374">      destServerName != null &amp;&amp; exclude.contains(ServerName.valueOf(Bytes.toString(destServerName)))</span>
+<span class="source-line-no">2375</span><span id="line-2375">    ) {</span>
+<span class="source-line-no">2376</span><span id="line-2376">      LOG.info(Bytes.toString(encodedRegionName) + " can not move to "</span>
+<span class="source-line-no">2377</span><span id="line-2377">        + Bytes.toString(destServerName) + " because the server is in exclude list");</span>
+<span class="source-line-no">2378</span><span id="line-2378">      destServerName = null;</span>
+<span class="source-line-no">2379</span><span id="line-2379">    }</span>
+<span class="source-line-no">2380</span><span id="line-2380">    if (destServerName == null || destServerName.length == 0) {</span>
+<span class="source-line-no">2381</span><span id="line-2381">      LOG.info("Passed destination servername is null/empty so " + "choosing a server at random");</span>
+<span class="source-line-no">2382</span><span id="line-2382">      exclude.add(regionState.getServerName());</span>
+<span class="source-line-no">2383</span><span id="line-2383">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList(exclude);</span>
+<span class="source-line-no">2384</span><span id="line-2384">      dest = balancer.randomAssignment(hri, destServers);</span>
+<span class="source-line-no">2385</span><span id="line-2385">      if (dest == null) {</span>
+<span class="source-line-no">2386</span><span id="line-2386">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
+<span class="source-line-no">2387</span><span id="line-2387">        return;</span>
+<span class="source-line-no">2388</span><span id="line-2388">      }</span>
+<span class="source-line-no">2389</span><span id="line-2389">    } else {</span>
+<span class="source-line-no">2390</span><span id="line-2390">      ServerName candidate = ServerName.valueOf(Bytes.toString(destServerName));</span>
+<span class="source-line-no">2391</span><span id="line-2391">      dest = balancer.randomAssignment(hri, Lists.newArrayList(candidate));</span>
+<span class="source-line-no">2392</span><span id="line-2392">      if (dest == null) {</span>
+<span class="source-line-no">2393</span><span id="line-2393">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
+<span class="source-line-no">2394</span><span id="line-2394">        return;</span>
+<span class="source-line-no">2395</span><span id="line-2395">      }</span>
+<span class="source-line-no">2396</span><span id="line-2396">      // TODO: deal with table on master for rs group.</span>
+<span class="source-line-no">2397</span><span id="line-2397">      if (dest.equals(serverName)) {</span>
+<span class="source-line-no">2398</span><span id="line-2398">        // To avoid unnecessary region moving later by balancer. Don't put user</span>
+<span class="source-line-no">2399</span><span id="line-2399">        // regions on master.</span>
+<span class="source-line-no">2400</span><span id="line-2400">        LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">2401</span><span id="line-2401">          + " to avoid unnecessary region moving later by load balancer,"</span>
+<span class="source-line-no">2402</span><span id="line-2402">          + " because it should not be on master");</span>
+<span class="source-line-no">2403</span><span id="line-2403">        return;</span>
+<span class="source-line-no">2404</span><span id="line-2404">      }</span>
+<span class="source-line-no">2405</span><span id="line-2405">    }</span>
+<span class="source-line-no">2406</span><span id="line-2406"></span>
+<span class="source-line-no">2407</span><span id="line-2407">    if (dest.equals(regionState.getServerName())) {</span>
+<span class="source-line-no">2408</span><span id="line-2408">      LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">2409</span><span id="line-2409">        + " because region already assigned to the same server " + dest + ".");</span>
+<span class="source-line-no">2410</span><span id="line-2410">      return;</span>
+<span class="source-line-no">2411</span><span id="line-2411">    }</span>
 <span class="source-line-no">2412</span><span id="line-2412"></span>
-<span class="source-line-no">2413</span><span id="line-2413">    try {</span>
-<span class="source-line-no">2414</span><span id="line-2414">      checkInitialized();</span>
-<span class="source-line-no">2415</span><span id="line-2415">      if (this.cpHost != null) {</span>
-<span class="source-line-no">2416</span><span id="line-2416">        this.cpHost.preMove(hri, rp.getSource(), rp.getDestination());</span>
-<span class="source-line-no">2417</span><span id="line-2417">      }</span>
-<span class="source-line-no">2418</span><span id="line-2418"></span>
-<span class="source-line-no">2419</span><span id="line-2419">      TransitRegionStateProcedure proc =</span>
-<span class="source-line-no">2420</span><span id="line-2420">        this.assignmentManager.createMoveRegionProcedure(rp.getRegionInfo(), rp.getDestination());</span>
-<span class="source-line-no">2421</span><span id="line-2421">      if (conf.getBoolean(WARMUP_BEFORE_MOVE, DEFAULT_WARMUP_BEFORE_MOVE)) {</span>
-<span class="source-line-no">2422</span><span id="line-2422">        // Warmup the region on the destination before initiating the move.</span>
-<span class="source-line-no">2423</span><span id="line-2423">        // A region server could reject the close request because it either does not</span>
-<span class="source-line-no">2424</span><span id="line-2424">        // have the specified region or the region is being split.</span>
-<span class="source-line-no">2425</span><span id="line-2425">        LOG.info(getClientIdAuditPrefix() + " move " + rp + ", warming up region on "</span>
-<span class="source-line-no">2426</span><span id="line-2426">          + rp.getDestination());</span>
-<span class="source-line-no">2427</span><span id="line-2427">        warmUpRegion(rp.getDestination(), hri);</span>
-<span class="source-line-no">2428</span><span id="line-2428">      }</span>
-<span class="source-line-no">2429</span><span id="line-2429">      LOG.info(getClientIdAuditPrefix() + " move " + rp + ", running balancer");</span>
-<span class="source-line-no">2430</span><span id="line-2430">      Future&lt;byte[]&gt; future = ProcedureSyncWait.submitProcedure(this.procedureExecutor, proc);</span>
-<span class="source-line-no">2431</span><span id="line-2431">      try {</span>
-<span class="source-line-no">2432</span><span id="line-2432">        // Is this going to work? Will we throw exception on error?</span>
-<span class="source-line-no">2433</span><span id="line-2433">        // TODO: CompletableFuture rather than this stunted Future.</span>
-<span class="source-line-no">2434</span><span id="line-2434">        future.get();</span>
-<span class="source-line-no">2435</span><span id="line-2435">      } catch (InterruptedException | ExecutionException e) {</span>
-<span class="source-line-no">2436</span><span id="line-2436">        throw new HBaseIOException(e);</span>
-<span class="source-line-no">2437</span><span id="line-2437">      }</span>
-<span class="source-line-no">2438</span><span id="line-2438">      if (this.cpHost != null) {</span>
-<span class="source-line-no">2439</span><span id="line-2439">        this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());</span>
-<span class="source-line-no">2440</span><span id="line-2440">      }</span>
-<span class="source-line-no">2441</span><span id="line-2441">    } catch (IOException ioe) {</span>
-<span class="source-line-no">2442</span><span id="line-2442">      if (ioe instanceof HBaseIOException) {</span>
-<span class="source-line-no">2443</span><span id="line-2443">        throw (HBaseIOException) ioe;</span>
+<span class="source-line-no">2413</span><span id="line-2413">    // Now we can do the move</span>
+<span class="source-line-no">2414</span><span id="line-2414">    RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest);</span>
+<span class="source-line-no">2415</span><span id="line-2415">    assert rp.getDestination() != null : rp.toString() + " " + dest;</span>
+<span class="source-line-no">2416</span><span id="line-2416"></span>
+<span class="source-line-no">2417</span><span id="line-2417">    try {</span>
+<span class="source-line-no">2418</span><span id="line-2418">      checkInitialized();</span>
+<span class="source-line-no">2419</span><span id="line-2419">      if (this.cpHost != null) {</span>
+<span class="source-line-no">2420</span><span id="line-2420">        this.cpHost.preMove(hri, rp.getSource(), rp.getDestination());</span>
+<span class="source-line-no">2421</span><span id="line-2421">      }</span>
+<span class="source-line-no">2422</span><span id="line-2422"></span>
+<span class="source-line-no">2423</span><span id="line-2423">      TransitRegionStateProcedure proc =</span>
+<span class="source-line-no">2424</span><span id="line-2424">        this.assignmentManager.createMoveRegionProcedure(rp.getRegionInfo(), rp.getDestination());</span>
+<span class="source-line-no">2425</span><span id="line-2425">      if (conf.getBoolean(WARMUP_BEFORE_MOVE, DEFAULT_WARMUP_BEFORE_MOVE)) {</span>
+<span class="source-line-no">2426</span><span id="line-2426">        // Warmup the region on the destination before initiating the move.</span>
+<span class="source-line-no">2427</span><span id="line-2427">        // A region server could reject the close request because it either does not</span>
+<span class="source-line-no">2428</span><span id="line-2428">        // have the specified region or the region is being split.</span>
+<span class="source-line-no">2429</span><span id="line-2429">        LOG.info(getClientIdAuditPrefix() + " move " + rp + ", warming up region on "</span>
+<span class="source-line-no">2430</span><span id="line-2430">          + rp.getDestination());</span>
+<span class="source-line-no">2431</span><span id="line-2431">        warmUpRegion(rp.getDestination(), hri);</span>
+<span class="source-line-no">2432</span><span id="line-2432">      }</span>
+<span class="source-line-no">2433</span><span id="line-2433">      LOG.info(getClientIdAuditPrefix() + " move " + rp + ", running balancer");</span>
+<span class="source-line-no">2434</span><span id="line-2434">      Future&lt;byte[]&gt; future = ProcedureSyncWait.submitProcedure(this.procedureExecutor, proc);</span>
+<span class="source-line-no">2435</span><span id="line-2435">      try {</span>
+<span class="source-line-no">2436</span><span id="line-2436">        // Is this going to work? Will we throw exception on error?</span>
+<span class="source-line-no">2437</span><span id="line-2437">        // TODO: CompletableFuture rather than this stunted Future.</span>
+<span class="source-line-no">2438</span><span id="line-2438">        future.get();</span>
+<span class="source-line-no">2439</span><span id="line-2439">      } catch (InterruptedException | ExecutionException e) {</span>
+<span class="source-line-no">2440</span><span id="line-2440">        throw new HBaseIOException(e);</span>
+<span class="source-line-no">2441</span><span id="line-2441">      }</span>
+<span class="source-line-no">2442</span><span id="line-2442">      if (this.cpHost != null) {</span>
+<span class="source-line-no">2443</span><span id="line-2443">        this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());</span>
 <span class="source-line-no">2444</span><span id="line-2444">      }</span>
-<span class="source-line-no">2445</span><span id="line-2445">      throw new HBaseIOException(ioe);</span>
-<span class="source-line-no">2446</span><span id="line-2446">    }</span>
-<span class="source-line-no">2447</span><span id="line-2447">  }</span>
-<span class="source-line-no">2448</span><span id="line-2448"></span>
-<span class="source-line-no">2449</span><span id="line-2449">  @Override</span>
-<span class="source-line-no">2450</span><span id="line-2450">  public long createTable(final TableDescriptor tableDescriptor, final byte[][] splitKeys,</span>
-<span class="source-line-no">2451</span><span id="line-2451">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2452</span><span id="line-2452">    checkInitialized();</span>
-<span class="source-line-no">2453</span><span id="line-2453">    TableDescriptor desc = getMasterCoprocessorHost().preCreateTableRegionsInfos(tableDescriptor);</span>
-<span class="source-line-no">2454</span><span id="line-2454">    if (desc == null) {</span>
-<span class="source-line-no">2455</span><span id="line-2455">      throw new IOException("Creation for " + tableDescriptor + " is canceled by CP");</span>
-<span class="source-line-no">2456</span><span id="line-2456">    }</span>
-<span class="source-line-no">2457</span><span id="line-2457">    String namespace = desc.getTableName().getNamespaceAsString();</span>
-<span class="source-line-no">2458</span><span id="line-2458">    this.clusterSchemaService.getNamespace(namespace);</span>
-<span class="source-line-no">2459</span><span id="line-2459"></span>
-<span class="source-line-no">2460</span><span id="line-2460">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(desc, splitKeys);</span>
-<span class="source-line-no">2461</span><span id="line-2461">    TableDescriptorChecker.sanityCheck(conf, desc);</span>
-<span class="source-line-no">2462</span><span id="line-2462"></span>
-<span class="source-line-no">2463</span><span id="line-2463">    return MasterProcedureUtil</span>
-<span class="source-line-no">2464</span><span id="line-2464">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2465</span><span id="line-2465">        @Override</span>
-<span class="source-line-no">2466</span><span id="line-2466">        protected void run() throws IOException {</span>
-<span class="source-line-no">2467</span><span id="line-2467">          getMaster().getMasterCoprocessorHost().preCreateTable(desc, newRegions);</span>
-<span class="source-line-no">2468</span><span id="line-2468"></span>
-<span class="source-line-no">2469</span><span id="line-2469">          LOG.info(getClientIdAuditPrefix() + " create " + desc);</span>
-<span class="source-line-no">2470</span><span id="line-2470"></span>
-<span class="source-line-no">2471</span><span id="line-2471">          // TODO: We can handle/merge duplicate requests, and differentiate the case of</span>
-<span class="source-line-no">2472</span><span id="line-2472">          // TableExistsException by saying if the schema is the same or not.</span>
-<span class="source-line-no">2473</span><span id="line-2473">          //</span>
-<span class="source-line-no">2474</span><span id="line-2474">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2475</span><span id="line-2475">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2476</span><span id="line-2476">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2477</span><span id="line-2477">          submitProcedure(</span>
-<span class="source-line-no">2478</span><span id="line-2478">            new CreateTableProcedure(procedureExecutor.getEnvironment(), desc, newRegions, latch));</span>
-<span class="source-line-no">2479</span><span id="line-2479">          latch.await();</span>
-<span class="source-line-no">2480</span><span id="line-2480"></span>
-<span class="source-line-no">2481</span><span id="line-2481">          getMaster().getMasterCoprocessorHost().postCreateTable(desc, newRegions);</span>
-<span class="source-line-no">2482</span><span id="line-2482">        }</span>
-<span class="source-line-no">2483</span><span id="line-2483"></span>
-<span class="source-line-no">2484</span><span id="line-2484">        @Override</span>
-<span class="source-line-no">2485</span><span id="line-2485">        protected String getDescription() {</span>
-<span class="source-line-no">2486</span><span id="line-2486">          return "CreateTableProcedure";</span>
-<span class="source-line-no">2487</span><span id="line-2487">        }</span>
-<span class="source-line-no">2488</span><span id="line-2488">      });</span>
-<span class="source-line-no">2489</span><span id="line-2489">  }</span>
-<span class="source-line-no">2490</span><span id="line-2490"></span>
-<span class="source-line-no">2491</span><span id="line-2491">  @Override</span>
-<span class="source-line-no">2492</span><span id="line-2492">  public long createSystemTable(final TableDescriptor tableDescriptor) throws IOException {</span>
-<span class="source-line-no">2493</span><span id="line-2493">    if (isStopped()) {</span>
-<span class="source-line-no">2494</span><span id="line-2494">      throw new MasterNotRunningException();</span>
-<span class="source-line-no">2495</span><span id="line-2495">    }</span>
-<span class="source-line-no">2496</span><span id="line-2496"></span>
-<span class="source-line-no">2497</span><span id="line-2497">    TableName tableName = tableDescriptor.getTableName();</span>
-<span class="source-line-no">2498</span><span id="line-2498">    if (!(tableName.isSystemTable())) {</span>
-<span class="source-line-no">2499</span><span id="line-2499">      throw new IllegalArgumentException(</span>
-<span class="source-line-no">2500</span><span id="line-2500">        "Only system table creation can use this createSystemTable API");</span>
-<span class="source-line-no">2501</span><span id="line-2501">    }</span>
-<span class="source-line-no">2502</span><span id="line-2502"></span>
-<span class="source-line-no">2503</span><span id="line-2503">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(tableDescriptor, null);</span>
-<span class="source-line-no">2504</span><span id="line-2504"></span>
-<span class="source-line-no">2505</span><span id="line-2505">    LOG.info(getClientIdAuditPrefix() + " create " + tableDescriptor);</span>
+<span class="source-line-no">2445</span><span id="line-2445">    } catch (IOException ioe) {</span>
+<span class="source-line-no">2446</span><span id="line-2446">      if (ioe instanceof HBaseIOException) {</span>
+<span class="source-line-no">2447</span><span id="line-2447">        throw (HBaseIOException) ioe;</span>
+<span class="source-line-no">2448</span><span id="line-2448">      }</span>
+<span class="source-line-no">2449</span><span id="line-2449">      throw new HBaseIOException(ioe);</span>
+<span class="source-line-no">2450</span><span id="line-2450">    }</span>
+<span class="source-line-no">2451</span><span id="line-2451">  }</span>
+<span class="source-line-no">2452</span><span id="line-2452"></span>
+<span class="source-line-no">2453</span><span id="line-2453">  @Override</span>
+<span class="source-line-no">2454</span><span id="line-2454">  public long createTable(final TableDescriptor tableDescriptor, final byte[][] splitKeys,</span>
+<span class="source-line-no">2455</span><span id="line-2455">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2456</span><span id="line-2456">    checkInitialized();</span>
+<span class="source-line-no">2457</span><span id="line-2457">    TableDescriptor desc = getMasterCoprocessorHost().preCreateTableRegionsInfos(tableDescriptor);</span>
+<span class="source-line-no">2458</span><span id="line-2458">    if (desc == null) {</span>
+<span class="source-line-no">2459</span><span id="line-2459">      throw new IOException("Creation for " + tableDescriptor + " is canceled by CP");</span>
+<span class="source-line-no">2460</span><span id="line-2460">    }</span>
+<span class="source-line-no">2461</span><span id="line-2461">    String namespace = desc.getTableName().getNamespaceAsString();</span>
+<span class="source-line-no">2462</span><span id="line-2462">    this.clusterSchemaService.getNamespace(namespace);</span>
+<span class="source-line-no">2463</span><span id="line-2463"></span>
+<span class="source-line-no">2464</span><span id="line-2464">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(desc, splitKeys);</span>
+<span class="source-line-no">2465</span><span id="line-2465">    TableDescriptorChecker.sanityCheck(conf, desc);</span>
+<span class="source-line-no">2466</span><span id="line-2466"></span>
+<span class="source-line-no">2467</span><span id="line-2467">    return MasterProcedureUtil</span>
+<span class="source-line-no">2468</span><span id="line-2468">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2469</span><span id="line-2469">        @Override</span>
+<span class="source-line-no">2470</span><span id="line-2470">        protected void run() throws IOException {</span>
+<span class="source-line-no">2471</span><span id="line-2471">          getMaster().getMasterCoprocessorHost().preCreateTable(desc, newRegions);</span>
+<span class="source-line-no">2472</span><span id="line-2472"></span>
+<span class="source-line-no">2473</span><span id="line-2473">          LOG.info(getClientIdAuditPrefix() + " create " + desc);</span>
+<span class="source-line-no">2474</span><span id="line-2474"></span>
+<span class="source-line-no">2475</span><span id="line-2475">          // TODO: We can handle/merge duplicate requests, and differentiate the case of</span>
+<span class="source-line-no">2476</span><span id="line-2476">          // TableExistsException by saying if the schema is the same or not.</span>
+<span class="source-line-no">2477</span><span id="line-2477">          //</span>
+<span class="source-line-no">2478</span><span id="line-2478">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2479</span><span id="line-2479">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2480</span><span id="line-2480">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2481</span><span id="line-2481">          submitProcedure(</span>
+<span class="source-line-no">2482</span><span id="line-2482">            new CreateTableProcedure(procedureExecutor.getEnvironment(), desc, newRegions, latch));</span>
+<span class="source-line-no">2483</span><span id="line-2483">          latch.await();</span>
+<span class="source-line-no">2484</span><span id="line-2484"></span>
+<span class="source-line-no">2485</span><span id="line-2485">          getMaster().getMasterCoprocessorHost().postCreateTable(desc, newRegions);</span>
+<span class="source-line-no">2486</span><span id="line-2486">        }</span>
+<span class="source-line-no">2487</span><span id="line-2487"></span>
+<span class="source-line-no">2488</span><span id="line-2488">        @Override</span>
+<span class="source-line-no">2489</span><span id="line-2489">        protected String getDescription() {</span>
+<span class="source-line-no">2490</span><span id="line-2490">          return "CreateTableProcedure";</span>
+<span class="source-line-no">2491</span><span id="line-2491">        }</span>
+<span class="source-line-no">2492</span><span id="line-2492">      });</span>
+<span class="source-line-no">2493</span><span id="line-2493">  }</span>
+<span class="source-line-no">2494</span><span id="line-2494"></span>
+<span class="source-line-no">2495</span><span id="line-2495">  @Override</span>
+<span class="source-line-no">2496</span><span id="line-2496">  public long createSystemTable(final TableDescriptor tableDescriptor) throws IOException {</span>
+<span class="source-line-no">2497</span><span id="line-2497">    if (isStopped()) {</span>
+<span class="source-line-no">2498</span><span id="line-2498">      throw new MasterNotRunningException();</span>
+<span class="source-line-no">2499</span><span id="line-2499">    }</span>
+<span class="source-line-no">2500</span><span id="line-2500"></span>
+<span class="source-line-no">2501</span><span id="line-2501">    TableName tableName = tableDescriptor.getTableName();</span>
+<span class="source-line-no">2502</span><span id="line-2502">    if (!(tableName.isSystemTable())) {</span>
+<span class="source-line-no">2503</span><span id="line-2503">      throw new IllegalArgumentException(</span>
+<span class="source-line-no">2504</span><span id="line-2504">        "Only system table creation can use this createSystemTable API");</span>
+<span class="source-line-no">2505</span><span id="line-2505">    }</span>
 <span class="source-line-no">2506</span><span id="line-2506"></span>
-<span class="source-line-no">2507</span><span id="line-2507">    // This special create table is called locally to master. Therefore, no RPC means no need</span>
-<span class="source-line-no">2508</span><span id="line-2508">    // to use nonce to detect duplicated RPC call.</span>
-<span class="source-line-no">2509</span><span id="line-2509">    long procId = this.procedureExecutor.submitProcedure(</span>
-<span class="source-line-no">2510</span><span id="line-2510">      new CreateTableProcedure(procedureExecutor.getEnvironment(), tableDescriptor, newRegions));</span>
-<span class="source-line-no">2511</span><span id="line-2511"></span>
-<span class="source-line-no">2512</span><span id="line-2512">    return procId;</span>
-<span class="source-line-no">2513</span><span id="line-2513">  }</span>
-<span class="source-line-no">2514</span><span id="line-2514"></span>
-<span class="source-line-no">2515</span><span id="line-2515">  private void startActiveMasterManager(int infoPort) throws KeeperException {</span>
-<span class="source-line-no">2516</span><span id="line-2516">    String backupZNode = ZNodePaths.joinZNode(zooKeeper.getZNodePaths().backupMasterAddressesZNode,</span>
-<span class="source-line-no">2517</span><span id="line-2517">      serverName.toString());</span>
-<span class="source-line-no">2518</span><span id="line-2518">    /*</span>
-<span class="source-line-no">2519</span><span id="line-2519">     * Add a ZNode for ourselves in the backup master directory since we may not become the active</span>
-<span class="source-line-no">2520</span><span id="line-2520">     * master. If so, we want the actual active master to know we are backup masters, so that it</span>
-<span class="source-line-no">2521</span><span id="line-2521">     * won't assign regions to us if so configured. If we become the active master later,</span>
-<span class="source-line-no">2522</span><span id="line-2522">     * ActiveMasterManager will delete this node explicitly. If we crash before then, ZooKeeper will</span>
-<span class="source-line-no">2523</span><span id="line-2523">     * delete this node for us since it is ephemeral.</span>
-<span class="source-line-no">2524</span><span id="line-2524">     */</span>
-<span class="source-line-no">2525</span><span id="line-2525">    LOG.info("Adding backup master ZNode " + backupZNode);</span>
-<span class="source-line-no">2526</span><span id="line-2526">    if (!MasterAddressTracker.setMasterAddress(zooKeeper, backupZNode, serverName, infoPort)) {</span>
-<span class="source-line-no">2527</span><span id="line-2527">      LOG.warn("Failed create of " + backupZNode + " by " + serverName);</span>
-<span class="source-line-no">2528</span><span id="line-2528">    }</span>
-<span class="source-line-no">2529</span><span id="line-2529">    this.activeMasterManager.setInfoPort(infoPort);</span>
-<span class="source-line-no">2530</span><span id="line-2530">    int timeout = conf.getInt(HConstants.ZK_SESSION_TIMEOUT, HConstants.DEFAULT_ZK_SESSION_TIMEOUT);</span>
-<span class="source-line-no">2531</span><span id="line-2531">    // If we're a backup master, stall until a primary to write this address</span>
-<span class="source-line-no">2532</span><span id="line-2532">    if (conf.getBoolean(HConstants.MASTER_TYPE_BACKUP, HConstants.DEFAULT_MASTER_TYPE_BACKUP)) {</span>
-<span class="source-line-no">2533</span><span id="line-2533">      LOG.debug("HMaster started in backup mode. Stalling until master znode is written.");</span>
-<span class="source-line-no">2534</span><span id="line-2534">      // This will only be a minute or so while the cluster starts up,</span>
-<span class="source-line-no">2535</span><span id="line-2535">      // so don't worry about setting watches on the parent znode</span>
-<span class="source-line-no">2536</span><span id="line-2536">      while (!activeMasterManager.hasActiveMaster()) {</span>
-<span class="source-line-no">2537</span><span id="line-2537">        LOG.debug("Waiting for master address and cluster state znode to be written.");</span>
-<span class="source-line-no">2538</span><span id="line-2538">        Threads.sleep(timeout);</span>
-<span class="source-line-no">2539</span><span id="line-2539">      }</span>
-<span class="source-line-no">2540</span><span id="line-2540">    }</span>
-<span class="source-line-no">2541</span><span id="line-2541"></span>
-<span class="source-line-no">2542</span><span id="line-2542">    // Here for the master startup process, we use TaskGroup to monitor the whole progress.</span>
-<span class="source-line-no">2543</span><span id="line-2543">    // The UI is similar to how Hadoop designed the startup page for the NameNode.</span>
-<span class="source-line-no">2544</span><span id="line-2544">    // See HBASE-21521 for more details.</span>
-<span class="source-line-no">2545</span><span id="line-2545">    // We do not cleanup the startupTaskGroup, let the startup progress information</span>
-<span class="source-line-no">2546</span><span id="line-2546">    // be permanent in the MEM.</span>
-<span class="source-line-no">2547</span><span id="line-2547">    startupTaskGroup = TaskMonitor.createTaskGroup(true, "Master startup");</span>
-<span class="source-line-no">2548</span><span id="line-2548">    try {</span>
-<span class="source-line-no">2549</span><span id="line-2549">      if (activeMasterManager.blockUntilBecomingActiveMaster(timeout, startupTaskGroup)) {</span>
-<span class="source-line-no">2550</span><span id="line-2550">        finishActiveMasterInitialization();</span>
-<span class="source-line-no">2551</span><span id="line-2551">      }</span>
-<span class="source-line-no">2552</span><span id="line-2552">    } catch (Throwable t) {</span>
-<span class="source-line-no">2553</span><span id="line-2553">      startupTaskGroup.abort("Failed to become active master due to:" + t.getMessage());</span>
-<span class="source-line-no">2554</span><span id="line-2554">      LOG.error(HBaseMarkers.FATAL, "Failed to become active master", t);</span>
-<span class="source-line-no">2555</span><span id="line-2555">      // HBASE-5680: Likely hadoop23 vs hadoop 20.x/1.x incompatibility</span>
-<span class="source-line-no">2556</span><span id="line-2556">      if (</span>
-<span class="source-line-no">2557</span><span id="line-2557">        t instanceof NoClassDefFoundError</span>
-<span class="source-line-no">2558</span><span id="line-2558">          &amp;&amp; t.getMessage().contains("org/apache/hadoop/hdfs/protocol/HdfsConstants$SafeModeAction")</span>
-<span class="source-line-no">2559</span><span id="line-2559">      ) {</span>
-<span class="source-line-no">2560</span><span id="line-2560">        // improved error message for this special case</span>
-<span class="source-line-no">2561</span><span id="line-2561">        abort("HBase is having a problem with its Hadoop jars.  You may need to recompile "</span>
-<span class="source-line-no">2562</span><span id="line-2562">          + "HBase against Hadoop version " + org.apache.hadoop.util.VersionInfo.getVersion()</span>
-<span class="source-line-no">2563</span><span id="line-2563">          + " or change your hadoop jars to start properly", t);</span>
-<span class="source-line-no">2564</span><span id="line-2564">      } else {</span>
-<span class="source-line-no">2565</span><span id="line-2565">        abort("Unhandled exception. Starting shutdown.", t);</span>
-<span class="source-line-no">2566</span><span id="line-2566">      }</span>
-<span class="source-line-no">2567</span><span id="line-2567">    }</span>
-<span class="source-line-no">2568</span><span id="line-2568">  }</span>
-<span class="source-line-no">2569</span><span id="line-2569"></span>
-<span class="source-line-no">2570</span><span id="line-2570">  private static boolean isCatalogTable(final TableName tableName) {</span>
-<span class="source-line-no">2571</span><span id="line-2571">    return tableName.equals(TableName.META_TABLE_NAME);</span>
+<span class="source-line-no">2507</span><span id="line-2507">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(tableDescriptor, null);</span>
+<span class="source-line-no">2508</span><span id="line-2508"></span>
+<span class="source-line-no">2509</span><span id="line-2509">    LOG.info(getClientIdAuditPrefix() + " create " + tableDescriptor);</span>
+<span class="source-line-no">2510</span><span id="line-2510"></span>
+<span class="source-line-no">2511</span><span id="line-2511">    // This special create table is called locally to master. Therefore, no RPC means no need</span>
+<span class="source-line-no">2512</span><span id="line-2512">    // to use nonce to detect duplicated RPC call.</span>
+<span class="source-line-no">2513</span><span id="line-2513">    long procId = this.procedureExecutor.submitProcedure(</span>
+<span class="source-line-no">2514</span><span id="line-2514">      new CreateTableProcedure(procedureExecutor.getEnvironment(), tableDescriptor, newRegions));</span>
+<span class="source-line-no">2515</span><span id="line-2515"></span>
+<span class="source-line-no">2516</span><span id="line-2516">    return procId;</span>
+<span class="source-line-no">2517</span><span id="line-2517">  }</span>
+<span class="source-line-no">2518</span><span id="line-2518"></span>
+<span class="source-line-no">2519</span><span id="line-2519">  private void startActiveMasterManager(int infoPort) throws KeeperException {</span>
+<span class="source-line-no">2520</span><span id="line-2520">    String backupZNode = ZNodePaths.joinZNode(zooKeeper.getZNodePaths().backupMasterAddressesZNode,</span>
+<span class="source-line-no">2521</span><span id="line-2521">      serverName.toString());</span>
+<span class="source-line-no">2522</span><span id="line-2522">    /*</span>
+<span class="source-line-no">2523</span><span id="line-2523">     * Add a ZNode for ourselves in the backup master directory since we may not become the active</span>
+<span class="source-line-no">2524</span><span id="line-2524">     * master. If so, we want the actual active master to know we are backup masters, so that it</span>
+<span class="source-line-no">2525</span><span id="line-2525">     * won't assign regions to us if so configured. If we become the active master later,</span>
+<span class="source-line-no">2526</span><span id="line-2526">     * ActiveMasterManager will delete this node explicitly. If we crash before then, ZooKeeper will</span>
+<span class="source-line-no">2527</span><span id="line-2527">     * delete this node for us since it is ephemeral.</span>
+<span class="source-line-no">2528</span><span id="line-2528">     */</span>
+<span class="source-line-no">2529</span><span id="line-2529">    LOG.info("Adding backup master ZNode " + backupZNode);</span>
+<span class="source-line-no">2530</span><span id="line-2530">    if (!MasterAddressTracker.setMasterAddress(zooKeeper, backupZNode, serverName, infoPort)) {</span>
+<span class="source-line-no">2531</span><span id="line-2531">      LOG.warn("Failed create of " + backupZNode + " by " + serverName);</span>
+<span class="source-line-no">2532</span><span id="line-2532">    }</span>
+<span class="source-line-no">2533</span><span id="line-2533">    this.activeMasterManager.setInfoPort(infoPort);</span>
+<span class="source-line-no">2534</span><span id="line-2534">    int timeout = conf.getInt(HConstants.ZK_SESSION_TIMEOUT, HConstants.DEFAULT_ZK_SESSION_TIMEOUT);</span>
+<span class="source-line-no">2535</span><span id="line-2535">    // If we're a backup master, stall until a primary to write this address</span>
+<span class="source-line-no">2536</span><span id="line-2536">    if (conf.getBoolean(HConstants.MASTER_TYPE_BACKUP, HConstants.DEFAULT_MASTER_TYPE_BACKUP)) {</span>
+<span class="source-line-no">2537</span><span id="line-2537">      LOG.debug("HMaster started in backup mode. Stalling until master znode is written.");</span>
+<span class="source-line-no">2538</span><span id="line-2538">      // This will only be a minute or so while the cluster starts up,</span>
+<span class="source-line-no">2539</span><span id="line-2539">      // so don't worry about setting watches on the parent znode</span>
+<span class="source-line-no">2540</span><span id="line-2540">      while (!activeMasterManager.hasActiveMaster()) {</span>
+<span class="source-line-no">2541</span><span id="line-2541">        LOG.debug("Waiting for master address and cluster state znode to be written.");</span>
+<span class="source-line-no">2542</span><span id="line-2542">        Threads.sleep(timeout);</span>
+<span class="source-line-no">2543</span><span id="line-2543">      }</span>
+<span class="source-line-no">2544</span><span id="line-2544">    }</span>
+<span class="source-line-no">2545</span><span id="line-2545"></span>
+<span class="source-line-no">2546</span><span id="line-2546">    // Here for the master startup process, we use TaskGroup to monitor the whole progress.</span>
+<span class="source-line-no">2547</span><span id="line-2547">    // The UI is similar to how Hadoop designed the startup page for the NameNode.</span>
+<span class="source-line-no">2548</span><span id="line-2548">    // See HBASE-21521 for more details.</span>
+<span class="source-line-no">2549</span><span id="line-2549">    // We do not cleanup the startupTaskGroup, let the startup progress information</span>
+<span class="source-line-no">2550</span><span id="line-2550">    // be permanent in the MEM.</span>
+<span class="source-line-no">2551</span><span id="line-2551">    startupTaskGroup = TaskMonitor.createTaskGroup(true, "Master startup");</span>
+<span class="source-line-no">2552</span><span id="line-2552">    try {</span>
+<span class="source-line-no">2553</span><span id="line-2553">      if (activeMasterManager.blockUntilBecomingActiveMaster(timeout, startupTaskGroup)) {</span>
+<span class="source-line-no">2554</span><span id="line-2554">        finishActiveMasterInitialization();</span>
+<span class="source-line-no">2555</span><span id="line-2555">      }</span>
+<span class="source-line-no">2556</span><span id="line-2556">    } catch (Throwable t) {</span>
+<span class="source-line-no">2557</span><span id="line-2557">      startupTaskGroup.abort("Failed to become active master due to:" + t.getMessage());</span>
+<span class="source-line-no">2558</span><span id="line-2558">      LOG.error(HBaseMarkers.FATAL, "Failed to become active master", t);</span>
+<span class="source-line-no">2559</span><span id="line-2559">      // HBASE-5680: Likely hadoop23 vs hadoop 20.x/1.x incompatibility</span>
+<span class="source-line-no">2560</span><span id="line-2560">      if (</span>
+<span class="source-line-no">2561</span><span id="line-2561">        t instanceof NoClassDefFoundError</span>
+<span class="source-line-no">2562</span><span id="line-2562">          &amp;&amp; t.getMessage().contains("org/apache/hadoop/hdfs/protocol/HdfsConstants$SafeModeAction")</span>
+<span class="source-line-no">2563</span><span id="line-2563">      ) {</span>
+<span class="source-line-no">2564</span><span id="line-2564">        // improved error message for this special case</span>
+<span class="source-line-no">2565</span><span id="line-2565">        abort("HBase is having a problem with its Hadoop jars.  You may need to recompile "</span>
+<span class="source-line-no">2566</span><span id="line-2566">          + "HBase against Hadoop version " + org.apache.hadoop.util.VersionInfo.getVersion()</span>
+<span class="source-line-no">2567</span><span id="line-2567">          + " or change your hadoop jars to start properly", t);</span>
+<span class="source-line-no">2568</span><span id="line-2568">      } else {</span>
+<span class="source-line-no">2569</span><span id="line-2569">        abort("Unhandled exception. Starting shutdown.", t);</span>
+<span class="source-line-no">2570</span><span id="line-2570">      }</span>
+<span class="source-line-no">2571</span><span id="line-2571">    }</span>
 <span class="source-line-no">2572</span><span id="line-2572">  }</span>
 <span class="source-line-no">2573</span><span id="line-2573"></span>
-<span class="source-line-no">2574</span><span id="line-2574">  @Override</span>
-<span class="source-line-no">2575</span><span id="line-2575">  public long deleteTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2576</span><span id="line-2576">    throws IOException {</span>
-<span class="source-line-no">2577</span><span id="line-2577">    checkInitialized();</span>
-<span class="source-line-no">2578</span><span id="line-2578"></span>
-<span class="source-line-no">2579</span><span id="line-2579">    return MasterProcedureUtil</span>
-<span class="source-line-no">2580</span><span id="line-2580">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2581</span><span id="line-2581">        @Override</span>
-<span class="source-line-no">2582</span><span id="line-2582">        protected void run() throws IOException {</span>
-<span class="source-line-no">2583</span><span id="line-2583">          getMaster().getMasterCoprocessorHost().preDeleteTable(tableName);</span>
-<span class="source-line-no">2584</span><span id="line-2584"></span>
-<span class="source-line-no">2585</span><span id="line-2585">          LOG.info(getClientIdAuditPrefix() + " delete " + tableName);</span>
-<span class="source-line-no">2586</span><span id="line-2586"></span>
-<span class="source-line-no">2587</span><span id="line-2587">          // TODO: We can handle/merge duplicate request</span>
-<span class="source-line-no">2588</span><span id="line-2588">          //</span>
-<span class="source-line-no">2589</span><span id="line-2589">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2590</span><span id="line-2590">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2591</span><span id="line-2591">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2592</span><span id="line-2592">          submitProcedure(</span>
-<span class="source-line-no">2593</span><span id="line-2593">            new DeleteTableProcedure(procedureExecutor.getEnvironment(), tableName, latch));</span>
-<span class="source-line-no">2594</span><span id="line-2594">          latch.await();</span>
-<span class="source-line-no">2595</span><span id="line-2595"></span>
-<span class="source-line-no">2596</span><span id="line-2596">          getMaster().getMasterCoprocessorHost().postDeleteTable(tableName);</span>
-<span class="source-line-no">2597</span><span id="line-2597">        }</span>
-<span class="source-line-no">2598</span><span id="line-2598"></span>
-<span class="source-line-no">2599</span><span id="line-2599">        @Override</span>
-<span class="source-line-no">2600</span><span id="line-2600">        protected String getDescription() {</span>
-<span class="source-line-no">2601</span><span id="line-2601">          return "DeleteTableProcedure";</span>
-<span class="source-line-no">2602</span><span id="line-2602">        }</span>
-<span class="source-line-no">2603</span><span id="line-2603">      });</span>
-<span class="source-line-no">2604</span><span id="line-2604">  }</span>
-<span class="source-line-no">2605</span><span id="line-2605"></span>
-<span class="source-line-no">2606</span><span id="line-2606">  @Override</span>
-<span class="source-line-no">2607</span><span id="line-2607">  public long truncateTable(final TableName tableName, final boolean preserveSplits,</span>
-<span class="source-line-no">2608</span><span id="line-2608">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2609</span><span id="line-2609">    checkInitialized();</span>
-<span class="source-line-no">2610</span><span id="line-2610"></span>
-<span class="source-line-no">2611</span><span id="line-2611">    return MasterProcedureUtil</span>
-<span class="source-line-no">2612</span><span id="line-2612">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2613</span><span id="line-2613">        @Override</span>
-<span class="source-line-no">2614</span><span id="line-2614">        protected void run() throws IOException {</span>
-<span class="source-line-no">2615</span><span id="line-2615">          getMaster().getMasterCoprocessorHost().preTruncateTable(tableName);</span>
-<span class="source-line-no">2616</span><span id="line-2616"></span>
-<span class="source-line-no">2617</span><span id="line-2617">          LOG.info(getClientIdAuditPrefix() + " truncate " + tableName);</span>
-<span class="source-line-no">2618</span><span id="line-2618">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
-<span class="source-line-no">2619</span><span id="line-2619">          submitProcedure(new TruncateTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
-<span class="source-line-no">2620</span><span id="line-2620">            preserveSplits, latch));</span>
-<span class="source-line-no">2621</span><span id="line-2621">          latch.await();</span>
-<span class="source-line-no">2622</span><span id="line-2622"></span>
-<span class="source-line-no">2623</span><span id="line-2623">          getMaster().getMasterCoprocessorHost().postTruncateTable(tableName);</span>
-<span class="source-line-no">2624</span><span id="line-2624">        }</span>
-<span class="source-line-no">2625</span><span id="line-2625"></span>
-<span class="source-line-no">2626</span><span id="line-2626">        @Override</span>
-<span class="source-line-no">2627</span><span id="line-2627">        protected String getDescription() {</span>
-<span class="source-line-no">2628</span><span id="line-2628">          return "TruncateTableProcedure";</span>
-<span class="source-line-no">2629</span><span id="line-2629">        }</span>
-<span class="source-line-no">2630</span><span id="line-2630">      });</span>
-<span class="source-line-no">2631</span><span id="line-2631">  }</span>
-<span class="source-line-no">2632</span><span id="line-2632"></span>
-<span class="source-line-no">2633</span><span id="line-2633">  @Override</span>
-<span class="source-line-no">2634</span><span id="line-2634">  public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2635</span><span id="line-2635">    throws IOException {</span>
-<span class="source-line-no">2636</span><span id="line-2636">    checkInitialized();</span>
-<span class="source-line-no">2637</span><span id="line-2637"></span>
-<span class="source-line-no">2638</span><span id="line-2638">    return MasterProcedureUtil</span>
-<span class="source-line-no">2639</span><span id="line-2639">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2640</span><span id="line-2640">        @Override</span>
-<span class="source-line-no">2641</span><span id="line-2641">        protected void run() throws IOException {</span>
-<span class="source-line-no">2642</span><span id="line-2642">          getMaster().getMasterCoprocessorHost().preTruncateRegion(regionInfo);</span>
-<span class="source-line-no">2643</span><span id="line-2643"></span>
-<span class="source-line-no">2644</span><span id="line-2644">          LOG.info(</span>
-<span class="source-line-no">2645</span><span id="line-2645">            getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">2646</span><span id="line-2646"></span>
-<span class="source-line-no">2647</span><span id="line-2647">          // Execute the operation asynchronously</span>
-<span class="source-line-no">2648</span><span id="line-2648">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
-<span class="source-line-no">2649</span><span id="line-2649">          submitProcedure(</span>
-<span class="source-line-no">2650</span><span id="line-2650">            new TruncateRegionProcedure(procedureExecutor.getEnvironment(), regionInfo, latch));</span>
-<span class="source-line-no">2651</span><span id="line-2651">          latch.await();</span>
-<span class="source-line-no">2652</span><span id="line-2652"></span>
-<span class="source-line-no">2653</span><span id="line-2653">          getMaster().getMasterCoprocessorHost().postTruncateRegion(regionInfo);</span>
-<span class="source-line-no">2654</span><span id="line-2654">        }</span>
-<span class="source-line-no">2655</span><span id="line-2655"></span>
-<span class="source-line-no">2656</span><span id="line-2656">        @Override</span>
-<span class="source-line-no">2657</span><span id="line-2657">        protected String getDescription() {</span>
-<span class="source-line-no">2658</span><span id="line-2658">          return "TruncateRegionProcedure";</span>
-<span class="source-line-no">2659</span><span id="line-2659">        }</span>
-<span class="source-line-no">2660</span><span id="line-2660">      });</span>
-<span class="source-line-no">2661</span><span id="line-2661">  }</span>
-<span class="source-line-no">2662</span><span id="line-2662"></span>
-<span class="source-line-no">2663</span><span id="line-2663">  @Override</span>
-<span class="source-line-no">2664</span><span id="line-2664">  public long addColumn(final TableName tableName, final ColumnFamilyDescriptor column,</span>
-<span class="source-line-no">2665</span><span id="line-2665">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2666</span><span id="line-2666">    checkInitialized();</span>
-<span class="source-line-no">2667</span><span id="line-2667">    checkTableExists(tableName);</span>
-<span class="source-line-no">2668</span><span id="line-2668"></span>
-<span class="source-line-no">2669</span><span id="line-2669">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2670</span><span id="line-2670"></span>
-<span class="source-line-no">2671</span><span id="line-2671">      @Override</span>
-<span class="source-line-no">2672</span><span id="line-2672">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2673</span><span id="line-2673">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2674</span><span id="line-2674">        if (old.hasColumnFamily(column.getName())) {</span>
-<span class="source-line-no">2675</span><span id="line-2675">          throw new InvalidFamilyOperationException("Column family '" + column.getNameAsString()</span>
-<span class="source-line-no">2676</span><span id="line-2676">            + "' in table '" + tableName + "' already exists so cannot be added");</span>
-<span class="source-line-no">2677</span><span id="line-2677">        }</span>
-<span class="source-line-no">2678</span><span id="line-2678"></span>
-<span class="source-line-no">2679</span><span id="line-2679">        return TableDescriptorBuilder.newBuilder(old).setColumnFamily(column).build();</span>
-<span class="source-line-no">2680</span><span id="line-2680">      }</span>
-<span class="source-line-no">2681</span><span id="line-2681">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2682</span><span id="line-2682">  }</span>
-<span class="source-line-no">2683</span><span id="line-2683"></span>
-<span class="source-line-no">2684</span><span id="line-2684">  /**</span>
-<span class="source-line-no">2685</span><span id="line-2685">   * Implement to return TableDescriptor after pre-checks</span>
-<span class="source-line-no">2686</span><span id="line-2686">   */</span>
-<span class="source-line-no">2687</span><span id="line-2687">  protected interface TableDescriptorGetter {</span>
-<span class="source-line-no">2688</span><span id="line-2688">    TableDescriptor get() throws IOException;</span>
-<span class="source-line-no">2689</span><span id="line-2689">  }</span>
-<span class="source-line-no">2690</span><span id="line-2690"></span>
-<span class="source-line-no">2691</span><span id="line-2691">  @Override</span>
-<span class="source-line-no">2692</span><span id="line-2692">  public long modifyColumn(final TableName tableName, final ColumnFamilyDescriptor descriptor,</span>
-<span class="source-line-no">2693</span><span id="line-2693">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2694</span><span id="line-2694">    checkInitialized();</span>
-<span class="source-line-no">2695</span><span id="line-2695">    checkTableExists(tableName);</span>
-<span class="source-line-no">2696</span><span id="line-2696">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2697</span><span id="line-2697"></span>
-<span class="source-line-no">2698</span><span id="line-2698">      @Override</span>
-<span class="source-line-no">2699</span><span id="line-2699">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2700</span><span id="line-2700">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2701</span><span id="line-2701">        if (!old.hasColumnFamily(descriptor.getName())) {</span>
-<span class="source-line-no">2702</span><span id="line-2702">          throw new InvalidFamilyOperationException("Family '" + descriptor.getNameAsString()</span>
-<span class="source-line-no">2703</span><span id="line-2703">            + "' does not exist, so it cannot be modified");</span>
-<span class="source-line-no">2704</span><span id="line-2704">        }</span>
-<span class="source-line-no">2705</span><span id="line-2705"></span>
-<span class="source-line-no">2706</span><span id="line-2706">        return TableDescriptorBuilder.newBuilder(old).modifyColumnFamily(descriptor).build();</span>
-<span class="source-line-no">2707</span><span id="line-2707">      }</span>
-<span class="source-line-no">2708</span><span id="line-2708">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2709</span><span id="line-2709">  }</span>
-<span class="source-line-no">2710</span><span id="line-2710"></span>
-<span class="source-line-no">2711</span><span id="line-2711">  @Override</span>
-<span class="source-line-no">2712</span><span id="line-2712">  public long modifyColumnStoreFileTracker(TableName tableName, byte[] family, String dstSFT,</span>
-<span class="source-line-no">2713</span><span id="line-2713">    long nonceGroup, long nonce) throws IOException {</span>
-<span class="source-line-no">2714</span><span id="line-2714">    checkInitialized();</span>
-<span class="source-line-no">2715</span><span id="line-2715">    return MasterProcedureUtil</span>
-<span class="source-line-no">2716</span><span id="line-2716">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2717</span><span id="line-2717"></span>
-<span class="source-line-no">2718</span><span id="line-2718">        @Override</span>
-<span class="source-line-no">2719</span><span id="line-2719">        protected void run() throws IOException {</span>
-<span class="source-line-no">2720</span><span id="line-2720">          String sft = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2721</span><span id="line-2721">            .preModifyColumnFamilyStoreFileTracker(tableName, family, dstSFT);</span>
-<span class="source-line-no">2722</span><span id="line-2722">          LOG.info("{} modify column {} store file tracker of table {} to {}",</span>
-<span class="source-line-no">2723</span><span id="line-2723">            getClientIdAuditPrefix(), Bytes.toStringBinary(family), tableName, sft);</span>
-<span class="source-line-no">2724</span><span id="line-2724">          submitProcedure(new ModifyColumnFamilyStoreFileTrackerProcedure(</span>
-<span class="source-line-no">2725</span><span id="line-2725">            procedureExecutor.getEnvironment(), tableName, family, sft));</span>
-<span class="source-line-no">2726</span><span id="line-2726">          getMaster().getMasterCoprocessorHost().postModifyColumnFamilyStoreFileTracker(tableName,</span>
-<span class="source-line-no">2727</span><span id="line-2727">            family, dstSFT);</span>
-<span class="source-line-no">2728</span><span id="line-2728">        }</span>
-<span class="source-line-no">2729</span><span id="line-2729"></span>
-<span class="source-line-no">2730</span><span id="line-2730">        @Override</span>
-<span class="source-line-no">2731</span><span id="line-2731">        protected String getDescription() {</span>
-<span class="source-line-no">2732</span><span id="line-2732">          return "ModifyColumnFamilyStoreFileTrackerProcedure";</span>
-<span class="source-line-no">2733</span><span id="line-2733">        }</span>
-<span class="source-line-no">2734</span><span id="line-2734">      });</span>
-<span class="source-line-no">2735</span><span id="line-2735">  }</span>
-<span class="source-line-no">2736</span><span id="line-2736"></span>
-<span class="source-line-no">2737</span><span id="line-2737">  @Override</span>
-<span class="source-line-no">2738</span><span id="line-2738">  public long deleteColumn(final TableName tableName, final byte[] columnName,</span>
-<span class="source-line-no">2739</span><span id="line-2739">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2740</span><span id="line-2740">    checkInitialized();</span>
-<span class="source-line-no">2741</span><span id="line-2741">    checkTableExists(tableName);</span>
-<span class="source-line-no">2742</span><span id="line-2742"></span>
-<span class="source-line-no">2743</span><span id="line-2743">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2744</span><span id="line-2744"></span>
-<span class="source-line-no">2745</span><span id="line-2745">      @Override</span>
-<span class="source-line-no">2746</span><span id="line-2746">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2747</span><span id="line-2747">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2574</span><span id="line-2574">  private static boolean isCatalogTable(final TableName tableName) {</span>
+<span class="source-line-no">2575</span><span id="line-2575">    return tableName.equals(TableName.META_TABLE_NAME);</span>
+<span class="source-line-no">2576</span><span id="line-2576">  }</span>
+<span class="source-line-no">2577</span><span id="line-2577"></span>
+<span class="source-line-no">2578</span><span id="line-2578">  @Override</span>
+<span class="source-line-no">2579</span><span id="line-2579">  public long deleteTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2580</span><span id="line-2580">    throws IOException {</span>
+<span class="source-line-no">2581</span><span id="line-2581">    checkInitialized();</span>
+<span class="source-line-no">2582</span><span id="line-2582"></span>
+<span class="source-line-no">2583</span><span id="line-2583">    return MasterProcedureUtil</span>
+<span class="source-line-no">2584</span><span id="line-2584">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2585</span><span id="line-2585">        @Override</span>
+<span class="source-line-no">2586</span><span id="line-2586">        protected void run() throws IOException {</span>
+<span class="source-line-no">2587</span><span id="line-2587">          getMaster().getMasterCoprocessorHost().preDeleteTable(tableName);</span>
+<span class="source-line-no">2588</span><span id="line-2588"></span>
+<span class="source-line-no">2589</span><span id="line-2589">          LOG.info(getClientIdAuditPrefix() + " delete " + tableName);</span>
+<span class="source-line-no">2590</span><span id="line-2590"></span>
+<span class="source-line-no">2591</span><span id="line-2591">          // TODO: We can handle/merge duplicate request</span>
+<span class="source-line-no">2592</span><span id="line-2592">          //</span>
+<span class="source-line-no">2593</span><span id="line-2593">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2594</span><span id="line-2594">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2595</span><span id="line-2595">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2596</span><span id="line-2596">          submitProcedure(</span>
+<span class="source-line-no">2597</span><span id="line-2597">            new DeleteTableProcedure(procedureExecutor.getEnvironment(), tableName, latch));</span>
+<span class="source-line-no">2598</span><span id="line-2598">          latch.await();</span>
+<span class="source-line-no">2599</span><span id="line-2599"></span>
+<span class="source-line-no">2600</span><span id="line-2600">          getMaster().getMasterCoprocessorHost().postDeleteTable(tableName);</span>
+<span class="source-line-no">2601</span><span id="line-2601">        }</span>
+<span class="source-line-no">2602</span><span id="line-2602"></span>
+<span class="source-line-no">2603</span><span id="line-2603">        @Override</span>
+<span class="source-line-no">2604</span><span id="line-2604">        protected String getDescription() {</span>
+<span class="source-line-no">2605</span><span id="line-2605">          return "DeleteTableProcedure";</span>
+<span class="source-line-no">2606</span><span id="line-2606">        }</span>
+<span class="source-line-no">2607</span><span id="line-2607">      });</span>
+<span class="source-line-no">2608</span><span id="line-2608">  }</span>
+<span class="source-line-no">2609</span><span id="line-2609"></span>
+<span class="source-line-no">2610</span><span id="line-2610">  @Override</span>
+<span class="source-line-no">2611</span><span id="line-2611">  public long truncateTable(final TableName tableName, final boolean preserveSplits,</span>
+<span class="source-line-no">2612</span><span id="line-2612">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2613</span><span id="line-2613">    checkInitialized();</span>
+<span class="source-line-no">2614</span><span id="line-2614"></span>
+<span class="source-line-no">2615</span><span id="line-2615">    return MasterProcedureUtil</span>
+<span class="source-line-no">2616</span><span id="line-2616">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2617</span><span id="line-2617">        @Override</span>
+<span class="source-line-no">2618</span><span id="line-2618">        protected void run() throws IOException {</span>
+<span class="source-line-no">2619</span><span id="line-2619">          getMaster().getMasterCoprocessorHost().preTruncateTable(tableName);</span>
+<span class="source-line-no">2620</span><span id="line-2620"></span>
+<span class="source-line-no">2621</span><span id="line-2621">          LOG.info(getClientIdAuditPrefix() + " truncate " + tableName);</span>
+<span class="source-line-no">2622</span><span id="line-2622">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
+<span class="source-line-no">2623</span><span id="line-2623">          submitProcedure(new TruncateTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
+<span class="source-line-no">2624</span><span id="line-2624">            preserveSplits, latch));</span>
+<span class="source-line-no">2625</span><span id="line-2625">          latch.await();</span>
+<span class="source-line-no">2626</span><span id="line-2626"></span>
+<span class="source-line-no">2627</span><span id="line-2627">          getMaster().getMasterCoprocessorHost().postTruncateTable(tableName);</span>
+<span class="source-line-no">2628</span><span id="line-2628">        }</span>
+<span class="source-line-no">2629</span><span id="line-2629"></span>
+<span class="source-line-no">2630</span><span id="line-2630">        @Override</span>
+<span class="source-line-no">2631</span><span id="line-2631">        protected String getDescription() {</span>
+<span class="source-line-no">2632</span><span id="line-2632">          return "TruncateTableProcedure";</span>
+<span class="source-line-no">2633</span><span id="line-2633">        }</span>
+<span class="source-line-no">2634</span><span id="line-2634">      });</span>
+<span class="source-line-no">2635</span><span id="line-2635">  }</span>
+<span class="source-line-no">2636</span><span id="line-2636"></span>
+<span class="source-line-no">2637</span><span id="line-2637">  @Override</span>
+<span class="source-line-no">2638</span><span id="line-2638">  public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2639</span><span id="line-2639">    throws IOException {</span>
+<span class="source-line-no">2640</span><span id="line-2640">    checkInitialized();</span>
+<span class="source-line-no">2641</span><span id="line-2641"></span>
+<span class="source-line-no">2642</span><span id="line-2642">    return MasterProcedureUtil</span>
+<span class="source-line-no">2643</span><span id="line-2643">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2644</span><span id="line-2644">        @Override</span>
+<span class="source-line-no">2645</span><span id="line-2645">        protected void run() throws IOException {</span>
+<span class="source-line-no">2646</span><span id="line-2646">          getMaster().getMasterCoprocessorHost().preTruncateRegion(regionInfo);</span>
+<span class="source-line-no">2647</span><span id="line-2647"></span>
+<span class="source-line-no">2648</span><span id="line-2648">          LOG.info(</span>
+<span class="source-line-no">2649</span><span id="line-2649">            getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());</span>
+<span class="source-line-no">2650</span><span id="line-2650"></span>
+<span class="source-line-no">2651</span><span id="line-2651">          // Execute the operation asynchronously</span>
+<span class="source-line-no">2652</span><span id="line-2652">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
+<span class="source-line-no">2653</span><span id="line-2653">          submitProcedure(</span>
+<span class="source-line-no">2654</span><span id="line-2654">            new TruncateRegionProcedure(procedureExecutor.getEnvironment(), regionInfo, latch));</span>
+<span class="source-line-no">2655</span><span id="line-2655">          latch.await();</span>
+<span class="source-line-no">2656</span><span id="line-2656"></span>
+<span class="source-line-no">2657</span><span id="line-2657">          getMaster().getMasterCoprocessorHost().postTruncateRegion(regionInfo);</span>
+<span class="source-line-no">2658</span><span id="line-2658">        }</span>
+<span class="source-line-no">2659</span><span id="line-2659"></span>
+<span class="source-line-no">2660</span><span id="line-2660">        @Override</span>
+<span class="source-line-no">2661</span><span id="line-2661">        protected String getDescription() {</span>
+<span class="source-line-no">2662</span><span id="line-2662">          return "TruncateRegionProcedure";</span>
+<span class="source-line-no">2663</span><span id="line-2663">        }</span>
+<span class="source-line-no">2664</span><span id="line-2664">      });</span>
+<span class="source-line-no">2665</span><span id="line-2665">  }</span>
+<span class="source-line-no">2666</span><span id="line-2666"></span>
+<span class="source-line-no">2667</span><span id="line-2667">  @Override</span>
+<span class="source-line-no">2668</span><span id="line-2668">  public long addColumn(final TableName tableName, final ColumnFamilyDescriptor column,</span>
+<span class="source-line-no">2669</span><span id="line-2669">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2670</span><span id="line-2670">    checkInitialized();</span>
+<span class="source-line-no">2671</span><span id="line-2671">    checkTableExists(tableName);</span>
+<span class="source-line-no">2672</span><span id="line-2672"></span>
+<span class="source-line-no">2673</span><span id="line-2673">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2674</span><span id="line-2674"></span>
+<span class="source-line-no">2675</span><span id="line-2675">      @Override</span>
+<span class="source-line-no">2676</span><span id="line-2676">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2677</span><span id="line-2677">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2678</span><span id="line-2678">        if (old.hasColumnFamily(column.getName())) {</span>
+<span class="source-line-no">2679</span><span id="line-2679">          throw new InvalidFamilyOperationException("Column family '" + column.getNameAsString()</span>
+<span class="source-line-no">2680</span><span id="line-2680">            + "' in table '" + tableName + "' already exists so cannot be added");</span>
+<span class="source-line-no">2681</span><span id="line-2681">        }</span>
+<span class="source-line-no">2682</span><span id="line-2682"></span>
+<span class="source-line-no">2683</span><span id="line-2683">        return TableDescriptorBuilder.newBuilder(old).setColumnFamily(column).build();</span>
+<span class="source-line-no">2684</span><span id="line-2684">      }</span>
+<span class="source-line-no">2685</span><span id="line-2685">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2686</span><span id="line-2686">  }</span>
+<span class="source-line-no">2687</span><span id="line-2687"></span>
+<span class="source-line-no">2688</span><span id="line-2688">  /**</span>
+<span class="source-line-no">2689</span><span id="line-2689">   * Implement to return TableDescriptor after pre-checks</span>
+<span class="source-line-no">2690</span><span id="line-2690">   */</span>
+<span class="source-line-no">2691</span><span id="line-2691">  protected interface TableDescriptorGetter {</span>
+<span class="source-line-no">2692</span><span id="line-2692">    TableDescriptor get() throws IOException;</span>
+<span class="source-line-no">2693</span><span id="line-2693">  }</span>
+<span class="source-line-no">2694</span><span id="line-2694"></span>
+<span class="source-line-no">2695</span><span id="line-2695">  @Override</span>
+<span class="source-line-no">2696</span><span id="line-2696">  public long modifyColumn(final TableName tableName, final ColumnFamilyDescriptor descriptor,</span>
+<span class="source-line-no">2697</span><span id="line-2697">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2698</span><span id="line-2698">    checkInitialized();</span>
+<span class="source-line-no">2699</span><span id="line-2699">    checkTableExists(tableName);</span>
+<span class="source-line-no">2700</span><span id="line-2700">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2701</span><span id="line-2701"></span>
+<span class="source-line-no">2702</span><span id="line-2702">      @Override</span>
+<span class="source-line-no">2703</span><span id="line-2703">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2704</span><span id="line-2704">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2705</span><span id="line-2705">        if (!old.hasColumnFamily(descriptor.getName())) {</span>
+<span class="source-line-no">2706</span><span id="line-2706">          throw new InvalidFamilyOperationException("Family '" + descriptor.getNameAsString()</span>
+<span class="source-line-no">2707</span><span id="line-2707">            + "' does not exist, so it cannot be modified");</span>
+<span class="source-line-no">2708</span><span id="line-2708">        }</span>
+<span class="source-line-no">2709</span><span id="line-2709"></span>
+<span class="source-line-no">2710</span><span id="line-2710">        return TableDescriptorBuilder.newBuilder(old).modifyColumnFamily(descriptor).build();</span>
+<span class="source-line-no">2711</span><span id="line-2711">      }</span>
+<span class="source-line-no">2712</span><span id="line-2712">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2713</span><span id="line-2713">  }</span>
+<span class="source-line-no">2714</span><span id="line-2714"></span>
+<span class="source-line-no">2715</span><span id="line-2715">  @Override</span>
+<span class="source-line-no">2716</span><span id="line-2716">  public long modifyColumnStoreFileTracker(TableName tableName, byte[] family, String dstSFT,</span>
+<span class="source-line-no">2717</span><span id="line-2717">    long nonceGroup, long nonce) throws IOException {</span>
+<span class="source-line-no">2718</span><span id="line-2718">    checkInitialized();</span>
+<span class="source-line-no">2719</span><span id="line-2719">    return MasterProcedureUtil</span>
+<span class="source-line-no">2720</span><span id="line-2720">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2721</span><span id="line-2721"></span>
+<span class="source-line-no">2722</span><span id="line-2722">        @Override</span>
+<span class="source-line-no">2723</span><span id="line-2723">        protected void run() throws IOException {</span>
+<span class="source-line-no">2724</span><span id="line-2724">          String sft = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2725</span><span id="line-2725">            .preModifyColumnFamilyStoreFileTracker(tableName, family, dstSFT);</span>
+<span class="source-line-no">2726</span><span id="line-2726">          LOG.info("{} modify column {} store file tracker of table {} to {}",</span>
+<span class="source-line-no">2727</span><span id="line-2727">            getClientIdAuditPrefix(), Bytes.toStringBinary(family), tableName, sft);</span>
+<span class="source-line-no">2728</span><span id="line-2728">          submitProcedure(new ModifyColumnFamilyStoreFileTrackerProcedure(</span>
+<span class="source-line-no">2729</span><span id="line-2729">            procedureExecutor.getEnvironment(), tableName, family, sft));</span>
+<span class="source-line-no">2730</span><span id="line-2730">          getMaster().getMasterCoprocessorHost().postModifyColumnFamilyStoreFileTracker(tableName,</span>
+<span class="source-line-no">2731</span><span id="line-2731">            family, dstSFT);</span>
+<span class="source-line-no">2732</span><span id="line-2732">        }</span>
+<span class="source-line-no">2733</span><span id="line-2733"></span>
+<span class="source-line-no">2734</span><span id="line-2734">        @Override</span>
+<span class="source-line-no">2735</span><span id="line-2735">        protected String getDescription() {</span>
+<span class="source-line-no">2736</span><span id="line-2736">          return "ModifyColumnFamilyStoreFileTrackerProcedure";</span>
+<span class="source-line-no">2737</span><span id="line-2737">        }</span>
+<span class="source-line-no">2738</span><span id="line-2738">      });</span>
+<span class="source-line-no">2739</span><span id="line-2739">  }</span>
+<span class="source-line-no">2740</span><span id="line-2740"></span>
+<span class="source-line-no">2741</span><span id="line-2741">  @Override</span>
+<span class="source-line-no">2742</span><span id="line-2742">  public long deleteColumn(final TableName tableName, final byte[] columnName,</span>
+<span class="source-line-no">2743</span><span id="line-2743">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2744</span><span id="line-2744">    checkInitialized();</span>
+<span class="source-line-no">2745</span><span id="line-2745">    checkTableExists(tableName);</span>
+<span class="source-line-no">2746</span><span id="line-2746"></span>
+<span class="source-line-no">2747</span><span id="line-2747">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
 <span class="source-line-no">2748</span><span id="line-2748"></span>
-<span class="source-line-no">2749</span><span id="line-2749">        if (!old.hasColumnFamily(columnName)) {</span>
-<span class="source-line-no">2750</span><span id="line-2750">          throw new InvalidFamilyOperationException(</span>
-<span class="source-line-no">2751</span><span id="line-2751">            "Family '" + Bytes.toString(columnName) + "' does not exist, so it cannot be deleted");</span>
-<span class="source-line-no">2752</span><span id="line-2752">        }</span>
-<span class="source-line-no">2753</span><span id="line-2753">        if (old.getColumnFamilyCount() == 1) {</span>
-<span class="source-line-no">2754</span><span id="line-2754">          throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName)</span>
-<span class="source-line-no">2755</span><span id="line-2755">            + "' is the only column family in the table, so it cannot be deleted");</span>
+<span class="source-line-no">2749</span><span id="line-2749">      @Override</span>
+<span class="source-line-no">2750</span><span id="line-2750">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2751</span><span id="line-2751">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2752</span><span id="line-2752"></span>
+<span class="source-line-no">2753</span><span id="line-2753">        if (!old.hasColumnFamily(columnName)) {</span>
+<span class="source-line-no">2754</span><span id="line-2754">          throw new InvalidFamilyOperationException(</span>
+<span class="source-line-no">2755</span><span id="line-2755">            "Family '" + Bytes.toString(columnName) + "' does not exist, so it cannot be deleted");</span>
 <span class="source-line-no">2756</span><span id="line-2756">        }</span>
-<span class="source-line-no">2757</span><span id="line-2757">        return TableDescriptorBuilder.newBuilder(old).removeColumnFamily(columnName).build();</span>
-<span class="source-line-no">2758</span><span id="line-2758">      }</span>
-<span class="source-line-no">2759</span><span id="line-2759">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2760</span><span id="line-2760">  }</span>
-<span class="source-line-no">2761</span><span id="line-2761"></span>
-<span class="source-line-no">2762</span><span id="line-2762">  @Override</span>
-<span class="source-line-no">2763</span><span id="line-2763">  public long enableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2764</span><span id="line-2764">    throws IOException {</span>
-<span class="source-line-no">2765</span><span id="line-2765">    checkInitialized();</span>
-<span class="source-line-no">2766</span><span id="line-2766"></span>
-<span class="source-line-no">2767</span><span id="line-2767">    return MasterProcedureUtil</span>
-<span class="source-line-no">2768</span><span id="line-2768">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2769</span><span id="line-2769">        @Override</span>
-<span class="source-line-no">2770</span><span id="line-2770">        protected void run() throws IOException {</span>
-<span class="source-line-no">2771</span><span id="line-2771">          getMaster().getMasterCoprocessorHost().preEnableTable(tableName);</span>
-<span class="source-line-no">2772</span><span id="line-2772"></span>
-<span class="source-line-no">2773</span><span id="line-2773">          // Normally, it would make sense for this authorization check to exist inside</span>
-<span class="source-line-no">2774</span><span id="line-2774">          // AccessController, but because the authorization check is done based on internal state</span>
-<span class="source-line-no">2775</span><span id="line-2775">          // (rather than explicit permissions) we'll do the check here instead of in the</span>
-<span class="source-line-no">2776</span><span id="line-2776">          // coprocessor.</span>
-<span class="source-line-no">2777</span><span id="line-2777">          MasterQuotaManager quotaManager = getMasterQuotaManager();</span>
-<span class="source-line-no">2778</span><span id="line-2778">          if (quotaManager != null) {</span>
-<span class="source-line-no">2779</span><span id="line-2779">            if (quotaManager.isQuotaInitialized()) {</span>
-<span class="source-line-no">2780</span><span id="line-2780">              // skip checking quotas for system tables, see:</span>
-<span class="source-line-no">2781</span><span id="line-2781">              // https://issues.apache.org/jira/browse/HBASE-28183</span>
-<span class="source-line-no">2782</span><span id="line-2782">              if (!tableName.isSystemTable()) {</span>
-<span class="source-line-no">2783</span><span id="line-2783">                SpaceQuotaSnapshot currSnapshotOfTable =</span>
-<span class="source-line-no">2784</span><span id="line-2784">                  QuotaTableUtil.getCurrentSnapshotFromQuotaTable(getConnection(), tableName);</span>
-<span class="source-line-no">2785</span><span id="line-2785">                if (currSnapshotOfTable != null) {</span>
-<span class="source-line-no">2786</span><span id="line-2786">                  SpaceQuotaStatus quotaStatus = currSnapshotOfTable.getQuotaStatus();</span>
-<span class="source-line-no">2787</span><span id="line-2787">                  if (</span>
-<span class="source-line-no">2788</span><span id="line-2788">                    quotaStatus.isInViolation()</span>
-<span class="source-line-no">2789</span><span id="line-2789">                      &amp;&amp; SpaceViolationPolicy.DISABLE == quotaStatus.getPolicy().orElse(null)</span>
-<span class="source-line-no">2790</span><span id="line-2790">                  ) {</span>
-<span class="source-line-no">2791</span><span id="line-2791">                    throw new AccessDeniedException("Enabling the table '" + tableName</span>
-<span class="source-line-no">2792</span><span id="line-2792">                      + "' is disallowed due to a violated space quota.");</span>
-<span class="source-line-no">2793</span><span id="line-2793">                  }</span>
-<span class="source-line-no">2794</span><span id="line-2794">                }</span>
-<span class="source-line-no">2795</span><span id="line-2795">              }</span>
-<span class="source-line-no">2796</span><span id="line-2796">            } else if (LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">2797</span><span id="line-2797">              LOG</span>
-<span class="source-line-no">2798</span><span id="line-2798">                .trace("Unable to check for space quotas as the MasterQuotaManager is not enabled");</span>
-<span class="source-line-no">2799</span><span id="line-2799">            }</span>
-<span class="source-line-no">2800</span><span id="line-2800">          }</span>
-<span class="source-line-no">2801</span><span id="line-2801"></span>
-<span class="source-line-no">2802</span><span id="line-2802">          LOG.info(getClientIdAuditPrefix() + " enable " + tableName);</span>
-<span class="source-line-no">2803</span><span id="line-2803"></span>
-<span class="source-line-no">2804</span><span id="line-2804">          // Execute the operation asynchronously - client will check the progress of the operation</span>
-<span class="source-line-no">2805</span><span id="line-2805">          // In case the request is from a &lt;1.1 client before returning,</span>
-<span class="source-line-no">2806</span><span id="line-2806">          // we want to make sure that the table is prepared to be</span>
-<span class="source-line-no">2807</span><span id="line-2807">          // enabled (the table is locked and the table state is set).</span>
-<span class="source-line-no">2808</span><span id="line-2808">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
-<span class="source-line-no">2809</span><span id="line-2809">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createLatch();</span>
-<span class="source-line-no">2810</span><span id="line-2810">          submitProcedure(</span>
-<span class="source-line-no">2811</span><span id="line-2811">            new EnableTableProcedure(procedureExecutor.getEnvironment(), tableName, prepareLatch));</span>
-<span class="source-line-no">2812</span><span id="line-2812">          prepareLatch.await();</span>
-<span class="source-line-no">2813</span><span id="line-2813"></span>
-<span class="source-line-no">2814</span><span id="line-2814">          getMaster().getMasterCoprocessorHost().postEnableTable(tableName);</span>
-<span class="source-line-no">2815</span><span id="line-2815">        }</span>
-<span class="source-line-no">2816</span><span id="line-2816"></span>
-<span class="source-line-no">2817</span><span id="line-2817">        @Override</span>
-<span class="source-line-no">2818</span><span id="line-2818">        protected String getDescription() {</span>
-<span class="source-line-no">2819</span><span id="line-2819">          return "EnableTableProcedure";</span>
-<span class="source-line-no">2820</span><span id="line-2820">        }</span>
-<span class="source-line-no">2821</span><span id="line-2821">      });</span>
-<span class="source-line-no">2822</span><span id="line-2822">  }</span>
-<span class="source-line-no">2823</span><span id="line-2823"></span>
-<span class="source-line-no">2824</span><span id="line-2824">  @Override</span>
-<span class="source-line-no">2825</span><span id="line-2825">  public long disableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2826</span><span id="line-2826">    throws IOException {</span>
-<span class="source-line-no">2827</span><span id="line-2827">    checkInitialized();</span>
-<span class="source-line-no">2828</span><span id="line-2828"></span>
-<span class="source-line-no">2829</span><span id="line-2829">    return MasterProcedureUtil</span>
-<span class="source-line-no">2830</span><span id="line-2830">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2831</span><span id="line-2831">        @Override</span>
-<span class="source-line-no">2832</span><span id="line-2832">        protected void run() throws IOException {</span>
-<span class="source-line-no">2833</span><span id="line-2833">          getMaster().getMasterCoprocessorHost().preDisableTable(tableName);</span>
-<span class="source-line-no">2834</span><span id="line-2834"></span>
-<span class="source-line-no">2835</span><span id="line-2835">          LOG.info(getClientIdAuditPrefix() + " disable " + tableName);</span>
-<span class="source-line-no">2836</span><span id="line-2836"></span>
-<span class="source-line-no">2837</span><span id="line-2837">          // Execute the operation asynchronously - client will check the progress of the operation</span>
-<span class="source-line-no">2838</span><span id="line-2838">          // In case the request is from a &lt;1.1 client before returning,</span>
-<span class="source-line-no">2839</span><span id="line-2839">          // we want to make sure that the table is prepared to be</span>
-<span class="source-line-no">2840</span><span id="line-2840">          // enabled (the table is locked and the table state is set).</span>
-<span class="source-line-no">2841</span><span id="line-2841">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
-<span class="source-line-no">2842</span><span id="line-2842">          //</span>
-<span class="source-line-no">2843</span><span id="line-2843">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2844</span><span id="line-2844">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2845</span><span id="line-2845">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2846</span><span id="line-2846">          submitProcedure(new DisableTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
-<span class="source-line-no">2847</span><span id="line-2847">            false, prepareLatch));</span>
-<span class="source-line-no">2848</span><span id="line-2848">          prepareLatch.await();</span>
-<span class="source-line-no">2849</span><span id="line-2849"></span>
-<span class="source-line-no">2850</span><span id="line-2850">          getMaster().getMasterCoprocessorHost().postDisableTable(tableName);</span>
-<span class="source-line-no">2851</span><span id="line-2851">        }</span>
-<span class="source-line-no">2852</span><span id="line-2852"></span>
-<span class="source-line-no">2853</span><span id="line-2853">        @Override</span>
-<span class="source-line-no">2854</span><span id="line-2854">        protected String getDescription() {</span>
-<span class="source-line-no">2855</span><span id="line-2855">          return "DisableTableProcedure";</span>
-<span class="source-line-no">2856</span><span id="line-2856">        }</span>
-<span class="source-line-no">2857</span><span id="line-2857">      });</span>
-<span class="source-line-no">2858</span><span id="line-2858">  }</span>
-<span class="source-line-no">2859</span><span id="line-2859"></span>
-<span class="source-line-no">2860</span><span id="line-2860">  private long modifyTable(final TableName tableName,</span>
-<span class="source-line-no">2861</span><span id="line-2861">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
-<span class="source-line-no">2862</span><span id="line-2862">    final boolean shouldCheckDescriptor) throws IOException {</span>
-<span class="source-line-no">2863</span><span id="line-2863">    return modifyTable(tableName, newDescriptorGetter, nonceGroup, nonce, shouldCheckDescriptor,</span>
-<span class="source-line-no">2864</span><span id="line-2864">      true);</span>
-<span class="source-line-no">2865</span><span id="line-2865">  }</span>
-<span class="source-line-no">2866</span><span id="line-2866"></span>
-<span class="source-line-no">2867</span><span id="line-2867">  private long modifyTable(final TableName tableName,</span>
-<span class="source-line-no">2868</span><span id="line-2868">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
-<span class="source-line-no">2869</span><span id="line-2869">    final boolean shouldCheckDescriptor, final boolean reopenRegions) throws IOException {</span>
-<span class="source-line-no">2870</span><span id="line-2870">    return MasterProcedureUtil</span>
-<span class="source-line-no">2871</span><span id="line-2871">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2872</span><span id="line-2872">        @Override</span>
-<span class="source-line-no">2873</span><span id="line-2873">        protected void run() throws IOException {</span>
-<span class="source-line-no">2874</span><span id="line-2874">          TableDescriptor oldDescriptor = getMaster().getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2875</span><span id="line-2875">          TableDescriptor newDescriptor = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2876</span><span id="line-2876">            .preModifyTable(tableName, oldDescriptor, newDescriptorGetter.get());</span>
-<span class="source-line-no">2877</span><span id="line-2877">          TableDescriptorChecker.sanityCheck(conf, newDescriptor);</span>
-<span class="source-line-no">2878</span><span id="line-2878">          LOG.info("{} modify table {} from {} to {}", getClientIdAuditPrefix(), tableName,</span>
-<span class="source-line-no">2879</span><span id="line-2879">            oldDescriptor, newDescriptor);</span>
-<span class="source-line-no">2880</span><span id="line-2880"></span>
-<span class="source-line-no">2881</span><span id="line-2881">          // Execute the operation synchronously - wait for the operation completes before</span>
-<span class="source-line-no">2882</span><span id="line-2882">          // continuing.</span>
-<span class="source-line-no">2883</span><span id="line-2883">          //</span>
-<span class="source-line-no">2884</span><span id="line-2884">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2885</span><span id="line-2885">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2886</span><span id="line-2886">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2887</span><span id="line-2887">          submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),</span>
-<span class="source-line-no">2888</span><span id="line-2888">            newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, reopenRegions));</span>
-<span class="source-line-no">2889</span><span id="line-2889">          latch.await();</span>
-<span class="source-line-no">2890</span><span id="line-2890"></span>
-<span class="source-line-no">2891</span><span id="line-2891">          getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,</span>
-<span class="source-line-no">2892</span><span id="line-2892">            newDescriptor);</span>
-<span class="source-line-no">2893</span><span id="line-2893">        }</span>
+<span class="source-line-no">2757</span><span id="line-2757">        if (old.getColumnFamilyCount() == 1) {</span>
+<span class="source-line-no">2758</span><span id="line-2758">          throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName)</span>
+<span class="source-line-no">2759</span><span id="line-2759">            + "' is the only column family in the table, so it cannot be deleted");</span>
+<span class="source-line-no">2760</span><span id="line-2760">        }</span>
+<span class="source-line-no">2761</span><span id="line-2761">        return TableDescriptorBuilder.newBuilder(old).removeColumnFamily(columnName).build();</span>
+<span class="source-line-no">2762</span><span id="line-2762">      }</span>
+<span class="source-line-no">2763</span><span id="line-2763">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2764</span><span id="line-2764">  }</span>
+<span class="source-line-no">2765</span><span id="line-2765"></span>
+<span class="source-line-no">2766</span><span id="line-2766">  @Override</span>
+<span class="source-line-no">2767</span><span id="line-2767">  public long enableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2768</span><span id="line-2768">    throws IOException {</span>
+<span class="source-line-no">2769</span><span id="line-2769">    checkInitialized();</span>
+<span class="source-line-no">2770</span><span id="line-2770"></span>
+<span class="source-line-no">2771</span><span id="line-2771">    return MasterProcedureUtil</span>
+<span class="source-line-no">2772</span><span id="line-2772">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2773</span><span id="line-2773">        @Override</span>
+<span class="source-line-no">2774</span><span id="line-2774">        protected void run() throws IOException {</span>
+<span class="source-line-no">2775</span><span id="line-2775">          getMaster().getMasterCoprocessorHost().preEnableTable(tableName);</span>
+<span class="source-line-no">2776</span><span id="line-2776"></span>
+<span class="source-line-no">2777</span><span id="line-2777">          // Normally, it would make sense for this authorization check to exist inside</span>
+<span class="source-line-no">2778</span><span id="line-2778">          // AccessController, but because the authorization check is done based on internal state</span>
+<span class="source-line-no">2779</span><span id="line-2779">          // (rather than explicit permissions) we'll do the check here instead of in the</span>
+<span class="source-line-no">2780</span><span id="line-2780">          // coprocessor.</span>
+<span class="source-line-no">2781</span><span id="line-2781">          MasterQuotaManager quotaManager = getMasterQuotaManager();</span>
+<span class="source-line-no">2782</span><span id="line-2782">          if (quotaManager != null) {</span>
+<span class="source-line-no">2783</span><span id="line-2783">            if (quotaManager.isQuotaInitialized()) {</span>
+<span class="source-line-no">2784</span><span id="line-2784">              // skip checking quotas for system tables, see:</span>
+<span class="source-line-no">2785</span><span id="line-2785">              // https://issues.apache.org/jira/browse/HBASE-28183</span>
+<span class="source-line-no">2786</span><span id="line-2786">              if (!tableName.isSystemTable()) {</span>
+<span class="source-line-no">2787</span><span id="line-2787">                SpaceQuotaSnapshot currSnapshotOfTable =</span>
+<span class="source-line-no">2788</span><span id="line-2788">                  QuotaTableUtil.getCurrentSnapshotFromQuotaTable(getConnection(), tableName);</span>
+<span class="source-line-no">2789</span><span id="line-2789">                if (currSnapshotOfTable != null) {</span>
+<span class="source-line-no">2790</span><span id="line-2790">                  SpaceQuotaStatus quotaStatus = currSnapshotOfTable.getQuotaStatus();</span>
+<span class="source-line-no">2791</span><span id="line-2791">                  if (</span>
+<span class="source-line-no">2792</span><span id="line-2792">                    quotaStatus.isInViolation()</span>
+<span class="source-line-no">2793</span><span id="line-2793">                      &amp;&amp; SpaceViolationPolicy.DISABLE == quotaStatus.getPolicy().orElse(null)</span>
+<span class="source-line-no">2794</span><span id="line-2794">                  ) {</span>
+<span class="source-line-no">2795</span><span id="line-2795">                    throw new AccessDeniedException("Enabling the table '" + tableName</span>
+<span class="source-line-no">2796</span><span id="line-2796">                      + "' is disallowed due to a violated space quota.");</span>
+<span class="source-line-no">2797</span><span id="line-2797">                  }</span>
+<span class="source-line-no">2798</span><span id="line-2798">                }</span>
+<span class="source-line-no">2799</span><span id="line-2799">              }</span>
+<span class="source-line-no">2800</span><span id="line-2800">            } else if (LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">2801</span><span id="line-2801">              LOG</span>
+<span class="source-line-no">2802</span><span id="line-2802">                .trace("Unable to check for space quotas as the MasterQuotaManager is not enabled");</span>
+<span class="source-line-no">2803</span><span id="line-2803">            }</span>
+<span class="source-line-no">2804</span><span id="line-2804">          }</span>
+<span class="source-line-no">2805</span><span id="line-2805"></span>
+<span class="source-line-no">2806</span><span id="line-2806">          LOG.info(getClientIdAuditPrefix() + " enable " + tableName);</span>
+<span class="source-line-no">2807</span><span id="line-2807"></span>
+<span class="source-line-no">2808</span><span id="line-2808">          // Execute the operation asynchronously - client will check the progress of the operation</span>
+<span class="source-line-no">2809</span><span id="line-2809">          // In case the request is from a &lt;1.1 client before returning,</span>
+<span class="source-line-no">2810</span><span id="line-2810">          // we want to make sure that the table is prepared to be</span>
+<span class="source-line-no">2811</span><span id="line-2811">          // enabled (the table is locked and the table state is set).</span>
+<span class="source-line-no">2812</span><span id="line-2812">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
+<span class="source-line-no">2813</span><span id="line-2813">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createLatch();</span>
+<span class="source-line-no">2814</span><span id="line-2814">          submitProcedure(</span>
+<span class="source-line-no">2815</span><span id="line-2815">            new EnableTableProcedure(procedureExecutor.getEnvironment(), tableName, prepareLatch));</span>
+<span class="source-line-no">2816</span><span id="line-2816">          prepareLatch.await();</span>
+<span class="source-line-no">2817</span><span id="line-2817"></span>
+<span class="source-line-no">2818</span><span id="line-2818">          getMaster().getMasterCoprocessorHost().postEnableTable(tableName);</span>
+<span class="source-line-no">2819</span><span id="line-2819">        }</span>
+<span class="source-line-no">2820</span><span id="line-2820"></span>
+<span class="source-line-no">2821</span><span id="line-2821">        @Override</span>
+<span class="source-line-no">2822</span><span id="line-2822">        protected String getDescription() {</span>
+<span class="source-line-no">2823</span><span id="line-2823">          return "EnableTableProcedure";</span>
+<span class="source-line-no">2824</span><span id="line-2824">        }</span>
+<span class="source-line-no">2825</span><span id="line-2825">      });</span>
+<span class="source-line-no">2826</span><span id="line-2826">  }</span>
+<span class="source-line-no">2827</span><span id="line-2827"></span>
+<span class="source-line-no">2828</span><span id="line-2828">  @Override</span>
+<span class="source-line-no">2829</span><span id="line-2829">  public long disableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2830</span><span id="line-2830">    throws IOException {</span>
+<span class="source-line-no">2831</span><span id="line-2831">    checkInitialized();</span>
+<span class="source-line-no">2832</span><span id="line-2832"></span>
+<span class="source-line-no">2833</span><span id="line-2833">    return MasterProcedureUtil</span>
+<span class="source-line-no">2834</span><span id="line-2834">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2835</span><span id="line-2835">        @Override</span>
+<span class="source-line-no">2836</span><span id="line-2836">        protected void run() throws IOException {</span>
+<span class="source-line-no">2837</span><span id="line-2837">          getMaster().getMasterCoprocessorHost().preDisableTable(tableName);</span>
+<span class="source-line-no">2838</span><span id="line-2838"></span>
+<span class="source-line-no">2839</span><span id="line-2839">          LOG.info(getClientIdAuditPrefix() + " disable " + tableName);</span>
+<span class="source-line-no">2840</span><span id="line-2840"></span>
+<span class="source-line-no">2841</span><span id="line-2841">          // Execute the operation asynchronously - client will check the progress of the operation</span>
+<span class="source-line-no">2842</span><span id="line-2842">          // In case the request is from a &lt;1.1 client before returning,</span>
+<span class="source-line-no">2843</span><span id="line-2843">          // we want to make sure that the table is prepared to be</span>
+<span class="source-line-no">2844</span><span id="line-2844">          // enabled (the table is locked and the table state is set).</span>
+<span class="source-line-no">2845</span><span id="line-2845">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
+<span class="source-line-no">2846</span><span id="line-2846">          //</span>
+<span class="source-line-no">2847</span><span id="line-2847">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2848</span><span id="line-2848">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2849</span><span id="line-2849">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2850</span><span id="line-2850">          submitProcedure(new DisableTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
+<span class="source-line-no">2851</span><span id="line-2851">            false, prepareLatch));</span>
+<span class="source-line-no">2852</span><span id="line-2852">          prepareLatch.await();</span>
+<span class="source-line-no">2853</span><span id="line-2853"></span>
+<span class="source-line-no">2854</span><span id="line-2854">          getMaster().getMasterCoprocessorHost().postDisableTable(tableName);</span>
+<span class="source-line-no">2855</span><span id="line-2855">        }</span>
+<span class="source-line-no">2856</span><span id="line-2856"></span>
+<span class="source-line-no">2857</span><span id="line-2857">        @Override</span>
+<span class="source-line-no">2858</span><span id="line-2858">        protected String getDescription() {</span>
+<span class="source-line-no">2859</span><span id="line-2859">          return "DisableTableProcedure";</span>
+<span class="source-line-no">2860</span><span id="line-2860">        }</span>
+<span class="source-line-no">2861</span><span id="line-2861">      });</span>
+<span class="source-line-no">2862</span><span id="line-2862">  }</span>
+<span class="source-line-no">2863</span><span id="line-2863"></span>
+<span class="source-line-no">2864</span><span id="line-2864">  private long modifyTable(final TableName tableName,</span>
+<span class="source-line-no">2865</span><span id="line-2865">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
+<span class="source-line-no">2866</span><span id="line-2866">    final boolean shouldCheckDescriptor) throws IOException {</span>
+<span class="source-line-no">2867</span><span id="line-2867">    return modifyTable(tableName, newDescriptorGetter, nonceGroup, nonce, shouldCheckDescriptor,</span>
+<span class="source-line-no">2868</span><span id="line-2868">      true);</span>
+<span class="source-line-no">2869</span><span id="line-2869">  }</span>
+<span class="source-line-no">2870</span><span id="line-2870"></span>
+<span class="source-line-no">2871</span><span id="line-2871">  private long modifyTable(final TableName tableName,</span>
+<span class="source-line-no">2872</span><span id="line-2872">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
+<span class="source-line-no">2873</span><span id="line-2873">    final boolean shouldCheckDescriptor, final boolean reopenRegions) throws IOException {</span>
+<span class="source-line-no">2874</span><span id="line-2874">    return MasterProcedureUtil</span>
+<span class="source-line-no">2875</span><span id="line-2875">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2876</span><span id="line-2876">        @Override</span>
+<span class="source-line-no">2877</span><span id="line-2877">        protected void run() throws IOException {</span>
+<span class="source-line-no">2878</span><span id="line-2878">          TableDescriptor oldDescriptor = getMaster().getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2879</span><span id="line-2879">          TableDescriptor newDescriptor = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2880</span><span id="line-2880">            .preModifyTable(tableName, oldDescriptor, newDescriptorGetter.get());</span>
+<span class="source-line-no">2881</span><span id="line-2881">          TableDescriptorChecker.sanityCheck(conf, newDescriptor);</span>
+<span class="source-line-no">2882</span><span id="line-2882">          LOG.info("{} modify table {} from {} to {}", getClientIdAuditPrefix(), tableName,</span>
+<span class="source-line-no">2883</span><span id="line-2883">            oldDescriptor, newDescriptor);</span>
+<span class="source-line-no">2884</span><span id="line-2884"></span>
+<span class="source-line-no">2885</span><span id="line-2885">          // Execute the operation synchronously - wait for the operation completes before</span>
+<span class="source-line-no">2886</span><span id="line-2886">          // continuing.</span>
+<span class="source-line-no">2887</span><span id="line-2887">          //</span>
+<span class="source-line-no">2888</span><span id="line-2888">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2889</span><span id="line-2889">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2890</span><span id="line-2890">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2891</span><span id="line-2891">          submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),</span>
+<span class="source-line-no">2892</span><span id="line-2892">            newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, reopenRegions));</span>
+<span class="source-line-no">2893</span><span id="line-2893">          latch.await();</span>
 <span class="source-line-no">2894</span><span id="line-2894"></span>
-<span class="source-line-no">2895</span><span id="line-2895">        @Override</span>
-<span class="source-line-no">2896</span><span id="line-2896">        protected String getDescription() {</span>
-<span class="source-line-no">2897</span><span id="line-2897">          return "ModifyTableProcedure";</span>
-<span class="source-line-no">2898</span><span id="line-2898">        }</span>
-<span class="source-line-no">2899</span><span id="line-2899">      });</span>
-<span class="source-line-no">2900</span><span id="line-2900"></span>
-<span class="source-line-no">2901</span><span id="line-2901">  }</span>
-<span class="source-line-no">2902</span><span id="line-2902"></span>
-<span class="source-line-no">2903</span><span id="line-2903">  @Override</span>
-<span class="source-line-no">2904</span><span id="line-2904">  public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,</span>
-<span class="source-line-no">2905</span><span id="line-2905">    final long nonceGroup, final long nonce, final boolean reopenRegions) throws IOException {</span>
-<span class="source-line-no">2906</span><span id="line-2906">    checkInitialized();</span>
-<span class="source-line-no">2907</span><span id="line-2907">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2908</span><span id="line-2908">      @Override</span>
-<span class="source-line-no">2909</span><span id="line-2909">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2910</span><span id="line-2910">        return newDescriptor;</span>
-<span class="source-line-no">2911</span><span id="line-2911">      }</span>
-<span class="source-line-no">2912</span><span id="line-2912">    }, nonceGroup, nonce, false, reopenRegions);</span>
-<span class="source-line-no">2913</span><span id="line-2913"></span>
-<span class="source-line-no">2914</span><span id="line-2914">  }</span>
-<span class="source-line-no">2915</span><span id="line-2915"></span>
-<span class="source-line-no">2916</span><span id="line-2916">  @Override</span>
-<span class="source-line-no">2917</span><span id="line-2917">  public long modifyTableStoreFileTracker(TableName tableName, String dstSFT, long nonceGroup,</span>
-<span class="source-line-no">2918</span><span id="line-2918">    long nonce) throws IOException {</span>
-<span class="source-line-no">2919</span><span id="line-2919">    checkInitialized();</span>
-<span class="source-line-no">2920</span><span id="line-2920">    return MasterProcedureUtil</span>
-<span class="source-line-no">2921</span><span id="line-2921">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2922</span><span id="line-2922"></span>
-<span class="source-line-no">2923</span><span id="line-2923">        @Override</span>
-<span class="source-line-no">2924</span><span id="line-2924">        protected void run() throws IOException {</span>
-<span class="source-line-no">2925</span><span id="line-2925">          String sft = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2926</span><span id="line-2926">            .preModifyTableStoreFileTracker(tableName, dstSFT);</span>
-<span class="source-line-no">2927</span><span id="line-2927">          LOG.info("{} modify table store file tracker of table {} to {}", getClientIdAuditPrefix(),</span>
-<span class="source-line-no">2928</span><span id="line-2928">            tableName, sft);</span>
-<span class="source-line-no">2929</span><span id="line-2929">          submitProcedure(new ModifyTableStoreFileTrackerProcedure(</span>
-<span class="source-line-no">2930</span><span id="line-2930">            procedureExecutor.getEnvironment(), tableName, sft));</span>
-<span class="source-line-no">2931</span><span id="line-2931">          getMaster().getMasterCoprocessorHost().postModifyTableStoreFileTracker(tableName, sft);</span>
-<span class="source-line-no">2932</span><span id="line-2932">        }</span>
-<span class="source-line-no">2933</span><span id="line-2933"></span>
-<span class="source-line-no">2934</span><span id="line-2934">        @Override</span>
-<span class="source-line-no">2935</span><span id="line-2935">        protected String getDescription() {</span>
-<span class="source-line-no">2936</span><span id="line-2936">          return "ModifyTableStoreFileTrackerProcedure";</span>
-<span class="source-line-no">2937</span><span id="line-2937">        }</span>
-<span class="source-line-no">2938</span><span id="line-2938">      });</span>
-<span class="source-line-no">2939</span><span id="line-2939">  }</span>
-<span class="source-line-no">2940</span><span id="line-2940"></span>
-<span class="source-line-no">2941</span><span id="line-2941">  public long restoreSnapshot(final SnapshotDescription snapshotDesc, final long nonceGroup,</span>
-<span class="source-line-no">2942</span><span id="line-2942">    final long nonce, final boolean restoreAcl, final String customSFT) throws IOException {</span>
-<span class="source-line-no">2943</span><span id="line-2943">    checkInitialized();</span>
-<span class="source-line-no">2944</span><span id="line-2944">    getSnapshotManager().checkSnapshotSupport();</span>
-<span class="source-line-no">2945</span><span id="line-2945"></span>
-<span class="source-line-no">2946</span><span id="line-2946">    // Ensure namespace exists. Will throw exception if non-known NS.</span>
-<span class="source-line-no">2947</span><span id="line-2947">    final TableName dstTable = TableName.valueOf(snapshotDesc.getTable());</span>
-<span class="source-line-no">2948</span><span id="line-2948">    getClusterSchema().getNamespace(dstTable.getNamespaceAsString());</span>
+<span class="source-line-no">2895</span><span id="line-2895">          getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,</span>
+<span class="source-line-no">2896</span><span id="line-2896">            newDescriptor);</span>
+<span class="source-line-no">2897</span><span id="line-2897">        }</span>
+<span class="source-line-no">2898</span><span id="line-2898"></span>
+<span class="source-line-no">2899</span><span id="line-2899">        @Override</span>
+<span class="source-line-no">2900</span><span id="line-2900">        protected String getDescription() {</span>
+<span class="source-line-no">2901</span><span id="line-2901">          return "ModifyTableProcedure";</span>
+<span class="source-line-no">2902</span><span id="line-2902">        }</span>
+<span class="source-line-no">2903</span><span id="line-2903">      });</span>
+<span class="source-line-no">2904</span><span id="line-2904"></span>
+<span class="source-line-no">2905</span><span id="line-2905">  }</span>
+<span class="source-line-no">2906</span><span id="line-2906"></span>
+<span class="source-line-no">2907</span><span id="line-2907">  @Override</span>
+<span class="source-line-no">2908</span><span id="line-2908">  public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,</span>
+<span class="source-line-no">2909</span><span id="line-2909">    final long nonceGroup, final long nonce, final boolean reopenRegions) throws IOException {</span>
+<span class="source-line-no">2910</span><span id="line-2910">    checkInitialized();</span>
+<span class="source-line-no">2911</span><span id="line-2911">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2912</span><span id="line-2912">      @Override</span>
+<span class="source-line-no">2913</span><span id="line-2913">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2914</span><span id="line-2914">        return newDescriptor;</span>
+<span class="source-line-no">2915</span><span id="line-2915">      }</span>
+<span class="source-line-no">2916</span><span id="line-2916">    }, nonceGroup, nonce, false, reopenRegions);</span>
+<span class="source-line-no">2917</span><span id="line-2917"></span>
+<span class="source-line-no">2918</span><span id="line-2918">  }</span>
+<span class="source-line-no">2919</span><span id="line-2919"></span>
+<span class="source-line-no">2920</span><span id="line-2920">  @Override</span>
+<span class="source-line-no">2921</span><span id="line-2921">  public long modifyTableStoreFileTracker(TableName tableName, String dstSFT, long nonceGroup,</span>
+<span class="source-line-no">2922</span><span id="line-2922">    long nonce) throws IOException {</span>
+<span class="source-line-no">2923</span><span id="line-2923">    checkInitialized();</span>
+<span class="source-line-no">2924</span><span id="line-2924">    return MasterProcedureUtil</span>
+<span class="source-line-no">2925</span><span id="line-2925">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2926</span><span id="line-2926"></span>
+<span class="source-line-no">2927</span><span id="line-2927">        @Override</span>
+<span class="source-line-no">2928</span><span id="line-2928">        protected void run() throws IOException {</span>
+<span class="source-line-no">2929</span><span id="line-2929">          String sft = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2930</span><span id="line-2930">            .preModifyTableStoreFileTracker(tableName, dstSFT);</span>
+<span class="source-line-no">2931</span><span id="line-2931">          LOG.info("{} modify table store file tracker of table {} to {}", getClientIdAuditPrefix(),</span>
+<span class="source-line-no">2932</span><span id="line-2932">            tableName, sft);</span>
+<span class="source-line-no">2933</span><span id="line-2933">          submitProcedure(new ModifyTableStoreFileTrackerProcedure(</span>
+<span class="source-line-no">2934</span><span id="line-2934">            procedureExecutor.getEnvironment(), tableName, sft));</span>
+<span class="source-line-no">2935</span><span id="line-2935">          getMaster().getMasterCoprocessorHost().postModifyTableStoreFileTracker(tableName, sft);</span>
+<span class="source-line-no">2936</span><span id="line-2936">        }</span>
+<span class="source-line-no">2937</span><span id="line-2937"></span>
+<span class="source-line-no">2938</span><span id="line-2938">        @Override</span>
+<span class="source-line-no">2939</span><span id="line-2939">        protected String getDescription() {</span>
+<span class="source-line-no">2940</span><span id="line-2940">          return "ModifyTableStoreFileTrackerProcedure";</span>
+<span class="source-line-no">2941</span><span id="line-2941">        }</span>
+<span class="source-line-no">2942</span><span id="line-2942">      });</span>
+<span class="source-line-no">2943</span><span id="line-2943">  }</span>
+<span class="source-line-no">2944</span><span id="line-2944"></span>
+<span class="source-line-no">2945</span><span id="line-2945">  public long restoreSnapshot(final SnapshotDescription snapshotDesc, final long nonceGroup,</span>
+<span class="source-line-no">2946</span><span id="line-2946">    final long nonce, final boolean restoreAcl, final String customSFT) throws IOException {</span>
+<span class="source-line-no">2947</span><span id="line-2947">    checkInitialized();</span>
+<span class="source-line-no">2948</span><span id="line-2948">    getSnapshotManager().checkSnapshotSupport();</span>
 <span class="source-line-no">2949</span><span id="line-2949"></span>
-<span class="source-line-no">2950</span><span id="line-2950">    return MasterProcedureUtil</span>
-<span class="source-line-no">2951</span><span id="line-2951">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2952</span><span id="line-2952">        @Override</span>
-<span class="source-line-no">2953</span><span id="line-2953">        protected void run() throws IOException {</span>
-<span class="source-line-no">2954</span><span id="line-2954">          setProcId(getSnapshotManager().restoreOrCloneSnapshot(snapshotDesc, getNonceKey(),</span>
-<span class="source-line-no">2955</span><span id="line-2955">            restoreAcl, customSFT));</span>
-<span class="source-line-no">2956</span><span id="line-2956">        }</span>
-<span class="source-line-no">2957</span><span id="line-2957"></span>
-<span class="source-line-no">2958</span><span id="line-2958">        @Override</span>
-<span class="source-line-no">2959</span><span id="line-2959">        protected String getDescription() {</span>
-<span class="source-line-no">2960</span><span id="line-2960">          return "RestoreSnapshotProcedure";</span>
-<span class="source-line-no">2961</span><span id="line-2961">        }</span>
-<span class="source-line-no">2962</span><span id="line-2962">      });</span>
-<span class="source-line-no">2963</span><span id="line-2963">  }</span>
-<span class="source-line-no">2964</span><span id="line-2964"></span>
-<span class="source-line-no">2965</span><span id="line-2965">  private void checkTableExists(final TableName tableName)</span>
-<span class="source-line-no">2966</span><span id="line-2966">    throws IOException, TableNotFoundException {</span>
-<span class="source-line-no">2967</span><span id="line-2967">    if (!tableDescriptors.exists(tableName)) {</span>
-<span class="source-line-no">2968</span><span id="line-2968">      throw new TableNotFoundException(tableName);</span>
-<span class="source-line-no">2969</span><span id="line-2969">    }</span>
-<span class="source-line-no">2970</span><span id="line-2970">  }</span>
-<span class="source-line-no">2971</span><span id="line-2971"></span>
-<span class="source-line-no">2972</span><span id="line-2972">  @Override</span>
-<span class="source-line-no">2973</span><span id="line-2973">  public void checkTableModifiable(final TableName tableName)</span>
-<span class="source-line-no">2974</span><span id="line-2974">    throws IOException, TableNotFoundException, TableNotDisabledException {</span>
-<span class="source-line-no">2975</span><span id="line-2975">    if (isCatalogTable(tableName)) {</span>
-<span class="source-line-no">2976</span><span id="line-2976">      throw new IOException("Can't modify catalog tables");</span>
-<span class="source-line-no">2977</span><span id="line-2977">    }</span>
-<span class="source-line-no">2978</span><span id="line-2978">    checkTableExists(tableName);</span>
-<span class="source-line-no">2979</span><span id="line-2979">    TableState ts = getTableStateManager().getTableState(tableName);</span>
-<span class="source-line-no">2980</span><span id="line-2980">    if (!ts.isDisabled()) {</span>
-<span class="source-line-no">2981</span><span id="line-2981">      throw new TableNotDisabledException("Not DISABLED; " + ts);</span>
-<span class="source-line-no">2982</span><span id="line-2982">    }</span>
-<span class="source-line-no">2983</span><span id="line-2983">  }</span>
-<span class="source-line-no">2984</span><span id="line-2984"></span>
-<span class="source-line-no">2985</span><span id="line-2985">  public ClusterMetrics getClusterMetricsWithoutCoprocessor() throws InterruptedIOException {</span>
-<span class="source-line-no">2986</span><span id="line-2986">    return getClusterMetricsWithoutCoprocessor(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">2950</span><span id="line-2950">    // Ensure namespace exists. Will throw exception if non-known NS.</span>
+<span class="source-line-no">2951</span><span id="line-2951">    final TableName dstTable = TableName.valueOf(snapshotDesc.getTable());</span>
+<span class="source-line-no">2952</span><span id="line-2952">    getClusterSchema().getNamespace(dstTable.getNamespaceAsString());</span>
+<span class="source-line-no">2953</span><span id="line-2953"></span>
+<span class="source-line-no">2954</span><span id="line-2954">    return MasterProcedureUtil</span>
+<span class="source-line-no">2955</span><span id="line-2955">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2956</span><span id="line-2956">        @Override</span>
+<span class="source-line-no">2957</span><span id="line-2957">        protected void run() throws IOException {</span>
+<span class="source-line-no">2958</span><span id="line-2958">          setProcId(getSnapshotManager().restoreOrCloneSnapshot(snapshotDesc, getNonceKey(),</span>
+<span class="source-line-no">2959</span><span id="line-2959">            restoreAcl, customSFT));</span>
+<span class="source-line-no">2960</span><span id="line-2960">        }</span>
+<span class="source-line-no">2961</span><span id="line-2961"></span>
+<span class="source-line-no">2962</span><span id="line-2962">        @Override</span>
+<span class="source-line-no">2963</span><span id="line-2963">        protected String getDescription() {</span>
+<span class="source-line-no">2964</span><span id="line-2964">          return "RestoreSnapshotProcedure";</span>
+<span class="source-line-no">2965</span><span id="line-2965">        }</span>
+<span class="source-line-no">2966</span><span id="line-2966">      });</span>
+<span class="source-line-no">2967</span><span id="line-2967">  }</span>
+<span class="source-line-no">2968</span><span id="line-2968"></span>
+<span class="source-line-no">2969</span><span id="line-2969">  private void checkTableExists(final TableName tableName)</span>
+<span class="source-line-no">2970</span><span id="line-2970">    throws IOException, TableNotFoundException {</span>
+<span class="source-line-no">2971</span><span id="line-2971">    if (!tableDescriptors.exists(tableName)) {</span>
+<span class="source-line-no">2972</span><span id="line-2972">      throw new TableNotFoundException(tableName);</span>
+<span class="source-line-no">2973</span><span id="line-2973">    }</span>
+<span class="source-line-no">2974</span><span id="line-2974">  }</span>
+<span class="source-line-no">2975</span><span id="line-2975"></span>
+<span class="source-line-no">2976</span><span id="line-2976">  @Override</span>
+<span class="source-line-no">2977</span><span id="line-2977">  public void checkTableModifiable(final TableName tableName)</span>
+<span class="source-line-no">2978</span><span id="line-2978">    throws IOException, TableNotFoundException, TableNotDisabledException {</span>
+<span class="source-line-no">2979</span><span id="line-2979">    if (isCatalogTable(tableName)) {</span>
+<span class="source-line-no">2980</span><span id="line-2980">      throw new IOException("Can't modify catalog tables");</span>
+<span class="source-line-no">2981</span><span id="line-2981">    }</span>
+<span class="source-line-no">2982</span><span id="line-2982">    checkTableExists(tableName);</span>
+<span class="source-line-no">2983</span><span id="line-2983">    TableState ts = getTableStateManager().getTableState(tableName);</span>
+<span class="source-line-no">2984</span><span id="line-2984">    if (!ts.isDisabled()) {</span>
+<span class="source-line-no">2985</span><span id="line-2985">      throw new TableNotDisabledException("Not DISABLED; " + ts);</span>
+<span class="source-line-no">2986</span><span id="line-2986">    }</span>
 <span class="source-line-no">2987</span><span id="line-2987">  }</span>
 <span class="source-line-no">2988</span><span id="line-2988"></span>
-<span class="source-line-no">2989</span><span id="line-2989">  public ClusterMetrics getClusterMetricsWithoutCoprocessor(EnumSet&lt;Option&gt; options)</span>
-<span class="source-line-no">2990</span><span id="line-2990">    throws InterruptedIOException {</span>
-<span class="source-line-no">2991</span><span id="line-2991">    ClusterMetricsBuilder builder = ClusterMetricsBuilder.newBuilder();</span>
-<span class="source-line-no">2992</span><span id="line-2992">    // given that hbase1 can't submit the request with Option,</span>
-<span class="source-line-no">2993</span><span id="line-2993">    // we return all information to client if the list of Option is empty.</span>
-<span class="source-line-no">2994</span><span id="line-2994">    if (options.isEmpty()) {</span>
-<span class="source-line-no">2995</span><span id="line-2995">      options = EnumSet.allOf(Option.class);</span>
-<span class="source-line-no">2996</span><span id="line-2996">    }</span>
-<span class="source-line-no">2997</span><span id="line-2997"></span>
-<span class="source-line-no">2998</span><span id="line-2998">    // TASKS and/or LIVE_SERVERS will populate this map, which will be given to the builder if</span>
-<span class="source-line-no">2999</span><span id="line-2999">    // not null after option processing completes.</span>
-<span class="source-line-no">3000</span><span id="line-3000">    Map&lt;ServerName, ServerMetrics&gt; serverMetricsMap = null;</span>
+<span class="source-line-no">2989</span><span id="line-2989">  public ClusterMetrics getClusterMetricsWithoutCoprocessor() throws InterruptedIOException {</span>
+<span class="source-line-no">2990</span><span id="line-2990">    return getClusterMetricsWithoutCoprocessor(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">2991</span><span id="line-2991">  }</span>
+<span class="source-line-no">2992</span><span id="line-2992"></span>
+<span class="source-line-no">2993</span><span id="line-2993">  public ClusterMetrics getClusterMetricsWithoutCoprocessor(EnumSet&lt;Option&gt; options)</span>
+<span class="source-line-no">2994</span><span id="line-2994">    throws InterruptedIOException {</span>
+<span class="source-line-no">2995</span><span id="line-2995">    ClusterMetricsBuilder builder = ClusterMetricsBuilder.newBuilder();</span>
+<span class="source-line-no">2996</span><span id="line-2996">    // given that hbase1 can't submit the request with Option,</span>
+<span class="source-line-no">2997</span><span id="line-2997">    // we return all information to client if the list of Option is empty.</span>
+<span class="source-line-no">2998</span><span id="line-2998">    if (options.isEmpty()) {</span>
+<span class="source-line-no">2999</span><span id="line-2999">      options = EnumSet.allOf(Option.class);</span>
+<span class="source-line-no">3000</span><span id="line-3000">    }</span>
 <span class="source-line-no">3001</span><span id="line-3001"></span>
-<span class="source-line-no">3002</span><span id="line-3002">    for (Option opt : options) {</span>
-<span class="source-line-no">3003</span><span id="line-3003">      switch (opt) {</span>
-<span class="source-line-no">3004</span><span id="line-3004">        case HBASE_VERSION:</span>
-<span class="source-line-no">3005</span><span id="line-3005">          builder.setHBaseVersion(VersionInfo.getVersion());</span>
-<span class="source-line-no">3006</span><span id="line-3006">          break;</span>
-<span class="source-line-no">3007</span><span id="line-3007">        case CLUSTER_ID:</span>
-<span class="source-line-no">3008</span><span id="line-3008">          builder.setClusterId(getClusterId());</span>
-<span class="source-line-no">3009</span><span id="line-3009">          break;</span>
-<span class="source-line-no">3010</span><span id="line-3010">        case MASTER:</span>
-<span class="source-line-no">3011</span><span id="line-3011">          builder.setMasterName(getServerName());</span>
-<span class="source-line-no">3012</span><span id="line-3012">          break;</span>
-<span class="source-line-no">3013</span><span id="line-3013">        case BACKUP_MASTERS:</span>
-<span class="source-line-no">3014</span><span id="line-3014">          builder.setBackerMasterNames(getBackupMasters());</span>
-<span class="source-line-no">3015</span><span id="line-3015">          break;</span>
-<span class="source-line-no">3016</span><span id="line-3016">        case TASKS: {</span>
-<span class="source-line-no">3017</span><span id="line-3017">          // Master tasks</span>
-<span class="source-line-no">3018</span><span id="line-3018">          builder.setMasterTasks(TaskMonitor.get().getTasks().stream()</span>
-<span class="source-line-no">3019</span><span id="line-3019">            .map(task -&gt; ServerTaskBuilder.newBuilder().setDescription(task.getDescription())</span>
-<span class="source-line-no">3020</span><span id="line-3020">              .setStatus(task.getStatus())</span>
-<span class="source-line-no">3021</span><span id="line-3021">              .setState(ServerTask.State.valueOf(task.getState().name()))</span>
-<span class="source-line-no">3022</span><span id="line-3022">              .setStartTime(task.getStartTime()).setCompletionTime(task.getCompletionTimestamp())</span>
-<span class="source-line-no">3023</span><span id="line-3023">              .build())</span>
-<span class="source-line-no">3024</span><span id="line-3024">            .collect(Collectors.toList()));</span>
-<span class="source-line-no">3025</span><span id="line-3025">          // TASKS is also synonymous with LIVE_SERVERS for now because task information for</span>
-<span class="source-line-no">3026</span><span id="line-3026">          // regionservers is carried in ServerLoad.</span>
-<span class="source-line-no">3027</span><span id="line-3027">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
-<span class="source-line-no">3028</span><span id="line-3028">          if (serverMetricsMap == null) {</span>
-<span class="source-line-no">3029</span><span id="line-3029">            serverMetricsMap = getOnlineServers();</span>
-<span class="source-line-no">3030</span><span id="line-3030">          }</span>
-<span class="source-line-no">3031</span><span id="line-3031">          break;</span>
-<span class="source-line-no">3032</span><span id="line-3032">        }</span>
-<span class="source-line-no">3033</span><span id="line-3033">        case LIVE_SERVERS: {</span>
-<span class="source-line-no">3034</span><span id="line-3034">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
-<span class="source-line-no">3035</span><span id="line-3035">          if (serverMetricsMap == null) {</span>
-<span class="source-line-no">3036</span><span id="line-3036">            serverMetricsMap = getOnlineServers();</span>
-<span class="source-line-no">3037</span><span id="line-3037">          }</span>
-<span class="source-line-no">3038</span><span id="line-3038">          break;</span>
-<span class="source-line-no">3039</span><span id="line-3039">        }</span>
-<span class="source-line-no">3040</span><span id="line-3040">        case DEAD_SERVERS: {</span>
-<span class="source-line-no">3041</span><span id="line-3041">          if (serverManager != null) {</span>
-<span class="source-line-no">3042</span><span id="line-3042">            builder.setDeadServerNames(</span>
-<span class="source-line-no">3043</span><span id="line-3043">              new ArrayList&lt;&gt;(serverManager.getDeadServers().copyServerNames()));</span>
-<span class="source-line-no">3044</span><span id="line-3044">          }</span>
-<span class="source-line-no">3045</span><span id="line-3045">          break;</span>
-<span class="source-line-no">3046</span><span id="line-3046">        }</span>
-<span class="source-line-no">3047</span><span id="line-3047">        case UNKNOWN_SERVERS: {</span>
-<span class="source-line-no">3048</span><span id="line-3048">          if (serverManager != null) {</span>
-<span class="source-line-no">3049</span><span id="line-3049">            builder.setUnknownServerNames(getUnknownServers());</span>
-<span class="source-line-no">3050</span><span id="line-3050">          }</span>
-<span class="source-line-no">3051</span><span id="line-3051">          break;</span>
-<span class="source-line-no">3052</span><span id="line-3052">        }</span>
-<span class="source-line-no">3053</span><span id="line-3053">        case MASTER_COPROCESSORS: {</span>
-<span class="source-line-no">3054</span><span id="line-3054">          if (cpHost != null) {</span>
-<span class="source-line-no">3055</span><span id="line-3055">            builder.setMasterCoprocessorNames(Arrays.asList(getMasterCoprocessors()));</span>
-<span class="source-line-no">3056</span><span id="line-3056">          }</span>
-<span class="source-line-no">3057</span><span id="line-3057">          break;</span>
-<span class="source-line-no">3058</span><span id="line-3058">        }</span>
-<span class="source-line-no">3059</span><span id="line-3059">        case REGIONS_IN_TRANSITION: {</span>
-<span class="source-line-no">3060</span><span id="line-3060">          if (assignmentManager != null) {</span>
-<span class="source-line-no">3061</span><span id="line-3061">            builder.setRegionsInTransition(</span>
-<span class="source-line-no">3062</span><span id="line-3062">              assignmentManager.getRegionStates().getRegionsStateInTransition());</span>
-<span class="source-line-no">3063</span><span id="line-3063">          }</span>
-<span class="source-line-no">3064</span><span id="line-3064">          break;</span>
-<span class="source-line-no">3065</span><span id="line-3065">        }</span>
-<span class="source-line-no">3066</span><span id="line-3066">        case BALANCER_ON: {</span>
-<span class="source-line-no">3067</span><span id="line-3067">          if (loadBalancerStateStore != null) {</span>
-<span class="source-line-no">3068</span><span id="line-3068">            builder.setBalancerOn(loadBalancerStateStore.get());</span>
-<span class="source-line-no">3069</span><span id="line-3069">          }</span>
-<span class="source-line-no">3070</span><span id="line-3070">          break;</span>
-<span class="source-line-no">3071</span><span id="line-3071">        }</span>
-<span class="source-line-no">3072</span><span id="line-3072">        case MASTER_INFO_PORT: {</span>
-<span class="source-line-no">3073</span><span id="line-3073">          if (infoServer != null) {</span>
-<span class="source-line-no">3074</span><span id="line-3074">            builder.setMasterInfoPort(infoServer.getPort());</span>
-<span class="source-line-no">3075</span><span id="line-3075">          }</span>
-<span class="source-line-no">3076</span><span id="line-3076">          break;</span>
-<span class="source-line-no">3077</span><span id="line-3077">        }</span>
-<span class="source-line-no">3078</span><span id="line-3078">        case SERVERS_NAME: {</span>
-<span class="source-line-no">3079</span><span id="line-3079">          if (serverManager != null) {</span>
-<span class="source-line-no">3080</span><span id="line-3080">            builder.setServerNames(serverManager.getOnlineServersList());</span>
-<span class="source-line-no">3081</span><span id="line-3081">          }</span>
-<span class="source-line-no">3082</span><span id="line-3082">          break;</span>
-<span class="source-line-no">3083</span><span id="line-3083">        }</span>
-<span class="source-line-no">3084</span><span id="line-3084">        case TABLE_TO_REGIONS_COUNT: {</span>
-<span class="source-line-no">3085</span><span id="line-3085">          if (isActiveMaster() &amp;&amp; isInitialized() &amp;&amp; assignmentManager != null) {</span>
-<span class="source-line-no">3086</span><span id="line-3086">            try {</span>
-<span class="source-line-no">3087</span><span id="line-3087">              Map&lt;TableName, RegionStatesCount&gt; tableRegionStatesCountMap = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">3088</span><span id="line-3088">              Map&lt;String, TableDescriptor&gt; tableDescriptorMap = getTableDescriptors().getAll();</span>
-<span class="source-line-no">3089</span><span id="line-3089">              for (TableDescriptor tableDescriptor : tableDescriptorMap.values()) {</span>
-<span class="source-line-no">3090</span><span id="line-3090">                TableName tableName = tableDescriptor.getTableName();</span>
-<span class="source-line-no">3091</span><span id="line-3091">                RegionStatesCount regionStatesCount =</span>
-<span class="source-line-no">3092</span><span id="line-3092">                  assignmentManager.getRegionStatesCount(tableName);</span>
-<span class="source-line-no">3093</span><span id="line-3093">                tableRegionStatesCountMap.put(tableName, regionStatesCount);</span>
-<span class="source-line-no">3094</span><span id="line-3094">              }</span>
-<span class="source-line-no">3095</span><span id="line-3095">              builder.setTableRegionStatesCount(tableRegionStatesCountMap);</span>
-<span class="source-line-no">3096</span><span id="line-3096">            } catch (IOException e) {</span>
-<span class="source-line-no">3097</span><span id="line-3097">              LOG.error("Error while populating TABLE_TO_REGIONS_COUNT for Cluster Metrics..", e);</span>
-<span class="source-line-no">3098</span><span id="line-3098">            }</span>
-<span class="source-line-no">3099</span><span id="line-3099">          }</span>
-<span class="source-line-no">3100</span><span id="line-3100">          break;</span>
-<span class="source-line-no">3101</span><span id="line-3101">        }</span>
-<span class="source-line-no">3102</span><span id="line-3102">        case DECOMMISSIONED_SERVERS: {</span>
-<span class="source-line-no">3103</span><span id="line-3103">          if (serverManager != null) {</span>
-<span class="source-line-no">3104</span><span id="line-3104">            builder.setDecommissionedServerNames(serverManager.getDrainingServersList());</span>
-<span class="source-line-no">3105</span><span id="line-3105">          }</span>
-<span class="source-line-no">3106</span><span id="line-3106">          break;</span>
-<span class="source-line-no">3107</span><span id="line-3107">        }</span>
-<span class="source-line-no">3108</span><span id="line-3108">      }</span>
-<span class="source-line-no">3109</span><span id="line-3109">    }</span>
-<span class="source-line-no">3110</span><span id="line-3110"></span>
-<span class="source-line-no">3111</span><span id="line-3111">    if (serverMetricsMap != null) {</span>
-<span class="source-line-no">3112</span><span id="line-3112">      builder.setLiveServerMetrics(serverMetricsMap);</span>
+<span class="source-line-no">3002</span><span id="line-3002">    // TASKS and/or LIVE_SERVERS will populate this map, which will be given to the builder if</span>
+<span class="source-line-no">3003</span><span id="line-3003">    // not null after option processing completes.</span>
+<span class="source-line-no">3004</span><span id="line-3004">    Map&lt;ServerName, ServerMetrics&gt; serverMetricsMap = null;</span>
+<span class="source-line-no">3005</span><span id="line-3005"></span>
+<span class="source-line-no">3006</span><span id="line-3006">    for (Option opt : options) {</span>
+<span class="source-line-no">3007</span><span id="line-3007">      switch (opt) {</span>
+<span class="source-line-no">3008</span><span id="line-3008">        case HBASE_VERSION:</span>
+<span class="source-line-no">3009</span><span id="line-3009">          builder.setHBaseVersion(VersionInfo.getVersion());</span>
+<span class="source-line-no">3010</span><span id="line-3010">          break;</span>
+<span class="source-line-no">3011</span><span id="line-3011">        case CLUSTER_ID:</span>
+<span class="source-line-no">3012</span><span id="line-3012">          builder.setClusterId(getClusterId());</span>
+<span class="source-line-no">3013</span><span id="line-3013">          break;</span>
+<span class="source-line-no">3014</span><span id="line-3014">        case MASTER:</span>
+<span class="source-line-no">3015</span><span id="line-3015">          builder.setMasterName(getServerName());</span>
+<span class="source-line-no">3016</span><span id="line-3016">          break;</span>
+<span class="source-line-no">3017</span><span id="line-3017">        case BACKUP_MASTERS:</span>
+<span class="source-line-no">3018</span><span id="line-3018">          builder.setBackerMasterNames(getBackupMasters());</span>
+<span class="source-line-no">3019</span><span id="line-3019">          break;</span>
+<span class="source-line-no">3020</span><span id="line-3020">        case TASKS: {</span>
+<span class="source-line-no">3021</span><span id="line-3021">          // Master tasks</span>
+<span class="source-line-no">3022</span><span id="line-3022">          builder.setMasterTasks(TaskMonitor.get().getTasks().stream()</span>
+<span class="source-line-no">3023</span><span id="line-3023">            .map(task -&gt; ServerTaskBuilder.newBuilder().setDescription(task.getDescription())</span>
+<span class="source-line-no">3024</span><span id="line-3024">              .setStatus(task.getStatus())</span>
+<span class="source-line-no">3025</span><span id="line-3025">              .setState(ServerTask.State.valueOf(task.getState().name()))</span>
+<span class="source-line-no">3026</span><span id="line-3026">              .setStartTime(task.getStartTime()).setCompletionTime(task.getCompletionTimestamp())</span>
+<span class="source-line-no">3027</span><span id="line-3027">              .build())</span>
+<span class="source-line-no">3028</span><span id="line-3028">            .collect(Collectors.toList()));</span>
+<span class="source-line-no">3029</span><span id="line-3029">          // TASKS is also synonymous with LIVE_SERVERS for now because task information for</span>
+<span class="source-line-no">3030</span><span id="line-3030">          // regionservers is carried in ServerLoad.</span>
+<span class="source-line-no">3031</span><span id="line-3031">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
+<span class="source-line-no">3032</span><span id="line-3032">          if (serverMetricsMap == null) {</span>
+<span class="source-line-no">3033</span><span id="line-3033">            serverMetricsMap = getOnlineServers();</span>
+<span class="source-line-no">3034</span><span id="line-3034">          }</span>
+<span class="source-line-no">3035</span><span id="line-3035">          break;</span>
+<span class="source-line-no">3036</span><span id="line-3036">        }</span>
+<span class="source-line-no">3037</span><span id="line-3037">        case LIVE_SERVERS: {</span>
+<span class="source-line-no">3038</span><span id="line-3038">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
+<span class="source-line-no">3039</span><span id="line-3039">          if (serverMetricsMap == null) {</span>
+<span class="source-line-no">3040</span><span id="line-3040">            serverMetricsMap = getOnlineServers();</span>
+<span class="source-line-no">3041</span><span id="line-3041">          }</span>
+<span class="source-line-no">3042</span><span id="line-3042">          break;</span>
+<span class="source-line-no">3043</span><span id="line-3043">        }</span>
+<span class="source-line-no">3044</span><span id="line-3044">        case DEAD_SERVERS: {</span>
+<span class="source-line-no">3045</span><span id="line-3045">          if (serverManager != null) {</span>
+<span class="source-line-no">3046</span><span id="line-3046">            builder.setDeadServerNames(</span>
+<span class="source-line-no">3047</span><span id="line-3047">              new ArrayList&lt;&gt;(serverManager.getDeadServers().copyServerNames()));</span>
+<span class="source-line-no">3048</span><span id="line-3048">          }</span>
+<span class="source-line-no">3049</span><span id="line-3049">          break;</span>
+<span class="source-line-no">3050</span><span id="line-3050">        }</span>
+<span class="source-line-no">3051</span><span id="line-3051">        case UNKNOWN_SERVERS: {</span>
+<span class="source-line-no">3052</span><span id="line-3052">          if (serverManager != null) {</span>
+<span class="source-line-no">3053</span><span id="line-3053">            builder.setUnknownServerNames(getUnknownServers());</span>
+<span class="source-line-no">3054</span><span id="line-3054">          }</span>
+<span class="source-line-no">3055</span><span id="line-3055">          break;</span>
+<span class="source-line-no">3056</span><span id="line-3056">        }</span>
+<span class="source-line-no">3057</span><span id="line-3057">        case MASTER_COPROCESSORS: {</span>
+<span class="source-line-no">3058</span><span id="line-3058">          if (cpHost != null) {</span>
+<span class="source-line-no">3059</span><span id="line-3059">            builder.setMasterCoprocessorNames(Arrays.asList(getMasterCoprocessors()));</span>
+<span class="source-line-no">3060</span><span id="line-3060">          }</span>
+<span class="source-line-no">3061</span><span id="line-3061">          break;</span>
+<span class="source-line-no">3062</span><span id="line-3062">        }</span>
+<span class="source-line-no">3063</span><span id="line-3063">        case REGIONS_IN_TRANSITION: {</span>
+<span class="source-line-no">3064</span><span id="line-3064">          if (assignmentManager != null) {</span>
+<span class="source-line-no">3065</span><span id="line-3065">            builder.setRegionsInTransition(</span>
+<span class="source-line-no">3066</span><span id="line-3066">              assignmentManager.getRegionStates().getRegionsStateInTransition());</span>
+<span class="source-line-no">3067</span><span id="line-3067">          }</span>
+<span class="source-line-no">3068</span><span id="line-3068">          break;</span>
+<span class="source-line-no">3069</span><span id="line-3069">        }</span>
+<span class="source-line-no">3070</span><span id="line-3070">        case BALANCER_ON: {</span>
+<span class="source-line-no">3071</span><span id="line-3071">          if (loadBalancerStateStore != null) {</span>
+<span class="source-line-no">3072</span><span id="line-3072">            builder.setBalancerOn(loadBalancerStateStore.get());</span>
+<span class="source-line-no">3073</span><span id="line-3073">          }</span>
+<span class="source-line-no">3074</span><span id="line-3074">          break;</span>
+<span class="source-line-no">3075</span><span id="line-3075">        }</span>
+<span class="source-line-no">3076</span><span id="line-3076">        case MASTER_INFO_PORT: {</span>
+<span class="source-line-no">3077</span><span id="line-3077">          if (infoServer != null) {</span>
+<span class="source-line-no">3078</span><span id="line-3078">            builder.setMasterInfoPort(infoServer.getPort());</span>
+<span class="source-line-no">3079</span><span id="line-3079">          }</span>
+<span class="source-line-no">3080</span><span id="line-3080">          break;</span>
+<span class="source-line-no">3081</span><span id="line-3081">        }</span>
+<span class="source-line-no">3082</span><span id="line-3082">        case SERVERS_NAME: {</span>
+<span class="source-line-no">3083</span><span id="line-3083">          if (serverManager != null) {</span>
+<span class="source-line-no">3084</span><span id="line-3084">            builder.setServerNames(serverManager.getOnlineServersList());</span>
+<span class="source-line-no">3085</span><span id="line-3085">          }</span>
+<span class="source-line-no">3086</span><span id="line-3086">          break;</span>
+<span class="source-line-no">3087</span><span id="line-3087">        }</span>
+<span class="source-line-no">3088</span><span id="line-3088">        case TABLE_TO_REGIONS_COUNT: {</span>
+<span class="source-line-no">3089</span><span id="line-3089">          if (isActiveMaster() &amp;&amp; isInitialized() &amp;&amp; assignmentManager != null) {</span>
+<span class="source-line-no">3090</span><span id="line-3090">            try {</span>
+<span class="source-line-no">3091</span><span id="line-3091">              Map&lt;TableName, RegionStatesCount&gt; tableRegionStatesCountMap = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">3092</span><span id="line-3092">              Map&lt;String, TableDescriptor&gt; tableDescriptorMap = getTableDescriptors().getAll();</span>
+<span class="source-line-no">3093</span><span id="line-3093">              for (TableDescriptor tableDescriptor : tableDescriptorMap.values()) {</span>
+<span class="source-line-no">3094</span><span id="line-3094">                TableName tableName = tableDescriptor.getTableName();</span>
+<span class="source-line-no">3095</span><span id="line-3095">                RegionStatesCount regionStatesCount =</span>
+<span class="source-line-no">3096</span><span id="line-3096">                  assignmentManager.getRegionStatesCount(tableName);</span>
+<span class="source-line-no">3097</span><span id="line-3097">                tableRegionStatesCountMap.put(tableName, regionStatesCount);</span>
+<span class="source-line-no">3098</span><span id="line-3098">              }</span>
+<span class="source-line-no">3099</span><span id="line-3099">              builder.setTableRegionStatesCount(tableRegionStatesCountMap);</span>
+<span class="source-line-no">3100</span><span id="line-3100">            } catch (IOException e) {</span>
+<span class="source-line-no">3101</span><span id="line-3101">              LOG.error("Error while populating TABLE_TO_REGIONS_COUNT for Cluster Metrics..", e);</span>
+<span class="source-line-no">3102</span><span id="line-3102">            }</span>
+<span class="source-line-no">3103</span><span id="line-3103">          }</span>
+<span class="source-line-no">3104</span><span id="line-3104">          break;</span>
+<span class="source-line-no">3105</span><span id="line-3105">        }</span>
+<span class="source-line-no">3106</span><span id="line-3106">        case DECOMMISSIONED_SERVERS: {</span>
+<span class="source-line-no">3107</span><span id="line-3107">          if (serverManager != null) {</span>
+<span class="source-line-no">3108</span><span id="line-3108">            builder.setDecommissionedServerNames(serverManager.getDrainingServersList());</span>
+<span class="source-line-no">3109</span><span id="line-3109">          }</span>
+<span class="source-line-no">3110</span><span id="line-3110">          break;</span>
+<span class="source-line-no">3111</span><span id="line-3111">        }</span>
+<span class="source-line-no">3112</span><span id="line-3112">      }</span>
 <span class="source-line-no">3113</span><span id="line-3113">    }</span>
 <span class="source-line-no">3114</span><span id="line-3114"></span>
-<span class="source-line-no">3115</span><span id="line-3115">    return builder.build();</span>
-<span class="source-line-no">3116</span><span id="line-3116">  }</span>
-<span class="source-line-no">3117</span><span id="line-3117"></span>
-<span class="source-line-no">3118</span><span id="line-3118">  private List&lt;ServerName&gt; getUnknownServers() {</span>
-<span class="source-line-no">3119</span><span id="line-3119">    if (serverManager != null) {</span>
-<span class="source-line-no">3120</span><span id="line-3120">      final Set&lt;ServerName&gt; serverNames = getAssignmentManager().getRegionStates().getRegionStates()</span>
-<span class="source-line-no">3121</span><span id="line-3121">        .stream().map(RegionState::getServerName).collect(Collectors.toSet());</span>
-<span class="source-line-no">3122</span><span id="line-3122">      final List&lt;ServerName&gt; unknownServerNames = serverNames.stream()</span>
-<span class="source-line-no">3123</span><span id="line-3123">        .filter(sn -&gt; sn != null &amp;&amp; serverManager.isServerUnknown(sn)).collect(Collectors.toList());</span>
-<span class="source-line-no">3124</span><span id="line-3124">      return unknownServerNames;</span>
-<span class="source-line-no">3125</span><span id="line-3125">    }</span>
-<span class="source-line-no">3126</span><span id="line-3126">    return null;</span>
-<span class="source-line-no">3127</span><span id="line-3127">  }</span>
-<span class="source-line-no">3128</span><span id="line-3128"></span>
-<span class="source-line-no">3129</span><span id="line-3129">  private Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {</span>
-<span class="source-line-no">3130</span><span id="line-3130">    if (serverManager != null) {</span>
-<span class="source-line-no">3131</span><span id="line-3131">      final Map&lt;ServerName, ServerMetrics&gt; map = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">3132</span><span id="line-3132">      serverManager.getOnlineServers().entrySet().forEach(e -&gt; map.put(e.getKey(), e.getValue()));</span>
-<span class="source-line-no">3133</span><span id="line-3133">      return map;</span>
-<span class="source-line-no">3134</span><span id="line-3134">    }</span>
-<span class="source-line-no">3135</span><span id="line-3135">    return null;</span>
-<span class="source-line-no">3136</span><span id="line-3136">  }</span>
-<span class="source-line-no">3137</span><span id="line-3137"></span>
-<span class="source-line-no">3138</span><span id="line-3138">  /** Returns cluster status */</span>
-<span class="source-line-no">3139</span><span id="line-3139">  public ClusterMetrics getClusterMetrics() throws IOException {</span>
-<span class="source-line-no">3140</span><span id="line-3140">    return getClusterMetrics(EnumSet.allOf(Option.class));</span>
-<span class="source-line-no">3141</span><span id="line-3141">  }</span>
-<span class="source-line-no">3142</span><span id="line-3142"></span>
-<span class="source-line-no">3143</span><span id="line-3143">  public ClusterMetrics getClusterMetrics(EnumSet&lt;Option&gt; options) throws IOException {</span>
-<span class="source-line-no">3144</span><span id="line-3144">    if (cpHost != null) {</span>
-<span class="source-line-no">3145</span><span id="line-3145">      cpHost.preGetClusterMetrics();</span>
-<span class="source-line-no">3146</span><span id="line-3146">    }</span>
-<span class="source-line-no">3147</span><span id="line-3147">    ClusterMetrics status = getClusterMetricsWithoutCoprocessor(options);</span>
+<span class="source-line-no">3115</span><span id="line-3115">    if (serverMetricsMap != null) {</span>
+<span class="source-line-no">3116</span><span id="line-3116">      builder.setLiveServerMetrics(serverMetricsMap);</span>
+<span class="source-line-no">3117</span><span id="line-3117">    }</span>
+<span class="source-line-no">3118</span><span id="line-3118"></span>
+<span class="source-line-no">3119</span><span id="line-3119">    return builder.build();</span>
+<span class="source-line-no">3120</span><span id="line-3120">  }</span>
+<span class="source-line-no">3121</span><span id="line-3121"></span>
+<span class="source-line-no">3122</span><span id="line-3122">  private List&lt;ServerName&gt; getUnknownServers() {</span>
+<span class="source-line-no">3123</span><span id="line-3123">    if (serverManager != null) {</span>
+<span class="source-line-no">3124</span><span id="line-3124">      final Set&lt;ServerName&gt; serverNames = getAssignmentManager().getRegionStates().getRegionStates()</span>
+<span class="source-line-no">3125</span><span id="line-3125">        .stream().map(RegionState::getServerName).collect(Collectors.toSet());</span>
+<span class="source-line-no">3126</span><span id="line-3126">      final List&lt;ServerName&gt; unknownServerNames = serverNames.stream()</span>
+<span class="source-line-no">3127</span><span id="line-3127">        .filter(sn -&gt; sn != null &amp;&amp; serverManager.isServerUnknown(sn)).collect(Collectors.toList());</span>
+<span class="source-line-no">3128</span><span id="line-3128">      return unknownServerNames;</span>
+<span class="source-line-no">3129</span><span id="line-3129">    }</span>
+<span class="source-line-no">3130</span><span id="line-3130">    return null;</span>
+<span class="source-line-no">3131</span><span id="line-3131">  }</span>
+<span class="source-line-no">3132</span><span id="line-3132"></span>
+<span class="source-line-no">3133</span><span id="line-3133">  private Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {</span>
+<span class="source-line-no">3134</span><span id="line-3134">    if (serverManager != null) {</span>
+<span class="source-line-no">3135</span><span id="line-3135">      final Map&lt;ServerName, ServerMetrics&gt; map = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">3136</span><span id="line-3136">      serverManager.getOnlineServers().entrySet().forEach(e -&gt; map.put(e.getKey(), e.getValue()));</span>
+<span class="source-line-no">3137</span><span id="line-3137">      return map;</span>
+<span class="source-line-no">3138</span><span id="line-3138">    }</span>
+<span class="source-line-no">3139</span><span id="line-3139">    return null;</span>
+<span class="source-line-no">3140</span><span id="line-3140">  }</span>
+<span class="source-line-no">3141</span><span id="line-3141"></span>
+<span class="source-line-no">3142</span><span id="line-3142">  /** Returns cluster status */</span>
+<span class="source-line-no">3143</span><span id="line-3143">  public ClusterMetrics getClusterMetrics() throws IOException {</span>
+<span class="source-line-no">3144</span><span id="line-3144">    return getClusterMetrics(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">3145</span><span id="line-3145">  }</span>
+<span class="source-line-no">3146</span><span id="line-3146"></span>
+<span class="source-line-no">3147</span><span id="line-3147">  public ClusterMetrics getClusterMetrics(EnumSet&lt;Option&gt; options) throws IOException {</span>
 <span class="source-line-no">3148</span><span id="line-3148">    if (cpHost != null) {</span>
-<span class="source-line-no">3149</span><span id="line-3149">      cpHost.postGetClusterMetrics(status);</span>
+<span class="source-line-no">3149</span><span id="line-3149">      cpHost.preGetClusterMetrics();</span>
 <span class="source-line-no">3150</span><span id="line-3150">    }</span>
-<span class="source-line-no">3151</span><span id="line-3151">    return status;</span>
-<span class="source-line-no">3152</span><span id="line-3152">  }</span>
-<span class="source-line-no">3153</span><span id="line-3153"></span>
-<span class="source-line-no">3154</span><span id="line-3154">  /** Returns info port of active master or 0 if any exception occurs. */</span>
-<span class="source-line-no">3155</span><span id="line-3155">  public int getActiveMasterInfoPort() {</span>
-<span class="source-line-no">3156</span><span id="line-3156">    return activeMasterManager.getActiveMasterInfoPort();</span>
-<span class="source-line-no">3157</span><span id="line-3157">  }</span>
-<span class="source-line-no">3158</span><span id="line-3158"></span>
-<span class="source-line-no">3159</span><span id="line-3159">  /**</span>
-<span class="source-line-no">3160</span><span id="line-3160">   * @param sn is ServerName of the backup master</span>
-<span class="source-line-no">3161</span><span id="line-3161">   * @return info port of backup master or 0 if any exception occurs.</span>
-<span class="source-line-no">3162</span><span id="line-3162">   */</span>
-<span class="source-line-no">3163</span><span id="line-3163">  public int getBackupMasterInfoPort(final ServerName sn) {</span>
-<span class="source-line-no">3164</span><span id="line-3164">    return activeMasterManager.getBackupMasterInfoPort(sn);</span>
-<span class="source-line-no">3165</span><span id="line-3165">  }</span>
-<span class="source-line-no">3166</span><span id="line-3166"></span>
-<span class="source-line-no">3167</span><span id="line-3167">  /**</span>
-<span class="source-line-no">3168</span><span id="line-3168">   * The set of loaded coprocessors is stored in a static set. Since it's statically allocated, it</span>
-<span class="source-line-no">3169</span><span id="line-3169">   * does not require that HMaster's cpHost be initialized prior to accessing it.</span>
-<span class="source-line-no">3170</span><span id="line-3170">   * @return a String representation of the set of names of the loaded coprocessors.</span>
-<span class="source-line-no">3171</span><span id="line-3171">   */</span>
-<span class="source-line-no">3172</span><span id="line-3172">  public static String getLoadedCoprocessors() {</span>
-<span class="source-line-no">3173</span><span id="line-3173">    return CoprocessorHost.getLoadedCoprocessors().toString();</span>
-<span class="source-line-no">3174</span><span id="line-3174">  }</span>
-<span class="source-line-no">3175</span><span id="line-3175"></span>
-<span class="source-line-no">3176</span><span id="line-3176">  /** Returns timestamp in millis when HMaster was started. */</span>
-<span class="source-line-no">3177</span><span id="line-3177">  public long getMasterStartTime() {</span>
-<span class="source-line-no">3178</span><span id="line-3178">    return startcode;</span>
-<span class="source-line-no">3179</span><span id="line-3179">  }</span>
-<span class="source-line-no">3180</span><span id="line-3180"></span>
-<span class="source-line-no">3181</span><span id="line-3181">  /** Returns timestamp in millis when HMaster became the active master. */</span>
-<span class="source-line-no">3182</span><span id="line-3182">  @Override</span>
-<span class="source-line-no">3183</span><span id="line-3183">  public long getMasterActiveTime() {</span>
-<span class="source-line-no">3184</span><span id="line-3184">    return masterActiveTime;</span>
-<span class="source-line-no">3185</span><span id="line-3185">  }</span>
-<span class="source-line-no">3186</span><span id="line-3186"></span>
-<span class="source-line-no">3187</span><span id="line-3187">  /** Returns timestamp in millis when HMaster finished becoming the active master */</span>
-<span class="source-line-no">3188</span><span id="line-3188">  public long getMasterFinishedInitializationTime() {</span>
-<span class="source-line-no">3189</span><span id="line-3189">    return masterFinishedInitializationTime;</span>
-<span class="source-line-no">3190</span><span id="line-3190">  }</span>
-<span class="source-line-no">3191</span><span id="line-3191"></span>
-<span class="source-line-no">3192</span><span id="line-3192">  public int getNumWALFiles() {</span>
-<span class="source-line-no">3193</span><span id="line-3193">    return 0;</span>
+<span class="source-line-no">3151</span><span id="line-3151">    ClusterMetrics status = getClusterMetricsWithoutCoprocessor(options);</span>
+<span class="source-line-no">3152</span><span id="line-3152">    if (cpHost != null) {</span>
+<span class="source-line-no">3153</span><span id="line-3153">      cpHost.postGetClusterMetrics(status);</span>
+<span class="source-line-no">3154</span><span id="line-3154">    }</span>
+<span class="source-line-no">3155</span><span id="line-3155">    return status;</span>
+<span class="source-line-no">3156</span><span id="line-3156">  }</span>
+<span class="source-line-no">3157</span><span id="line-3157"></span>
+<span class="source-line-no">3158</span><span id="line-3158">  /** Returns info port of active master or 0 if any exception occurs. */</span>
+<span class="source-line-no">3159</span><span id="line-3159">  public int getActiveMasterInfoPort() {</span>
+<span class="source-line-no">3160</span><span id="line-3160">    return activeMasterManager.getActiveMasterInfoPort();</span>
+<span class="source-line-no">3161</span><span id="line-3161">  }</span>
+<span class="source-line-no">3162</span><span id="line-3162"></span>
+<span class="source-line-no">3163</span><span id="line-3163">  /**</span>
+<span class="source-line-no">3164</span><span id="line-3164">   * @param sn is ServerName of the backup master</span>
+<span class="source-line-no">3165</span><span id="line-3165">   * @return info port of backup master or 0 if any exception occurs.</span>
+<span class="source-line-no">3166</span><span id="line-3166">   */</span>
+<span class="source-line-no">3167</span><span id="line-3167">  public int getBackupMasterInfoPort(final ServerName sn) {</span>
+<span class="source-line-no">3168</span><span id="line-3168">    return activeMasterManager.getBackupMasterInfoPort(sn);</span>
+<span class="source-line-no">3169</span><span id="line-3169">  }</span>
+<span class="source-line-no">3170</span><span id="line-3170"></span>
+<span class="source-line-no">3171</span><span id="line-3171">  /**</span>
+<span class="source-line-no">3172</span><span id="line-3172">   * The set of loaded coprocessors is stored in a static set. Since it's statically allocated, it</span>
+<span class="source-line-no">3173</span><span id="line-3173">   * does not require that HMaster's cpHost be initialized prior to accessing it.</span>
+<span class="source-line-no">3174</span><span id="line-3174">   * @return a String representation of the set of names of the loaded coprocessors.</span>
+<span class="source-line-no">3175</span><span id="line-3175">   */</span>
+<span class="source-line-no">3176</span><span id="line-3176">  public static String getLoadedCoprocessors() {</span>
+<span class="source-line-no">3177</span><span id="line-3177">    return CoprocessorHost.getLoadedCoprocessors().toString();</span>
+<span class="source-line-no">3178</span><span id="line-3178">  }</span>
+<span class="source-line-no">3179</span><span id="line-3179"></span>
+<span class="source-line-no">3180</span><span id="line-3180">  /** Returns timestamp in millis when HMaster was started. */</span>
+<span class="source-line-no">3181</span><span id="line-3181">  public long getMasterStartTime() {</span>
+<span class="source-line-no">3182</span><span id="line-3182">    return startcode;</span>
+<span class="source-line-no">3183</span><span id="line-3183">  }</span>
+<span class="source-line-no">3184</span><span id="line-3184"></span>
+<span class="source-line-no">3185</span><span id="line-3185">  /** Returns timestamp in millis when HMaster became the active master. */</span>
+<span class="source-line-no">3186</span><span id="line-3186">  @Override</span>
+<span class="source-line-no">3187</span><span id="line-3187">  public long getMasterActiveTime() {</span>
+<span class="source-line-no">3188</span><span id="line-3188">    return masterActiveTime;</span>
+<span class="source-line-no">3189</span><span id="line-3189">  }</span>
+<span class="source-line-no">3190</span><span id="line-3190"></span>
+<span class="source-line-no">3191</span><span id="line-3191">  /** Returns timestamp in millis when HMaster finished becoming the active master */</span>
+<span class="source-line-no">3192</span><span id="line-3192">  public long getMasterFinishedInitializationTime() {</span>
+<span class="source-line-no">3193</span><span id="line-3193">    return masterFinishedInitializationTime;</span>
 <span class="source-line-no">3194</span><span id="line-3194">  }</span>
 <span class="source-line-no">3195</span><span id="line-3195"></span>
-<span class="source-line-no">3196</span><span id="line-3196">  public ProcedureStore getProcedureStore() {</span>
-<span class="source-line-no">3197</span><span id="line-3197">    return procedureStore;</span>
+<span class="source-line-no">3196</span><span id="line-3196">  public int getNumWALFiles() {</span>
+<span class="source-line-no">3197</span><span id="line-3197">    return 0;</span>
 <span class="source-line-no">3198</span><span id="line-3198">  }</span>
 <span class="source-line-no">3199</span><span id="line-3199"></span>
-<span class="source-line-no">3200</span><span id="line-3200">  public int getRegionServerInfoPort(final ServerName sn) {</span>
-<span class="source-line-no">3201</span><span id="line-3201">    int port = this.serverManager.getInfoPort(sn);</span>
-<span class="source-line-no">3202</span><span id="line-3202">    return port == 0</span>
-<span class="source-line-no">3203</span><span id="line-3203">      ? conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT)</span>
-<span class="source-line-no">3204</span><span id="line-3204">      : port;</span>
-<span class="source-line-no">3205</span><span id="line-3205">  }</span>
-<span class="source-line-no">3206</span><span id="line-3206"></span>
-<span class="source-line-no">3207</span><span id="line-3207">  @Override</span>
-<span class="source-line-no">3208</span><span id="line-3208">  public String getRegionServerVersion(ServerName sn) {</span>
-<span class="source-line-no">3209</span><span id="line-3209">    // Will return "0.0.0" if the server is not online to prevent move system region to unknown</span>
-<span class="source-line-no">3210</span><span id="line-3210">    // version RS.</span>
-<span class="source-line-no">3211</span><span id="line-3211">    return this.serverManager.getVersion(sn);</span>
-<span class="source-line-no">3212</span><span id="line-3212">  }</span>
-<span class="source-line-no">3213</span><span id="line-3213"></span>
-<span class="source-line-no">3214</span><span id="line-3214">  @Override</span>
-<span class="source-line-no">3215</span><span id="line-3215">  public void checkIfShouldMoveSystemRegionAsync() {</span>
-<span class="source-line-no">3216</span><span id="line-3216">    assignmentManager.checkIfShouldMoveSystemRegionAsync();</span>
-<span class="source-line-no">3217</span><span id="line-3217">  }</span>
-<span class="source-line-no">3218</span><span id="line-3218"></span>
-<span class="source-line-no">3219</span><span id="line-3219">  /** Returns array of coprocessor SimpleNames. */</span>
-<span class="source-line-no">3220</span><span id="line-3220">  public String[] getMasterCoprocessors() {</span>
-<span class="source-line-no">3221</span><span id="line-3221">    Set&lt;String&gt; masterCoprocessors = getMasterCoprocessorHost().getCoprocessors();</span>
-<span class="source-line-no">3222</span><span id="line-3222">    return masterCoprocessors.toArray(new String[masterCoprocessors.size()]);</span>
-<span class="source-line-no">3223</span><span id="line-3223">  }</span>
-<span class="source-line-no">3224</span><span id="line-3224"></span>
-<span class="source-line-no">3225</span><span id="line-3225">  @Override</span>
-<span class="source-line-no">3226</span><span id="line-3226">  public void abort(String reason, Throwable cause) {</span>
-<span class="source-line-no">3227</span><span id="line-3227">    if (!setAbortRequested() || isStopped()) {</span>
-<span class="source-line-no">3228</span><span id="line-3228">      LOG.debug("Abort called but aborted={}, stopped={}", isAborted(), isStopped());</span>
-<span class="source-line-no">3229</span><span id="line-3229">      return;</span>
-<span class="source-line-no">3230</span><span id="line-3230">    }</span>
-<span class="source-line-no">3231</span><span id="line-3231">    if (cpHost != null) {</span>
-<span class="source-line-no">3232</span><span id="line-3232">      // HBASE-4014: dump a list of loaded coprocessors.</span>
-<span class="source-line-no">3233</span><span id="line-3233">      LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">3234</span><span id="line-3234">        "Master server abort: loaded coprocessors are: " + getLoadedCoprocessors());</span>
-<span class="source-line-no">3235</span><span id="line-3235">    }</span>
-<span class="source-line-no">3236</span><span id="line-3236">    String msg = "***** ABORTING master " + this + ": " + reason + " *****";</span>
-<span class="source-line-no">3237</span><span id="line-3237">    if (cause != null) {</span>
-<span class="source-line-no">3238</span><span id="line-3238">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
-<span class="source-line-no">3239</span><span id="line-3239">    } else {</span>
-<span class="source-line-no">3240</span><span id="line-3240">      LOG.error(HBaseMarkers.FATAL, msg);</span>
-<span class="source-line-no">3241</span><span id="line-3241">    }</span>
-<span class="source-line-no">3242</span><span id="line-3242"></span>
-<span class="source-line-no">3243</span><span id="line-3243">    try {</span>
-<span class="source-line-no">3244</span><span id="line-3244">      stopMaster();</span>
-<span class="source-line-no">3245</span><span id="line-3245">    } catch (IOException e) {</span>
-<span class="source-line-no">3246</span><span id="line-3246">      LOG.error("Exception occurred while stopping master", e);</span>
-<span class="source-line-no">3247</span><span id="line-3247">    }</span>
-<span class="source-line-no">3248</span><span id="line-3248">  }</span>
-<span class="source-line-no">3249</span><span id="line-3249"></span>
-<span class="source-line-no">3250</span><span id="line-3250">  @Override</span>
-<span class="source-line-no">3251</span><span id="line-3251">  public MasterCoprocessorHost getMasterCoprocessorHost() {</span>
-<span class="source-line-no">3252</span><span id="line-3252">    return cpHost;</span>
-<span class="source-line-no">3253</span><span id="line-3253">  }</span>
-<span class="source-line-no">3254</span><span id="line-3254"></span>
-<span class="source-line-no">3255</span><span id="line-3255">  @Override</span>
-<span class="source-line-no">3256</span><span id="line-3256">  public MasterQuotaManager getMasterQuotaManager() {</span>
-<span class="source-line-no">3257</span><span id="line-3257">    return quotaManager;</span>
-<span class="source-line-no">3258</span><span id="line-3258">  }</span>
-<span class="source-line-no">3259</span><span id="line-3259"></span>
-<span class="source-line-no">3260</span><span id="line-3260">  @Override</span>
-<span class="source-line-no">3261</span><span id="line-3261">  public ProcedureExecutor&lt;MasterProcedureEnv&gt; getMasterProcedureExecutor() {</span>
-<span class="source-line-no">3262</span><span id="line-3262">    return procedureExecutor;</span>
-<span class="source-line-no">3263</span><span id="line-3263">  }</span>
-<span class="source-line-no">3264</span><span id="line-3264"></span>
-<span class="source-line-no">3265</span><span id="line-3265">  @Override</span>
-<span class="source-line-no">3266</span><span id="line-3266">  public ServerName getServerName() {</span>
-<span class="source-line-no">3267</span><span id="line-3267">    return this.serverName;</span>
-<span class="source-line-no">3268</span><span id="line-3268">  }</span>
-<span class="source-line-no">3269</span><span id="line-3269"></span>
-<span class="source-line-no">3270</span><span id="line-3270">  @Override</span>
-<span class="source-line-no">3271</span><span id="line-3271">  public AssignmentManager getAssignmentManager() {</span>
-<span class="source-line-no">3272</span><span id="line-3272">    return this.assignmentManager;</span>
-<span class="source-line-no">3273</span><span id="line-3273">  }</span>
-<span class="source-line-no">3274</span><span id="line-3274"></span>
-<span class="source-line-no">3275</span><span id="line-3275">  @Override</span>
-<span class="source-line-no">3276</span><span id="line-3276">  public CatalogJanitor getCatalogJanitor() {</span>
-<span class="source-line-no">3277</span><span id="line-3277">    return this.catalogJanitorChore;</span>
-<span class="source-line-no">3278</span><span id="line-3278">  }</span>
-<span class="source-line-no">3279</span><span id="line-3279"></span>
-<span class="source-line-no">3280</span><span id="line-3280">  public MemoryBoundedLogMessageBuffer getRegionServerFatalLogBuffer() {</span>
-<span class="source-line-no">3281</span><span id="line-3281">    return rsFatals;</span>
+<span class="source-line-no">3200</span><span id="line-3200">  public ProcedureStore getProcedureStore() {</span>
+<span class="source-line-no">3201</span><span id="line-3201">    return procedureStore;</span>
+<span class="source-line-no">3202</span><span id="line-3202">  }</span>
+<span class="source-line-no">3203</span><span id="line-3203"></span>
+<span class="source-line-no">3204</span><span id="line-3204">  public int getRegionServerInfoPort(final ServerName sn) {</span>
+<span class="source-line-no">3205</span><span id="line-3205">    int port = this.serverManager.getInfoPort(sn);</span>
+<span class="source-line-no">3206</span><span id="line-3206">    return port == 0</span>
+<span class="source-line-no">3207</span><span id="line-3207">      ? conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT)</span>
+<span class="source-line-no">3208</span><span id="line-3208">      : port;</span>
+<span class="source-line-no">3209</span><span id="line-3209">  }</span>
+<span class="source-line-no">3210</span><span id="line-3210"></span>
+<span class="source-line-no">3211</span><span id="line-3211">  @Override</span>
+<span class="source-line-no">3212</span><span id="line-3212">  public String getRegionServerVersion(ServerName sn) {</span>
+<span class="source-line-no">3213</span><span id="line-3213">    // Will return "0.0.0" if the server is not online to prevent move system region to unknown</span>
+<span class="source-line-no">3214</span><span id="line-3214">    // version RS.</span>
+<span class="source-line-no">3215</span><span id="line-3215">    return this.serverManager.getVersion(sn);</span>
+<span class="source-line-no">3216</span><span id="line-3216">  }</span>
+<span class="source-line-no">3217</span><span id="line-3217"></span>
+<span class="source-line-no">3218</span><span id="line-3218">  @Override</span>
+<span class="source-line-no">3219</span><span id="line-3219">  public void checkIfShouldMoveSystemRegionAsync() {</span>
+<span class="source-line-no">3220</span><span id="line-3220">    assignmentManager.checkIfShouldMoveSystemRegionAsync();</span>
+<span class="source-line-no">3221</span><span id="line-3221">  }</span>
+<span class="source-line-no">3222</span><span id="line-3222"></span>
+<span class="source-line-no">3223</span><span id="line-3223">  /** Returns array of coprocessor SimpleNames. */</span>
+<span class="source-line-no">3224</span><span id="line-3224">  public String[] getMasterCoprocessors() {</span>
+<span class="source-line-no">3225</span><span id="line-3225">    Set&lt;String&gt; masterCoprocessors = getMasterCoprocessorHost().getCoprocessors();</span>
+<span class="source-line-no">3226</span><span id="line-3226">    return masterCoprocessors.toArray(new String[masterCoprocessors.size()]);</span>
+<span class="source-line-no">3227</span><span id="line-3227">  }</span>
+<span class="source-line-no">3228</span><span id="line-3228"></span>
+<span class="source-line-no">3229</span><span id="line-3229">  @Override</span>
+<span class="source-line-no">3230</span><span id="line-3230">  public void abort(String reason, Throwable cause) {</span>
+<span class="source-line-no">3231</span><span id="line-3231">    if (!setAbortRequested() || isStopped()) {</span>
+<span class="source-line-no">3232</span><span id="line-3232">      LOG.debug("Abort called but aborted={}, stopped={}", isAborted(), isStopped());</span>
+<span class="source-line-no">3233</span><span id="line-3233">      return;</span>
+<span class="source-line-no">3234</span><span id="line-3234">    }</span>
+<span class="source-line-no">3235</span><span id="line-3235">    if (cpHost != null) {</span>
+<span class="source-line-no">3236</span><span id="line-3236">      // HBASE-4014: dump a list of loaded coprocessors.</span>
+<span class="source-line-no">3237</span><span id="line-3237">      LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">3238</span><span id="line-3238">        "Master server abort: loaded coprocessors are: " + getLoadedCoprocessors());</span>
+<span class="source-line-no">3239</span><span id="line-3239">    }</span>
+<span class="source-line-no">3240</span><span id="line-3240">    String msg = "***** ABORTING master " + this + ": " + reason + " *****";</span>
+<span class="source-line-no">3241</span><span id="line-3241">    if (cause != null) {</span>
+<span class="source-line-no">3242</span><span id="line-3242">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
+<span class="source-line-no">3243</span><span id="line-3243">    } else {</span>
+<span class="source-line-no">3244</span><span id="line-3244">      LOG.error(HBaseMarkers.FATAL, msg);</span>
+<span class="source-line-no">3245</span><span id="line-3245">    }</span>
+<span class="source-line-no">3246</span><span id="line-3246"></span>
+<span class="source-line-no">3247</span><span id="line-3247">    try {</span>
+<span class="source-line-no">3248</span><span id="line-3248">      stopMaster();</span>
+<span class="source-line-no">3249</span><span id="line-3249">    } catch (IOException e) {</span>
+<span class="source-line-no">3250</span><span id="line-3250">      LOG.error("Exception occurred while stopping master", e);</span>
+<span class="source-line-no">3251</span><span id="line-3251">    }</span>
+<span class="source-line-no">3252</span><span id="line-3252">  }</span>
+<span class="source-line-no">3253</span><span id="line-3253"></span>
+<span class="source-line-no">3254</span><span id="line-3254">  @Override</span>
+<span class="source-line-no">3255</span><span id="line-3255">  public MasterCoprocessorHost getMasterCoprocessorHost() {</span>
+<span class="source-line-no">3256</span><span id="line-3256">    return cpHost;</span>
+<span class="source-line-no">3257</span><span id="line-3257">  }</span>
+<span class="source-line-no">3258</span><span id="line-3258"></span>
+<span class="source-line-no">3259</span><span id="line-3259">  @Override</span>
+<span class="source-line-no">3260</span><span id="line-3260">  public MasterQuotaManager getMasterQuotaManager() {</span>
+<span class="source-line-no">3261</span><span id="line-3261">    return quotaManager;</span>
+<span class="source-line-no">3262</span><span id="line-3262">  }</span>
+<span class="source-line-no">3263</span><span id="line-3263"></span>
+<span class="source-line-no">3264</span><span id="line-3264">  @Override</span>
+<span class="source-line-no">3265</span><span id="line-3265">  public ProcedureExecutor&lt;MasterProcedureEnv&gt; getMasterProcedureExecutor() {</span>
+<span class="source-line-no">3266</span><span id="line-3266">    return procedureExecutor;</span>
+<span class="source-line-no">3267</span><span id="line-3267">  }</span>
+<span class="source-line-no">3268</span><span id="line-3268"></span>
+<span class="source-line-no">3269</span><span id="line-3269">  @Override</span>
+<span class="source-line-no">3270</span><span id="line-3270">  public ServerName getServerName() {</span>
+<span class="source-line-no">3271</span><span id="line-3271">    return this.serverName;</span>
+<span class="source-line-no">3272</span><span id="line-3272">  }</span>
+<span class="source-line-no">3273</span><span id="line-3273"></span>
+<span class="source-line-no">3274</span><span id="line-3274">  @Override</span>
+<span class="source-line-no">3275</span><span id="line-3275">  public AssignmentManager getAssignmentManager() {</span>
+<span class="source-line-no">3276</span><span id="line-3276">    return this.assignmentManager;</span>
+<span class="source-line-no">3277</span><span id="line-3277">  }</span>
+<span class="source-line-no">3278</span><span id="line-3278"></span>
+<span class="source-line-no">3279</span><span id="line-3279">  @Override</span>
+<span class="source-line-no">3280</span><span id="line-3280">  public CatalogJanitor getCatalogJanitor() {</span>
+<span class="source-line-no">3281</span><span id="line-3281">    return this.catalogJanitorChore;</span>
 <span class="source-line-no">3282</span><span id="line-3282">  }</span>
 <span class="source-line-no">3283</span><span id="line-3283"></span>
-<span class="source-line-no">3284</span><span id="line-3284">  public TaskGroup getStartupProgress() {</span>
-<span class="source-line-no">3285</span><span id="line-3285">    return startupTaskGroup;</span>
+<span class="source-line-no">3284</span><span id="line-3284">  public MemoryBoundedLogMessageBuffer getRegionServerFatalLogBuffer() {</span>
+<span class="source-line-no">3285</span><span id="line-3285">    return rsFatals;</span>
 <span class="source-line-no">3286</span><span id="line-3286">  }</span>
 <span class="source-line-no">3287</span><span id="line-3287"></span>
-<span class="source-line-no">3288</span><span id="line-3288">  /**</span>
-<span class="source-line-no">3289</span><span id="line-3289">   * Shutdown the cluster. Master runs a coordinated stop of all RegionServers and then itself.</span>
-<span class="source-line-no">3290</span><span id="line-3290">   */</span>
-<span class="source-line-no">3291</span><span id="line-3291">  public void shutdown() throws IOException {</span>
-<span class="source-line-no">3292</span><span id="line-3292">    TraceUtil.trace(() -&gt; {</span>
-<span class="source-line-no">3293</span><span id="line-3293">      if (cpHost != null) {</span>
-<span class="source-line-no">3294</span><span id="line-3294">        cpHost.preShutdown();</span>
-<span class="source-line-no">3295</span><span id="line-3295">      }</span>
-<span class="source-line-no">3296</span><span id="line-3296"></span>
-<span class="source-line-no">3297</span><span id="line-3297">      // Tell the servermanager cluster shutdown has been called. This makes it so when Master is</span>
-<span class="source-line-no">3298</span><span id="line-3298">      // last running server, it'll stop itself. Next, we broadcast the cluster shutdown by setting</span>
-<span class="source-line-no">3299</span><span id="line-3299">      // the cluster status as down. RegionServers will notice this change in state and will start</span>
-<span class="source-line-no">3300</span><span id="line-3300">      // shutting themselves down. When last has exited, Master can go down.</span>
-<span class="source-line-no">3301</span><span id="line-3301">      if (this.serverManager != null) {</span>
-<span class="source-line-no">3302</span><span id="line-3302">        this.serverManager.shutdownCluster();</span>
-<span class="source-line-no">3303</span><span id="line-3303">      }</span>
-<span class="source-line-no">3304</span><span id="line-3304">      if (this.clusterStatusTracker != null) {</span>
-<span class="source-line-no">3305</span><span id="line-3305">        try {</span>
-<span class="source-line-no">3306</span><span id="line-3306">          this.clusterStatusTracker.setClusterDown();</span>
-<span class="source-line-no">3307</span><span id="line-3307">        } catch (KeeperException e) {</span>
-<span class="source-line-no">3308</span><span id="line-3308">          LOG.error("ZooKeeper exception trying to set cluster as down in ZK", e);</span>
-<span class="source-line-no">3309</span><span id="line-3309">        }</span>
-<span class="source-line-no">3310</span><span id="line-3310">      }</span>
-<span class="source-line-no">3311</span><span id="line-3311">      // Stop the procedure executor. Will stop any ongoing assign, unassign, server crash etc.,</span>
-<span class="source-line-no">3312</span><span id="line-3312">      // processing so we can go down.</span>
-<span class="source-line-no">3313</span><span id="line-3313">      if (this.procedureExecutor != null) {</span>
-<span class="source-line-no">3314</span><span id="line-3314">        this.procedureExecutor.stop();</span>
-<span class="source-line-no">3315</span><span id="line-3315">      }</span>
-<span class="source-line-no">3316</span><span id="line-3316">      // Shutdown our cluster connection. This will kill any hosted RPCs that might be going on;</span>
-<span class="source-line-no">3317</span><span id="line-3317">      // this is what we want especially if the Master is in startup phase doing call outs to</span>
-<span class="source-line-no">3318</span><span id="line-3318">      // hbase:meta, etc. when cluster is down. Without ths connection close, we'd have to wait on</span>
-<span class="source-line-no">3319</span><span id="line-3319">      // the rpc to timeout.</span>
-<span class="source-line-no">3320</span><span id="line-3320">      if (this.asyncClusterConnection != null) {</span>
-<span class="source-line-no">3321</span><span id="line-3321">        this.asyncClusterConnection.close();</span>
-<span class="source-line-no">3322</span><span id="line-3322">      }</span>
-<span class="source-line-no">3323</span><span id="line-3323">    }, "HMaster.shutdown");</span>
-<span class="source-line-no">3324</span><span id="line-3324">  }</span>
-<span class="source-line-no">3325</span><span id="line-3325"></span>
-<span class="source-line-no">3326</span><span id="line-3326">  public void stopMaster() throws IOException {</span>
-<span class="source-line-no">3327</span><span id="line-3327">    if (cpHost != null) {</span>
-<span class="source-line-no">3328</span><span id="line-3328">      cpHost.preStopMaster();</span>
-<span class="source-line-no">3329</span><span id="line-3329">    }</span>
-<span class="source-line-no">3330</span><span id="line-3330">    stop("Stopped by " + Thread.currentThread().getName());</span>
-<span class="source-line-no">3331</span><span id="line-3331">  }</span>
-<span class="source-line-no">3332</span><span id="line-3332"></span>
-<span class="source-line-no">3333</span><span id="line-3333">  @Override</span>
-<span class="source-line-no">3334</span><span id="line-3334">  public void stop(String msg) {</span>
-<span class="source-line-no">3335</span><span id="line-3335">    if (!this.stopped) {</span>
-<span class="source-line-no">3336</span><span id="line-3336">      LOG.info("***** STOPPING master '" + this + "' *****");</span>
-<span class="source-line-no">3337</span><span id="line-3337">      this.stopped = true;</span>
-<span class="source-line-no">3338</span><span id="line-3338">      LOG.info("STOPPED: " + msg);</span>
-<span class="source-line-no">3339</span><span id="line-3339">      // Wakes run() if it is sleeping</span>
-<span class="source-line-no">3340</span><span id="line-3340">      sleeper.skipSleepCycle();</span>
-<span class="source-line-no">3341</span><span id="line-3341">      if (this.activeMasterManager != null) {</span>
-<span class="source-line-no">3342</span><span id="line-3342">        this.activeMasterManager.stop();</span>
-<span class="source-line-no">3343</span><span id="line-3343">      }</span>
-<span class="source-line-no">3344</span><span id="line-3344">    }</span>
-<span class="source-line-no">3345</span><span id="line-3345">  }</span>
-<span class="source-line-no">3346</span><span id="line-3346"></span>
-<span class="source-line-no">3347</span><span id="line-3347">  protected void checkServiceStarted() throws ServerNotRunningYetException {</span>
-<span class="source-line-no">3348</span><span id="line-3348">    if (!serviceStarted) {</span>
-<span class="source-line-no">3349</span><span id="line-3349">      throw new ServerNotRunningYetException("Server is not running yet");</span>
-<span class="source-line-no">3350</span><span id="line-3350">    }</span>
-<span class="source-line-no">3351</span><span id="line-3351">  }</span>
-<span class="source-line-no">3352</span><span id="line-3352"></span>
-<span class="source-line-no">3353</span><span id="line-3353">  void checkInitialized() throws PleaseHoldException, ServerNotRunningYetException,</span>
-<span class="source-line-no">3354</span><span id="line-3354">    MasterNotRunningException, MasterStoppedException {</span>
-<span class="source-line-no">3355</span><span id="line-3355">    checkServiceStarted();</span>
-<span class="source-line-no">3356</span><span id="line-3356">    if (!isInitialized()) {</span>
-<span class="source-line-no">3357</span><span id="line-3357">      throw new PleaseHoldException("Master is initializing");</span>
-<span class="source-line-no">3358</span><span id="line-3358">    }</span>
-<span class="source-line-no">3359</span><span id="line-3359">    if (isStopped()) {</span>
-<span class="source-line-no">3360</span><span id="line-3360">      throw new MasterStoppedException();</span>
-<span class="source-line-no">3361</span><span id="line-3361">    }</span>
-<span class="source-line-no">3362</span><span id="line-3362">  }</span>
-<span class="source-line-no">3363</span><span id="line-3363"></span>
-<span class="source-line-no">3364</span><span id="line-3364">  /**</span>
-<span class="source-line-no">3365</span><span id="line-3365">   * Report whether this master is currently the active master or not. If not active master, we are</span>
-<span class="source-line-no">3366</span><span id="line-3366">   * parked on ZK waiting to become active. This method is used for testing.</span>
-<span class="source-line-no">3367</span><span id="line-3367">   * @return true if active master, false if not.</span>
-<span class="source-line-no">3368</span><span id="line-3368">   */</span>
-<span class="source-line-no">3369</span><span id="line-3369">  @Override</span>
-<span class="source-line-no">3370</span><span id="line-3370">  public boolean isActiveMaster() {</span>
-<span class="source-line-no">3371</span><span id="line-3371">    return activeMaster;</span>
-<span class="source-line-no">3372</span><span id="line-3372">  }</span>
-<span class="source-line-no">3373</span><span id="line-3373"></span>
-<span class="source-line-no">3374</span><span id="line-3374">  /**</span>
-<span class="source-line-no">3375</span><span id="line-3375">   * Report whether this master has completed with its initialization and is ready. If ready, the</span>
-<span class="source-line-no">3376</span><span id="line-3376">   * master is also the active master. A standby master is never ready. This method is used for</span>
-<span class="source-line-no">3377</span><span id="line-3377">   * testing.</span>
-<span class="source-line-no">3378</span><span id="line-3378">   * @return true if master is ready to go, false if not.</span>
-<span class="source-line-no">3379</span><span id="line-3379">   */</span>
-<span class="source-line-no">3380</span><span id="line-3380">  @Override</span>
-<span class="source-line-no">3381</span><span id="line-3381">  public boolean isInitialized() {</span>
-<span class="source-line-no">3382</span><span id="line-3382">    return initialized.isReady();</span>
-<span class="source-line-no">3383</span><span id="line-3383">  }</span>
-<span class="source-line-no">3384</span><span id="line-3384"></span>
-<span class="source-line-no">3385</span><span id="line-3385">  /**</span>
-<span class="source-line-no">3386</span><span id="line-3386">   * Report whether this master is started This method is used for testing.</span>
-<span class="source-line-no">3387</span><span id="line-3387">   * @return true if master is ready to go, false if not.</span>
-<span class="source-line-no">3388</span><span id="line-3388">   */</span>
-<span class="source-line-no">3389</span><span id="line-3389">  public boolean isOnline() {</span>
-<span class="source-line-no">3390</span><span id="line-3390">    return serviceStarted;</span>
-<span class="source-line-no">3391</span><span id="line-3391">  }</span>
-<span class="source-line-no">3392</span><span id="line-3392"></span>
-<span class="source-line-no">3393</span><span id="line-3393">  /**</span>
-<span class="source-line-no">3394</span><span id="line-3394">   * Report whether this master is in maintenance mode.</span>
-<span class="source-line-no">3395</span><span id="line-3395">   * @return true if master is in maintenanceMode</span>
-<span class="source-line-no">3396</span><span id="line-3396">   */</span>
-<span class="source-line-no">3397</span><span id="line-3397">  @Override</span>
-<span class="source-line-no">3398</span><span id="line-3398">  public boolean isInMaintenanceMode() {</span>
-<span class="source-line-no">3399</span><span id="line-3399">    return maintenanceMode;</span>
-<span class="source-line-no">3400</span><span id="line-3400">  }</span>
-<span class="source-line-no">3401</span><span id="line-3401"></span>
-<span class="source-line-no">3402</span><span id="line-3402">  public void setInitialized(boolean isInitialized) {</span>
-<span class="source-line-no">3403</span><span id="line-3403">    procedureExecutor.getEnvironment().setEventReady(initialized, isInitialized);</span>
+<span class="source-line-no">3288</span><span id="line-3288">  public TaskGroup getStartupProgress() {</span>
+<span class="source-line-no">3289</span><span id="line-3289">    return startupTaskGroup;</span>
+<span class="source-line-no">3290</span><span id="line-3290">  }</span>
+<span class="source-line-no">3291</span><span id="line-3291"></span>
+<span class="source-line-no">3292</span><span id="line-3292">  /**</span>
+<span class="source-line-no">3293</span><span id="line-3293">   * Shutdown the cluster. Master runs a coordinated stop of all RegionServers and then itself.</span>
+<span class="source-line-no">3294</span><span id="line-3294">   */</span>
+<span class="source-line-no">3295</span><span id="line-3295">  public void shutdown() throws IOException {</span>
+<span class="source-line-no">3296</span><span id="line-3296">    TraceUtil.trace(() -&gt; {</span>
+<span class="source-line-no">3297</span><span id="line-3297">      if (cpHost != null) {</span>
+<span class="source-line-no">3298</span><span id="line-3298">        cpHost.preShutdown();</span>
+<span class="source-line-no">3299</span><span id="line-3299">      }</span>
+<span class="source-line-no">3300</span><span id="line-3300"></span>
+<span class="source-line-no">3301</span><span id="line-3301">      // Tell the servermanager cluster shutdown has been called. This makes it so when Master is</span>
+<span class="source-line-no">3302</span><span id="line-3302">      // last running server, it'll stop itself. Next, we broadcast the cluster shutdown by setting</span>
+<span class="source-line-no">3303</span><span id="line-3303">      // the cluster status as down. RegionServers will notice this change in state and will start</span>
+<span class="source-line-no">3304</span><span id="line-3304">      // shutting themselves down. When last has exited, Master can go down.</span>
+<span class="source-line-no">3305</span><span id="line-3305">      if (this.serverManager != null) {</span>
+<span class="source-line-no">3306</span><span id="line-3306">        this.serverManager.shutdownCluster();</span>
+<span class="source-line-no">3307</span><span id="line-3307">      }</span>
+<span class="source-line-no">3308</span><span id="line-3308">      if (this.clusterStatusTracker != null) {</span>
+<span class="source-line-no">3309</span><span id="line-3309">        try {</span>
+<span class="source-line-no">3310</span><span id="line-3310">          this.clusterStatusTracker.setClusterDown();</span>
+<span class="source-line-no">3311</span><span id="line-3311">        } catch (KeeperException e) {</span>
+<span class="source-line-no">3312</span><span id="line-3312">          LOG.error("ZooKeeper exception trying to set cluster as down in ZK", e);</span>
+<span class="source-line-no">3313</span><span id="line-3313">        }</span>
+<span class="source-line-no">3314</span><span id="line-3314">      }</span>
+<span class="source-line-no">3315</span><span id="line-3315">      // Stop the procedure executor. Will stop any ongoing assign, unassign, server crash etc.,</span>
+<span class="source-line-no">3316</span><span id="line-3316">      // processing so we can go down.</span>
+<span class="source-line-no">3317</span><span id="line-3317">      if (this.procedureExecutor != null) {</span>
+<span class="source-line-no">3318</span><span id="line-3318">        this.procedureExecutor.stop();</span>
+<span class="source-line-no">3319</span><span id="line-3319">      }</span>
+<span class="source-line-no">3320</span><span id="line-3320">      // Shutdown our cluster connection. This will kill any hosted RPCs that might be going on;</span>
+<span class="source-line-no">3321</span><span id="line-3321">      // this is what we want especially if the Master is in startup phase doing call outs to</span>
+<span class="source-line-no">3322</span><span id="line-3322">      // hbase:meta, etc. when cluster is down. Without ths connection close, we'd have to wait on</span>
+<span class="source-line-no">3323</span><span id="line-3323">      // the rpc to timeout.</span>
+<span class="source-line-no">3324</span><span id="line-3324">      if (this.asyncClusterConnection != null) {</span>
+<span class="source-line-no">3325</span><span id="line-3325">        this.asyncClusterConnection.close();</span>
+<span class="source-line-no">3326</span><span id="line-3326">      }</span>
+<span class="source-line-no">3327</span><span id="line-3327">    }, "HMaster.shutdown");</span>
+<span class="source-line-no">3328</span><span id="line-3328">  }</span>
+<span class="source-line-no">3329</span><span id="line-3329"></span>
+<span class="source-line-no">3330</span><span id="line-3330">  public void stopMaster() throws IOException {</span>
+<span class="source-line-no">3331</span><span id="line-3331">    if (cpHost != null) {</span>
+<span class="source-line-no">3332</span><span id="line-3332">      cpHost.preStopMaster();</span>
+<span class="source-line-no">3333</span><span id="line-3333">    }</span>
+<span class="source-line-no">3334</span><span id="line-3334">    stop("Stopped by " + Thread.currentThread().getName());</span>
+<span class="source-line-no">3335</span><span id="line-3335">  }</span>
+<span class="source-line-no">3336</span><span id="line-3336"></span>
+<span class="source-line-no">3337</span><span id="line-3337">  @Override</span>
+<span class="source-line-no">3338</span><span id="line-3338">  public void stop(String msg) {</span>
+<span class="source-line-no">3339</span><span id="line-3339">    if (!this.stopped) {</span>
+<span class="source-line-no">3340</span><span id="line-3340">      LOG.info("***** STOPPING master '" + this + "' *****");</span>
+<span class="source-line-no">3341</span><span id="line-3341">      this.stopped = true;</span>
+<span class="source-line-no">3342</span><span id="line-3342">      LOG.info("STOPPED: " + msg);</span>
+<span class="source-line-no">3343</span><span id="line-3343">      // Wakes run() if it is sleeping</span>
+<span class="source-line-no">3344</span><span id="line-3344">      sleeper.skipSleepCycle();</span>
+<span class="source-line-no">3345</span><span id="line-3345">      if (this.activeMasterManager != null) {</span>
+<span class="source-line-no">3346</span><span id="line-3346">        this.activeMasterManager.stop();</span>
+<span class="source-line-no">3347</span><span id="line-3347">      }</span>
+<span class="source-line-no">3348</span><span id="line-3348">    }</span>
+<span class="source-line-no">3349</span><span id="line-3349">  }</span>
+<span class="source-line-no">3350</span><span id="line-3350"></span>
+<span class="source-line-no">3351</span><span id="line-3351">  protected void checkServiceStarted() throws ServerNotRunningYetException {</span>
+<span class="source-line-no">3352</span><span id="line-3352">    if (!serviceStarted) {</span>
+<span class="source-line-no">3353</span><span id="line-3353">      throw new ServerNotRunningYetException("Server is not running yet");</span>
+<span class="source-line-no">3354</span><span id="line-3354">    }</span>
+<span class="source-line-no">3355</span><span id="line-3355">  }</span>
+<span class="source-line-no">3356</span><span id="line-3356"></span>
+<span class="source-line-no">3357</span><span id="line-3357">  void checkInitialized() throws PleaseHoldException, ServerNotRunningYetException,</span>
+<span class="source-line-no">3358</span><span id="line-3358">    MasterNotRunningException, MasterStoppedException {</span>
+<span class="source-line-no">3359</span><span id="line-3359">    checkServiceStarted();</span>
+<span class="source-line-no">3360</span><span id="line-3360">    if (!isInitialized()) {</span>
+<span class="source-line-no">3361</span><span id="line-3361">      throw new PleaseHoldException("Master is initializing");</span>
+<span class="source-line-no">3362</span><span id="line-3362">    }</span>
+<span class="source-line-no">3363</span><span id="line-3363">    if (isStopped()) {</span>
+<span class="source-line-no">3364</span><span id="line-3364">      throw new MasterStoppedException();</span>
+<span class="source-line-no">3365</span><span id="line-3365">    }</span>
+<span class="source-line-no">3366</span><span id="line-3366">  }</span>
+<span class="source-line-no">3367</span><span id="line-3367"></span>
+<span class="source-line-no">3368</span><span id="line-3368">  /**</span>
+<span class="source-line-no">3369</span><span id="line-3369">   * Report whether this master is currently the active master or not. If not active master, we are</span>
+<span class="source-line-no">3370</span><span id="line-3370">   * parked on ZK waiting to become active. This method is used for testing.</span>
+<span class="source-line-no">3371</span><span id="line-3371">   * @return true if active master, false if not.</span>
+<span class="source-line-no">3372</span><span id="line-3372">   */</span>
+<span class="source-line-no">3373</span><span id="line-3373">  @Override</span>
+<span class="source-line-no">3374</span><span id="line-3374">  public boolean isActiveMaster() {</span>
+<span class="source-line-no">3375</span><span id="line-3375">    return activeMaster;</span>
+<span class="source-line-no">3376</span><span id="line-3376">  }</span>
+<span class="source-line-no">3377</span><span id="line-3377"></span>
+<span class="source-line-no">3378</span><span id="line-3378">  /**</span>
+<span class="source-line-no">3379</span><span id="line-3379">   * Report whether this master has completed with its initialization and is ready. If ready, the</span>
+<span class="source-line-no">3380</span><span id="line-3380">   * master is also the active master. A standby master is never ready. This method is used for</span>
+<span class="source-line-no">3381</span><span id="line-3381">   * testing.</span>
+<span class="source-line-no">3382</span><span id="line-3382">   * @return true if master is ready to go, false if not.</span>
+<span class="source-line-no">3383</span><span id="line-3383">   */</span>
+<span class="source-line-no">3384</span><span id="line-3384">  @Override</span>
+<span class="source-line-no">3385</span><span id="line-3385">  public boolean isInitialized() {</span>
+<span class="source-line-no">3386</span><span id="line-3386">    return initialized.isReady();</span>
+<span class="source-line-no">3387</span><span id="line-3387">  }</span>
+<span class="source-line-no">3388</span><span id="line-3388"></span>
+<span class="source-line-no">3389</span><span id="line-3389">  /**</span>
+<span class="source-line-no">3390</span><span id="line-3390">   * Report whether this master is started This method is used for testing.</span>
+<span class="source-line-no">3391</span><span id="line-3391">   * @return true if master is ready to go, false if not.</span>
+<span class="source-line-no">3392</span><span id="line-3392">   */</span>
+<span class="source-line-no">3393</span><span id="line-3393">  public boolean isOnline() {</span>
+<span class="source-line-no">3394</span><span id="line-3394">    return serviceStarted;</span>
+<span class="source-line-no">3395</span><span id="line-3395">  }</span>
+<span class="source-line-no">3396</span><span id="line-3396"></span>
+<span class="source-line-no">3397</span><span id="line-3397">  /**</span>
+<span class="source-line-no">3398</span><span id="line-3398">   * Report whether this master is in maintenance mode.</span>
+<span class="source-line-no">3399</span><span id="line-3399">   * @return true if master is in maintenanceMode</span>
+<span class="source-line-no">3400</span><span id="line-3400">   */</span>
+<span class="source-line-no">3401</span><span id="line-3401">  @Override</span>
+<span class="source-line-no">3402</span><span id="line-3402">  public boolean isInMaintenanceMode() {</span>
+<span class="source-line-no">3403</span><span id="line-3403">    return maintenanceMode;</span>
 <span class="source-line-no">3404</span><span id="line-3404">  }</span>
 <span class="source-line-no">3405</span><span id="line-3405"></span>
-<span class="source-line-no">3406</span><span id="line-3406">  /**</span>
-<span class="source-line-no">3407</span><span id="line-3407">   * Mainly used in procedure related tests, where we will restart ProcedureExecutor and</span>
-<span class="source-line-no">3408</span><span id="line-3408">   * AssignmentManager, but we do not want to restart master(to speed up the test), so we need to</span>
-<span class="source-line-no">3409</span><span id="line-3409">   * disable rpc for a while otherwise some critical rpc requests such as</span>
-<span class="source-line-no">3410</span><span id="line-3410">   * reportRegionStateTransition could fail and cause region server to abort.</span>
-<span class="source-line-no">3411</span><span id="line-3411">   */</span>
-<span class="source-line-no">3412</span><span id="line-3412">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">3413</span><span id="line-3413">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">3414</span><span id="line-3414">  public void setServiceStarted(boolean started) {</span>
-<span class="source-line-no">3415</span><span id="line-3415">    this.serviceStarted = started;</span>
-<span class="source-line-no">3416</span><span id="line-3416">  }</span>
-<span class="source-line-no">3417</span><span id="line-3417"></span>
-<span class="source-line-no">3418</span><span id="line-3418">  @Override</span>
-<span class="source-line-no">3419</span><span id="line-3419">  public ProcedureEvent&lt;?&gt; getInitializedEvent() {</span>
-<span class="source-line-no">3420</span><span id="line-3420">    return initialized;</span>
-<span class="source-line-no">3421</span><span id="line-3421">  }</span>
-<span class="source-line-no">3422</span><span id="line-3422"></span>
-<span class="source-line-no">3423</span><span id="line-3423">  /**</span>
-<span class="source-line-no">3424</span><span id="line-3424">   * Compute the average load across all region servers. Currently, this uses a very naive</span>
-<span class="source-line-no">3425</span><span id="line-3425">   * computation - just uses the number of regions being served, ignoring stats about number of</span>
-<span class="source-line-no">3426</span><span id="line-3426">   * requests.</span>
-<span class="source-line-no">3427</span><span id="line-3427">   * @return the average load</span>
-<span class="source-line-no">3428</span><span id="line-3428">   */</span>
-<span class="source-line-no">3429</span><span id="line-3429">  public double getAverageLoad() {</span>
-<span class="source-line-no">3430</span><span id="line-3430">    if (this.assignmentManager == null) {</span>
-<span class="source-line-no">3431</span><span id="line-3431">      return 0;</span>
-<span class="source-line-no">3432</span><span id="line-3432">    }</span>
-<span class="source-line-no">3433</span><span id="line-3433"></span>
-<span class="source-line-no">3434</span><span id="line-3434">    RegionStates regionStates = this.assignmentManager.getRegionStates();</span>
-<span class="source-line-no">3435</span><span id="line-3435">    if (regionStates == null) {</span>
-<span class="source-line-no">3436</span><span id="line-3436">      return 0;</span>
-<span class="source-line-no">3437</span><span id="line-3437">    }</span>
-<span class="source-line-no">3438</span><span id="line-3438">    return regionStates.getAverageLoad();</span>
-<span class="source-line-no">3439</span><span id="line-3439">  }</span>
-<span class="source-line-no">3440</span><span id="line-3440"></span>
-<span class="source-line-no">3441</span><span id="line-3441">  @Override</span>
-<span class="source-line-no">3442</span><span id="line-3442">  public boolean registerService(Service instance) {</span>
-<span class="source-line-no">3443</span><span id="line-3443">    /*</span>
-<span class="source-line-no">3444</span><span id="line-3444">     * No stacking of instances is allowed for a single service name</span>
-<span class="source-line-no">3445</span><span id="line-3445">     */</span>
-<span class="source-line-no">3446</span><span id="line-3446">    Descriptors.ServiceDescriptor serviceDesc = instance.getDescriptorForType();</span>
-<span class="source-line-no">3447</span><span id="line-3447">    String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc);</span>
-<span class="source-line-no">3448</span><span id="line-3448">    if (coprocessorServiceHandlers.containsKey(serviceName)) {</span>
-<span class="source-line-no">3449</span><span id="line-3449">      LOG.error("Coprocessor service " + serviceName</span>
-<span class="source-line-no">3450</span><span id="line-3450">        + " already registered, rejecting request from " + instance);</span>
-<span class="source-line-no">3451</span><span id="line-3451">      return false;</span>
-<span class="source-line-no">3452</span><span id="line-3452">    }</span>
-<span class="source-line-no">3453</span><span id="line-3453"></span>
-<span class="source-line-no">3454</span><span id="line-3454">    coprocessorServiceHandlers.put(serviceName, instance);</span>
-<span class="source-line-no">3455</span><span id="line-3455">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">3456</span><span id="line-3456">      LOG.debug("Registered master coprocessor service: service=" + serviceName);</span>
-<span class="source-line-no">3457</span><span id="line-3457">    }</span>
-<span class="source-line-no">3458</span><span id="line-3458">    return true;</span>
-<span class="source-line-no">3459</span><span id="line-3459">  }</span>
-<span class="source-line-no">3460</span><span id="line-3460"></span>
-<span class="source-line-no">3461</span><span id="line-3461">  /**</span>
-<span class="source-line-no">3462</span><span id="line-3462">   * Utility for constructing an instance of the passed HMaster class.</span>
-<span class="source-line-no">3463</span><span id="line-3463">   * @return HMaster instance.</span>
-<span class="source-line-no">3464</span><span id="line-3464">   */</span>
-<span class="source-line-no">3465</span><span id="line-3465">  public static HMaster constructMaster(Class&lt;? extends HMaster&gt; masterClass,</span>
-<span class="source-line-no">3466</span><span id="line-3466">    final Configuration conf) {</span>
-<span class="source-line-no">3467</span><span id="line-3467">    try {</span>
-<span class="source-line-no">3468</span><span id="line-3468">      Constructor&lt;? extends HMaster&gt; c = masterClass.getConstructor(Configuration.class);</span>
-<span class="source-line-no">3469</span><span id="line-3469">      return c.newInstance(conf);</span>
-<span class="source-line-no">3470</span><span id="line-3470">    } catch (Exception e) {</span>
-<span class="source-line-no">3471</span><span id="line-3471">      Throwable error = e;</span>
-<span class="source-line-no">3472</span><span id="line-3472">      if (</span>
-<span class="source-line-no">3473</span><span id="line-3473">        e instanceof InvocationTargetException</span>
-<span class="source-line-no">3474</span><span id="line-3474">          &amp;&amp; ((InvocationTargetException) e).getTargetException() != null</span>
-<span class="source-line-no">3475</span><span id="line-3475">      ) {</span>
-<span class="source-line-no">3476</span><span id="line-3476">        error = ((InvocationTargetException) e).getTargetException();</span>
-<span class="source-line-no">3477</span><span id="line-3477">      }</span>
-<span class="source-line-no">3478</span><span id="line-3478">      throw new RuntimeException("Failed construction of Master: " + masterClass.toString() + ". ",</span>
-<span class="source-line-no">3479</span><span id="line-3479">        error);</span>
-<span class="source-line-no">3480</span><span id="line-3480">    }</span>
-<span class="source-line-no">3481</span><span id="line-3481">  }</span>
-<span class="source-line-no">3482</span><span id="line-3482"></span>
-<span class="source-line-no">3483</span><span id="line-3483">  /**</span>
-<span class="source-line-no">3484</span><span id="line-3484">   * @see org.apache.hadoop.hbase.master.HMasterCommandLine</span>
-<span class="source-line-no">3485</span><span id="line-3485">   */</span>
-<span class="source-line-no">3486</span><span id="line-3486">  public static void main(String[] args) {</span>
-<span class="source-line-no">3487</span><span id="line-3487">    LOG.info("STARTING service " + HMaster.class.getSimpleName());</span>
-<span class="source-line-no">3488</span><span id="line-3488">    VersionInfo.logVersion();</span>
-<span class="source-line-no">3489</span><span id="line-3489">    new HMasterCommandLine(HMaster.class).doMain(args);</span>
-<span class="source-line-no">3490</span><span id="line-3490">  }</span>
-<span class="source-line-no">3491</span><span id="line-3491"></span>
-<span class="source-line-no">3492</span><span id="line-3492">  public HFileCleaner getHFileCleaner() {</span>
-<span class="source-line-no">3493</span><span id="line-3493">    return this.hfileCleaners.get(0);</span>
+<span class="source-line-no">3406</span><span id="line-3406">  public void setInitialized(boolean isInitialized) {</span>
+<span class="source-line-no">3407</span><span id="line-3407">    procedureExecutor.getEnvironment().setEventReady(initialized, isInitialized);</span>
+<span class="source-line-no">3408</span><span id="line-3408">  }</span>
+<span class="source-line-no">3409</span><span id="line-3409"></span>
+<span class="source-line-no">3410</span><span id="line-3410">  /**</span>
+<span class="source-line-no">3411</span><span id="line-3411">   * Mainly used in procedure related tests, where we will restart ProcedureExecutor and</span>
+<span class="source-line-no">3412</span><span id="line-3412">   * AssignmentManager, but we do not want to restart master(to speed up the test), so we need to</span>
+<span class="source-line-no">3413</span><span id="line-3413">   * disable rpc for a while otherwise some critical rpc requests such as</span>
+<span class="source-line-no">3414</span><span id="line-3414">   * reportRegionStateTransition could fail and cause region server to abort.</span>
+<span class="source-line-no">3415</span><span id="line-3415">   */</span>
+<span class="source-line-no">3416</span><span id="line-3416">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">3417</span><span id="line-3417">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">3418</span><span id="line-3418">  public void setServiceStarted(boolean started) {</span>
+<span class="source-line-no">3419</span><span id="line-3419">    this.serviceStarted = started;</span>
+<span class="source-line-no">3420</span><span id="line-3420">  }</span>
+<span class="source-line-no">3421</span><span id="line-3421"></span>
+<span class="source-line-no">3422</span><span id="line-3422">  @Override</span>
+<span class="source-line-no">3423</span><span id="line-3423">  public ProcedureEvent&lt;?&gt; getInitializedEvent() {</span>
+<span class="source-line-no">3424</span><span id="line-3424">    return initialized;</span>
+<span class="source-line-no">3425</span><span id="line-3425">  }</span>
+<span class="source-line-no">3426</span><span id="line-3426"></span>
+<span class="source-line-no">3427</span><span id="line-3427">  /**</span>
+<span class="source-line-no">3428</span><span id="line-3428">   * Compute the average load across all region servers. Currently, this uses a very naive</span>
+<span class="source-line-no">3429</span><span id="line-3429">   * computation - just uses the number of regions being served, ignoring stats about number of</span>
+<span class="source-line-no">3430</span><span id="line-3430">   * requests.</span>
+<span class="source-line-no">3431</span><span id="line-3431">   * @return the average load</span>
+<span class="source-line-no">3432</span><span id="line-3432">   */</span>
+<span class="source-line-no">3433</span><span id="line-3433">  public double getAverageLoad() {</span>
+<span class="source-line-no">3434</span><span id="line-3434">    if (this.assignmentManager == null) {</span>
+<span class="source-line-no">3435</span><span id="line-3435">      return 0;</span>
+<span class="source-line-no">3436</span><span id="line-3436">    }</span>
+<span class="source-line-no">3437</span><span id="line-3437"></span>
+<span class="source-line-no">3438</span><span id="line-3438">    RegionStates regionStates = this.assignmentManager.getRegionStates();</span>
+<span class="source-line-no">3439</span><span id="line-3439">    if (regionStates == null) {</span>
+<span class="source-line-no">3440</span><span id="line-3440">      return 0;</span>
+<span class="source-line-no">3441</span><span id="line-3441">    }</span>
+<span class="source-line-no">3442</span><span id="line-3442">    return regionStates.getAverageLoad();</span>
+<span class="source-line-no">3443</span><span id="line-3443">  }</span>
+<span class="source-line-no">3444</span><span id="line-3444"></span>
+<span class="source-line-no">3445</span><span id="line-3445">  @Override</span>
+<span class="source-line-no">3446</span><span id="line-3446">  public boolean registerService(Service instance) {</span>
+<span class="source-line-no">3447</span><span id="line-3447">    /*</span>
+<span class="source-line-no">3448</span><span id="line-3448">     * No stacking of instances is allowed for a single service name</span>
+<span class="source-line-no">3449</span><span id="line-3449">     */</span>
+<span class="source-line-no">3450</span><span id="line-3450">    Descriptors.ServiceDescriptor serviceDesc = instance.getDescriptorForType();</span>
+<span class="source-line-no">3451</span><span id="line-3451">    String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc);</span>
+<span class="source-line-no">3452</span><span id="line-3452">    if (coprocessorServiceHandlers.containsKey(serviceName)) {</span>
+<span class="source-line-no">3453</span><span id="line-3453">      LOG.error("Coprocessor service " + serviceName</span>
+<span class="source-line-no">3454</span><span id="line-3454">        + " already registered, rejecting request from " + instance);</span>
+<span class="source-line-no">3455</span><span id="line-3455">      return false;</span>
+<span class="source-line-no">3456</span><span id="line-3456">    }</span>
+<span class="source-line-no">3457</span><span id="line-3457"></span>
+<span class="source-line-no">3458</span><span id="line-3458">    coprocessorServiceHandlers.put(serviceName, instance);</span>
+<span class="source-line-no">3459</span><span id="line-3459">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">3460</span><span id="line-3460">      LOG.debug("Registered master coprocessor service: service=" + serviceName);</span>
+<span class="source-line-no">3461</span><span id="line-3461">    }</span>
+<span class="source-line-no">3462</span><span id="line-3462">    return true;</span>
+<span class="source-line-no">3463</span><span id="line-3463">  }</span>
+<span class="source-line-no">3464</span><span id="line-3464"></span>
+<span class="source-line-no">3465</span><span id="line-3465">  /**</span>
+<span class="source-line-no">3466</span><span id="line-3466">   * Utility for constructing an instance of the passed HMaster class.</span>
+<span class="source-line-no">3467</span><span id="line-3467">   * @return HMaster instance.</span>
+<span class="source-line-no">3468</span><span id="line-3468">   */</span>
+<span class="source-line-no">3469</span><span id="line-3469">  public static HMaster constructMaster(Class&lt;? extends HMaster&gt; masterClass,</span>
+<span class="source-line-no">3470</span><span id="line-3470">    final Configuration conf) {</span>
+<span class="source-line-no">3471</span><span id="line-3471">    try {</span>
+<span class="source-line-no">3472</span><span id="line-3472">      Constructor&lt;? extends HMaster&gt; c = masterClass.getConstructor(Configuration.class);</span>
+<span class="source-line-no">3473</span><span id="line-3473">      return c.newInstance(conf);</span>
+<span class="source-line-no">3474</span><span id="line-3474">    } catch (Exception e) {</span>
+<span class="source-line-no">3475</span><span id="line-3475">      Throwable error = e;</span>
+<span class="source-line-no">3476</span><span id="line-3476">      if (</span>
+<span class="source-line-no">3477</span><span id="line-3477">        e instanceof InvocationTargetException</span>
+<span class="source-line-no">3478</span><span id="line-3478">          &amp;&amp; ((InvocationTargetException) e).getTargetException() != null</span>
+<span class="source-line-no">3479</span><span id="line-3479">      ) {</span>
+<span class="source-line-no">3480</span><span id="line-3480">        error = ((InvocationTargetException) e).getTargetException();</span>
+<span class="source-line-no">3481</span><span id="line-3481">      }</span>
+<span class="source-line-no">3482</span><span id="line-3482">      throw new RuntimeException("Failed construction of Master: " + masterClass.toString() + ". ",</span>
+<span class="source-line-no">3483</span><span id="line-3483">        error);</span>
+<span class="source-line-no">3484</span><span id="line-3484">    }</span>
+<span class="source-line-no">3485</span><span id="line-3485">  }</span>
+<span class="source-line-no">3486</span><span id="line-3486"></span>
+<span class="source-line-no">3487</span><span id="line-3487">  /**</span>
+<span class="source-line-no">3488</span><span id="line-3488">   * @see org.apache.hadoop.hbase.master.HMasterCommandLine</span>
+<span class="source-line-no">3489</span><span id="line-3489">   */</span>
+<span class="source-line-no">3490</span><span id="line-3490">  public static void main(String[] args) {</span>
+<span class="source-line-no">3491</span><span id="line-3491">    LOG.info("STARTING service " + HMaster.class.getSimpleName());</span>
+<span class="source-line-no">3492</span><span id="line-3492">    VersionInfo.logVersion();</span>
+<span class="source-line-no">3493</span><span id="line-3493">    new HMasterCommandLine(HMaster.class).doMain(args);</span>
 <span class="source-line-no">3494</span><span id="line-3494">  }</span>
 <span class="source-line-no">3495</span><span id="line-3495"></span>
-<span class="source-line-no">3496</span><span id="line-3496">  public List&lt;HFileCleaner&gt; getHFileCleaners() {</span>
-<span class="source-line-no">3497</span><span id="line-3497">    return this.hfileCleaners;</span>
+<span class="source-line-no">3496</span><span id="line-3496">  public HFileCleaner getHFileCleaner() {</span>
+<span class="source-line-no">3497</span><span id="line-3497">    return this.hfileCleaners.get(0);</span>
 <span class="source-line-no">3498</span><span id="line-3498">  }</span>
 <span class="source-line-no">3499</span><span id="line-3499"></span>
-<span class="source-line-no">3500</span><span id="line-3500">  public LogCleaner getLogCleaner() {</span>
-<span class="source-line-no">3501</span><span id="line-3501">    return this.logCleaner;</span>
+<span class="source-line-no">3500</span><span id="line-3500">  public List&lt;HFileCleaner&gt; getHFileCleaners() {</span>
+<span class="source-line-no">3501</span><span id="line-3501">    return this.hfileCleaners;</span>
 <span class="source-line-no">3502</span><span id="line-3502">  }</span>
 <span class="source-line-no">3503</span><span id="line-3503"></span>
-<span class="source-line-no">3504</span><span id="line-3504">  /** Returns the underlying snapshot manager */</span>
-<span class="source-line-no">3505</span><span id="line-3505">  @Override</span>
-<span class="source-line-no">3506</span><span id="line-3506">  public SnapshotManager getSnapshotManager() {</span>
-<span class="source-line-no">3507</span><span id="line-3507">    return this.snapshotManager;</span>
-<span class="source-line-no">3508</span><span id="line-3508">  }</span>
-<span class="source-line-no">3509</span><span id="line-3509"></span>
-<span class="source-line-no">3510</span><span id="line-3510">  /** Returns the underlying MasterProcedureManagerHost */</span>
-<span class="source-line-no">3511</span><span id="line-3511">  @Override</span>
-<span class="source-line-no">3512</span><span id="line-3512">  public MasterProcedureManagerHost getMasterProcedureManagerHost() {</span>
-<span class="source-line-no">3513</span><span id="line-3513">    return mpmHost;</span>
-<span class="source-line-no">3514</span><span id="line-3514">  }</span>
-<span class="source-line-no">3515</span><span id="line-3515"></span>
-<span class="source-line-no">3516</span><span id="line-3516">  @Override</span>
-<span class="source-line-no">3517</span><span id="line-3517">  public ClusterSchema getClusterSchema() {</span>
-<span class="source-line-no">3518</span><span id="line-3518">    return this.clusterSchemaService;</span>
-<span class="source-line-no">3519</span><span id="line-3519">  }</span>
-<span class="source-line-no">3520</span><span id="line-3520"></span>
-<span class="source-line-no">3521</span><span id="line-3521">  /**</span>
-<span class="source-line-no">3522</span><span id="line-3522">   * Create a new Namespace.</span>
-<span class="source-line-no">3523</span><span id="line-3523">   * @param namespaceDescriptor descriptor for new Namespace</span>
-<span class="source-line-no">3524</span><span id="line-3524">   * @param nonceGroup          Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3525</span><span id="line-3525">   * @param nonce               A unique identifier for this operation from the client or process</span>
-<span class="source-line-no">3526</span><span id="line-3526">   *                            identified by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each</span>
-<span class="source-line-no">3527</span><span id="line-3527">   *                            operation gets a unique id).</span>
-<span class="source-line-no">3528</span><span id="line-3528">   * @return procedure id</span>
-<span class="source-line-no">3529</span><span id="line-3529">   */</span>
-<span class="source-line-no">3530</span><span id="line-3530">  long createNamespace(final NamespaceDescriptor namespaceDescriptor, final long nonceGroup,</span>
-<span class="source-line-no">3531</span><span id="line-3531">    final long nonce) throws IOException {</span>
-<span class="source-line-no">3532</span><span id="line-3532">    checkInitialized();</span>
-<span class="source-line-no">3533</span><span id="line-3533"></span>
-<span class="source-line-no">3534</span><span id="line-3534">    TableName.isLegalNamespaceName(Bytes.toBytes(namespaceDescriptor.getName()));</span>
-<span class="source-line-no">3535</span><span id="line-3535"></span>
-<span class="source-line-no">3536</span><span id="line-3536">    return MasterProcedureUtil</span>
-<span class="source-line-no">3537</span><span id="line-3537">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3538</span><span id="line-3538">        @Override</span>
-<span class="source-line-no">3539</span><span id="line-3539">        protected void run() throws IOException {</span>
-<span class="source-line-no">3540</span><span id="line-3540">          getMaster().getMasterCoprocessorHost().preCreateNamespace(namespaceDescriptor);</span>
-<span class="source-line-no">3541</span><span id="line-3541">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3542</span><span id="line-3542">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3543</span><span id="line-3543">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3544</span><span id="line-3544">          LOG.info(getClientIdAuditPrefix() + " creating " + namespaceDescriptor);</span>
-<span class="source-line-no">3545</span><span id="line-3545">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3546</span><span id="line-3546">          // continuing.</span>
-<span class="source-line-no">3547</span><span id="line-3547">          setProcId(getClusterSchema().createNamespace(namespaceDescriptor, getNonceKey(), latch));</span>
-<span class="source-line-no">3548</span><span id="line-3548">          latch.await();</span>
-<span class="source-line-no">3549</span><span id="line-3549">          getMaster().getMasterCoprocessorHost().postCreateNamespace(namespaceDescriptor);</span>
-<span class="source-line-no">3550</span><span id="line-3550">        }</span>
-<span class="source-line-no">3551</span><span id="line-3551"></span>
-<span class="source-line-no">3552</span><span id="line-3552">        @Override</span>
-<span class="source-line-no">3553</span><span id="line-3553">        protected String getDescription() {</span>
-<span class="source-line-no">3554</span><span id="line-3554">          return "CreateNamespaceProcedure";</span>
-<span class="source-line-no">3555</span><span id="line-3555">        }</span>
-<span class="source-line-no">3556</span><span id="line-3556">      });</span>
-<span class="source-line-no">3557</span><span id="line-3557">  }</span>
-<span class="source-line-no">3558</span><span id="line-3558"></span>
-<span class="source-line-no">3559</span><span id="line-3559">  /**</span>
-<span class="source-line-no">3560</span><span id="line-3560">   * Modify an existing Namespace.</span>
-<span class="source-line-no">3561</span><span id="line-3561">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3562</span><span id="line-3562">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">3563</span><span id="line-3563">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">3564</span><span id="line-3564">   *                   unique id).</span>
-<span class="source-line-no">3565</span><span id="line-3565">   * @return procedure id</span>
-<span class="source-line-no">3566</span><span id="line-3566">   */</span>
-<span class="source-line-no">3567</span><span id="line-3567">  long modifyNamespace(final NamespaceDescriptor newNsDescriptor, final long nonceGroup,</span>
-<span class="source-line-no">3568</span><span id="line-3568">    final long nonce) throws IOException {</span>
-<span class="source-line-no">3569</span><span id="line-3569">    checkInitialized();</span>
-<span class="source-line-no">3570</span><span id="line-3570"></span>
-<span class="source-line-no">3571</span><span id="line-3571">    TableName.isLegalNamespaceName(Bytes.toBytes(newNsDescriptor.getName()));</span>
-<span class="source-line-no">3572</span><span id="line-3572"></span>
-<span class="source-line-no">3573</span><span id="line-3573">    return MasterProcedureUtil</span>
-<span class="source-line-no">3574</span><span id="line-3574">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3575</span><span id="line-3575">        @Override</span>
-<span class="source-line-no">3576</span><span id="line-3576">        protected void run() throws IOException {</span>
-<span class="source-line-no">3577</span><span id="line-3577">          NamespaceDescriptor oldNsDescriptor = getNamespace(newNsDescriptor.getName());</span>
-<span class="source-line-no">3578</span><span id="line-3578">          getMaster().getMasterCoprocessorHost().preModifyNamespace(oldNsDescriptor,</span>
-<span class="source-line-no">3579</span><span id="line-3579">            newNsDescriptor);</span>
-<span class="source-line-no">3580</span><span id="line-3580">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3581</span><span id="line-3581">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3582</span><span id="line-3582">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3583</span><span id="line-3583">          LOG.info(getClientIdAuditPrefix() + " modify " + newNsDescriptor);</span>
-<span class="source-line-no">3584</span><span id="line-3584">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3585</span><span id="line-3585">          // continuing.</span>
-<span class="source-line-no">3586</span><span id="line-3586">          setProcId(getClusterSchema().modifyNamespace(newNsDescriptor, getNonceKey(), latch));</span>
-<span class="source-line-no">3587</span><span id="line-3587">          latch.await();</span>
-<span class="source-line-no">3588</span><span id="line-3588">          getMaster().getMasterCoprocessorHost().postModifyNamespace(oldNsDescriptor,</span>
-<span class="source-line-no">3589</span><span id="line-3589">            newNsDescriptor);</span>
-<span class="source-line-no">3590</span><span id="line-3590">        }</span>
-<span class="source-line-no">3591</span><span id="line-3591"></span>
-<span class="source-line-no">3592</span><span id="line-3592">        @Override</span>
-<span class="source-line-no">3593</span><span id="line-3593">        protected String getDescription() {</span>
-<span class="source-line-no">3594</span><span id="line-3594">          return "ModifyNamespaceProcedure";</span>
-<span class="source-line-no">3595</span><span id="line-3595">        }</span>
-<span class="source-line-no">3596</span><span id="line-3596">      });</span>
-<span class="source-line-no">3597</span><span id="line-3597">  }</span>
-<span class="source-line-no">3598</span><span id="line-3598"></span>
-<span class="source-line-no">3599</span><span id="line-3599">  /**</span>
-<span class="source-line-no">3600</span><span id="line-3600">   * Delete an existing Namespace. Only empty Namespaces (no tables) can be removed.</span>
-<span class="source-line-no">3601</span><span id="line-3601">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3602</span><span id="line-3602">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">3603</span><span id="line-3603">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">3604</span><span id="line-3604">   *                   unique id).</span>
-<span class="source-line-no">3605</span><span id="line-3605">   * @return procedure id</span>
-<span class="source-line-no">3606</span><span id="line-3606">   */</span>
-<span class="source-line-no">3607</span><span id="line-3607">  long deleteNamespace(final String name, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">3608</span><span id="line-3608">    throws IOException {</span>
-<span class="source-line-no">3609</span><span id="line-3609">    checkInitialized();</span>
-<span class="source-line-no">3610</span><span id="line-3610"></span>
-<span class="source-line-no">3611</span><span id="line-3611">    return MasterProcedureUtil</span>
-<span class="source-line-no">3612</span><span id="line-3612">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3613</span><span id="line-3613">        @Override</span>
-<span class="source-line-no">3614</span><span id="line-3614">        protected void run() throws IOException {</span>
-<span class="source-line-no">3615</span><span id="line-3615">          getMaster().getMasterCoprocessorHost().preDeleteNamespace(name);</span>
-<span class="source-line-no">3616</span><span id="line-3616">          LOG.info(getClientIdAuditPrefix() + " delete " + name);</span>
-<span class="source-line-no">3617</span><span id="line-3617">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3618</span><span id="line-3618">          // continuing.</span>
-<span class="source-line-no">3619</span><span id="line-3619">          //</span>
-<span class="source-line-no">3620</span><span id="line-3620">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3621</span><span id="line-3621">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3622</span><span id="line-3622">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3623</span><span id="line-3623">          setProcId(submitProcedure(</span>
-<span class="source-line-no">3624</span><span id="line-3624">            new DeleteNamespaceProcedure(procedureExecutor.getEnvironment(), name, latch)));</span>
-<span class="source-line-no">3625</span><span id="line-3625">          latch.await();</span>
-<span class="source-line-no">3626</span><span id="line-3626">          // Will not be invoked in the face of Exception thrown by the Procedure's execution</span>
-<span class="source-line-no">3627</span><span id="line-3627">          getMaster().getMasterCoprocessorHost().postDeleteNamespace(name);</span>
-<span class="source-line-no">3628</span><span id="line-3628">        }</span>
-<span class="source-line-no">3629</span><span id="line-3629"></span>
-<span class="source-line-no">3630</span><span id="line-3630">        @Override</span>
-<span class="source-line-no">3631</span><span id="line-3631">        protected String getDescription() {</span>
-<span class="source-line-no">3632</span><span id="line-3632">          return "DeleteNamespaceProcedure";</span>
-<span class="source-line-no">3633</span><span id="line-3633">        }</span>
-<span class="source-line-no">3634</span><span id="line-3634">      });</span>
-<span class="source-line-no">3635</span><span id="line-3635">  }</span>
-<span class="source-line-no">3636</span><span id="line-3636"></span>
-<span class="source-line-no">3637</span><span id="line-3637">  /**</span>
-<span class="source-line-no">3638</span><span id="line-3638">   * Get a Namespace</span>
-<span class="source-line-no">3639</span><span id="line-3639">   * @param name Name of the Namespace</span>
-<span class="source-line-no">3640</span><span id="line-3640">   * @return Namespace descriptor for &lt;code&gt;name&lt;/code&gt;</span>
-<span class="source-line-no">3641</span><span id="line-3641">   */</span>
-<span class="source-line-no">3642</span><span id="line-3642">  NamespaceDescriptor getNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3643</span><span id="line-3643">    checkInitialized();</span>
-<span class="source-line-no">3644</span><span id="line-3644">    if (this.cpHost != null) this.cpHost.preGetNamespaceDescriptor(name);</span>
-<span class="source-line-no">3645</span><span id="line-3645">    NamespaceDescriptor nsd = this.clusterSchemaService.getNamespace(name);</span>
-<span class="source-line-no">3646</span><span id="line-3646">    if (this.cpHost != null) this.cpHost.postGetNamespaceDescriptor(nsd);</span>
-<span class="source-line-no">3647</span><span id="line-3647">    return nsd;</span>
-<span class="source-line-no">3648</span><span id="line-3648">  }</span>
-<span class="source-line-no">3649</span><span id="line-3649"></span>
-<span class="source-line-no">3650</span><span id="line-3650">  /**</span>
-<span class="source-line-no">3651</span><span id="line-3651">   * Get all Namespaces</span>
-<span class="source-line-no">3652</span><span id="line-3652">   * @return All Namespace descriptors</span>
-<span class="source-line-no">3653</span><span id="line-3653">   */</span>
-<span class="source-line-no">3654</span><span id="line-3654">  List&lt;NamespaceDescriptor&gt; getNamespaces() throws IOException {</span>
-<span class="source-line-no">3655</span><span id="line-3655">    checkInitialized();</span>
-<span class="source-line-no">3656</span><span id="line-3656">    final List&lt;NamespaceDescriptor&gt; nsds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3657</span><span id="line-3657">    if (cpHost != null) {</span>
-<span class="source-line-no">3658</span><span id="line-3658">      cpHost.preListNamespaceDescriptors(nsds);</span>
-<span class="source-line-no">3659</span><span id="line-3659">    }</span>
-<span class="source-line-no">3660</span><span id="line-3660">    nsds.addAll(this.clusterSchemaService.getNamespaces());</span>
-<span class="source-line-no">3661</span><span id="line-3661">    if (this.cpHost != null) {</span>
-<span class="source-line-no">3662</span><span id="line-3662">      this.cpHost.postListNamespaceDescriptors(nsds);</span>
+<span class="source-line-no">3504</span><span id="line-3504">  public LogCleaner getLogCleaner() {</span>
+<span class="source-line-no">3505</span><span id="line-3505">    return this.logCleaner;</span>
+<span class="source-line-no">3506</span><span id="line-3506">  }</span>
+<span class="source-line-no">3507</span><span id="line-3507"></span>
+<span class="source-line-no">3508</span><span id="line-3508">  /** Returns the underlying snapshot manager */</span>
+<span class="source-line-no">3509</span><span id="line-3509">  @Override</span>
+<span class="source-line-no">3510</span><span id="line-3510">  public SnapshotManager getSnapshotManager() {</span>
+<span class="source-line-no">3511</span><span id="line-3511">    return this.snapshotManager;</span>
+<span class="source-line-no">3512</span><span id="line-3512">  }</span>
+<span class="source-line-no">3513</span><span id="line-3513"></span>
+<span class="source-line-no">3514</span><span id="line-3514">  /** Returns the underlying MasterProcedureManagerHost */</span>
+<span class="source-line-no">3515</span><span id="line-3515">  @Override</span>
+<span class="source-line-no">3516</span><span id="line-3516">  public MasterProcedureManagerHost getMasterProcedureManagerHost() {</span>
+<span class="source-line-no">3517</span><span id="line-3517">    return mpmHost;</span>
+<span class="source-line-no">3518</span><span id="line-3518">  }</span>
+<span class="source-line-no">3519</span><span id="line-3519"></span>
+<span class="source-line-no">3520</span><span id="line-3520">  @Override</span>
+<span class="source-line-no">3521</span><span id="line-3521">  public ClusterSchema getClusterSchema() {</span>
+<span class="source-line-no">3522</span><span id="line-3522">    return this.clusterSchemaService;</span>
+<span class="source-line-no">3523</span><span id="line-3523">  }</span>
+<span class="source-line-no">3524</span><span id="line-3524"></span>
+<span class="source-line-no">3525</span><span id="line-3525">  /**</span>
+<span class="source-line-no">3526</span><span id="line-3526">   * Create a new Namespace.</span>
+<span class="source-line-no">3527</span><span id="line-3527">   * @param namespaceDescriptor descriptor for new Namespace</span>
+<span class="source-line-no">3528</span><span id="line-3528">   * @param nonceGroup          Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3529</span><span id="line-3529">   * @param nonce               A unique identifier for this operation from the client or process</span>
+<span class="source-line-no">3530</span><span id="line-3530">   *                            identified by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each</span>
+<span class="source-line-no">3531</span><span id="line-3531">   *                            operation gets a unique id).</span>
+<span class="source-line-no">3532</span><span id="line-3532">   * @return procedure id</span>
+<span class="source-line-no">3533</span><span id="line-3533">   */</span>
+<span class="source-line-no">3534</span><span id="line-3534">  long createNamespace(final NamespaceDescriptor namespaceDescriptor, final long nonceGroup,</span>
+<span class="source-line-no">3535</span><span id="line-3535">    final long nonce) throws IOException {</span>
+<span class="source-line-no">3536</span><span id="line-3536">    checkInitialized();</span>
+<span class="source-line-no">3537</span><span id="line-3537"></span>
+<span class="source-line-no">3538</span><span id="line-3538">    TableName.isLegalNamespaceName(Bytes.toBytes(namespaceDescriptor.getName()));</span>
+<span class="source-line-no">3539</span><span id="line-3539"></span>
+<span class="source-line-no">3540</span><span id="line-3540">    return MasterProcedureUtil</span>
+<span class="source-line-no">3541</span><span id="line-3541">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3542</span><span id="line-3542">        @Override</span>
+<span class="source-line-no">3543</span><span id="line-3543">        protected void run() throws IOException {</span>
+<span class="source-line-no">3544</span><span id="line-3544">          getMaster().getMasterCoprocessorHost().preCreateNamespace(namespaceDescriptor);</span>
+<span class="source-line-no">3545</span><span id="line-3545">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3546</span><span id="line-3546">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3547</span><span id="line-3547">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3548</span><span id="line-3548">          LOG.info(getClientIdAuditPrefix() + " creating " + namespaceDescriptor);</span>
+<span class="source-line-no">3549</span><span id="line-3549">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3550</span><span id="line-3550">          // continuing.</span>
+<span class="source-line-no">3551</span><span id="line-3551">          setProcId(getClusterSchema().createNamespace(namespaceDescriptor, getNonceKey(), latch));</span>
+<span class="source-line-no">3552</span><span id="line-3552">          latch.await();</span>
+<span class="source-line-no">3553</span><span id="line-3553">          getMaster().getMasterCoprocessorHost().postCreateNamespace(namespaceDescriptor);</span>
+<span class="source-line-no">3554</span><span id="line-3554">        }</span>
+<span class="source-line-no">3555</span><span id="line-3555"></span>
+<span class="source-line-no">3556</span><span id="line-3556">        @Override</span>
+<span class="source-line-no">3557</span><span id="line-3557">        protected String getDescription() {</span>
+<span class="source-line-no">3558</span><span id="line-3558">          return "CreateNamespaceProcedure";</span>
+<span class="source-line-no">3559</span><span id="line-3559">        }</span>
+<span class="source-line-no">3560</span><span id="line-3560">      });</span>
+<span class="source-line-no">3561</span><span id="line-3561">  }</span>
+<span class="source-line-no">3562</span><span id="line-3562"></span>
+<span class="source-line-no">3563</span><span id="line-3563">  /**</span>
+<span class="source-line-no">3564</span><span id="line-3564">   * Modify an existing Namespace.</span>
+<span class="source-line-no">3565</span><span id="line-3565">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3566</span><span id="line-3566">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">3567</span><span id="line-3567">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">3568</span><span id="line-3568">   *                   unique id).</span>
+<span class="source-line-no">3569</span><span id="line-3569">   * @return procedure id</span>
+<span class="source-line-no">3570</span><span id="line-3570">   */</span>
+<span class="source-line-no">3571</span><span id="line-3571">  long modifyNamespace(final NamespaceDescriptor newNsDescriptor, final long nonceGroup,</span>
+<span class="source-line-no">3572</span><span id="line-3572">    final long nonce) throws IOException {</span>
+<span class="source-line-no">3573</span><span id="line-3573">    checkInitialized();</span>
+<span class="source-line-no">3574</span><span id="line-3574"></span>
+<span class="source-line-no">3575</span><span id="line-3575">    TableName.isLegalNamespaceName(Bytes.toBytes(newNsDescriptor.getName()));</span>
+<span class="source-line-no">3576</span><span id="line-3576"></span>
+<span class="source-line-no">3577</span><span id="line-3577">    return MasterProcedureUtil</span>
+<span class="source-line-no">3578</span><span id="line-3578">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3579</span><span id="line-3579">        @Override</span>
+<span class="source-line-no">3580</span><span id="line-3580">        protected void run() throws IOException {</span>
+<span class="source-line-no">3581</span><span id="line-3581">          NamespaceDescriptor oldNsDescriptor = getNamespace(newNsDescriptor.getName());</span>
+<span class="source-line-no">3582</span><span id="line-3582">          getMaster().getMasterCoprocessorHost().preModifyNamespace(oldNsDescriptor,</span>
+<span class="source-line-no">3583</span><span id="line-3583">            newNsDescriptor);</span>
+<span class="source-line-no">3584</span><span id="line-3584">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3585</span><span id="line-3585">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3586</span><span id="line-3586">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3587</span><span id="line-3587">          LOG.info(getClientIdAuditPrefix() + " modify " + newNsDescriptor);</span>
+<span class="source-line-no">3588</span><span id="line-3588">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3589</span><span id="line-3589">          // continuing.</span>
+<span class="source-line-no">3590</span><span id="line-3590">          setProcId(getClusterSchema().modifyNamespace(newNsDescriptor, getNonceKey(), latch));</span>
+<span class="source-line-no">3591</span><span id="line-3591">          latch.await();</span>
+<span class="source-line-no">3592</span><span id="line-3592">          getMaster().getMasterCoprocessorHost().postModifyNamespace(oldNsDescriptor,</span>
+<span class="source-line-no">3593</span><span id="line-3593">            newNsDescriptor);</span>
+<span class="source-line-no">3594</span><span id="line-3594">        }</span>
+<span class="source-line-no">3595</span><span id="line-3595"></span>
+<span class="source-line-no">3596</span><span id="line-3596">        @Override</span>
+<span class="source-line-no">3597</span><span id="line-3597">        protected String getDescription() {</span>
+<span class="source-line-no">3598</span><span id="line-3598">          return "ModifyNamespaceProcedure";</span>
+<span class="source-line-no">3599</span><span id="line-3599">        }</span>
+<span class="source-line-no">3600</span><span id="line-3600">      });</span>
+<span class="source-line-no">3601</span><span id="line-3601">  }</span>
+<span class="source-line-no">3602</span><span id="line-3602"></span>
+<span class="source-line-no">3603</span><span id="line-3603">  /**</span>
+<span class="source-line-no">3604</span><span id="line-3604">   * Delete an existing Namespace. Only empty Namespaces (no tables) can be removed.</span>
+<span class="source-line-no">3605</span><span id="line-3605">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3606</span><span id="line-3606">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">3607</span><span id="line-3607">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">3608</span><span id="line-3608">   *                   unique id).</span>
+<span class="source-line-no">3609</span><span id="line-3609">   * @return procedure id</span>
+<span class="source-line-no">3610</span><span id="line-3610">   */</span>
+<span class="source-line-no">3611</span><span id="line-3611">  long deleteNamespace(final String name, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">3612</span><span id="line-3612">    throws IOException {</span>
+<span class="source-line-no">3613</span><span id="line-3613">    checkInitialized();</span>
+<span class="source-line-no">3614</span><span id="line-3614"></span>
+<span class="source-line-no">3615</span><span id="line-3615">    return MasterProcedureUtil</span>
+<span class="source-line-no">3616</span><span id="line-3616">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3617</span><span id="line-3617">        @Override</span>
+<span class="source-line-no">3618</span><span id="line-3618">        protected void run() throws IOException {</span>
+<span class="source-line-no">3619</span><span id="line-3619">          getMaster().getMasterCoprocessorHost().preDeleteNamespace(name);</span>
+<span class="source-line-no">3620</span><span id="line-3620">          LOG.info(getClientIdAuditPrefix() + " delete " + name);</span>
+<span class="source-line-no">3621</span><span id="line-3621">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3622</span><span id="line-3622">          // continuing.</span>
+<span class="source-line-no">3623</span><span id="line-3623">          //</span>
+<span class="source-line-no">3624</span><span id="line-3624">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3625</span><span id="line-3625">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3626</span><span id="line-3626">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3627</span><span id="line-3627">          setProcId(submitProcedure(</span>
+<span class="source-line-no">3628</span><span id="line-3628">            new DeleteNamespaceProcedure(procedureExecutor.getEnvironment(), name, latch)));</span>
+<span class="source-line-no">3629</span><span id="line-3629">          latch.await();</span>
+<span class="source-line-no">3630</span><span id="line-3630">          // Will not be invoked in the face of Exception thrown by the Procedure's execution</span>
+<span class="source-line-no">3631</span><span id="line-3631">          getMaster().getMasterCoprocessorHost().postDeleteNamespace(name);</span>
+<span class="source-line-no">3632</span><span id="line-3632">        }</span>
+<span class="source-line-no">3633</span><span id="line-3633"></span>
+<span class="source-line-no">3634</span><span id="line-3634">        @Override</span>
+<span class="source-line-no">3635</span><span id="line-3635">        protected String getDescription() {</span>
+<span class="source-line-no">3636</span><span id="line-3636">          return "DeleteNamespaceProcedure";</span>
+<span class="source-line-no">3637</span><span id="line-3637">        }</span>
+<span class="source-line-no">3638</span><span id="line-3638">      });</span>
+<span class="source-line-no">3639</span><span id="line-3639">  }</span>
+<span class="source-line-no">3640</span><span id="line-3640"></span>
+<span class="source-line-no">3641</span><span id="line-3641">  /**</span>
+<span class="source-line-no">3642</span><span id="line-3642">   * Get a Namespace</span>
+<span class="source-line-no">3643</span><span id="line-3643">   * @param name Name of the Namespace</span>
+<span class="source-line-no">3644</span><span id="line-3644">   * @return Namespace descriptor for &lt;code&gt;name&lt;/code&gt;</span>
+<span class="source-line-no">3645</span><span id="line-3645">   */</span>
+<span class="source-line-no">3646</span><span id="line-3646">  NamespaceDescriptor getNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3647</span><span id="line-3647">    checkInitialized();</span>
+<span class="source-line-no">3648</span><span id="line-3648">    if (this.cpHost != null) this.cpHost.preGetNamespaceDescriptor(name);</span>
+<span class="source-line-no">3649</span><span id="line-3649">    NamespaceDescriptor nsd = this.clusterSchemaService.getNamespace(name);</span>
+<span class="source-line-no">3650</span><span id="line-3650">    if (this.cpHost != null) this.cpHost.postGetNamespaceDescriptor(nsd);</span>
+<span class="source-line-no">3651</span><span id="line-3651">    return nsd;</span>
+<span class="source-line-no">3652</span><span id="line-3652">  }</span>
+<span class="source-line-no">3653</span><span id="line-3653"></span>
+<span class="source-line-no">3654</span><span id="line-3654">  /**</span>
+<span class="source-line-no">3655</span><span id="line-3655">   * Get all Namespaces</span>
+<span class="source-line-no">3656</span><span id="line-3656">   * @return All Namespace descriptors</span>
+<span class="source-line-no">3657</span><span id="line-3657">   */</span>
+<span class="source-line-no">3658</span><span id="line-3658">  List&lt;NamespaceDescriptor&gt; getNamespaces() throws IOException {</span>
+<span class="source-line-no">3659</span><span id="line-3659">    checkInitialized();</span>
+<span class="source-line-no">3660</span><span id="line-3660">    final List&lt;NamespaceDescriptor&gt; nsds = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">3661</span><span id="line-3661">    if (cpHost != null) {</span>
+<span class="source-line-no">3662</span><span id="line-3662">      cpHost.preListNamespaceDescriptors(nsds);</span>
 <span class="source-line-no">3663</span><span id="line-3663">    }</span>
-<span class="source-line-no">3664</span><span id="line-3664">    return nsds;</span>
-<span class="source-line-no">3665</span><span id="line-3665">  }</span>
-<span class="source-line-no">3666</span><span id="line-3666"></span>
-<span class="source-line-no">3667</span><span id="line-3667">  /**</span>
-<span class="source-line-no">3668</span><span id="line-3668">   * List namespace names</span>
-<span class="source-line-no">3669</span><span id="line-3669">   * @return All namespace names</span>
-<span class="source-line-no">3670</span><span id="line-3670">   */</span>
-<span class="source-line-no">3671</span><span id="line-3671">  public List&lt;String&gt; listNamespaces() throws IOException {</span>
-<span class="source-line-no">3672</span><span id="line-3672">    checkInitialized();</span>
-<span class="source-line-no">3673</span><span id="line-3673">    List&lt;String&gt; namespaces = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3674</span><span id="line-3674">    if (cpHost != null) {</span>
-<span class="source-line-no">3675</span><span id="line-3675">      cpHost.preListNamespaces(namespaces);</span>
-<span class="source-line-no">3676</span><span id="line-3676">    }</span>
-<span class="source-line-no">3677</span><span id="line-3677">    for (NamespaceDescriptor namespace : clusterSchemaService.getNamespaces()) {</span>
-<span class="source-line-no">3678</span><span id="line-3678">      namespaces.add(namespace.getName());</span>
-<span class="source-line-no">3679</span><span id="line-3679">    }</span>
-<span class="source-line-no">3680</span><span id="line-3680">    if (cpHost != null) {</span>
-<span class="source-line-no">3681</span><span id="line-3681">      cpHost.postListNamespaces(namespaces);</span>
-<span class="source-line-no">3682</span><span id="line-3682">    }</span>
-<span class="source-line-no">3683</span><span id="line-3683">    return namespaces;</span>
-<span class="source-line-no">3684</span><span id="line-3684">  }</span>
-<span class="source-line-no">3685</span><span id="line-3685"></span>
-<span class="source-line-no">3686</span><span id="line-3686">  @Override</span>
-<span class="source-line-no">3687</span><span id="line-3687">  public List&lt;TableName&gt; listTableNamesByNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3688</span><span id="line-3688">    checkInitialized();</span>
-<span class="source-line-no">3689</span><span id="line-3689">    return listTableNames(name, null, true);</span>
-<span class="source-line-no">3690</span><span id="line-3690">  }</span>
-<span class="source-line-no">3691</span><span id="line-3691"></span>
-<span class="source-line-no">3692</span><span id="line-3692">  @Override</span>
-<span class="source-line-no">3693</span><span id="line-3693">  public List&lt;TableDescriptor&gt; listTableDescriptorsByNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3694</span><span id="line-3694">    checkInitialized();</span>
-<span class="source-line-no">3695</span><span id="line-3695">    return listTableDescriptors(name, null, null, true);</span>
-<span class="source-line-no">3696</span><span id="line-3696">  }</span>
-<span class="source-line-no">3697</span><span id="line-3697"></span>
-<span class="source-line-no">3698</span><span id="line-3698">  @Override</span>
-<span class="source-line-no">3699</span><span id="line-3699">  public boolean abortProcedure(final long procId, final boolean mayInterruptIfRunning)</span>
-<span class="source-line-no">3700</span><span id="line-3700">    throws IOException {</span>
-<span class="source-line-no">3701</span><span id="line-3701">    if (cpHost != null) {</span>
-<span class="source-line-no">3702</span><span id="line-3702">      cpHost.preAbortProcedure(this.procedureExecutor, procId);</span>
-<span class="source-line-no">3703</span><span id="line-3703">    }</span>
-<span class="source-line-no">3704</span><span id="line-3704"></span>
-<span class="source-line-no">3705</span><span id="line-3705">    final boolean result = this.procedureExecutor.abort(procId, mayInterruptIfRunning);</span>
-<span class="source-line-no">3706</span><span id="line-3706"></span>
-<span class="source-line-no">3707</span><span id="line-3707">    if (cpHost != null) {</span>
-<span class="source-line-no">3708</span><span id="line-3708">      cpHost.postAbortProcedure();</span>
-<span class="source-line-no">3709</span><span id="line-3709">    }</span>
+<span class="source-line-no">3664</span><span id="line-3664">    nsds.addAll(this.clusterSchemaService.getNamespaces());</span>
+<span class="source-line-no">3665</span><span id="line-3665">    if (this.cpHost != null) {</span>
+<span class="source-line-no">3666</span><span id="line-3666">      this.cpHost.postListNamespaceDescriptors(nsds);</span>
+<span class="source-line-no">3667</span><span id="line-3667">    }</span>
+<span class="source-line-no">3668</span><span id="line-3668">    return nsds;</span>
+<span class="source-line-no">3669</span><span id="line-3669">  }</span>
+<span class="source-line-no">3670</span><span id="line-3670"></span>
+<span class="source-line-no">3671</span><span id="line-3671">  /**</span>
+<span class="source-line-no">3672</span><span id="line-3672">   * List namespace names</span>
+<span class="source-line-no">3673</span><span id="line-3673">   * @return All namespace names</span>
+<span class="source-line-no">3674</span><span id="line-3674">   */</span>
+<span class="source-line-no">3675</span><span id="line-3675">  public List&lt;String&gt; listNamespaces() throws IOException {</span>
+<span class="source-line-no">3676</span><span id="line-3676">    checkInitialized();</span>
+<span class="source-line-no">3677</span><span id="line-3677">    List&lt;String&gt; namespaces = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">3678</span><span id="line-3678">    if (cpHost != null) {</span>
+<span class="source-line-no">3679</span><span id="line-3679">      cpHost.preListNamespaces(namespaces);</span>
+<span class="source-line-no">3680</span><span id="line-3680">    }</span>
+<span class="source-line-no">3681</span><span id="line-3681">    for (NamespaceDescriptor namespace : clusterSchemaService.getNamespaces()) {</span>
+<span class="source-line-no">3682</span><span id="line-3682">      namespaces.add(namespace.getName());</span>
+<span class="source-line-no">3683</span><span id="line-3683">    }</span>
+<span class="source-line-no">3684</span><span id="line-3684">    if (cpHost != null) {</span>
+<span class="source-line-no">3685</span><span id="line-3685">      cpHost.postListNamespaces(namespaces);</span>
+<span class="source-line-no">3686</span><span id="line-3686">    }</span>
+<span class="source-line-no">3687</span><span id="line-3687">    return namespaces;</span>
+<span class="source-line-no">3688</span><span id="line-3688">  }</span>
+<span class="source-line-no">3689</span><span id="line-3689"></span>
+<span class="source-line-no">3690</span><span id="line-3690">  @Override</span>
+<span class="source-line-no">3691</span><span id="line-3691">  public List&lt;TableName&gt; listTableNamesByNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3692</span><span id="line-3692">    checkInitialized();</span>
+<span class="source-line-no">3693</span><span id="line-3693">    return listTableNames(name, null, true);</span>
+<span class="source-line-no">3694</span><span id="line-3694">  }</span>
+<span class="source-line-no">3695</span><span id="line-3695"></span>
+<span class="source-line-no">3696</span><span id="line-3696">  @Override</span>
+<span class="source-line-no">3697</span><span id="line-3697">  public List&lt;TableDescriptor&gt; listTableDescriptorsByNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3698</span><span id="line-3698">    checkInitialized();</span>
+<span class="source-line-no">3699</span><span id="line-3699">    return listTableDescriptors(name, null, null, true);</span>
+<span class="source-line-no">3700</span><span id="line-3700">  }</span>
+<span class="source-line-no">3701</span><span id="line-3701"></span>
+<span class="source-line-no">3702</span><span id="line-3702">  @Override</span>
+<span class="source-line-no">3703</span><span id="line-3703">  public boolean abortProcedure(final long procId, final boolean mayInterruptIfRunning)</span>
+<span class="source-line-no">3704</span><span id="line-3704">    throws IOException {</span>
+<span class="source-line-no">3705</span><span id="line-3705">    if (cpHost != null) {</span>
+<span class="source-line-no">3706</span><span id="line-3706">      cpHost.preAbortProcedure(this.procedureExecutor, procId);</span>
+<span class="source-line-no">3707</span><span id="line-3707">    }</span>
+<span class="source-line-no">3708</span><span id="line-3708"></span>
+<span class="source-line-no">3709</span><span id="line-3709">    final boolean result = this.procedureExecutor.abort(procId, mayInterruptIfRunning);</span>
 <span class="source-line-no">3710</span><span id="line-3710"></span>
-<span class="source-line-no">3711</span><span id="line-3711">    return result;</span>
-<span class="source-line-no">3712</span><span id="line-3712">  }</span>
-<span class="source-line-no">3713</span><span id="line-3713"></span>
-<span class="source-line-no">3714</span><span id="line-3714">  @Override</span>
-<span class="source-line-no">3715</span><span id="line-3715">  public List&lt;Procedure&lt;?&gt;&gt; getProcedures() throws IOException {</span>
-<span class="source-line-no">3716</span><span id="line-3716">    if (cpHost != null) {</span>
-<span class="source-line-no">3717</span><span id="line-3717">      cpHost.preGetProcedures();</span>
-<span class="source-line-no">3718</span><span id="line-3718">    }</span>
-<span class="source-line-no">3719</span><span id="line-3719"></span>
-<span class="source-line-no">3720</span><span id="line-3720">    @SuppressWarnings({ "unchecked", "rawtypes" })</span>
-<span class="source-line-no">3721</span><span id="line-3721">    List&lt;Procedure&lt;?&gt;&gt; procList = (List) this.procedureExecutor.getProcedures();</span>
-<span class="source-line-no">3722</span><span id="line-3722"></span>
-<span class="source-line-no">3723</span><span id="line-3723">    if (cpHost != null) {</span>
-<span class="source-line-no">3724</span><span id="line-3724">      cpHost.postGetProcedures(procList);</span>
-<span class="source-line-no">3725</span><span id="line-3725">    }</span>
+<span class="source-line-no">3711</span><span id="line-3711">    if (cpHost != null) {</span>
+<span class="source-line-no">3712</span><span id="line-3712">      cpHost.postAbortProcedure();</span>
+<span class="source-line-no">3713</span><span id="line-3713">    }</span>
+<span class="source-line-no">3714</span><span id="line-3714"></span>
+<span class="source-line-no">3715</span><span id="line-3715">    return result;</span>
+<span class="source-line-no">3716</span><span id="line-3716">  }</span>
+<span class="source-line-no">3717</span><span id="line-3717"></span>
+<span class="source-line-no">3718</span><span id="line-3718">  @Override</span>
+<span class="source-line-no">3719</span><span id="line-3719">  public List&lt;Procedure&lt;?&gt;&gt; getProcedures() throws IOException {</span>
+<span class="source-line-no">3720</span><span id="line-3720">    if (cpHost != null) {</span>
+<span class="source-line-no">3721</span><span id="line-3721">      cpHost.preGetProcedures();</span>
+<span class="source-line-no">3722</span><span id="line-3722">    }</span>
+<span class="source-line-no">3723</span><span id="line-3723"></span>
+<span class="source-line-no">3724</span><span id="line-3724">    @SuppressWarnings({ "unchecked", "rawtypes" })</span>
+<span class="source-line-no">3725</span><span id="line-3725">    List&lt;Procedure&lt;?&gt;&gt; procList = (List) this.procedureExecutor.getProcedures();</span>
 <span class="source-line-no">3726</span><span id="line-3726"></span>
-<span class="source-line-no">3727</span><span id="line-3727">    return procList;</span>
-<span class="source-line-no">3728</span><span id="line-3728">  }</span>
-<span class="source-line-no">3729</span><span id="line-3729"></span>
-<span class="source-line-no">3730</span><span id="line-3730">  @Override</span>
-<span class="source-line-no">3731</span><span id="line-3731">  public List&lt;LockedResource&gt; getLocks() throws IOException {</span>
-<span class="source-line-no">3732</span><span id="line-3732">    if (cpHost != null) {</span>
-<span class="source-line-no">3733</span><span id="line-3733">      cpHost.preGetLocks();</span>
-<span class="source-line-no">3734</span><span id="line-3734">    }</span>
-<span class="source-line-no">3735</span><span id="line-3735"></span>
-<span class="source-line-no">3736</span><span id="line-3736">    MasterProcedureScheduler procedureScheduler =</span>
-<span class="source-line-no">3737</span><span id="line-3737">      procedureExecutor.getEnvironment().getProcedureScheduler();</span>
-<span class="source-line-no">3738</span><span id="line-3738"></span>
-<span class="source-line-no">3739</span><span id="line-3739">    final List&lt;LockedResource&gt; lockedResources = procedureScheduler.getLocks();</span>
-<span class="source-line-no">3740</span><span id="line-3740"></span>
-<span class="source-line-no">3741</span><span id="line-3741">    if (cpHost != null) {</span>
-<span class="source-line-no">3742</span><span id="line-3742">      cpHost.postGetLocks(lockedResources);</span>
-<span class="source-line-no">3743</span><span id="line-3743">    }</span>
+<span class="source-line-no">3727</span><span id="line-3727">    if (cpHost != null) {</span>
+<span class="source-line-no">3728</span><span id="line-3728">      cpHost.postGetProcedures(procList);</span>
+<span class="source-line-no">3729</span><span id="line-3729">    }</span>
+<span class="source-line-no">3730</span><span id="line-3730"></span>
+<span class="source-line-no">3731</span><span id="line-3731">    return procList;</span>
+<span class="source-line-no">3732</span><span id="line-3732">  }</span>
+<span class="source-line-no">3733</span><span id="line-3733"></span>
+<span class="source-line-no">3734</span><span id="line-3734">  @Override</span>
+<span class="source-line-no">3735</span><span id="line-3735">  public List&lt;LockedResource&gt; getLocks() throws IOException {</span>
+<span class="source-line-no">3736</span><span id="line-3736">    if (cpHost != null) {</span>
+<span class="source-line-no">3737</span><span id="line-3737">      cpHost.preGetLocks();</span>
+<span class="source-line-no">3738</span><span id="line-3738">    }</span>
+<span class="source-line-no">3739</span><span id="line-3739"></span>
+<span class="source-line-no">3740</span><span id="line-3740">    MasterProcedureScheduler procedureScheduler =</span>
+<span class="source-line-no">3741</span><span id="line-3741">      procedureExecutor.getEnvironment().getProcedureScheduler();</span>
+<span class="source-line-no">3742</span><span id="line-3742"></span>
+<span class="source-line-no">3743</span><span id="line-3743">    final List&lt;LockedResource&gt; lockedResources = procedureScheduler.getLocks();</span>
 <span class="source-line-no">3744</span><span id="line-3744"></span>
-<span class="source-line-no">3745</span><span id="line-3745">    return lockedResources;</span>
-<span class="source-line-no">3746</span><span id="line-3746">  }</span>
-<span class="source-line-no">3747</span><span id="line-3747"></span>
-<span class="source-line-no">3748</span><span id="line-3748">  /**</span>
-<span class="source-line-no">3749</span><span id="line-3749">   * Returns the list of table descriptors that match the specified request</span>
-<span class="source-line-no">3750</span><span id="line-3750">   * @param namespace        the namespace to query, or null if querying for all</span>
-<span class="source-line-no">3751</span><span id="line-3751">   * @param regex            The regular expression to match against, or null if querying for all</span>
-<span class="source-line-no">3752</span><span id="line-3752">   * @param tableNameList    the list of table names, or null if querying for all</span>
-<span class="source-line-no">3753</span><span id="line-3753">   * @param includeSysTables False to match only against userspace tables</span>
-<span class="source-line-no">3754</span><span id="line-3754">   * @return the list of table descriptors</span>
-<span class="source-line-no">3755</span><span id="line-3755">   */</span>
-<span class="source-line-no">3756</span><span id="line-3756">  public List&lt;TableDescriptor&gt; listTableDescriptors(final String namespace, final String regex,</span>
-<span class="source-line-no">3757</span><span id="line-3757">    final List&lt;TableName&gt; tableNameList, final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3758</span><span id="line-3758">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3759</span><span id="line-3759">    if (cpHost != null) {</span>
-<span class="source-line-no">3760</span><span id="line-3760">      cpHost.preGetTableDescriptors(tableNameList, htds, regex);</span>
-<span class="source-line-no">3761</span><span id="line-3761">    }</span>
-<span class="source-line-no">3762</span><span id="line-3762">    htds = getTableDescriptors(htds, namespace, regex, tableNameList, includeSysTables);</span>
+<span class="source-line-no">3745</span><span id="line-3745">    if (cpHost != null) {</span>
+<span class="source-line-no">3746</span><span id="line-3746">      cpHost.postGetLocks(lockedResources);</span>
+<span class="source-line-no">3747</span><span id="line-3747">    }</span>
+<span class="source-line-no">3748</span><span id="line-3748"></span>
+<span class="source-line-no">3749</span><span id="line-3749">    return lockedResources;</span>
+<span class="source-line-no">3750</span><span id="line-3750">  }</span>
+<span class="source-line-no">3751</span><span id="line-3751"></span>
+<span class="source-line-no">3752</span><span id="line-3752">  /**</span>
+<span class="source-line-no">3753</span><span id="line-3753">   * Returns the list of table descriptors that match the specified request</span>
+<span class="source-line-no">3754</span><span id="line-3754">   * @param namespace        the namespace to query, or null if querying for all</span>
+<span class="source-line-no">3755</span><span id="line-3755">   * @param regex            The regular expression to match against, or null if querying for all</span>
+<span class="source-line-no">3756</span><span id="line-3756">   * @param tableNameList    the list of table names, or null if querying for all</span>
+<span class="source-line-no">3757</span><span id="line-3757">   * @param includeSysTables False to match only against userspace tables</span>
+<span class="source-line-no">3758</span><span id="line-3758">   * @return the list of table descriptors</span>
+<span class="source-line-no">3759</span><span id="line-3759">   */</span>
+<span class="source-line-no">3760</span><span id="line-3760">  public List&lt;TableDescriptor&gt; listTableDescriptors(final String namespace, final String regex,</span>
+<span class="source-line-no">3761</span><span id="line-3761">    final List&lt;TableName&gt; tableNameList, final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3762</span><span id="line-3762">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
 <span class="source-line-no">3763</span><span id="line-3763">    if (cpHost != null) {</span>
-<span class="source-line-no">3764</span><span id="line-3764">      cpHost.postGetTableDescriptors(tableNameList, htds, regex);</span>
+<span class="source-line-no">3764</span><span id="line-3764">      cpHost.preGetTableDescriptors(tableNameList, htds, regex);</span>
 <span class="source-line-no">3765</span><span id="line-3765">    }</span>
-<span class="source-line-no">3766</span><span id="line-3766">    return htds;</span>
-<span class="source-line-no">3767</span><span id="line-3767">  }</span>
-<span class="source-line-no">3768</span><span id="line-3768"></span>
-<span class="source-line-no">3769</span><span id="line-3769">  /**</span>
-<span class="source-line-no">3770</span><span id="line-3770">   * Returns the list of table names that match the specified request</span>
-<span class="source-line-no">3771</span><span id="line-3771">   * @param regex            The regular expression to match against, or null if querying for all</span>
-<span class="source-line-no">3772</span><span id="line-3772">   * @param namespace        the namespace to query, or null if querying for all</span>
-<span class="source-line-no">3773</span><span id="line-3773">   * @param includeSysTables False to match only against userspace tables</span>
-<span class="source-line-no">3774</span><span id="line-3774">   * @return the list of table names</span>
-<span class="source-line-no">3775</span><span id="line-3775">   */</span>
-<span class="source-line-no">3776</span><span id="line-3776">  public List&lt;TableName&gt; listTableNames(final String namespace, final String regex,</span>
-<span class="source-line-no">3777</span><span id="line-3777">    final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3778</span><span id="line-3778">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3779</span><span id="line-3779">    if (cpHost != null) {</span>
-<span class="source-line-no">3780</span><span id="line-3780">      cpHost.preGetTableNames(htds, regex);</span>
-<span class="source-line-no">3781</span><span id="line-3781">    }</span>
-<span class="source-line-no">3782</span><span id="line-3782">    htds = getTableDescriptors(htds, namespace, regex, null, includeSysTables);</span>
+<span class="source-line-no">3766</span><span id="line-3766">    htds = getTableDescriptors(htds, namespace, regex, tableNameList, includeSysTables);</span>
+<span class="source-line-no">3767</span><span id="line-3767">    if (cpHost != null) {</span>
+<span class="source-line-no">3768</span><span id="line-3768">      cpHost.postGetTableDescriptors(tableNameList, htds, regex);</span>
+<span class="source-line-no">3769</span><span id="line-3769">    }</span>
+<span class="source-line-no">3770</span><span id="line-3770">    return htds;</span>
+<span class="source-line-no">3771</span><span id="line-3771">  }</span>
+<span class="source-line-no">3772</span><span id="line-3772"></span>
+<span class="source-line-no">3773</span><span id="line-3773">  /**</span>
+<span class="source-line-no">3774</span><span id="line-3774">   * Returns the list of table names that match the specified request</span>
+<span class="source-line-no">3775</span><span id="line-3775">   * @param regex            The regular expression to match against, or null if querying for all</span>
+<span class="source-line-no">3776</span><span id="line-3776">   * @param namespace        the namespace to query, or null if querying for all</span>
+<span class="source-line-no">3777</span><span id="line-3777">   * @param includeSysTables False to match only against userspace tables</span>
+<span class="source-line-no">3778</span><span id="line-3778">   * @return the list of table names</span>
+<span class="source-line-no">3779</span><span id="line-3779">   */</span>
+<span class="source-line-no">3780</span><span id="line-3780">  public List&lt;TableName&gt; listTableNames(final String namespace, final String regex,</span>
+<span class="source-line-no">3781</span><span id="line-3781">    final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3782</span><span id="line-3782">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
 <span class="source-line-no">3783</span><span id="line-3783">    if (cpHost != null) {</span>
-<span class="source-line-no">3784</span><span id="line-3784">      cpHost.postGetTableNames(htds, regex);</span>
+<span class="source-line-no">3784</span><span id="line-3784">      cpHost.preGetTableNames(htds, regex);</span>
 <span class="source-line-no">3785</span><span id="line-3785">    }</span>
-<span class="source-line-no">3786</span><span id="line-3786">    List&lt;TableName&gt; result = new ArrayList&lt;&gt;(htds.size());</span>
-<span class="source-line-no">3787</span><span id="line-3787">    for (TableDescriptor htd : htds)</span>
-<span class="source-line-no">3788</span><span id="line-3788">      result.add(htd.getTableName());</span>
-<span class="source-line-no">3789</span><span id="line-3789">    return result;</span>
-<span class="source-line-no">3790</span><span id="line-3790">  }</span>
-<span class="source-line-no">3791</span><span id="line-3791"></span>
-<span class="source-line-no">3792</span><span id="line-3792">  /**</span>
-<span class="source-line-no">3793</span><span id="line-3793">   * Return a list of table table descriptors after applying any provided filter parameters. Note</span>
-<span class="source-line-no">3794</span><span id="line-3794">   * that the user-facing description of this filter logic is presented on the class-level javadoc</span>
-<span class="source-line-no">3795</span><span id="line-3795">   * of {@link NormalizeTableFilterParams}.</span>
-<span class="source-line-no">3796</span><span id="line-3796">   */</span>
-<span class="source-line-no">3797</span><span id="line-3797">  private List&lt;TableDescriptor&gt; getTableDescriptors(final List&lt;TableDescriptor&gt; htds,</span>
-<span class="source-line-no">3798</span><span id="line-3798">    final String namespace, final String regex, final List&lt;TableName&gt; tableNameList,</span>
-<span class="source-line-no">3799</span><span id="line-3799">    final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3800</span><span id="line-3800">    if (tableNameList == null || tableNameList.isEmpty()) {</span>
-<span class="source-line-no">3801</span><span id="line-3801">      // request for all TableDescriptors</span>
-<span class="source-line-no">3802</span><span id="line-3802">      Collection&lt;TableDescriptor&gt; allHtds;</span>
-<span class="source-line-no">3803</span><span id="line-3803">      if (namespace != null &amp;&amp; namespace.length() &gt; 0) {</span>
-<span class="source-line-no">3804</span><span id="line-3804">        // Do a check on the namespace existence. Will fail if does not exist.</span>
-<span class="source-line-no">3805</span><span id="line-3805">        this.clusterSchemaService.getNamespace(namespace);</span>
-<span class="source-line-no">3806</span><span id="line-3806">        allHtds = tableDescriptors.getByNamespace(namespace).values();</span>
-<span class="source-line-no">3807</span><span id="line-3807">      } else {</span>
-<span class="source-line-no">3808</span><span id="line-3808">        allHtds = tableDescriptors.getAll().values();</span>
-<span class="source-line-no">3809</span><span id="line-3809">      }</span>
-<span class="source-line-no">3810</span><span id="line-3810">      for (TableDescriptor desc : allHtds) {</span>
-<span class="source-line-no">3811</span><span id="line-3811">        if (</span>
-<span class="source-line-no">3812</span><span id="line-3812">          tableStateManager.isTablePresent(desc.getTableName())</span>
-<span class="source-line-no">3813</span><span id="line-3813">            &amp;&amp; (includeSysTables || !desc.getTableName().isSystemTable())</span>
-<span class="source-line-no">3814</span><span id="line-3814">        ) {</span>
-<span class="source-line-no">3815</span><span id="line-3815">          htds.add(desc);</span>
-<span class="source-line-no">3816</span><span id="line-3816">        }</span>
-<span class="source-line-no">3817</span><span id="line-3817">      }</span>
-<span class="source-line-no">3818</span><span id="line-3818">    } else {</span>
-<span class="source-line-no">3819</span><span id="line-3819">      for (TableName s : tableNameList) {</span>
-<span class="source-line-no">3820</span><span id="line-3820">        if (tableStateManager.isTablePresent(s)) {</span>
-<span class="source-line-no">3821</span><span id="line-3821">          TableDescriptor desc = tableDescriptors.get(s);</span>
-<span class="source-line-no">3822</span><span id="line-3822">          if (desc != null) {</span>
-<span class="source-line-no">3823</span><span id="line-3823">            htds.add(desc);</span>
-<span class="source-line-no">3824</span><span id="line-3824">          }</span>
-<span class="source-line-no">3825</span><span id="line-3825">        }</span>
-<span class="source-line-no">3826</span><span id="line-3826">      }</span>
-<span class="source-line-no">3827</span><span id="line-3827">    }</span>
-<span class="source-line-no">3828</span><span id="line-3828"></span>
-<span class="source-line-no">3829</span><span id="line-3829">    // Retains only those matched by regular expression.</span>
-<span class="source-line-no">3830</span><span id="line-3830">    if (regex != null) filterTablesByRegex(htds, Pattern.compile(regex));</span>
-<span class="source-line-no">3831</span><span id="line-3831">    return htds;</span>
-<span class="source-line-no">3832</span><span id="line-3832">  }</span>
-<span class="source-line-no">3833</span><span id="line-3833"></span>
-<span class="source-line-no">3834</span><span id="line-3834">  /**</span>
-<span class="source-line-no">3835</span><span id="line-3835">   * Removes the table descriptors that don't match the pattern.</span>
-<span class="source-line-no">3836</span><span id="line-3836">   * @param descriptors list of table descriptors to filter</span>
-<span class="source-line-no">3837</span><span id="line-3837">   * @param pattern     the regex to use</span>
-<span class="source-line-no">3838</span><span id="line-3838">   */</span>
-<span class="source-line-no">3839</span><span id="line-3839">  private static void filterTablesByRegex(final Collection&lt;TableDescriptor&gt; descriptors,</span>
-<span class="source-line-no">3840</span><span id="line-3840">    final Pattern pattern) {</span>
-<span class="source-line-no">3841</span><span id="line-3841">    final String defaultNS = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;</span>
-<span class="source-line-no">3842</span><span id="line-3842">    Iterator&lt;TableDescriptor&gt; itr = descriptors.iterator();</span>
-<span class="source-line-no">3843</span><span id="line-3843">    while (itr.hasNext()) {</span>
-<span class="source-line-no">3844</span><span id="line-3844">      TableDescriptor htd = itr.next();</span>
-<span class="source-line-no">3845</span><span id="line-3845">      String tableName = htd.getTableName().getNameAsString();</span>
-<span class="source-line-no">3846</span><span id="line-3846">      boolean matched = pattern.matcher(tableName).matches();</span>
-<span class="source-line-no">3847</span><span id="line-3847">      if (!matched &amp;&amp; htd.getTableName().getNamespaceAsString().equals(defaultNS)) {</span>
-<span class="source-line-no">3848</span><span id="line-3848">        matched = pattern.matcher(defaultNS + TableName.NAMESPACE_DELIM + tableName).matches();</span>
-<span class="source-line-no">3849</span><span id="line-3849">      }</span>
-<span class="source-line-no">3850</span><span id="line-3850">      if (!matched) {</span>
-<span class="source-line-no">3851</span><span id="line-3851">        itr.remove();</span>
-<span class="source-line-no">3852</span><span id="line-3852">      }</span>
-<span class="source-line-no">3853</span><span id="line-3853">    }</span>
-<span class="source-line-no">3854</span><span id="line-3854">  }</span>
-<span class="source-line-no">3855</span><span id="line-3855"></span>
-<span class="source-line-no">3856</span><span id="line-3856">  @Override</span>
-<span class="source-line-no">3857</span><span id="line-3857">  public long getLastMajorCompactionTimestamp(TableName table) throws IOException {</span>
-<span class="source-line-no">3858</span><span id="line-3858">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
-<span class="source-line-no">3859</span><span id="line-3859">      .getLastMajorCompactionTimestamp(table);</span>
-<span class="source-line-no">3860</span><span id="line-3860">  }</span>
-<span class="source-line-no">3861</span><span id="line-3861"></span>
-<span class="source-line-no">3862</span><span id="line-3862">  @Override</span>
-<span class="source-line-no">3863</span><span id="line-3863">  public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {</span>
-<span class="source-line-no">3864</span><span id="line-3864">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
-<span class="source-line-no">3865</span><span id="line-3865">      .getLastMajorCompactionTimestamp(regionName);</span>
-<span class="source-line-no">3866</span><span id="line-3866">  }</span>
-<span class="source-line-no">3867</span><span id="line-3867"></span>
-<span class="source-line-no">3868</span><span id="line-3868">  /**</span>
-<span class="source-line-no">3869</span><span id="line-3869">   * Gets the mob file compaction state for a specific table. Whether all the mob files are selected</span>
-<span class="source-line-no">3870</span><span id="line-3870">   * is known during the compaction execution, but the statistic is done just before compaction</span>
-<span class="source-line-no">3871</span><span id="line-3871">   * starts, it is hard to know the compaction type at that time, so the rough statistics are chosen</span>
-<span class="source-line-no">3872</span><span id="line-3872">   * for the mob file compaction. Only two compaction states are available,</span>
-<span class="source-line-no">3873</span><span id="line-3873">   * CompactionState.MAJOR_AND_MINOR and CompactionState.NONE.</span>
-<span class="source-line-no">3874</span><span id="line-3874">   * @param tableName The current table name.</span>
-<span class="source-line-no">3875</span><span id="line-3875">   * @return If a given table is in mob file compaction now.</span>
-<span class="source-line-no">3876</span><span id="line-3876">   */</span>
-<span class="source-line-no">3877</span><span id="line-3877">  public GetRegionInfoResponse.CompactionState getMobCompactionState(TableName tableName) {</span>
-<span class="source-line-no">3878</span><span id="line-3878">    AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3879</span><span id="line-3879">    if (compactionsCount != null &amp;&amp; compactionsCount.get() != 0) {</span>
-<span class="source-line-no">3880</span><span id="line-3880">      return GetRegionInfoResponse.CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">3881</span><span id="line-3881">    }</span>
-<span class="source-line-no">3882</span><span id="line-3882">    return GetRegionInfoResponse.CompactionState.NONE;</span>
-<span class="source-line-no">3883</span><span id="line-3883">  }</span>
-<span class="source-line-no">3884</span><span id="line-3884"></span>
-<span class="source-line-no">3885</span><span id="line-3885">  public void reportMobCompactionStart(TableName tableName) throws IOException {</span>
-<span class="source-line-no">3886</span><span id="line-3886">    IdLock.Entry lockEntry = null;</span>
-<span class="source-line-no">3887</span><span id="line-3887">    try {</span>
-<span class="source-line-no">3888</span><span id="line-3888">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
-<span class="source-line-no">3889</span><span id="line-3889">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3890</span><span id="line-3890">      if (compactionsCount == null) {</span>
-<span class="source-line-no">3891</span><span id="line-3891">        compactionsCount = new AtomicInteger(0);</span>
-<span class="source-line-no">3892</span><span id="line-3892">        mobCompactionStates.put(tableName, compactionsCount);</span>
-<span class="source-line-no">3893</span><span id="line-3893">      }</span>
-<span class="source-line-no">3894</span><span id="line-3894">      compactionsCount.incrementAndGet();</span>
-<span class="source-line-no">3895</span><span id="line-3895">    } finally {</span>
-<span class="source-line-no">3896</span><span id="line-3896">      if (lockEntry != null) {</span>
-<span class="source-line-no">3897</span><span id="line-3897">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
-<span class="source-line-no">3898</span><span id="line-3898">      }</span>
-<span class="source-line-no">3899</span><span id="line-3899">    }</span>
-<span class="source-line-no">3900</span><span id="line-3900">  }</span>
-<span class="source-line-no">3901</span><span id="line-3901"></span>
-<span class="source-line-no">3902</span><span id="line-3902">  public void reportMobCompactionEnd(TableName tableName) throws IOException {</span>
-<span class="source-line-no">3903</span><span id="line-3903">    IdLock.Entry lockEntry = null;</span>
-<span class="source-line-no">3904</span><span id="line-3904">    try {</span>
-<span class="source-line-no">3905</span><span id="line-3905">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
-<span class="source-line-no">3906</span><span id="line-3906">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3907</span><span id="line-3907">      if (compactionsCount != null) {</span>
-<span class="source-line-no">3908</span><span id="line-3908">        int count = compactionsCount.decrementAndGet();</span>
-<span class="source-line-no">3909</span><span id="line-3909">        // remove the entry if the count is 0.</span>
-<span class="source-line-no">3910</span><span id="line-3910">        if (count == 0) {</span>
-<span class="source-line-no">3911</span><span id="line-3911">          mobCompactionStates.remove(tableName);</span>
-<span class="source-line-no">3912</span><span id="line-3912">        }</span>
-<span class="source-line-no">3913</span><span id="line-3913">      }</span>
-<span class="source-line-no">3914</span><span id="line-3914">    } finally {</span>
-<span class="source-line-no">3915</span><span id="line-3915">      if (lockEntry != null) {</span>
-<span class="source-line-no">3916</span><span id="line-3916">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3786</span><span id="line-3786">    htds = getTableDescriptors(htds, namespace, regex, null, includeSysTables);</span>
+<span class="source-line-no">3787</span><span id="line-3787">    if (cpHost != null) {</span>
+<span class="source-line-no">3788</span><span id="line-3788">      cpHost.postGetTableNames(htds, regex);</span>
+<span class="source-line-no">3789</span><span id="line-3789">    }</span>
+<span class="source-line-no">3790</span><span id="line-3790">    List&lt;TableName&gt; result = new ArrayList&lt;&gt;(htds.size());</span>
+<span class="source-line-no">3791</span><span id="line-3791">    for (TableDescriptor htd : htds)</span>
+<span class="source-line-no">3792</span><span id="line-3792">      result.add(htd.getTableName());</span>
+<span class="source-line-no">3793</span><span id="line-3793">    return result;</span>
+<span class="source-line-no">3794</span><span id="line-3794">  }</span>
+<span class="source-line-no">3795</span><span id="line-3795"></span>
+<span class="source-line-no">3796</span><span id="line-3796">  /**</span>
+<span class="source-line-no">3797</span><span id="line-3797">   * Return a list of table table descriptors after applying any provided filter parameters. Note</span>
+<span class="source-line-no">3798</span><span id="line-3798">   * that the user-facing description of this filter logic is presented on the class-level javadoc</span>
+<span class="source-line-no">3799</span><span id="line-3799">   * of {@link NormalizeTableFilterParams}.</span>
+<span class="source-line-no">3800</span><span id="line-3800">   */</span>
+<span class="source-line-no">3801</span><span id="line-3801">  private List&lt;TableDescriptor&gt; getTableDescriptors(final List&lt;TableDescriptor&gt; htds,</span>
+<span class="source-line-no">3802</span><span id="line-3802">    final String namespace, final String regex, final List&lt;TableName&gt; tableNameList,</span>
+<span class="source-line-no">3803</span><span id="line-3803">    final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3804</span><span id="line-3804">    if (tableNameList == null || tableNameList.isEmpty()) {</span>
+<span class="source-line-no">3805</span><span id="line-3805">      // request for all TableDescriptors</span>
+<span class="source-line-no">3806</span><span id="line-3806">      Collection&lt;TableDescriptor&gt; allHtds;</span>
+<span class="source-line-no">3807</span><span id="line-3807">      if (namespace != null &amp;&amp; namespace.length() &gt; 0) {</span>
+<span class="source-line-no">3808</span><span id="line-3808">        // Do a check on the namespace existence. Will fail if does not exist.</span>
+<span class="source-line-no">3809</span><span id="line-3809">        this.clusterSchemaService.getNamespace(namespace);</span>
+<span class="source-line-no">3810</span><span id="line-3810">        allHtds = tableDescriptors.getByNamespace(namespace).values();</span>
+<span class="source-line-no">3811</span><span id="line-3811">      } else {</span>
+<span class="source-line-no">3812</span><span id="line-3812">        allHtds = tableDescriptors.getAll().values();</span>
+<span class="source-line-no">3813</span><span id="line-3813">      }</span>
+<span class="source-line-no">3814</span><span id="line-3814">      for (TableDescriptor desc : allHtds) {</span>
+<span class="source-line-no">3815</span><span id="line-3815">        if (</span>
+<span class="source-line-no">3816</span><span id="line-3816">          tableStateManager.isTablePresent(desc.getTableName())</span>
+<span class="source-line-no">3817</span><span id="line-3817">            &amp;&amp; (includeSysTables || !desc.getTableName().isSystemTable())</span>
+<span class="source-line-no">3818</span><span id="line-3818">        ) {</span>
+<span class="source-line-no">3819</span><span id="line-3819">          htds.add(desc);</span>
+<span class="source-line-no">3820</span><span id="line-3820">        }</span>
+<span class="source-line-no">3821</span><span id="line-3821">      }</span>
+<span class="source-line-no">3822</span><span id="line-3822">    } else {</span>
+<span class="source-line-no">3823</span><span id="line-3823">      for (TableName s : tableNameList) {</span>
+<span class="source-line-no">3824</span><span id="line-3824">        if (tableStateManager.isTablePresent(s)) {</span>
+<span class="source-line-no">3825</span><span id="line-3825">          TableDescriptor desc = tableDescriptors.get(s);</span>
+<span class="source-line-no">3826</span><span id="line-3826">          if (desc != null) {</span>
+<span class="source-line-no">3827</span><span id="line-3827">            htds.add(desc);</span>
+<span class="source-line-no">3828</span><span id="line-3828">          }</span>
+<span class="source-line-no">3829</span><span id="line-3829">        }</span>
+<span class="source-line-no">3830</span><span id="line-3830">      }</span>
+<span class="source-line-no">3831</span><span id="line-3831">    }</span>
+<span class="source-line-no">3832</span><span id="line-3832"></span>
+<span class="source-line-no">3833</span><span id="line-3833">    // Retains only those matched by regular expression.</span>
+<span class="source-line-no">3834</span><span id="line-3834">    if (regex != null) filterTablesByRegex(htds, Pattern.compile(regex));</span>
+<span class="source-line-no">3835</span><span id="line-3835">    return htds;</span>
+<span class="source-line-no">3836</span><span id="line-3836">  }</span>
+<span class="source-line-no">3837</span><span id="line-3837"></span>
+<span class="source-line-no">3838</span><span id="line-3838">  /**</span>
+<span class="source-line-no">3839</span><span id="line-3839">   * Removes the table descriptors that don't match the pattern.</span>
+<span class="source-line-no">3840</span><span id="line-3840">   * @param descriptors list of table descriptors to filter</span>
+<span class="source-line-no">3841</span><span id="line-3841">   * @param pattern     the regex to use</span>
+<span class="source-line-no">3842</span><span id="line-3842">   */</span>
+<span class="source-line-no">3843</span><span id="line-3843">  private static void filterTablesByRegex(final Collection&lt;TableDescriptor&gt; descriptors,</span>
+<span class="source-line-no">3844</span><span id="line-3844">    final Pattern pattern) {</span>
+<span class="source-line-no">3845</span><span id="line-3845">    final String defaultNS = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;</span>
+<span class="source-line-no">3846</span><span id="line-3846">    Iterator&lt;TableDescriptor&gt; itr = descriptors.iterator();</span>
+<span class="source-line-no">3847</span><span id="line-3847">    while (itr.hasNext()) {</span>
+<span class="source-line-no">3848</span><span id="line-3848">      TableDescriptor htd = itr.next();</span>
+<span class="source-line-no">3849</span><span id="line-3849">      String tableName = htd.getTableName().getNameAsString();</span>
+<span class="source-line-no">3850</span><span id="line-3850">      boolean matched = pattern.matcher(tableName).matches();</span>
+<span class="source-line-no">3851</span><span id="line-3851">      if (!matched &amp;&amp; htd.getTableName().getNamespaceAsString().equals(defaultNS)) {</span>
+<span class="source-line-no">3852</span><span id="line-3852">        matched = pattern.matcher(defaultNS + TableName.NAMESPACE_DELIM + tableName).matches();</span>
+<span class="source-line-no">3853</span><span id="line-3853">      }</span>
+<span class="source-line-no">3854</span><span id="line-3854">      if (!matched) {</span>
+<span class="source-line-no">3855</span><span id="line-3855">        itr.remove();</span>
+<span class="source-line-no">3856</span><span id="line-3856">      }</span>
+<span class="source-line-no">3857</span><span id="line-3857">    }</span>
+<span class="source-line-no">3858</span><span id="line-3858">  }</span>
+<span class="source-line-no">3859</span><span id="line-3859"></span>
+<span class="source-line-no">3860</span><span id="line-3860">  @Override</span>
+<span class="source-line-no">3861</span><span id="line-3861">  public long getLastMajorCompactionTimestamp(TableName table) throws IOException {</span>
+<span class="source-line-no">3862</span><span id="line-3862">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
+<span class="source-line-no">3863</span><span id="line-3863">      .getLastMajorCompactionTimestamp(table);</span>
+<span class="source-line-no">3864</span><span id="line-3864">  }</span>
+<span class="source-line-no">3865</span><span id="line-3865"></span>
+<span class="source-line-no">3866</span><span id="line-3866">  @Override</span>
+<span class="source-line-no">3867</span><span id="line-3867">  public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {</span>
+<span class="source-line-no">3868</span><span id="line-3868">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
+<span class="source-line-no">3869</span><span id="line-3869">      .getLastMajorCompactionTimestamp(regionName);</span>
+<span class="source-line-no">3870</span><span id="line-3870">  }</span>
+<span class="source-line-no">3871</span><span id="line-3871"></span>
+<span class="source-line-no">3872</span><span id="line-3872">  /**</span>
+<span class="source-line-no">3873</span><span id="line-3873">   * Gets the mob file compaction state for a specific table. Whether all the mob files are selected</span>
+<span class="source-line-no">3874</span><span id="line-3874">   * is known during the compaction execution, but the statistic is done just before compaction</span>
+<span class="source-line-no">3875</span><span id="line-3875">   * starts, it is hard to know the compaction type at that time, so the rough statistics are chosen</span>
+<span class="source-line-no">3876</span><span id="line-3876">   * for the mob file compaction. Only two compaction states are available,</span>
+<span class="source-line-no">3877</span><span id="line-3877">   * CompactionState.MAJOR_AND_MINOR and CompactionState.NONE.</span>
+<span class="source-line-no">3878</span><span id="line-3878">   * @param tableName The current table name.</span>
+<span class="source-line-no">3879</span><span id="line-3879">   * @return If a given table is in mob file compaction now.</span>
+<span class="source-line-no">3880</span><span id="line-3880">   */</span>
+<span class="source-line-no">3881</span><span id="line-3881">  public GetRegionInfoResponse.CompactionState getMobCompactionState(TableName tableName) {</span>
+<span class="source-line-no">3882</span><span id="line-3882">    AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3883</span><span id="line-3883">    if (compactionsCount != null &amp;&amp; compactionsCount.get() != 0) {</span>
+<span class="source-line-no">3884</span><span id="line-3884">      return GetRegionInfoResponse.CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">3885</span><span id="line-3885">    }</span>
+<span class="source-line-no">3886</span><span id="line-3886">    return GetRegionInfoResponse.CompactionState.NONE;</span>
+<span class="source-line-no">3887</span><span id="line-3887">  }</span>
+<span class="source-line-no">3888</span><span id="line-3888"></span>
+<span class="source-line-no">3889</span><span id="line-3889">  public void reportMobCompactionStart(TableName tableName) throws IOException {</span>
+<span class="source-line-no">3890</span><span id="line-3890">    IdLock.Entry lockEntry = null;</span>
+<span class="source-line-no">3891</span><span id="line-3891">    try {</span>
+<span class="source-line-no">3892</span><span id="line-3892">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
+<span class="source-line-no">3893</span><span id="line-3893">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3894</span><span id="line-3894">      if (compactionsCount == null) {</span>
+<span class="source-line-no">3895</span><span id="line-3895">        compactionsCount = new AtomicInteger(0);</span>
+<span class="source-line-no">3896</span><span id="line-3896">        mobCompactionStates.put(tableName, compactionsCount);</span>
+<span class="source-line-no">3897</span><span id="line-3897">      }</span>
+<span class="source-line-no">3898</span><span id="line-3898">      compactionsCount.incrementAndGet();</span>
+<span class="source-line-no">3899</span><span id="line-3899">    } finally {</span>
+<span class="source-line-no">3900</span><span id="line-3900">      if (lockEntry != null) {</span>
+<span class="source-line-no">3901</span><span id="line-3901">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3902</span><span id="line-3902">      }</span>
+<span class="source-line-no">3903</span><span id="line-3903">    }</span>
+<span class="source-line-no">3904</span><span id="line-3904">  }</span>
+<span class="source-line-no">3905</span><span id="line-3905"></span>
+<span class="source-line-no">3906</span><span id="line-3906">  public void reportMobCompactionEnd(TableName tableName) throws IOException {</span>
+<span class="source-line-no">3907</span><span id="line-3907">    IdLock.Entry lockEntry = null;</span>
+<span class="source-line-no">3908</span><span id="line-3908">    try {</span>
+<span class="source-line-no">3909</span><span id="line-3909">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
+<span class="source-line-no">3910</span><span id="line-3910">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3911</span><span id="line-3911">      if (compactionsCount != null) {</span>
+<span class="source-line-no">3912</span><span id="line-3912">        int count = compactionsCount.decrementAndGet();</span>
+<span class="source-line-no">3913</span><span id="line-3913">        // remove the entry if the count is 0.</span>
+<span class="source-line-no">3914</span><span id="line-3914">        if (count == 0) {</span>
+<span class="source-line-no">3915</span><span id="line-3915">          mobCompactionStates.remove(tableName);</span>
+<span class="source-line-no">3916</span><span id="line-3916">        }</span>
 <span class="source-line-no">3917</span><span id="line-3917">      }</span>
-<span class="source-line-no">3918</span><span id="line-3918">    }</span>
-<span class="source-line-no">3919</span><span id="line-3919">  }</span>
-<span class="source-line-no">3920</span><span id="line-3920"></span>
-<span class="source-line-no">3921</span><span id="line-3921">  /**</span>
-<span class="source-line-no">3922</span><span id="line-3922">   * Queries the state of the {@link LoadBalancerStateStore}. If the balancer is not initialized,</span>
-<span class="source-line-no">3923</span><span id="line-3923">   * false is returned.</span>
-<span class="source-line-no">3924</span><span id="line-3924">   * @return The state of the load balancer, or false if the load balancer isn't defined.</span>
-<span class="source-line-no">3925</span><span id="line-3925">   */</span>
-<span class="source-line-no">3926</span><span id="line-3926">  public boolean isBalancerOn() {</span>
-<span class="source-line-no">3927</span><span id="line-3927">    return !isInMaintenanceMode() &amp;&amp; loadBalancerStateStore != null &amp;&amp; loadBalancerStateStore.get();</span>
-<span class="source-line-no">3928</span><span id="line-3928">  }</span>
-<span class="source-line-no">3929</span><span id="line-3929"></span>
-<span class="source-line-no">3930</span><span id="line-3930">  /**</span>
-<span class="source-line-no">3931</span><span id="line-3931">   * Queries the state of the {@link RegionNormalizerStateStore}. If it's not initialized, false is</span>
-<span class="source-line-no">3932</span><span id="line-3932">   * returned.</span>
-<span class="source-line-no">3933</span><span id="line-3933">   */</span>
-<span class="source-line-no">3934</span><span id="line-3934">  public boolean isNormalizerOn() {</span>
-<span class="source-line-no">3935</span><span id="line-3935">    return !isInMaintenanceMode() &amp;&amp; getRegionNormalizerManager().isNormalizerOn();</span>
-<span class="source-line-no">3936</span><span id="line-3936">  }</span>
-<span class="source-line-no">3937</span><span id="line-3937"></span>
-<span class="source-line-no">3938</span><span id="line-3938">  /**</span>
-<span class="source-line-no">3939</span><span id="line-3939">   * Queries the state of the {@link SplitOrMergeStateStore}. If it is not initialized, false is</span>
-<span class="source-line-no">3940</span><span id="line-3940">   * returned. If switchType is illegal, false will return.</span>
-<span class="source-line-no">3941</span><span id="line-3941">   * @param switchType see {@link org.apache.hadoop.hbase.client.MasterSwitchType}</span>
-<span class="source-line-no">3942</span><span id="line-3942">   * @return The state of the switch</span>
-<span class="source-line-no">3943</span><span id="line-3943">   */</span>
-<span class="source-line-no">3944</span><span id="line-3944">  @Override</span>
-<span class="source-line-no">3945</span><span id="line-3945">  public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) {</span>
-<span class="source-line-no">3946</span><span id="line-3946">    return !isInMaintenanceMode() &amp;&amp; splitOrMergeStateStore != null</span>
-<span class="source-line-no">3947</span><span id="line-3947">      &amp;&amp; splitOrMergeStateStore.isSplitOrMergeEnabled(switchType);</span>
-<span class="source-line-no">3948</span><span id="line-3948">  }</span>
-<span class="source-line-no">3949</span><span id="line-3949"></span>
-<span class="source-line-no">3950</span><span id="line-3950">  /**</span>
-<span class="source-line-no">3951</span><span id="line-3951">   * Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned.</span>
-<span class="source-line-no">3952</span><span id="line-3952">   * &lt;p/&gt;</span>
-<span class="source-line-no">3953</span><span id="line-3953">   * Notice that, the base load balancer will always be {@link RSGroupBasedLoadBalancer} now, so</span>
-<span class="source-line-no">3954</span><span id="line-3954">   * this method will return the balancer used inside each rs group.</span>
-<span class="source-line-no">3955</span><span id="line-3955">   * @return The name of the {@link LoadBalancer} in use.</span>
-<span class="source-line-no">3956</span><span id="line-3956">   */</span>
-<span class="source-line-no">3957</span><span id="line-3957">  public String getLoadBalancerClassName() {</span>
-<span class="source-line-no">3958</span><span id="line-3958">    return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,</span>
-<span class="source-line-no">3959</span><span id="line-3959">      LoadBalancerFactory.getDefaultLoadBalancerClass().getName());</span>
-<span class="source-line-no">3960</span><span id="line-3960">  }</span>
-<span class="source-line-no">3961</span><span id="line-3961"></span>
-<span class="source-line-no">3962</span><span id="line-3962">  public SplitOrMergeStateStore getSplitOrMergeStateStore() {</span>
-<span class="source-line-no">3963</span><span id="line-3963">    return splitOrMergeStateStore;</span>
+<span class="source-line-no">3918</span><span id="line-3918">    } finally {</span>
+<span class="source-line-no">3919</span><span id="line-3919">      if (lockEntry != null) {</span>
+<span class="source-line-no">3920</span><span id="line-3920">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3921</span><span id="line-3921">      }</span>
+<span class="source-line-no">3922</span><span id="line-3922">    }</span>
+<span class="source-line-no">3923</span><span id="line-3923">  }</span>
+<span class="source-line-no">3924</span><span id="line-3924"></span>
+<span class="source-line-no">3925</span><span id="line-3925">  /**</span>
+<span class="source-line-no">3926</span><span id="line-3926">   * Queries the state of the {@link LoadBalancerStateStore}. If the balancer is not initialized,</span>
+<span class="source-line-no">3927</span><span id="line-3927">   * false is returned.</span>
+<span class="source-line-no">3928</span><span id="line-3928">   * @return The state of the load balancer, or false if the load balancer isn't defined.</span>
+<span class="source-line-no">3929</span><span id="line-3929">   */</span>
+<span class="source-line-no">3930</span><span id="line-3930">  public boolean isBalancerOn() {</span>
+<span class="source-line-no">3931</span><span id="line-3931">    return !isInMaintenanceMode() &amp;&amp; loadBalancerStateStore != null &amp;&amp; loadBalancerStateStore.get();</span>
+<span class="source-line-no">3932</span><span id="line-3932">  }</span>
+<span class="source-line-no">3933</span><span id="line-3933"></span>
+<span class="source-line-no">3934</span><span id="line-3934">  /**</span>
+<span class="source-line-no">3935</span><span id="line-3935">   * Queries the state of the {@link RegionNormalizerStateStore}. If it's not initialized, false is</span>
+<span class="source-line-no">3936</span><span id="line-3936">   * returned.</span>
+<span class="source-line-no">3937</span><span id="line-3937">   */</span>
+<span class="source-line-no">3938</span><span id="line-3938">  public boolean isNormalizerOn() {</span>
+<span class="source-line-no">3939</span><span id="line-3939">    return !isInMaintenanceMode() &amp;&amp; getRegionNormalizerManager().isNormalizerOn();</span>
+<span class="source-line-no">3940</span><span id="line-3940">  }</span>
+<span class="source-line-no">3941</span><span id="line-3941"></span>
+<span class="source-line-no">3942</span><span id="line-3942">  /**</span>
+<span class="source-line-no">3943</span><span id="line-3943">   * Queries the state of the {@link SplitOrMergeStateStore}. If it is not initialized, false is</span>
+<span class="source-line-no">3944</span><span id="line-3944">   * returned. If switchType is illegal, false will return.</span>
+<span class="source-line-no">3945</span><span id="line-3945">   * @param switchType see {@link org.apache.hadoop.hbase.client.MasterSwitchType}</span>
+<span class="source-line-no">3946</span><span id="line-3946">   * @return The state of the switch</span>
+<span class="source-line-no">3947</span><span id="line-3947">   */</span>
+<span class="source-line-no">3948</span><span id="line-3948">  @Override</span>
+<span class="source-line-no">3949</span><span id="line-3949">  public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) {</span>
+<span class="source-line-no">3950</span><span id="line-3950">    return !isInMaintenanceMode() &amp;&amp; splitOrMergeStateStore != null</span>
+<span class="source-line-no">3951</span><span id="line-3951">      &amp;&amp; splitOrMergeStateStore.isSplitOrMergeEnabled(switchType);</span>
+<span class="source-line-no">3952</span><span id="line-3952">  }</span>
+<span class="source-line-no">3953</span><span id="line-3953"></span>
+<span class="source-line-no">3954</span><span id="line-3954">  /**</span>
+<span class="source-line-no">3955</span><span id="line-3955">   * Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned.</span>
+<span class="source-line-no">3956</span><span id="line-3956">   * &lt;p/&gt;</span>
+<span class="source-line-no">3957</span><span id="line-3957">   * Notice that, the base load balancer will always be {@link RSGroupBasedLoadBalancer} now, so</span>
+<span class="source-line-no">3958</span><span id="line-3958">   * this method will return the balancer used inside each rs group.</span>
+<span class="source-line-no">3959</span><span id="line-3959">   * @return The name of the {@link LoadBalancer} in use.</span>
+<span class="source-line-no">3960</span><span id="line-3960">   */</span>
+<span class="source-line-no">3961</span><span id="line-3961">  public String getLoadBalancerClassName() {</span>
+<span class="source-line-no">3962</span><span id="line-3962">    return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,</span>
+<span class="source-line-no">3963</span><span id="line-3963">      LoadBalancerFactory.getDefaultLoadBalancerClass().getName());</span>
 <span class="source-line-no">3964</span><span id="line-3964">  }</span>
 <span class="source-line-no">3965</span><span id="line-3965"></span>
-<span class="source-line-no">3966</span><span id="line-3966">  @Override</span>
-<span class="source-line-no">3967</span><span id="line-3967">  public RSGroupBasedLoadBalancer getLoadBalancer() {</span>
-<span class="source-line-no">3968</span><span id="line-3968">    return balancer;</span>
-<span class="source-line-no">3969</span><span id="line-3969">  }</span>
-<span class="source-line-no">3970</span><span id="line-3970"></span>
-<span class="source-line-no">3971</span><span id="line-3971">  @Override</span>
-<span class="source-line-no">3972</span><span id="line-3972">  public FavoredNodesManager getFavoredNodesManager() {</span>
-<span class="source-line-no">3973</span><span id="line-3973">    return balancer.getFavoredNodesManager();</span>
-<span class="source-line-no">3974</span><span id="line-3974">  }</span>
-<span class="source-line-no">3975</span><span id="line-3975"></span>
-<span class="source-line-no">3976</span><span id="line-3976">  private long executePeerProcedure(AbstractPeerProcedure&lt;?&gt; procedure) throws IOException {</span>
-<span class="source-line-no">3977</span><span id="line-3977">    if (!isReplicationPeerModificationEnabled()) {</span>
-<span class="source-line-no">3978</span><span id="line-3978">      throw new IOException("Replication peer modification disabled");</span>
-<span class="source-line-no">3979</span><span id="line-3979">    }</span>
-<span class="source-line-no">3980</span><span id="line-3980">    long procId = procedureExecutor.submitProcedure(procedure);</span>
-<span class="source-line-no">3981</span><span id="line-3981">    procedure.getLatch().await();</span>
-<span class="source-line-no">3982</span><span id="line-3982">    return procId;</span>
-<span class="source-line-no">3983</span><span id="line-3983">  }</span>
-<span class="source-line-no">3984</span><span id="line-3984"></span>
-<span class="source-line-no">3985</span><span id="line-3985">  @Override</span>
-<span class="source-line-no">3986</span><span id="line-3986">  public long addReplicationPeer(String peerId, ReplicationPeerConfig peerConfig, boolean enabled)</span>
-<span class="source-line-no">3987</span><span id="line-3987">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">3988</span><span id="line-3988">    LOG.info(getClientIdAuditPrefix() + " creating replication peer, id=" + peerId + ", config="</span>
-<span class="source-line-no">3989</span><span id="line-3989">      + peerConfig + ", state=" + (enabled ? "ENABLED" : "DISABLED"));</span>
-<span class="source-line-no">3990</span><span id="line-3990">    return executePeerProcedure(new AddPeerProcedure(peerId, peerConfig, enabled));</span>
-<span class="source-line-no">3991</span><span id="line-3991">  }</span>
-<span class="source-line-no">3992</span><span id="line-3992"></span>
-<span class="source-line-no">3993</span><span id="line-3993">  @Override</span>
-<span class="source-line-no">3994</span><span id="line-3994">  public long removeReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">3995</span><span id="line-3995">    LOG.info(getClientIdAuditPrefix() + " removing replication peer, id=" + peerId);</span>
-<span class="source-line-no">3996</span><span id="line-3996">    return executePeerProcedure(new RemovePeerProcedure(peerId));</span>
-<span class="source-line-no">3997</span><span id="line-3997">  }</span>
-<span class="source-line-no">3998</span><span id="line-3998"></span>
-<span class="source-line-no">3999</span><span id="line-3999">  @Override</span>
-<span class="source-line-no">4000</span><span id="line-4000">  public long enableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">4001</span><span id="line-4001">    LOG.info(getClientIdAuditPrefix() + " enable replication peer, id=" + peerId);</span>
-<span class="source-line-no">4002</span><span id="line-4002">    return executePeerProcedure(new EnablePeerProcedure(peerId));</span>
-<span class="source-line-no">4003</span><span id="line-4003">  }</span>
-<span class="source-line-no">4004</span><span id="line-4004"></span>
-<span class="source-line-no">4005</span><span id="line-4005">  @Override</span>
-<span class="source-line-no">4006</span><span id="line-4006">  public long disableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">4007</span><span id="line-4007">    LOG.info(getClientIdAuditPrefix() + " disable replication peer, id=" + peerId);</span>
-<span class="source-line-no">4008</span><span id="line-4008">    return executePeerProcedure(new DisablePeerProcedure(peerId));</span>
-<span class="source-line-no">4009</span><span id="line-4009">  }</span>
-<span class="source-line-no">4010</span><span id="line-4010"></span>
-<span class="source-line-no">4011</span><span id="line-4011">  @Override</span>
-<span class="source-line-no">4012</span><span id="line-4012">  public ReplicationPeerConfig getReplicationPeerConfig(String peerId)</span>
-<span class="source-line-no">4013</span><span id="line-4013">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4014</span><span id="line-4014">    if (cpHost != null) {</span>
-<span class="source-line-no">4015</span><span id="line-4015">      cpHost.preGetReplicationPeerConfig(peerId);</span>
-<span class="source-line-no">4016</span><span id="line-4016">    }</span>
-<span class="source-line-no">4017</span><span id="line-4017">    LOG.info(getClientIdAuditPrefix() + " get replication peer config, id=" + peerId);</span>
-<span class="source-line-no">4018</span><span id="line-4018">    ReplicationPeerConfig peerConfig = this.replicationPeerManager.getPeerConfig(peerId)</span>
-<span class="source-line-no">4019</span><span id="line-4019">      .orElseThrow(() -&gt; new ReplicationPeerNotFoundException(peerId));</span>
-<span class="source-line-no">4020</span><span id="line-4020">    if (cpHost != null) {</span>
-<span class="source-line-no">4021</span><span id="line-4021">      cpHost.postGetReplicationPeerConfig(peerId);</span>
-<span class="source-line-no">4022</span><span id="line-4022">    }</span>
-<span class="source-line-no">4023</span><span id="line-4023">    return peerConfig;</span>
-<span class="source-line-no">4024</span><span id="line-4024">  }</span>
-<span class="source-line-no">4025</span><span id="line-4025"></span>
-<span class="source-line-no">4026</span><span id="line-4026">  @Override</span>
-<span class="source-line-no">4027</span><span id="line-4027">  public long updateReplicationPeerConfig(String peerId, ReplicationPeerConfig peerConfig)</span>
-<span class="source-line-no">4028</span><span id="line-4028">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4029</span><span id="line-4029">    LOG.info(getClientIdAuditPrefix() + " update replication peer config, id=" + peerId</span>
-<span class="source-line-no">4030</span><span id="line-4030">      + ", config=" + peerConfig);</span>
-<span class="source-line-no">4031</span><span id="line-4031">    return executePeerProcedure(new UpdatePeerConfigProcedure(peerId, peerConfig));</span>
-<span class="source-line-no">4032</span><span id="line-4032">  }</span>
-<span class="source-line-no">4033</span><span id="line-4033"></span>
-<span class="source-line-no">4034</span><span id="line-4034">  @Override</span>
-<span class="source-line-no">4035</span><span id="line-4035">  public List&lt;ReplicationPeerDescription&gt; listReplicationPeers(String regex)</span>
-<span class="source-line-no">4036</span><span id="line-4036">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4037</span><span id="line-4037">    if (cpHost != null) {</span>
-<span class="source-line-no">4038</span><span id="line-4038">      cpHost.preListReplicationPeers(regex);</span>
-<span class="source-line-no">4039</span><span id="line-4039">    }</span>
-<span class="source-line-no">4040</span><span id="line-4040">    LOG.debug("{} list replication peers, regex={}", getClientIdAuditPrefix(), regex);</span>
-<span class="source-line-no">4041</span><span id="line-4041">    Pattern pattern = regex == null ? null : Pattern.compile(regex);</span>
-<span class="source-line-no">4042</span><span id="line-4042">    List&lt;ReplicationPeerDescription&gt; peers = this.replicationPeerManager.listPeers(pattern);</span>
-<span class="source-line-no">4043</span><span id="line-4043">    if (cpHost != null) {</span>
-<span class="source-line-no">4044</span><span id="line-4044">      cpHost.postListReplicationPeers(regex);</span>
-<span class="source-line-no">4045</span><span id="line-4045">    }</span>
-<span class="source-line-no">4046</span><span id="line-4046">    return peers;</span>
-<span class="source-line-no">4047</span><span id="line-4047">  }</span>
-<span class="source-line-no">4048</span><span id="line-4048"></span>
-<span class="source-line-no">4049</span><span id="line-4049">  @Override</span>
-<span class="source-line-no">4050</span><span id="line-4050">  public long transitReplicationPeerSyncReplicationState(String peerId, SyncReplicationState state)</span>
-<span class="source-line-no">4051</span><span id="line-4051">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4052</span><span id="line-4052">    LOG.info(</span>
-<span class="source-line-no">4053</span><span id="line-4053">      getClientIdAuditPrefix()</span>
-<span class="source-line-no">4054</span><span id="line-4054">        + " transit current cluster state to {} in a synchronous replication peer id={}",</span>
-<span class="source-line-no">4055</span><span id="line-4055">      state, peerId);</span>
-<span class="source-line-no">4056</span><span id="line-4056">    return executePeerProcedure(new TransitPeerSyncReplicationStateProcedure(peerId, state));</span>
-<span class="source-line-no">4057</span><span id="line-4057">  }</span>
-<span class="source-line-no">4058</span><span id="line-4058"></span>
-<span class="source-line-no">4059</span><span id="line-4059">  @Override</span>
-<span class="source-line-no">4060</span><span id="line-4060">  public boolean replicationPeerModificationSwitch(boolean on) throws IOException {</span>
-<span class="source-line-no">4061</span><span id="line-4061">    return replicationPeerModificationStateStore.set(on);</span>
-<span class="source-line-no">4062</span><span id="line-4062">  }</span>
-<span class="source-line-no">4063</span><span id="line-4063"></span>
-<span class="source-line-no">4064</span><span id="line-4064">  @Override</span>
-<span class="source-line-no">4065</span><span id="line-4065">  public boolean isReplicationPeerModificationEnabled() {</span>
-<span class="source-line-no">4066</span><span id="line-4066">    return replicationPeerModificationStateStore.get();</span>
-<span class="source-line-no">4067</span><span id="line-4067">  }</span>
-<span class="source-line-no">4068</span><span id="line-4068"></span>
-<span class="source-line-no">4069</span><span id="line-4069">  /**</span>
-<span class="source-line-no">4070</span><span id="line-4070">   * Mark region server(s) as decommissioned (previously called 'draining') to prevent additional</span>
-<span class="source-line-no">4071</span><span id="line-4071">   * regions from getting assigned to them. Also unload the regions on the servers asynchronously.0</span>
-<span class="source-line-no">4072</span><span id="line-4072">   * @param servers Region servers to decommission.</span>
-<span class="source-line-no">4073</span><span id="line-4073">   */</span>
-<span class="source-line-no">4074</span><span id="line-4074">  public void decommissionRegionServers(final List&lt;ServerName&gt; servers, final boolean offload)</span>
-<span class="source-line-no">4075</span><span id="line-4075">    throws IOException {</span>
-<span class="source-line-no">4076</span><span id="line-4076">    List&lt;ServerName&gt; serversAdded = new ArrayList&lt;&gt;(servers.size());</span>
-<span class="source-line-no">4077</span><span id="line-4077">    // Place the decommission marker first.</span>
-<span class="source-line-no">4078</span><span id="line-4078">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
-<span class="source-line-no">4079</span><span id="line-4079">    for (ServerName server : servers) {</span>
-<span class="source-line-no">4080</span><span id="line-4080">      try {</span>
-<span class="source-line-no">4081</span><span id="line-4081">        String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
-<span class="source-line-no">4082</span><span id="line-4082">        ZKUtil.createAndFailSilent(getZooKeeper(), node);</span>
-<span class="source-line-no">4083</span><span id="line-4083">      } catch (KeeperException ke) {</span>
-<span class="source-line-no">4084</span><span id="line-4084">        throw new HBaseIOException(</span>
-<span class="source-line-no">4085</span><span id="line-4085">          this.zooKeeper.prefix("Unable to decommission '" + server.getServerName() + "'."), ke);</span>
-<span class="source-line-no">4086</span><span id="line-4086">      }</span>
-<span class="source-line-no">4087</span><span id="line-4087">      if (this.serverManager.addServerToDrainList(server)) {</span>
-<span class="source-line-no">4088</span><span id="line-4088">        serversAdded.add(server);</span>
-<span class="source-line-no">4089</span><span id="line-4089">      }</span>
-<span class="source-line-no">4090</span><span id="line-4090">    }</span>
-<span class="source-line-no">4091</span><span id="line-4091">    // Move the regions off the decommissioned servers.</span>
-<span class="source-line-no">4092</span><span id="line-4092">    if (offload) {</span>
-<span class="source-line-no">4093</span><span id="line-4093">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList();</span>
-<span class="source-line-no">4094</span><span id="line-4094">      for (ServerName server : serversAdded) {</span>
-<span class="source-line-no">4095</span><span id="line-4095">        final List&lt;RegionInfo&gt; regionsOnServer = this.assignmentManager.getRegionsOnServer(server);</span>
-<span class="source-line-no">4096</span><span id="line-4096">        for (RegionInfo hri : regionsOnServer) {</span>
-<span class="source-line-no">4097</span><span id="line-4097">          ServerName dest = balancer.randomAssignment(hri, destServers);</span>
-<span class="source-line-no">4098</span><span id="line-4098">          if (dest == null) {</span>
-<span class="source-line-no">4099</span><span id="line-4099">            throw new HBaseIOException("Unable to determine a plan to move " + hri);</span>
-<span class="source-line-no">4100</span><span id="line-4100">          }</span>
-<span class="source-line-no">4101</span><span id="line-4101">          RegionPlan rp = new RegionPlan(hri, server, dest);</span>
-<span class="source-line-no">4102</span><span id="line-4102">          this.assignmentManager.moveAsync(rp);</span>
-<span class="source-line-no">4103</span><span id="line-4103">        }</span>
-<span class="source-line-no">4104</span><span id="line-4104">      }</span>
-<span class="source-line-no">4105</span><span id="line-4105">    }</span>
-<span class="source-line-no">4106</span><span id="line-4106">  }</span>
-<span class="source-line-no">4107</span><span id="line-4107"></span>
-<span class="source-line-no">4108</span><span id="line-4108">  /**</span>
-<span class="source-line-no">4109</span><span id="line-4109">   * List region servers marked as decommissioned (previously called 'draining') to not get regions</span>
-<span class="source-line-no">4110</span><span id="line-4110">   * assigned to them.</span>
-<span class="source-line-no">4111</span><span id="line-4111">   * @return List of decommissioned servers.</span>
-<span class="source-line-no">4112</span><span id="line-4112">   */</span>
-<span class="source-line-no">4113</span><span id="line-4113">  public List&lt;ServerName&gt; listDecommissionedRegionServers() {</span>
-<span class="source-line-no">4114</span><span id="line-4114">    return this.serverManager.getDrainingServersList();</span>
-<span class="source-line-no">4115</span><span id="line-4115">  }</span>
-<span class="source-line-no">4116</span><span id="line-4116"></span>
-<span class="source-line-no">4117</span><span id="line-4117">  /**</span>
-<span class="source-line-no">4118</span><span id="line-4118">   * Remove decommission marker (previously called 'draining') from a region server to allow regions</span>
-<span class="source-line-no">4119</span><span id="line-4119">   * assignments. Load regions onto the server asynchronously if a list of regions is given</span>
-<span class="source-line-no">4120</span><span id="line-4120">   * @param server Region server to remove decommission marker from.</span>
-<span class="source-line-no">4121</span><span id="line-4121">   */</span>
-<span class="source-line-no">4122</span><span id="line-4122">  public void recommissionRegionServer(final ServerName server,</span>
-<span class="source-line-no">4123</span><span id="line-4123">    final List&lt;byte[]&gt; encodedRegionNames) throws IOException {</span>
-<span class="source-line-no">4124</span><span id="line-4124">    // Remove the server from decommissioned (draining) server list.</span>
-<span class="source-line-no">4125</span><span id="line-4125">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
-<span class="source-line-no">4126</span><span id="line-4126">    String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
-<span class="source-line-no">4127</span><span id="line-4127">    try {</span>
-<span class="source-line-no">4128</span><span id="line-4128">      ZKUtil.deleteNodeFailSilent(getZooKeeper(), node);</span>
-<span class="source-line-no">4129</span><span id="line-4129">    } catch (KeeperException ke) {</span>
-<span class="source-line-no">4130</span><span id="line-4130">      throw new HBaseIOException(</span>
-<span class="source-line-no">4131</span><span id="line-4131">        this.zooKeeper.prefix("Unable to recommission '" + server.getServerName() + "'."), ke);</span>
-<span class="source-line-no">4132</span><span id="line-4132">    }</span>
-<span class="source-line-no">4133</span><span id="line-4133">    this.serverManager.removeServerFromDrainList(server);</span>
-<span class="source-line-no">4134</span><span id="line-4134"></span>
-<span class="source-line-no">4135</span><span id="line-4135">    // Load the regions onto the server if we are given a list of regions.</span>
-<span class="source-line-no">4136</span><span id="line-4136">    if (encodedRegionNames == null || encodedRegionNames.isEmpty()) {</span>
-<span class="source-line-no">4137</span><span id="line-4137">      return;</span>
-<span class="source-line-no">4138</span><span id="line-4138">    }</span>
-<span class="source-line-no">4139</span><span id="line-4139">    if (!this.serverManager.isServerOnline(server)) {</span>
-<span class="source-line-no">4140</span><span id="line-4140">      return;</span>
-<span class="source-line-no">4141</span><span id="line-4141">    }</span>
-<span class="source-line-no">4142</span><span id="line-4142">    for (byte[] encodedRegionName : encodedRegionNames) {</span>
-<span class="source-line-no">4143</span><span id="line-4143">      RegionState regionState =</span>
-<span class="source-line-no">4144</span><span id="line-4144">        assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
-<span class="source-line-no">4145</span><span id="line-4145">      if (regionState == null) {</span>
-<span class="source-line-no">4146</span><span id="line-4146">        LOG.warn("Unknown region " + Bytes.toStringBinary(encodedRegionName));</span>
-<span class="source-line-no">4147</span><span id="line-4147">        continue;</span>
-<span class="source-line-no">4148</span><span id="line-4148">      }</span>
-<span class="source-line-no">4149</span><span id="line-4149">      RegionInfo hri = regionState.getRegion();</span>
-<span class="source-line-no">4150</span><span id="line-4150">      if (server.equals(regionState.getServerName())) {</span>
-<span class="source-line-no">4151</span><span id="line-4151">        LOG.info("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">4152</span><span id="line-4152">          + " because region already assigned to the same server " + server + ".");</span>
-<span class="source-line-no">4153</span><span id="line-4153">        continue;</span>
-<span class="source-line-no">4154</span><span id="line-4154">      }</span>
-<span class="source-line-no">4155</span><span id="line-4155">      RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), server);</span>
-<span class="source-line-no">4156</span><span id="line-4156">      this.assignmentManager.moveAsync(rp);</span>
-<span class="source-line-no">4157</span><span id="line-4157">    }</span>
-<span class="source-line-no">4158</span><span id="line-4158">  }</span>
-<span class="source-line-no">4159</span><span id="line-4159"></span>
-<span class="source-line-no">4160</span><span id="line-4160">  @Override</span>
-<span class="source-line-no">4161</span><span id="line-4161">  public LockManager getLockManager() {</span>
-<span class="source-line-no">4162</span><span id="line-4162">    return lockManager;</span>
-<span class="source-line-no">4163</span><span id="line-4163">  }</span>
-<span class="source-line-no">4164</span><span id="line-4164"></span>
-<span class="source-line-no">4165</span><span id="line-4165">  public QuotaObserverChore getQuotaObserverChore() {</span>
-<span class="source-line-no">4166</span><span id="line-4166">    return this.quotaObserverChore;</span>
+<span class="source-line-no">3966</span><span id="line-3966">  public SplitOrMergeStateStore getSplitOrMergeStateStore() {</span>
+<span class="source-line-no">3967</span><span id="line-3967">    return splitOrMergeStateStore;</span>
+<span class="source-line-no">3968</span><span id="line-3968">  }</span>
+<span class="source-line-no">3969</span><span id="line-3969"></span>
+<span class="source-line-no">3970</span><span id="line-3970">  @Override</span>
+<span class="source-line-no">3971</span><span id="line-3971">  public RSGroupBasedLoadBalancer getLoadBalancer() {</span>
+<span class="source-line-no">3972</span><span id="line-3972">    return balancer;</span>
+<span class="source-line-no">3973</span><span id="line-3973">  }</span>
+<span class="source-line-no">3974</span><span id="line-3974"></span>
+<span class="source-line-no">3975</span><span id="line-3975">  @Override</span>
+<span class="source-line-no">3976</span><span id="line-3976">  public FavoredNodesManager getFavoredNodesManager() {</span>
+<span class="source-line-no">3977</span><span id="line-3977">    return balancer.getFavoredNodesManager();</span>
+<span class="source-line-no">3978</span><span id="line-3978">  }</span>
+<span class="source-line-no">3979</span><span id="line-3979"></span>
+<span class="source-line-no">3980</span><span id="line-3980">  private long executePeerProcedure(AbstractPeerProcedure&lt;?&gt; procedure) throws IOException {</span>
+<span class="source-line-no">3981</span><span id="line-3981">    if (!isReplicationPeerModificationEnabled()) {</span>
+<span class="source-line-no">3982</span><span id="line-3982">      throw new IOException("Replication peer modification disabled");</span>
+<span class="source-line-no">3983</span><span id="line-3983">    }</span>
+<span class="source-line-no">3984</span><span id="line-3984">    long procId = procedureExecutor.submitProcedure(procedure);</span>
+<span class="source-line-no">3985</span><span id="line-3985">    procedure.getLatch().await();</span>
+<span class="source-line-no">3986</span><span id="line-3986">    return procId;</span>
+<span class="source-line-no">3987</span><span id="line-3987">  }</span>
+<span class="source-line-no">3988</span><span id="line-3988"></span>
+<span class="source-line-no">3989</span><span id="line-3989">  @Override</span>
+<span class="source-line-no">3990</span><span id="line-3990">  public long addReplicationPeer(String peerId, ReplicationPeerConfig peerConfig, boolean enabled)</span>
+<span class="source-line-no">3991</span><span id="line-3991">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">3992</span><span id="line-3992">    LOG.info(getClientIdAuditPrefix() + " creating replication peer, id=" + peerId + ", config="</span>
+<span class="source-line-no">3993</span><span id="line-3993">      + peerConfig + ", state=" + (enabled ? "ENABLED" : "DISABLED"));</span>
+<span class="source-line-no">3994</span><span id="line-3994">    return executePeerProcedure(new AddPeerProcedure(peerId, peerConfig, enabled));</span>
+<span class="source-line-no">3995</span><span id="line-3995">  }</span>
+<span class="source-line-no">3996</span><span id="line-3996"></span>
+<span class="source-line-no">3997</span><span id="line-3997">  @Override</span>
+<span class="source-line-no">3998</span><span id="line-3998">  public long removeReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">3999</span><span id="line-3999">    LOG.info(getClientIdAuditPrefix() + " removing replication peer, id=" + peerId);</span>
+<span class="source-line-no">4000</span><span id="line-4000">    return executePeerProcedure(new RemovePeerProcedure(peerId));</span>
+<span class="source-line-no">4001</span><span id="line-4001">  }</span>
+<span class="source-line-no">4002</span><span id="line-4002"></span>
+<span class="source-line-no">4003</span><span id="line-4003">  @Override</span>
+<span class="source-line-no">4004</span><span id="line-4004">  public long enableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">4005</span><span id="line-4005">    LOG.info(getClientIdAuditPrefix() + " enable replication peer, id=" + peerId);</span>
+<span class="source-line-no">4006</span><span id="line-4006">    return executePeerProcedure(new EnablePeerProcedure(peerId));</span>
+<span class="source-line-no">4007</span><span id="line-4007">  }</span>
+<span class="source-line-no">4008</span><span id="line-4008"></span>
+<span class="source-line-no">4009</span><span id="line-4009">  @Override</span>
+<span class="source-line-no">4010</span><span id="line-4010">  public long disableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">4011</span><span id="line-4011">    LOG.info(getClientIdAuditPrefix() + " disable replication peer, id=" + peerId);</span>
+<span class="source-line-no">4012</span><span id="line-4012">    return executePeerProcedure(new DisablePeerProcedure(peerId));</span>
+<span class="source-line-no">4013</span><span id="line-4013">  }</span>
+<span class="source-line-no">4014</span><span id="line-4014"></span>
+<span class="source-line-no">4015</span><span id="line-4015">  @Override</span>
+<span class="source-line-no">4016</span><span id="line-4016">  public ReplicationPeerConfig getReplicationPeerConfig(String peerId)</span>
+<span class="source-line-no">4017</span><span id="line-4017">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4018</span><span id="line-4018">    if (cpHost != null) {</span>
+<span class="source-line-no">4019</span><span id="line-4019">      cpHost.preGetReplicationPeerConfig(peerId);</span>
+<span class="source-line-no">4020</span><span id="line-4020">    }</span>
+<span class="source-line-no">4021</span><span id="line-4021">    LOG.info(getClientIdAuditPrefix() + " get replication peer config, id=" + peerId);</span>
+<span class="source-line-no">4022</span><span id="line-4022">    ReplicationPeerConfig peerConfig = this.replicationPeerManager.getPeerConfig(peerId)</span>
+<span class="source-line-no">4023</span><span id="line-4023">      .orElseThrow(() -&gt; new ReplicationPeerNotFoundException(peerId));</span>
+<span class="source-line-no">4024</span><span id="line-4024">    if (cpHost != null) {</span>
+<span class="source-line-no">4025</span><span id="line-4025">      cpHost.postGetReplicationPeerConfig(peerId);</span>
+<span class="source-line-no">4026</span><span id="line-4026">    }</span>
+<span class="source-line-no">4027</span><span id="line-4027">    return peerConfig;</span>
+<span class="source-line-no">4028</span><span id="line-4028">  }</span>
+<span class="source-line-no">4029</span><span id="line-4029"></span>
+<span class="source-line-no">4030</span><span id="line-4030">  @Override</span>
+<span class="source-line-no">4031</span><span id="line-4031">  public long updateReplicationPeerConfig(String peerId, ReplicationPeerConfig peerConfig)</span>
+<span class="source-line-no">4032</span><span id="line-4032">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4033</span><span id="line-4033">    LOG.info(getClientIdAuditPrefix() + " update replication peer config, id=" + peerId</span>
+<span class="source-line-no">4034</span><span id="line-4034">      + ", config=" + peerConfig);</span>
+<span class="source-line-no">4035</span><span id="line-4035">    return executePeerProcedure(new UpdatePeerConfigProcedure(peerId, peerConfig));</span>
+<span class="source-line-no">4036</span><span id="line-4036">  }</span>
+<span class="source-line-no">4037</span><span id="line-4037"></span>
+<span class="source-line-no">4038</span><span id="line-4038">  @Override</span>
+<span class="source-line-no">4039</span><span id="line-4039">  public List&lt;ReplicationPeerDescription&gt; listReplicationPeers(String regex)</span>
+<span class="source-line-no">4040</span><span id="line-4040">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4041</span><span id="line-4041">    if (cpHost != null) {</span>
+<span class="source-line-no">4042</span><span id="line-4042">      cpHost.preListReplicationPeers(regex);</span>
+<span class="source-line-no">4043</span><span id="line-4043">    }</span>
+<span class="source-line-no">4044</span><span id="line-4044">    LOG.debug("{} list replication peers, regex={}", getClientIdAuditPrefix(), regex);</span>
+<span class="source-line-no">4045</span><span id="line-4045">    Pattern pattern = regex == null ? null : Pattern.compile(regex);</span>
+<span class="source-line-no">4046</span><span id="line-4046">    List&lt;ReplicationPeerDescription&gt; peers = this.replicationPeerManager.listPeers(pattern);</span>
+<span class="source-line-no">4047</span><span id="line-4047">    if (cpHost != null) {</span>
+<span class="source-line-no">4048</span><span id="line-4048">      cpHost.postListReplicationPeers(regex);</span>
+<span class="source-line-no">4049</span><span id="line-4049">    }</span>
+<span class="source-line-no">4050</span><span id="line-4050">    return peers;</span>
+<span class="source-line-no">4051</span><span id="line-4051">  }</span>
+<span class="source-line-no">4052</span><span id="line-4052"></span>
+<span class="source-line-no">4053</span><span id="line-4053">  @Override</span>
+<span class="source-line-no">4054</span><span id="line-4054">  public long transitReplicationPeerSyncReplicationState(String peerId, SyncReplicationState state)</span>
+<span class="source-line-no">4055</span><span id="line-4055">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4056</span><span id="line-4056">    LOG.info(</span>
+<span class="source-line-no">4057</span><span id="line-4057">      getClientIdAuditPrefix()</span>
+<span class="source-line-no">4058</span><span id="line-4058">        + " transit current cluster state to {} in a synchronous replication peer id={}",</span>
+<span class="source-line-no">4059</span><span id="line-4059">      state, peerId);</span>
+<span class="source-line-no">4060</span><span id="line-4060">    return executePeerProcedure(new TransitPeerSyncReplicationStateProcedure(peerId, state));</span>
+<span class="source-line-no">4061</span><span id="line-4061">  }</span>
+<span class="source-line-no">4062</span><span id="line-4062"></span>
+<span class="source-line-no">4063</span><span id="line-4063">  @Override</span>
+<span class="source-line-no">4064</span><span id="line-4064">  public boolean replicationPeerModificationSwitch(boolean on) throws IOException {</span>
+<span class="source-line-no">4065</span><span id="line-4065">    return replicationPeerModificationStateStore.set(on);</span>
+<span class="source-line-no">4066</span><span id="line-4066">  }</span>
+<span class="source-line-no">4067</span><span id="line-4067"></span>
+<span class="source-line-no">4068</span><span id="line-4068">  @Override</span>
+<span class="source-line-no">4069</span><span id="line-4069">  public boolean isReplicationPeerModificationEnabled() {</span>
+<span class="source-line-no">4070</span><span id="line-4070">    return replicationPeerModificationStateStore.get();</span>
+<span class="source-line-no">4071</span><span id="line-4071">  }</span>
+<span class="source-line-no">4072</span><span id="line-4072"></span>
+<span class="source-line-no">4073</span><span id="line-4073">  /**</span>
+<span class="source-line-no">4074</span><span id="line-4074">   * Mark region server(s) as decommissioned (previously called 'draining') to prevent additional</span>
+<span class="source-line-no">4075</span><span id="line-4075">   * regions from getting assigned to them. Also unload the regions on the servers asynchronously.0</span>
+<span class="source-line-no">4076</span><span id="line-4076">   * @param servers Region servers to decommission.</span>
+<span class="source-line-no">4077</span><span id="line-4077">   */</span>
+<span class="source-line-no">4078</span><span id="line-4078">  public void decommissionRegionServers(final List&lt;ServerName&gt; servers, final boolean offload)</span>
+<span class="source-line-no">4079</span><span id="line-4079">    throws IOException {</span>
+<span class="source-line-no">4080</span><span id="line-4080">    List&lt;ServerName&gt; serversAdded = new ArrayList&lt;&gt;(servers.size());</span>
+<span class="source-line-no">4081</span><span id="line-4081">    // Place the decommission marker first.</span>
+<span class="source-line-no">4082</span><span id="line-4082">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
+<span class="source-line-no">4083</span><span id="line-4083">    for (ServerName server : servers) {</span>
+<span class="source-line-no">4084</span><span id="line-4084">      try {</span>
+<span class="source-line-no">4085</span><span id="line-4085">        String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
+<span class="source-line-no">4086</span><span id="line-4086">        ZKUtil.createAndFailSilent(getZooKeeper(), node);</span>
+<span class="source-line-no">4087</span><span id="line-4087">      } catch (KeeperException ke) {</span>
+<span class="source-line-no">4088</span><span id="line-4088">        throw new HBaseIOException(</span>
+<span class="source-line-no">4089</span><span id="line-4089">          this.zooKeeper.prefix("Unable to decommission '" + server.getServerName() + "'."), ke);</span>
+<span class="source-line-no">4090</span><span id="line-4090">      }</span>
+<span class="source-line-no">4091</span><span id="line-4091">      if (this.serverManager.addServerToDrainList(server)) {</span>
+<span class="source-line-no">4092</span><span id="line-4092">        serversAdded.add(server);</span>
+<span class="source-line-no">4093</span><span id="line-4093">      }</span>
+<span class="source-line-no">4094</span><span id="line-4094">    }</span>
+<span class="source-line-no">4095</span><span id="line-4095">    // Move the regions off the decommissioned servers.</span>
+<span class="source-line-no">4096</span><span id="line-4096">    if (offload) {</span>
+<span class="source-line-no">4097</span><span id="line-4097">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList();</span>
+<span class="source-line-no">4098</span><span id="line-4098">      for (ServerName server : serversAdded) {</span>
+<span class="source-line-no">4099</span><span id="line-4099">        final List&lt;RegionInfo&gt; regionsOnServer = this.assignmentManager.getRegionsOnServer(server);</span>
+<span class="source-line-no">4100</span><span id="line-4100">        for (RegionInfo hri : regionsOnServer) {</span>
+<span class="source-line-no">4101</span><span id="line-4101">          ServerName dest = balancer.randomAssignment(hri, destServers);</span>
+<span class="source-line-no">4102</span><span id="line-4102">          if (dest == null) {</span>
+<span class="source-line-no">4103</span><span id="line-4103">            throw new HBaseIOException("Unable to determine a plan to move " + hri);</span>
+<span class="source-line-no">4104</span><span id="line-4104">          }</span>
+<span class="source-line-no">4105</span><span id="line-4105">          RegionPlan rp = new RegionPlan(hri, server, dest);</span>
+<span class="source-line-no">4106</span><span id="line-4106">          this.assignmentManager.moveAsync(rp);</span>
+<span class="source-line-no">4107</span><span id="line-4107">        }</span>
+<span class="source-line-no">4108</span><span id="line-4108">      }</span>
+<span class="source-line-no">4109</span><span id="line-4109">    }</span>
+<span class="source-line-no">4110</span><span id="line-4110">  }</span>
+<span class="source-line-no">4111</span><span id="line-4111"></span>
+<span class="source-line-no">4112</span><span id="line-4112">  /**</span>
+<span class="source-line-no">4113</span><span id="line-4113">   * List region servers marked as decommissioned (previously called 'draining') to not get regions</span>
+<span class="source-line-no">4114</span><span id="line-4114">   * assigned to them.</span>
+<span class="source-line-no">4115</span><span id="line-4115">   * @return List of decommissioned servers.</span>
+<span class="source-line-no">4116</span><span id="line-4116">   */</span>
+<span class="source-line-no">4117</span><span id="line-4117">  public List&lt;ServerName&gt; listDecommissionedRegionServers() {</span>
+<span class="source-line-no">4118</span><span id="line-4118">    return this.serverManager.getDrainingServersList();</span>
+<span class="source-line-no">4119</span><span id="line-4119">  }</span>
+<span class="source-line-no">4120</span><span id="line-4120"></span>
+<span class="source-line-no">4121</span><span id="line-4121">  /**</span>
+<span class="source-line-no">4122</span><span id="line-4122">   * Remove decommission marker (previously called 'draining') from a region server to allow regions</span>
+<span class="source-line-no">4123</span><span id="line-4123">   * assignments. Load regions onto the server asynchronously if a list of regions is given</span>
+<span class="source-line-no">4124</span><span id="line-4124">   * @param server Region server to remove decommission marker from.</span>
+<span class="source-line-no">4125</span><span id="line-4125">   */</span>
+<span class="source-line-no">4126</span><span id="line-4126">  public void recommissionRegionServer(final ServerName server,</span>
+<span class="source-line-no">4127</span><span id="line-4127">    final List&lt;byte[]&gt; encodedRegionNames) throws IOException {</span>
+<span class="source-line-no">4128</span><span id="line-4128">    // Remove the server from decommissioned (draining) server list.</span>
+<span class="source-line-no">4129</span><span id="line-4129">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
+<span class="source-line-no">4130</span><span id="line-4130">    String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
+<span class="source-line-no">4131</span><span id="line-4131">    try {</span>
+<span class="source-line-no">4132</span><span id="line-4132">      ZKUtil.deleteNodeFailSilent(getZooKeeper(), node);</span>
+<span class="source-line-no">4133</span><span id="line-4133">    } catch (KeeperException ke) {</span>
+<span class="source-line-no">4134</span><span id="line-4134">      throw new HBaseIOException(</span>
+<span class="source-line-no">4135</span><span id="line-4135">        this.zooKeeper.prefix("Unable to recommission '" + server.getServerName() + "'."), ke);</span>
+<span class="source-line-no">4136</span><span id="line-4136">    }</span>
+<span class="source-line-no">4137</span><span id="line-4137">    this.serverManager.removeServerFromDrainList(server);</span>
+<span class="source-line-no">4138</span><span id="line-4138"></span>
+<span class="source-line-no">4139</span><span id="line-4139">    // Load the regions onto the server if we are given a list of regions.</span>
+<span class="source-line-no">4140</span><span id="line-4140">    if (encodedRegionNames == null || encodedRegionNames.isEmpty()) {</span>
+<span class="source-line-no">4141</span><span id="line-4141">      return;</span>
+<span class="source-line-no">4142</span><span id="line-4142">    }</span>
+<span class="source-line-no">4143</span><span id="line-4143">    if (!this.serverManager.isServerOnline(server)) {</span>
+<span class="source-line-no">4144</span><span id="line-4144">      return;</span>
+<span class="source-line-no">4145</span><span id="line-4145">    }</span>
+<span class="source-line-no">4146</span><span id="line-4146">    for (byte[] encodedRegionName : encodedRegionNames) {</span>
+<span class="source-line-no">4147</span><span id="line-4147">      RegionState regionState =</span>
+<span class="source-line-no">4148</span><span id="line-4148">        assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
+<span class="source-line-no">4149</span><span id="line-4149">      if (regionState == null) {</span>
+<span class="source-line-no">4150</span><span id="line-4150">        LOG.warn("Unknown region " + Bytes.toStringBinary(encodedRegionName));</span>
+<span class="source-line-no">4151</span><span id="line-4151">        continue;</span>
+<span class="source-line-no">4152</span><span id="line-4152">      }</span>
+<span class="source-line-no">4153</span><span id="line-4153">      RegionInfo hri = regionState.getRegion();</span>
+<span class="source-line-no">4154</span><span id="line-4154">      if (server.equals(regionState.getServerName())) {</span>
+<span class="source-line-no">4155</span><span id="line-4155">        LOG.info("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">4156</span><span id="line-4156">          + " because region already assigned to the same server " + server + ".");</span>
+<span class="source-line-no">4157</span><span id="line-4157">        continue;</span>
+<span class="source-line-no">4158</span><span id="line-4158">      }</span>
+<span class="source-line-no">4159</span><span id="line-4159">      RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), server);</span>
+<span class="source-line-no">4160</span><span id="line-4160">      this.assignmentManager.moveAsync(rp);</span>
+<span class="source-line-no">4161</span><span id="line-4161">    }</span>
+<span class="source-line-no">4162</span><span id="line-4162">  }</span>
+<span class="source-line-no">4163</span><span id="line-4163"></span>
+<span class="source-line-no">4164</span><span id="line-4164">  @Override</span>
+<span class="source-line-no">4165</span><span id="line-4165">  public LockManager getLockManager() {</span>
+<span class="source-line-no">4166</span><span id="line-4166">    return lockManager;</span>
 <span class="source-line-no">4167</span><span id="line-4167">  }</span>
 <span class="source-line-no">4168</span><span id="line-4168"></span>
-<span class="source-line-no">4169</span><span id="line-4169">  public SpaceQuotaSnapshotNotifier getSpaceQuotaSnapshotNotifier() {</span>
-<span class="source-line-no">4170</span><span id="line-4170">    return this.spaceQuotaSnapshotNotifier;</span>
+<span class="source-line-no">4169</span><span id="line-4169">  public QuotaObserverChore getQuotaObserverChore() {</span>
+<span class="source-line-no">4170</span><span id="line-4170">    return this.quotaObserverChore;</span>
 <span class="source-line-no">4171</span><span id="line-4171">  }</span>
 <span class="source-line-no">4172</span><span id="line-4172"></span>
-<span class="source-line-no">4173</span><span id="line-4173">  @SuppressWarnings("unchecked")</span>
-<span class="source-line-no">4174</span><span id="line-4174">  private RemoteProcedure&lt;MasterProcedureEnv, ?&gt; getRemoteProcedure(long procId) {</span>
-<span class="source-line-no">4175</span><span id="line-4175">    Procedure&lt;?&gt; procedure = procedureExecutor.getProcedure(procId);</span>
-<span class="source-line-no">4176</span><span id="line-4176">    if (procedure == null) {</span>
-<span class="source-line-no">4177</span><span id="line-4177">      return null;</span>
-<span class="source-line-no">4178</span><span id="line-4178">    }</span>
-<span class="source-line-no">4179</span><span id="line-4179">    assert procedure instanceof RemoteProcedure;</span>
-<span class="source-line-no">4180</span><span id="line-4180">    return (RemoteProcedure&lt;MasterProcedureEnv, ?&gt;) procedure;</span>
-<span class="source-line-no">4181</span><span id="line-4181">  }</span>
-<span class="source-line-no">4182</span><span id="line-4182"></span>
-<span class="source-line-no">4183</span><span id="line-4183">  public void remoteProcedureCompleted(long procId) {</span>
-<span class="source-line-no">4184</span><span id="line-4184">    LOG.debug("Remote procedure done, pid={}", procId);</span>
-<span class="source-line-no">4185</span><span id="line-4185">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
-<span class="source-line-no">4186</span><span id="line-4186">    if (procedure != null) {</span>
-<span class="source-line-no">4187</span><span id="line-4187">      procedure.remoteOperationCompleted(procedureExecutor.getEnvironment());</span>
-<span class="source-line-no">4188</span><span id="line-4188">    }</span>
-<span class="source-line-no">4189</span><span id="line-4189">  }</span>
-<span class="source-line-no">4190</span><span id="line-4190"></span>
-<span class="source-line-no">4191</span><span id="line-4191">  public void remoteProcedureFailed(long procId, RemoteProcedureException error) {</span>
-<span class="source-line-no">4192</span><span id="line-4192">    LOG.debug("Remote procedure failed, pid={}", procId, error);</span>
-<span class="source-line-no">4193</span><span id="line-4193">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
-<span class="source-line-no">4194</span><span id="line-4194">    if (procedure != null) {</span>
-<span class="source-line-no">4195</span><span id="line-4195">      procedure.remoteOperationFailed(procedureExecutor.getEnvironment(), error);</span>
-<span class="source-line-no">4196</span><span id="line-4196">    }</span>
-<span class="source-line-no">4197</span><span id="line-4197">  }</span>
-<span class="source-line-no">4198</span><span id="line-4198"></span>
-<span class="source-line-no">4199</span><span id="line-4199">  /**</span>
-<span class="source-line-no">4200</span><span id="line-4200">   * Reopen regions provided in the argument</span>
-<span class="source-line-no">4201</span><span id="line-4201">   * @param tableName   The current table name</span>
-<span class="source-line-no">4202</span><span id="line-4202">   * @param regionNames The region names of the regions to reopen</span>
-<span class="source-line-no">4203</span><span id="line-4203">   * @param nonceGroup  Identifier for the source of the request, a client or process</span>
-<span class="source-line-no">4204</span><span id="line-4204">   * @param nonce       A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">4205</span><span id="line-4205">   *                    by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">4206</span><span id="line-4206">   *                    unique id).</span>
-<span class="source-line-no">4207</span><span id="line-4207">   * @return procedure Id</span>
-<span class="source-line-no">4208</span><span id="line-4208">   * @throws IOException if reopening region fails while running procedure</span>
-<span class="source-line-no">4209</span><span id="line-4209">   */</span>
-<span class="source-line-no">4210</span><span id="line-4210">  long reopenRegions(final TableName tableName, final List&lt;byte[]&gt; regionNames,</span>
-<span class="source-line-no">4211</span><span id="line-4211">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">4212</span><span id="line-4212"></span>
-<span class="source-line-no">4213</span><span id="line-4213">    return MasterProcedureUtil</span>
-<span class="source-line-no">4214</span><span id="line-4214">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">4215</span><span id="line-4215"></span>
-<span class="source-line-no">4216</span><span id="line-4216">        @Override</span>
-<span class="source-line-no">4217</span><span id="line-4217">        protected void run() throws IOException {</span>
-<span class="source-line-no">4218</span><span id="line-4218">          submitProcedure(new ReopenTableRegionsProcedure(tableName, regionNames));</span>
-<span class="source-line-no">4219</span><span id="line-4219">        }</span>
-<span class="source-line-no">4220</span><span id="line-4220"></span>
-<span class="source-line-no">4221</span><span id="line-4221">        @Override</span>
-<span class="source-line-no">4222</span><span id="line-4222">        protected String getDescription() {</span>
-<span class="source-line-no">4223</span><span id="line-4223">          return "ReopenTableRegionsProcedure";</span>
-<span class="source-line-no">4224</span><span id="line-4224">        }</span>
-<span class="source-line-no">4225</span><span id="line-4225"></span>
-<span class="source-line-no">4226</span><span id="line-4226">      });</span>
-<span class="source-line-no">4227</span><span id="line-4227"></span>
-<span class="source-line-no">4228</span><span id="line-4228">  }</span>
+<span class="source-line-no">4173</span><span id="line-4173">  public SpaceQuotaSnapshotNotifier getSpaceQuotaSnapshotNotifier() {</span>
+<span class="source-line-no">4174</span><span id="line-4174">    return this.spaceQuotaSnapshotNotifier;</span>
+<span class="source-line-no">4175</span><span id="line-4175">  }</span>
+<span class="source-line-no">4176</span><span id="line-4176"></span>
+<span class="source-line-no">4177</span><span id="line-4177">  @SuppressWarnings("unchecked")</span>
+<span class="source-line-no">4178</span><span id="line-4178">  private RemoteProcedure&lt;MasterProcedureEnv, ?&gt; getRemoteProcedure(long procId) {</span>
+<span class="source-line-no">4179</span><span id="line-4179">    Procedure&lt;?&gt; procedure = procedureExecutor.getProcedure(procId);</span>
+<span class="source-line-no">4180</span><span id="line-4180">    if (procedure == null) {</span>
+<span class="source-line-no">4181</span><span id="line-4181">      return null;</span>
+<span class="source-line-no">4182</span><span id="line-4182">    }</span>
+<span class="source-line-no">4183</span><span id="line-4183">    assert procedure instanceof RemoteProcedure;</span>
+<span class="source-line-no">4184</span><span id="line-4184">    return (RemoteProcedure&lt;MasterProcedureEnv, ?&gt;) procedure;</span>
+<span class="source-line-no">4185</span><span id="line-4185">  }</span>
+<span class="source-line-no">4186</span><span id="line-4186"></span>
+<span class="source-line-no">4187</span><span id="line-4187">  public void remoteProcedureCompleted(long procId) {</span>
+<span class="source-line-no">4188</span><span id="line-4188">    LOG.debug("Remote procedure done, pid={}", procId);</span>
+<span class="source-line-no">4189</span><span id="line-4189">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
+<span class="source-line-no">4190</span><span id="line-4190">    if (procedure != null) {</span>
+<span class="source-line-no">4191</span><span id="line-4191">      procedure.remoteOperationCompleted(procedureExecutor.getEnvironment());</span>
+<span class="source-line-no">4192</span><span id="line-4192">    }</span>
+<span class="source-line-no">4193</span><span id="line-4193">  }</span>
+<span class="source-line-no">4194</span><span id="line-4194"></span>
+<span class="source-line-no">4195</span><span id="line-4195">  public void remoteProcedureFailed(long procId, RemoteProcedureException error) {</span>
+<span class="source-line-no">4196</span><span id="line-4196">    LOG.debug("Remote procedure failed, pid={}", procId, error);</span>
+<span class="source-line-no">4197</span><span id="line-4197">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
+<span class="source-line-no">4198</span><span id="line-4198">    if (procedure != null) {</span>
+<span class="source-line-no">4199</span><span id="line-4199">      procedure.remoteOperationFailed(procedureExecutor.getEnvironment(), error);</span>
+<span class="source-line-no">4200</span><span id="line-4200">    }</span>
+<span class="source-line-no">4201</span><span id="line-4201">  }</span>
+<span class="source-line-no">4202</span><span id="line-4202"></span>
+<span class="source-line-no">4203</span><span id="line-4203">  /**</span>
+<span class="source-line-no">4204</span><span id="line-4204">   * Reopen regions provided in the argument</span>
+<span class="source-line-no">4205</span><span id="line-4205">   * @param tableName   The current table name</span>
+<span class="source-line-no">4206</span><span id="line-4206">   * @param regionNames The region names of the regions to reopen</span>
+<span class="source-line-no">4207</span><span id="line-4207">   * @param nonceGroup  Identifier for the source of the request, a client or process</span>
+<span class="source-line-no">4208</span><span id="line-4208">   * @param nonce       A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">4209</span><span id="line-4209">   *                    by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">4210</span><span id="line-4210">   *                    unique id).</span>
+<span class="source-line-no">4211</span><span id="line-4211">   * @return procedure Id</span>
+<span class="source-line-no">4212</span><span id="line-4212">   * @throws IOException if reopening region fails while running procedure</span>
+<span class="source-line-no">4213</span><span id="line-4213">   */</span>
+<span class="source-line-no">4214</span><span id="line-4214">  long reopenRegions(final TableName tableName, final List&lt;byte[]&gt; regionNames,</span>
+<span class="source-line-no">4215</span><span id="line-4215">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">4216</span><span id="line-4216"></span>
+<span class="source-line-no">4217</span><span id="line-4217">    return MasterProcedureUtil</span>
+<span class="source-line-no">4218</span><span id="line-4218">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">4219</span><span id="line-4219"></span>
+<span class="source-line-no">4220</span><span id="line-4220">        @Override</span>
+<span class="source-line-no">4221</span><span id="line-4221">        protected void run() throws IOException {</span>
+<span class="source-line-no">4222</span><span id="line-4222">          submitProcedure(new ReopenTableRegionsProcedure(tableName, regionNames));</span>
+<span class="source-line-no">4223</span><span id="line-4223">        }</span>
+<span class="source-line-no">4224</span><span id="line-4224"></span>
+<span class="source-line-no">4225</span><span id="line-4225">        @Override</span>
+<span class="source-line-no">4226</span><span id="line-4226">        protected String getDescription() {</span>
+<span class="source-line-no">4227</span><span id="line-4227">          return "ReopenTableRegionsProcedure";</span>
+<span class="source-line-no">4228</span><span id="line-4228">        }</span>
 <span class="source-line-no">4229</span><span id="line-4229"></span>
-<span class="source-line-no">4230</span><span id="line-4230">  @Override</span>
-<span class="source-line-no">4231</span><span id="line-4231">  public ReplicationPeerManager getReplicationPeerManager() {</span>
-<span class="source-line-no">4232</span><span id="line-4232">    return replicationPeerManager;</span>
-<span class="source-line-no">4233</span><span id="line-4233">  }</span>
-<span class="source-line-no">4234</span><span id="line-4234"></span>
-<span class="source-line-no">4235</span><span id="line-4235">  @Override</span>
-<span class="source-line-no">4236</span><span id="line-4236">  public ReplicationLogCleanerBarrier getReplicationLogCleanerBarrier() {</span>
-<span class="source-line-no">4237</span><span id="line-4237">    return replicationLogCleanerBarrier;</span>
-<span class="source-line-no">4238</span><span id="line-4238">  }</span>
-<span class="source-line-no">4239</span><span id="line-4239"></span>
-<span class="source-line-no">4240</span><span id="line-4240">  @Override</span>
-<span class="source-line-no">4241</span><span id="line-4241">  public Semaphore getSyncReplicationPeerLock() {</span>
-<span class="source-line-no">4242</span><span id="line-4242">    return syncReplicationPeerLock;</span>
-<span class="source-line-no">4243</span><span id="line-4243">  }</span>
-<span class="source-line-no">4244</span><span id="line-4244"></span>
-<span class="source-line-no">4245</span><span id="line-4245">  public HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt;</span>
-<span class="source-line-no">4246</span><span id="line-4246">    getReplicationLoad(ServerName[] serverNames) {</span>
-<span class="source-line-no">4247</span><span id="line-4247">    List&lt;ReplicationPeerDescription&gt; peerList = this.getReplicationPeerManager().listPeers(null);</span>
-<span class="source-line-no">4248</span><span id="line-4248">    if (peerList == null) {</span>
-<span class="source-line-no">4249</span><span id="line-4249">      return null;</span>
-<span class="source-line-no">4250</span><span id="line-4250">    }</span>
-<span class="source-line-no">4251</span><span id="line-4251">    HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt; replicationLoadSourceMap =</span>
-<span class="source-line-no">4252</span><span id="line-4252">      new HashMap&lt;&gt;(peerList.size());</span>
-<span class="source-line-no">4253</span><span id="line-4253">    peerList.stream()</span>
-<span class="source-line-no">4254</span><span id="line-4254">      .forEach(peer -&gt; replicationLoadSourceMap.put(peer.getPeerId(), new ArrayList&lt;&gt;()));</span>
-<span class="source-line-no">4255</span><span id="line-4255">    for (ServerName serverName : serverNames) {</span>
-<span class="source-line-no">4256</span><span id="line-4256">      List&lt;ReplicationLoadSource&gt; replicationLoadSources =</span>
-<span class="source-line-no">4257</span><span id="line-4257">        getServerManager().getLoad(serverName).getReplicationLoadSourceList();</span>
-<span class="source-line-no">4258</span><span id="line-4258">      for (ReplicationLoadSource replicationLoadSource : replicationLoadSources) {</span>
-<span class="source-line-no">4259</span><span id="line-4259">        List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; replicationLoadSourceList =</span>
-<span class="source-line-no">4260</span><span id="line-4260">          replicationLoadSourceMap.get(replicationLoadSource.getPeerID());</span>
-<span class="source-line-no">4261</span><span id="line-4261">        if (replicationLoadSourceList == null) {</span>
-<span class="source-line-no">4262</span><span id="line-4262">          LOG.debug("{} does not exist, but it exists "</span>
-<span class="source-line-no">4263</span><span id="line-4263">            + "in znode(/hbase/replication/rs). when the rs restarts, peerId is deleted, so "</span>
-<span class="source-line-no">4264</span><span id="line-4264">            + "we just need to ignore it", replicationLoadSource.getPeerID());</span>
-<span class="source-line-no">4265</span><span id="line-4265">          continue;</span>
-<span class="source-line-no">4266</span><span id="line-4266">        }</span>
-<span class="source-line-no">4267</span><span id="line-4267">        replicationLoadSourceList.add(new Pair&lt;&gt;(serverName, replicationLoadSource));</span>
-<span class="source-line-no">4268</span><span id="line-4268">      }</span>
-<span class="source-line-no">4269</span><span id="line-4269">    }</span>
-<span class="source-line-no">4270</span><span id="line-4270">    for (List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; loads : replicationLoadSourceMap.values()) {</span>
-<span class="source-line-no">4271</span><span id="line-4271">      if (loads.size() &gt; 0) {</span>
-<span class="source-line-no">4272</span><span id="line-4272">        loads.sort(Comparator.comparingLong(load -&gt; (-1) * load.getSecond().getReplicationLag()));</span>
-<span class="source-line-no">4273</span><span id="line-4273">      }</span>
-<span class="source-line-no">4274</span><span id="line-4274">    }</span>
-<span class="source-line-no">4275</span><span id="line-4275">    return replicationLoadSourceMap;</span>
-<span class="source-line-no">4276</span><span id="line-4276">  }</span>
-<span class="source-line-no">4277</span><span id="line-4277"></span>
-<span class="source-line-no">4278</span><span id="line-4278">  /**</span>
-<span class="source-line-no">4279</span><span id="line-4279">   * This method modifies the master's configuration in order to inject replication-related features</span>
-<span class="source-line-no">4280</span><span id="line-4280">   */</span>
-<span class="source-line-no">4281</span><span id="line-4281">  @InterfaceAudience.Private</span>
-<span class="source-line-no">4282</span><span id="line-4282">  public static void decorateMasterConfiguration(Configuration conf) {</span>
-<span class="source-line-no">4283</span><span id="line-4283">    String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);</span>
-<span class="source-line-no">4284</span><span id="line-4284">    String cleanerClass = ReplicationLogCleaner.class.getCanonicalName();</span>
-<span class="source-line-no">4285</span><span id="line-4285">    if (plugins == null || !plugins.contains(cleanerClass)) {</span>
-<span class="source-line-no">4286</span><span id="line-4286">      conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
-<span class="source-line-no">4287</span><span id="line-4287">    }</span>
-<span class="source-line-no">4288</span><span id="line-4288">    if (ReplicationUtils.isReplicationForBulkLoadDataEnabled(conf)) {</span>
-<span class="source-line-no">4289</span><span id="line-4289">      plugins = conf.get(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS);</span>
-<span class="source-line-no">4290</span><span id="line-4290">      cleanerClass = ReplicationHFileCleaner.class.getCanonicalName();</span>
-<span class="source-line-no">4291</span><span id="line-4291">      if (!plugins.contains(cleanerClass)) {</span>
-<span class="source-line-no">4292</span><span id="line-4292">        conf.set(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
-<span class="source-line-no">4293</span><span id="line-4293">      }</span>
-<span class="source-line-no">4294</span><span id="line-4294">    }</span>
-<span class="source-line-no">4295</span><span id="line-4295">  }</span>
-<span class="source-line-no">4296</span><span id="line-4296"></span>
-<span class="source-line-no">4297</span><span id="line-4297">  public SnapshotQuotaObserverChore getSnapshotQuotaObserverChore() {</span>
-<span class="source-line-no">4298</span><span id="line-4298">    return this.snapshotQuotaChore;</span>
+<span class="source-line-no">4230</span><span id="line-4230">      });</span>
+<span class="source-line-no">4231</span><span id="line-4231"></span>
+<span class="source-line-no">4232</span><span id="line-4232">  }</span>
+<span class="source-line-no">4233</span><span id="line-4233"></span>
+<span class="source-line-no">4234</span><span id="line-4234">  @Override</span>
+<span class="source-line-no">4235</span><span id="line-4235">  public ReplicationPeerManager getReplicationPeerManager() {</span>
+<span class="source-line-no">4236</span><span id="line-4236">    return replicationPeerManager;</span>
+<span class="source-line-no">4237</span><span id="line-4237">  }</span>
+<span class="source-line-no">4238</span><span id="line-4238"></span>
+<span class="source-line-no">4239</span><span id="line-4239">  @Override</span>
+<span class="source-line-no">4240</span><span id="line-4240">  public ReplicationLogCleanerBarrier getReplicationLogCleanerBarrier() {</span>
+<span class="source-line-no">4241</span><span id="line-4241">    return replicationLogCleanerBarrier;</span>
+<span class="source-line-no">4242</span><span id="line-4242">  }</span>
+<span class="source-line-no">4243</span><span id="line-4243"></span>
+<span class="source-line-no">4244</span><span id="line-4244">  @Override</span>
+<span class="source-line-no">4245</span><span id="line-4245">  public Semaphore getSyncReplicationPeerLock() {</span>
+<span class="source-line-no">4246</span><span id="line-4246">    return syncReplicationPeerLock;</span>
+<span class="source-line-no">4247</span><span id="line-4247">  }</span>
+<span class="source-line-no">4248</span><span id="line-4248"></span>
+<span class="source-line-no">4249</span><span id="line-4249">  public HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt;</span>
+<span class="source-line-no">4250</span><span id="line-4250">    getReplicationLoad(ServerName[] serverNames) {</span>
+<span class="source-line-no">4251</span><span id="line-4251">    List&lt;ReplicationPeerDescription&gt; peerList = this.getReplicationPeerManager().listPeers(null);</span>
+<span class="source-line-no">4252</span><span id="line-4252">    if (peerList == null) {</span>
+<span class="source-line-no">4253</span><span id="line-4253">      return null;</span>
+<span class="source-line-no">4254</span><span id="line-4254">    }</span>
+<span class="source-line-no">4255</span><span id="line-4255">    HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt; replicationLoadSourceMap =</span>
+<span class="source-line-no">4256</span><span id="line-4256">      new HashMap&lt;&gt;(peerList.size());</span>
+<span class="source-line-no">4257</span><span id="line-4257">    peerList.stream()</span>
+<span class="source-line-no">4258</span><span id="line-4258">      .forEach(peer -&gt; replicationLoadSourceMap.put(peer.getPeerId(), new ArrayList&lt;&gt;()));</span>
+<span class="source-line-no">4259</span><span id="line-4259">    for (ServerName serverName : serverNames) {</span>
+<span class="source-line-no">4260</span><span id="line-4260">      List&lt;ReplicationLoadSource&gt; replicationLoadSources =</span>
+<span class="source-line-no">4261</span><span id="line-4261">        getServerManager().getLoad(serverName).getReplicationLoadSourceList();</span>
+<span class="source-line-no">4262</span><span id="line-4262">      for (ReplicationLoadSource replicationLoadSource : replicationLoadSources) {</span>
+<span class="source-line-no">4263</span><span id="line-4263">        List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; replicationLoadSourceList =</span>
+<span class="source-line-no">4264</span><span id="line-4264">          replicationLoadSourceMap.get(replicationLoadSource.getPeerID());</span>
+<span class="source-line-no">4265</span><span id="line-4265">        if (replicationLoadSourceList == null) {</span>
+<span class="source-line-no">4266</span><span id="line-4266">          LOG.debug("{} does not exist, but it exists "</span>
+<span class="source-line-no">4267</span><span id="line-4267">            + "in znode(/hbase/replication/rs). when the rs restarts, peerId is deleted, so "</span>
+<span class="source-line-no">4268</span><span id="line-4268">            + "we just need to ignore it", replicationLoadSource.getPeerID());</span>
+<span class="source-line-no">4269</span><span id="line-4269">          continue;</span>
+<span class="source-line-no">4270</span><span id="line-4270">        }</span>
+<span class="source-line-no">4271</span><span id="line-4271">        replicationLoadSourceList.add(new Pair&lt;&gt;(serverName, replicationLoadSource));</span>
+<span class="source-line-no">4272</span><span id="line-4272">      }</span>
+<span class="source-line-no">4273</span><span id="line-4273">    }</span>
+<span class="source-line-no">4274</span><span id="line-4274">    for (List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; loads : replicationLoadSourceMap.values()) {</span>
+<span class="source-line-no">4275</span><span id="line-4275">      if (loads.size() &gt; 0) {</span>
+<span class="source-line-no">4276</span><span id="line-4276">        loads.sort(Comparator.comparingLong(load -&gt; (-1) * load.getSecond().getReplicationLag()));</span>
+<span class="source-line-no">4277</span><span id="line-4277">      }</span>
+<span class="source-line-no">4278</span><span id="line-4278">    }</span>
+<span class="source-line-no">4279</span><span id="line-4279">    return replicationLoadSourceMap;</span>
+<span class="source-line-no">4280</span><span id="line-4280">  }</span>
+<span class="source-line-no">4281</span><span id="line-4281"></span>
+<span class="source-line-no">4282</span><span id="line-4282">  /**</span>
+<span class="source-line-no">4283</span><span id="line-4283">   * This method modifies the master's configuration in order to inject replication-related features</span>
+<span class="source-line-no">4284</span><span id="line-4284">   */</span>
+<span class="source-line-no">4285</span><span id="line-4285">  @InterfaceAudience.Private</span>
+<span class="source-line-no">4286</span><span id="line-4286">  public static void decorateMasterConfiguration(Configuration conf) {</span>
+<span class="source-line-no">4287</span><span id="line-4287">    String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);</span>
+<span class="source-line-no">4288</span><span id="line-4288">    String cleanerClass = ReplicationLogCleaner.class.getCanonicalName();</span>
+<span class="source-line-no">4289</span><span id="line-4289">    if (plugins == null || !plugins.contains(cleanerClass)) {</span>
+<span class="source-line-no">4290</span><span id="line-4290">      conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
+<span class="source-line-no">4291</span><span id="line-4291">    }</span>
+<span class="source-line-no">4292</span><span id="line-4292">    if (ReplicationUtils.isReplicationForBulkLoadDataEnabled(conf)) {</span>
+<span class="source-line-no">4293</span><span id="line-4293">      plugins = conf.get(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS);</span>
+<span class="source-line-no">4294</span><span id="line-4294">      cleanerClass = ReplicationHFileCleaner.class.getCanonicalName();</span>
+<span class="source-line-no">4295</span><span id="line-4295">      if (!plugins.contains(cleanerClass)) {</span>
+<span class="source-line-no">4296</span><span id="line-4296">        conf.set(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
+<span class="source-line-no">4297</span><span id="line-4297">      }</span>
+<span class="source-line-no">4298</span><span id="line-4298">    }</span>
 <span class="source-line-no">4299</span><span id="line-4299">  }</span>
 <span class="source-line-no">4300</span><span id="line-4300"></span>
-<span class="source-line-no">4301</span><span id="line-4301">  public ActiveMasterManager getActiveMasterManager() {</span>
-<span class="source-line-no">4302</span><span id="line-4302">    return activeMasterManager;</span>
+<span class="source-line-no">4301</span><span id="line-4301">  public SnapshotQuotaObserverChore getSnapshotQuotaObserverChore() {</span>
+<span class="source-line-no">4302</span><span id="line-4302">    return this.snapshotQuotaChore;</span>
 <span class="source-line-no">4303</span><span id="line-4303">  }</span>
 <span class="source-line-no">4304</span><span id="line-4304"></span>
-<span class="source-line-no">4305</span><span id="line-4305">  @Override</span>
-<span class="source-line-no">4306</span><span id="line-4306">  public SyncReplicationReplayWALManager getSyncReplicationReplayWALManager() {</span>
-<span class="source-line-no">4307</span><span id="line-4307">    return this.syncReplicationReplayWALManager;</span>
-<span class="source-line-no">4308</span><span id="line-4308">  }</span>
-<span class="source-line-no">4309</span><span id="line-4309"></span>
-<span class="source-line-no">4310</span><span id="line-4310">  @Override</span>
-<span class="source-line-no">4311</span><span id="line-4311">  public HbckChore getHbckChore() {</span>
-<span class="source-line-no">4312</span><span id="line-4312">    return this.hbckChore;</span>
-<span class="source-line-no">4313</span><span id="line-4313">  }</span>
-<span class="source-line-no">4314</span><span id="line-4314"></span>
-<span class="source-line-no">4315</span><span id="line-4315">  @Override</span>
-<span class="source-line-no">4316</span><span id="line-4316">  public void runReplicationBarrierCleaner() {</span>
-<span class="source-line-no">4317</span><span id="line-4317">    ReplicationBarrierCleaner rbc = this.replicationBarrierCleaner;</span>
-<span class="source-line-no">4318</span><span id="line-4318">    if (rbc != null) {</span>
-<span class="source-line-no">4319</span><span id="line-4319">      rbc.chore();</span>
-<span class="source-line-no">4320</span><span id="line-4320">    }</span>
-<span class="source-line-no">4321</span><span id="line-4321">  }</span>
-<span class="source-line-no">4322</span><span id="line-4322"></span>
-<span class="source-line-no">4323</span><span id="line-4323">  @Override</span>
-<span class="source-line-no">4324</span><span id="line-4324">  public RSGroupInfoManager getRSGroupInfoManager() {</span>
-<span class="source-line-no">4325</span><span id="line-4325">    return rsGroupInfoManager;</span>
-<span class="source-line-no">4326</span><span id="line-4326">  }</span>
-<span class="source-line-no">4327</span><span id="line-4327"></span>
-<span class="source-line-no">4328</span><span id="line-4328">  /**</span>
-<span class="source-line-no">4329</span><span id="line-4329">   * Get the compaction state of the table</span>
-<span class="source-line-no">4330</span><span id="line-4330">   * @param tableName The table name</span>
-<span class="source-line-no">4331</span><span id="line-4331">   * @return CompactionState Compaction state of the table</span>
-<span class="source-line-no">4332</span><span id="line-4332">   */</span>
-<span class="source-line-no">4333</span><span id="line-4333">  public CompactionState getCompactionState(final TableName tableName) {</span>
-<span class="source-line-no">4334</span><span id="line-4334">    CompactionState compactionState = CompactionState.NONE;</span>
-<span class="source-line-no">4335</span><span id="line-4335">    try {</span>
-<span class="source-line-no">4336</span><span id="line-4336">      List&lt;RegionInfo&gt; regions = assignmentManager.getRegionStates().getRegionsOfTable(tableName);</span>
-<span class="source-line-no">4337</span><span id="line-4337">      for (RegionInfo regionInfo : regions) {</span>
-<span class="source-line-no">4338</span><span id="line-4338">        ServerName serverName =</span>
-<span class="source-line-no">4339</span><span id="line-4339">          assignmentManager.getRegionStates().getRegionServerOfRegion(regionInfo);</span>
-<span class="source-line-no">4340</span><span id="line-4340">        if (serverName == null) {</span>
-<span class="source-line-no">4341</span><span id="line-4341">          continue;</span>
-<span class="source-line-no">4342</span><span id="line-4342">        }</span>
-<span class="source-line-no">4343</span><span id="line-4343">        ServerMetrics sl = serverManager.getLoad(serverName);</span>
-<span class="source-line-no">4344</span><span id="line-4344">        if (sl == null) {</span>
+<span class="source-line-no">4305</span><span id="line-4305">  public ActiveMasterManager getActiveMasterManager() {</span>
+<span class="source-line-no">4306</span><span id="line-4306">    return activeMasterManager;</span>
+<span class="source-line-no">4307</span><span id="line-4307">  }</span>
+<span class="source-line-no">4308</span><span id="line-4308"></span>
+<span class="source-line-no">4309</span><span id="line-4309">  @Override</span>
+<span class="source-line-no">4310</span><span id="line-4310">  public SyncReplicationReplayWALManager getSyncReplicationReplayWALManager() {</span>
+<span class="source-line-no">4311</span><span id="line-4311">    return this.syncReplicationReplayWALManager;</span>
+<span class="source-line-no">4312</span><span id="line-4312">  }</span>
+<span class="source-line-no">4313</span><span id="line-4313"></span>
+<span class="source-line-no">4314</span><span id="line-4314">  @Override</span>
+<span class="source-line-no">4315</span><span id="line-4315">  public HbckChore getHbckChore() {</span>
+<span class="source-line-no">4316</span><span id="line-4316">    return this.hbckChore;</span>
+<span class="source-line-no">4317</span><span id="line-4317">  }</span>
+<span class="source-line-no">4318</span><span id="line-4318"></span>
+<span class="source-line-no">4319</span><span id="line-4319">  @Override</span>
+<span class="source-line-no">4320</span><span id="line-4320">  public void runReplicationBarrierCleaner() {</span>
+<span class="source-line-no">4321</span><span id="line-4321">    ReplicationBarrierCleaner rbc = this.replicationBarrierCleaner;</span>
+<span class="source-line-no">4322</span><span id="line-4322">    if (rbc != null) {</span>
+<span class="source-line-no">4323</span><span id="line-4323">      rbc.chore();</span>
+<span class="source-line-no">4324</span><span id="line-4324">    }</span>
+<span class="source-line-no">4325</span><span id="line-4325">  }</span>
+<span class="source-line-no">4326</span><span id="line-4326"></span>
+<span class="source-line-no">4327</span><span id="line-4327">  @Override</span>
+<span class="source-line-no">4328</span><span id="line-4328">  public RSGroupInfoManager getRSGroupInfoManager() {</span>
+<span class="source-line-no">4329</span><span id="line-4329">    return rsGroupInfoManager;</span>
+<span class="source-line-no">4330</span><span id="line-4330">  }</span>
+<span class="source-line-no">4331</span><span id="line-4331"></span>
+<span class="source-line-no">4332</span><span id="line-4332">  /**</span>
+<span class="source-line-no">4333</span><span id="line-4333">   * Get the compaction state of the table</span>
+<span class="source-line-no">4334</span><span id="line-4334">   * @param tableName The table name</span>
+<span class="source-line-no">4335</span><span id="line-4335">   * @return CompactionState Compaction state of the table</span>
+<span class="source-line-no">4336</span><span id="line-4336">   */</span>
+<span class="source-line-no">4337</span><span id="line-4337">  public CompactionState getCompactionState(final TableName tableName) {</span>
+<span class="source-line-no">4338</span><span id="line-4338">    CompactionState compactionState = CompactionState.NONE;</span>
+<span class="source-line-no">4339</span><span id="line-4339">    try {</span>
+<span class="source-line-no">4340</span><span id="line-4340">      List&lt;RegionInfo&gt; regions = assignmentManager.getRegionStates().getRegionsOfTable(tableName);</span>
+<span class="source-line-no">4341</span><span id="line-4341">      for (RegionInfo regionInfo : regions) {</span>
+<span class="source-line-no">4342</span><span id="line-4342">        ServerName serverName =</span>
+<span class="source-line-no">4343</span><span id="line-4343">          assignmentManager.getRegionStates().getRegionServerOfRegion(regionInfo);</span>
+<span class="source-line-no">4344</span><span id="line-4344">        if (serverName == null) {</span>
 <span class="source-line-no">4345</span><span id="line-4345">          continue;</span>
 <span class="source-line-no">4346</span><span id="line-4346">        }</span>
-<span class="source-line-no">4347</span><span id="line-4347">        RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());</span>
-<span class="source-line-no">4348</span><span id="line-4348">        if (regionMetrics == null) {</span>
-<span class="source-line-no">4349</span><span id="line-4349">          LOG.warn("Can not get compaction details for the region: {} , it may be not online.",</span>
-<span class="source-line-no">4350</span><span id="line-4350">            regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">4351</span><span id="line-4351">          continue;</span>
-<span class="source-line-no">4352</span><span id="line-4352">        }</span>
-<span class="source-line-no">4353</span><span id="line-4353">        if (regionMetrics.getCompactionState() == CompactionState.MAJOR) {</span>
-<span class="source-line-no">4354</span><span id="line-4354">          if (compactionState == CompactionState.MINOR) {</span>
-<span class="source-line-no">4355</span><span id="line-4355">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">4356</span><span id="line-4356">          } else {</span>
-<span class="source-line-no">4357</span><span id="line-4357">            compactionState = CompactionState.MAJOR;</span>
-<span class="source-line-no">4358</span><span id="line-4358">          }</span>
-<span class="source-line-no">4359</span><span id="line-4359">        } else if (regionMetrics.getCompactionState() == CompactionState.MINOR) {</span>
-<span class="source-line-no">4360</span><span id="line-4360">          if (compactionState == CompactionState.MAJOR) {</span>
-<span class="source-line-no">4361</span><span id="line-4361">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">4362</span><span id="line-4362">          } else {</span>
-<span class="source-line-no">4363</span><span id="line-4363">            compactionState = CompactionState.MINOR;</span>
-<span class="source-line-no">4364</span><span id="line-4364">          }</span>
-<span class="source-line-no">4365</span><span id="line-4365">        }</span>
-<span class="source-line-no">4366</span><span id="line-4366">      }</span>
-<span class="source-line-no">4367</span><span id="line-4367">    } catch (Exception e) {</span>
-<span class="source-line-no">4368</span><span id="line-4368">      compactionState = null;</span>
-<span class="source-line-no">4369</span><span id="line-4369">      LOG.error("Exception when get compaction state for " + tableName.getNameAsString(), e);</span>
-<span class="source-line-no">4370</span><span id="line-4370">    }</span>
-<span class="source-line-no">4371</span><span id="line-4371">    return compactionState;</span>
-<span class="source-line-no">4372</span><span id="line-4372">  }</span>
-<span class="source-line-no">4373</span><span id="line-4373"></span>
-<span class="source-line-no">4374</span><span id="line-4374">  @Override</span>
-<span class="source-line-no">4375</span><span id="line-4375">  public MetaLocationSyncer getMetaLocationSyncer() {</span>
-<span class="source-line-no">4376</span><span id="line-4376">    return metaLocationSyncer;</span>
-<span class="source-line-no">4377</span><span id="line-4377">  }</span>
-<span class="source-line-no">4378</span><span id="line-4378"></span>
-<span class="source-line-no">4379</span><span id="line-4379">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4380</span><span id="line-4380">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4381</span><span id="line-4381">  public MasterRegion getMasterRegion() {</span>
-<span class="source-line-no">4382</span><span id="line-4382">    return masterRegion;</span>
-<span class="source-line-no">4383</span><span id="line-4383">  }</span>
-<span class="source-line-no">4384</span><span id="line-4384"></span>
-<span class="source-line-no">4385</span><span id="line-4385">  @Override</span>
-<span class="source-line-no">4386</span><span id="line-4386">  public void onConfigurationChange(Configuration newConf) {</span>
-<span class="source-line-no">4387</span><span id="line-4387">    try {</span>
-<span class="source-line-no">4388</span><span id="line-4388">      Superusers.initialize(newConf);</span>
-<span class="source-line-no">4389</span><span id="line-4389">    } catch (IOException e) {</span>
-<span class="source-line-no">4390</span><span id="line-4390">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
-<span class="source-line-no">4391</span><span id="line-4391">    }</span>
-<span class="source-line-no">4392</span><span id="line-4392">    // append the quotas observer back to the master coprocessor key</span>
-<span class="source-line-no">4393</span><span id="line-4393">    setQuotasObserver(newConf);</span>
-<span class="source-line-no">4394</span><span id="line-4394">    // update region server coprocessor if the configuration has changed.</span>
-<span class="source-line-no">4395</span><span id="line-4395">    if (</span>
-<span class="source-line-no">4396</span><span id="line-4396">      CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,</span>
-<span class="source-line-no">4397</span><span id="line-4397">        CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) &amp;&amp; !maintenanceMode</span>
-<span class="source-line-no">4398</span><span id="line-4398">    ) {</span>
-<span class="source-line-no">4399</span><span id="line-4399">      LOG.info("Update the master coprocessor(s) because the configuration has changed");</span>
-<span class="source-line-no">4400</span><span id="line-4400">      initializeCoprocessorHost(newConf);</span>
-<span class="source-line-no">4401</span><span id="line-4401">    }</span>
-<span class="source-line-no">4402</span><span id="line-4402">  }</span>
-<span class="source-line-no">4403</span><span id="line-4403"></span>
-<span class="source-line-no">4404</span><span id="line-4404">  @Override</span>
-<span class="source-line-no">4405</span><span id="line-4405">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
-<span class="source-line-no">4406</span><span id="line-4406">    final boolean isBalancerDecisionRecording =</span>
-<span class="source-line-no">4407</span><span id="line-4407">      conf.getBoolean(BaseLoadBalancer.BALANCER_DECISION_BUFFER_ENABLED,</span>
-<span class="source-line-no">4408</span><span id="line-4408">        BaseLoadBalancer.DEFAULT_BALANCER_DECISION_BUFFER_ENABLED);</span>
-<span class="source-line-no">4409</span><span id="line-4409">    final boolean isBalancerRejectionRecording =</span>
-<span class="source-line-no">4410</span><span id="line-4410">      conf.getBoolean(BaseLoadBalancer.BALANCER_REJECTION_BUFFER_ENABLED,</span>
-<span class="source-line-no">4411</span><span id="line-4411">        BaseLoadBalancer.DEFAULT_BALANCER_REJECTION_BUFFER_ENABLED);</span>
-<span class="source-line-no">4412</span><span id="line-4412">    if (isBalancerDecisionRecording || isBalancerRejectionRecording) {</span>
-<span class="source-line-no">4413</span><span id="line-4413">      return NamedQueueRecorder.getInstance(conf);</span>
-<span class="source-line-no">4414</span><span id="line-4414">    } else {</span>
-<span class="source-line-no">4415</span><span id="line-4415">      return null;</span>
-<span class="source-line-no">4416</span><span id="line-4416">    }</span>
-<span class="source-line-no">4417</span><span id="line-4417">  }</span>
-<span class="source-line-no">4418</span><span id="line-4418"></span>
-<span class="source-line-no">4419</span><span id="line-4419">  @Override</span>
-<span class="source-line-no">4420</span><span id="line-4420">  protected boolean clusterMode() {</span>
-<span class="source-line-no">4421</span><span id="line-4421">    return true;</span>
-<span class="source-line-no">4422</span><span id="line-4422">  }</span>
-<span class="source-line-no">4423</span><span id="line-4423"></span>
-<span class="source-line-no">4424</span><span id="line-4424">  public String getClusterId() {</span>
-<span class="source-line-no">4425</span><span id="line-4425">    if (activeMaster) {</span>
-<span class="source-line-no">4426</span><span id="line-4426">      return clusterId;</span>
-<span class="source-line-no">4427</span><span id="line-4427">    }</span>
-<span class="source-line-no">4428</span><span id="line-4428">    return cachedClusterId.getFromCacheOrFetch();</span>
-<span class="source-line-no">4429</span><span id="line-4429">  }</span>
-<span class="source-line-no">4430</span><span id="line-4430"></span>
-<span class="source-line-no">4431</span><span id="line-4431">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
-<span class="source-line-no">4432</span><span id="line-4432">    return activeMasterManager.getActiveMasterServerName();</span>
+<span class="source-line-no">4347</span><span id="line-4347">        ServerMetrics sl = serverManager.getLoad(serverName);</span>
+<span class="source-line-no">4348</span><span id="line-4348">        if (sl == null) {</span>
+<span class="source-line-no">4349</span><span id="line-4349">          continue;</span>
+<span class="source-line-no">4350</span><span id="line-4350">        }</span>
+<span class="source-line-no">4351</span><span id="line-4351">        RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());</span>
+<span class="source-line-no">4352</span><span id="line-4352">        if (regionMetrics == null) {</span>
+<span class="source-line-no">4353</span><span id="line-4353">          LOG.warn("Can not get compaction details for the region: {} , it may be not online.",</span>
+<span class="source-line-no">4354</span><span id="line-4354">            regionInfo.getRegionNameAsString());</span>
+<span class="source-line-no">4355</span><span id="line-4355">          continue;</span>
+<span class="source-line-no">4356</span><span id="line-4356">        }</span>
+<span class="source-line-no">4357</span><span id="line-4357">        if (regionMetrics.getCompactionState() == CompactionState.MAJOR) {</span>
+<span class="source-line-no">4358</span><span id="line-4358">          if (compactionState == CompactionState.MINOR) {</span>
+<span class="source-line-no">4359</span><span id="line-4359">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">4360</span><span id="line-4360">          } else {</span>
+<span class="source-line-no">4361</span><span id="line-4361">            compactionState = CompactionState.MAJOR;</span>
+<span class="source-line-no">4362</span><span id="line-4362">          }</span>
+<span class="source-line-no">4363</span><span id="line-4363">        } else if (regionMetrics.getCompactionState() == CompactionState.MINOR) {</span>
+<span class="source-line-no">4364</span><span id="line-4364">          if (compactionState == CompactionState.MAJOR) {</span>
+<span class="source-line-no">4365</span><span id="line-4365">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">4366</span><span id="line-4366">          } else {</span>
+<span class="source-line-no">4367</span><span id="line-4367">            compactionState = CompactionState.MINOR;</span>
+<span class="source-line-no">4368</span><span id="line-4368">          }</span>
+<span class="source-line-no">4369</span><span id="line-4369">        }</span>
+<span class="source-line-no">4370</span><span id="line-4370">      }</span>
+<span class="source-line-no">4371</span><span id="line-4371">    } catch (Exception e) {</span>
+<span class="source-line-no">4372</span><span id="line-4372">      compactionState = null;</span>
+<span class="source-line-no">4373</span><span id="line-4373">      LOG.error("Exception when get compaction state for " + tableName.getNameAsString(), e);</span>
+<span class="source-line-no">4374</span><span id="line-4374">    }</span>
+<span class="source-line-no">4375</span><span id="line-4375">    return compactionState;</span>
+<span class="source-line-no">4376</span><span id="line-4376">  }</span>
+<span class="source-line-no">4377</span><span id="line-4377"></span>
+<span class="source-line-no">4378</span><span id="line-4378">  @Override</span>
+<span class="source-line-no">4379</span><span id="line-4379">  public MetaLocationSyncer getMetaLocationSyncer() {</span>
+<span class="source-line-no">4380</span><span id="line-4380">    return metaLocationSyncer;</span>
+<span class="source-line-no">4381</span><span id="line-4381">  }</span>
+<span class="source-line-no">4382</span><span id="line-4382"></span>
+<span class="source-line-no">4383</span><span id="line-4383">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4384</span><span id="line-4384">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4385</span><span id="line-4385">  public MasterRegion getMasterRegion() {</span>
+<span class="source-line-no">4386</span><span id="line-4386">    return masterRegion;</span>
+<span class="source-line-no">4387</span><span id="line-4387">  }</span>
+<span class="source-line-no">4388</span><span id="line-4388"></span>
+<span class="source-line-no">4389</span><span id="line-4389">  @Override</span>
+<span class="source-line-no">4390</span><span id="line-4390">  public void onConfigurationChange(Configuration newConf) {</span>
+<span class="source-line-no">4391</span><span id="line-4391">    try {</span>
+<span class="source-line-no">4392</span><span id="line-4392">      Superusers.initialize(newConf);</span>
+<span class="source-line-no">4393</span><span id="line-4393">    } catch (IOException e) {</span>
+<span class="source-line-no">4394</span><span id="line-4394">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
+<span class="source-line-no">4395</span><span id="line-4395">    }</span>
+<span class="source-line-no">4396</span><span id="line-4396">    // append the quotas observer back to the master coprocessor key</span>
+<span class="source-line-no">4397</span><span id="line-4397">    setQuotasObserver(newConf);</span>
+<span class="source-line-no">4398</span><span id="line-4398">    // update region server coprocessor if the configuration has changed.</span>
+<span class="source-line-no">4399</span><span id="line-4399">    if (</span>
+<span class="source-line-no">4400</span><span id="line-4400">      CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,</span>
+<span class="source-line-no">4401</span><span id="line-4401">        CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) &amp;&amp; !maintenanceMode</span>
+<span class="source-line-no">4402</span><span id="line-4402">    ) {</span>
+<span class="source-line-no">4403</span><span id="line-4403">      LOG.info("Update the master coprocessor(s) because the configuration has changed");</span>
+<span class="source-line-no">4404</span><span id="line-4404">      initializeCoprocessorHost(newConf);</span>
+<span class="source-line-no">4405</span><span id="line-4405">    }</span>
+<span class="source-line-no">4406</span><span id="line-4406">  }</span>
+<span class="source-line-no">4407</span><span id="line-4407"></span>
+<span class="source-line-no">4408</span><span id="line-4408">  @Override</span>
+<span class="source-line-no">4409</span><span id="line-4409">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
+<span class="source-line-no">4410</span><span id="line-4410">    final boolean isBalancerDecisionRecording =</span>
+<span class="source-line-no">4411</span><span id="line-4411">      conf.getBoolean(BaseLoadBalancer.BALANCER_DECISION_BUFFER_ENABLED,</span>
+<span class="source-line-no">4412</span><span id="line-4412">        BaseLoadBalancer.DEFAULT_BALANCER_DECISION_BUFFER_ENABLED);</span>
+<span class="source-line-no">4413</span><span id="line-4413">    final boolean isBalancerRejectionRecording =</span>
+<span class="source-line-no">4414</span><span id="line-4414">      conf.getBoolean(BaseLoadBalancer.BALANCER_REJECTION_BUFFER_ENABLED,</span>
+<span class="source-line-no">4415</span><span id="line-4415">        BaseLoadBalancer.DEFAULT_BALANCER_REJECTION_BUFFER_ENABLED);</span>
+<span class="source-line-no">4416</span><span id="line-4416">    if (isBalancerDecisionRecording || isBalancerRejectionRecording) {</span>
+<span class="source-line-no">4417</span><span id="line-4417">      return NamedQueueRecorder.getInstance(conf);</span>
+<span class="source-line-no">4418</span><span id="line-4418">    } else {</span>
+<span class="source-line-no">4419</span><span id="line-4419">      return null;</span>
+<span class="source-line-no">4420</span><span id="line-4420">    }</span>
+<span class="source-line-no">4421</span><span id="line-4421">  }</span>
+<span class="source-line-no">4422</span><span id="line-4422"></span>
+<span class="source-line-no">4423</span><span id="line-4423">  @Override</span>
+<span class="source-line-no">4424</span><span id="line-4424">  protected boolean clusterMode() {</span>
+<span class="source-line-no">4425</span><span id="line-4425">    return true;</span>
+<span class="source-line-no">4426</span><span id="line-4426">  }</span>
+<span class="source-line-no">4427</span><span id="line-4427"></span>
+<span class="source-line-no">4428</span><span id="line-4428">  public String getClusterId() {</span>
+<span class="source-line-no">4429</span><span id="line-4429">    if (activeMaster) {</span>
+<span class="source-line-no">4430</span><span id="line-4430">      return clusterId;</span>
+<span class="source-line-no">4431</span><span id="line-4431">    }</span>
+<span class="source-line-no">4432</span><span id="line-4432">    return cachedClusterId.getFromCacheOrFetch();</span>
 <span class="source-line-no">4433</span><span id="line-4433">  }</span>
 <span class="source-line-no">4434</span><span id="line-4434"></span>
-<span class="source-line-no">4435</span><span id="line-4435">  public List&lt;ServerName&gt; getBackupMasters() {</span>
-<span class="source-line-no">4436</span><span id="line-4436">    return activeMasterManager.getBackupMasters();</span>
+<span class="source-line-no">4435</span><span id="line-4435">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
+<span class="source-line-no">4436</span><span id="line-4436">    return activeMasterManager.getActiveMasterServerName();</span>
 <span class="source-line-no">4437</span><span id="line-4437">  }</span>
 <span class="source-line-no">4438</span><span id="line-4438"></span>
-<span class="source-line-no">4439</span><span id="line-4439">  @Override</span>
-<span class="source-line-no">4440</span><span id="line-4440">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
-<span class="source-line-no">4441</span><span id="line-4441">    return regionServerTracker.getRegionServers().iterator();</span>
-<span class="source-line-no">4442</span><span id="line-4442">  }</span>
-<span class="source-line-no">4443</span><span id="line-4443"></span>
-<span class="source-line-no">4444</span><span id="line-4444">  @Override</span>
-<span class="source-line-no">4445</span><span id="line-4445">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
-<span class="source-line-no">4446</span><span id="line-4446">    return metaRegionLocationCache.getMetaRegionLocations();</span>
-<span class="source-line-no">4447</span><span id="line-4447">  }</span>
-<span class="source-line-no">4448</span><span id="line-4448"></span>
-<span class="source-line-no">4449</span><span id="line-4449">  @Override</span>
-<span class="source-line-no">4450</span><span id="line-4450">  public void flushMasterStore() throws IOException {</span>
-<span class="source-line-no">4451</span><span id="line-4451">    LOG.info("Force flush master local region.");</span>
-<span class="source-line-no">4452</span><span id="line-4452">    if (this.cpHost != null) {</span>
-<span class="source-line-no">4453</span><span id="line-4453">      try {</span>
-<span class="source-line-no">4454</span><span id="line-4454">        cpHost.preMasterStoreFlush();</span>
-<span class="source-line-no">4455</span><span id="line-4455">      } catch (IOException ioe) {</span>
-<span class="source-line-no">4456</span><span id="line-4456">        LOG.error("Error invoking master coprocessor preMasterStoreFlush()", ioe);</span>
-<span class="source-line-no">4457</span><span id="line-4457">      }</span>
-<span class="source-line-no">4458</span><span id="line-4458">    }</span>
-<span class="source-line-no">4459</span><span id="line-4459">    masterRegion.flush(true);</span>
-<span class="source-line-no">4460</span><span id="line-4460">    if (this.cpHost != null) {</span>
-<span class="source-line-no">4461</span><span id="line-4461">      try {</span>
-<span class="source-line-no">4462</span><span id="line-4462">        cpHost.postMasterStoreFlush();</span>
-<span class="source-line-no">4463</span><span id="line-4463">      } catch (IOException ioe) {</span>
-<span class="source-line-no">4464</span><span id="line-4464">        LOG.error("Error invoking master coprocessor postMasterStoreFlush()", ioe);</span>
-<span class="source-line-no">4465</span><span id="line-4465">      }</span>
-<span class="source-line-no">4466</span><span id="line-4466">    }</span>
-<span class="source-line-no">4467</span><span id="line-4467">  }</span>
-<span class="source-line-no">4468</span><span id="line-4468"></span>
-<span class="source-line-no">4469</span><span id="line-4469">  public Collection&lt;ServerName&gt; getLiveRegionServers() {</span>
-<span class="source-line-no">4470</span><span id="line-4470">    return regionServerTracker.getRegionServers();</span>
+<span class="source-line-no">4439</span><span id="line-4439">  public List&lt;ServerName&gt; getBackupMasters() {</span>
+<span class="source-line-no">4440</span><span id="line-4440">    return activeMasterManager.getBackupMasters();</span>
+<span class="source-line-no">4441</span><span id="line-4441">  }</span>
+<span class="source-line-no">4442</span><span id="line-4442"></span>
+<span class="source-line-no">4443</span><span id="line-4443">  @Override</span>
+<span class="source-line-no">4444</span><span id="line-4444">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
+<span class="source-line-no">4445</span><span id="line-4445">    return regionServerTracker.getRegionServers().iterator();</span>
+<span class="source-line-no">4446</span><span id="line-4446">  }</span>
+<span class="source-line-no">4447</span><span id="line-4447"></span>
+<span class="source-line-no">4448</span><span id="line-4448">  @Override</span>
+<span class="source-line-no">4449</span><span id="line-4449">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
+<span class="source-line-no">4450</span><span id="line-4450">    return metaRegionLocationCache.getMetaRegionLocations();</span>
+<span class="source-line-no">4451</span><span id="line-4451">  }</span>
+<span class="source-line-no">4452</span><span id="line-4452"></span>
+<span class="source-line-no">4453</span><span id="line-4453">  @Override</span>
+<span class="source-line-no">4454</span><span id="line-4454">  public void flushMasterStore() throws IOException {</span>
+<span class="source-line-no">4455</span><span id="line-4455">    LOG.info("Force flush master local region.");</span>
+<span class="source-line-no">4456</span><span id="line-4456">    if (this.cpHost != null) {</span>
+<span class="source-line-no">4457</span><span id="line-4457">      try {</span>
+<span class="source-line-no">4458</span><span id="line-4458">        cpHost.preMasterStoreFlush();</span>
+<span class="source-line-no">4459</span><span id="line-4459">      } catch (IOException ioe) {</span>
+<span class="source-line-no">4460</span><span id="line-4460">        LOG.error("Error invoking master coprocessor preMasterStoreFlush()", ioe);</span>
+<span class="source-line-no">4461</span><span id="line-4461">      }</span>
+<span class="source-line-no">4462</span><span id="line-4462">    }</span>
+<span class="source-line-no">4463</span><span id="line-4463">    masterRegion.flush(true);</span>
+<span class="source-line-no">4464</span><span id="line-4464">    if (this.cpHost != null) {</span>
+<span class="source-line-no">4465</span><span id="line-4465">      try {</span>
+<span class="source-line-no">4466</span><span id="line-4466">        cpHost.postMasterStoreFlush();</span>
+<span class="source-line-no">4467</span><span id="line-4467">      } catch (IOException ioe) {</span>
+<span class="source-line-no">4468</span><span id="line-4468">        LOG.error("Error invoking master coprocessor postMasterStoreFlush()", ioe);</span>
+<span class="source-line-no">4469</span><span id="line-4469">      }</span>
+<span class="source-line-no">4470</span><span id="line-4470">    }</span>
 <span class="source-line-no">4471</span><span id="line-4471">  }</span>
 <span class="source-line-no">4472</span><span id="line-4472"></span>
-<span class="source-line-no">4473</span><span id="line-4473">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4474</span><span id="line-4474">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4475</span><span id="line-4475">  void setLoadBalancer(RSGroupBasedLoadBalancer loadBalancer) {</span>
-<span class="source-line-no">4476</span><span id="line-4476">    this.balancer = loadBalancer;</span>
-<span class="source-line-no">4477</span><span id="line-4477">  }</span>
-<span class="source-line-no">4478</span><span id="line-4478"></span>
-<span class="source-line-no">4479</span><span id="line-4479">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4480</span><span id="line-4480">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4481</span><span id="line-4481">  void setAssignmentManager(AssignmentManager assignmentManager) {</span>
-<span class="source-line-no">4482</span><span id="line-4482">    this.assignmentManager = assignmentManager;</span>
-<span class="source-line-no">4483</span><span id="line-4483">  }</span>
-<span class="source-line-no">4484</span><span id="line-4484"></span>
-<span class="source-line-no">4485</span><span id="line-4485">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4486</span><span id="line-4486">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4487</span><span id="line-4487">  static void setDisableBalancerChoreForTest(boolean disable) {</span>
-<span class="source-line-no">4488</span><span id="line-4488">    disableBalancerChoreForTest = disable;</span>
-<span class="source-line-no">4489</span><span id="line-4489">  }</span>
-<span class="source-line-no">4490</span><span id="line-4490"></span>
-<span class="source-line-no">4491</span><span id="line-4491">  private void setQuotasObserver(Configuration conf) {</span>
-<span class="source-line-no">4492</span><span id="line-4492">    // Add the Observer to delete quotas on table deletion before starting all CPs by</span>
-<span class="source-line-no">4493</span><span id="line-4493">    // default with quota support, avoiding if user specifically asks to not load this Observer.</span>
-<span class="source-line-no">4494</span><span id="line-4494">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
-<span class="source-line-no">4495</span><span id="line-4495">      updateConfigurationForQuotasObserver(conf);</span>
-<span class="source-line-no">4496</span><span id="line-4496">    }</span>
-<span class="source-line-no">4497</span><span id="line-4497">  }</span>
-<span class="source-line-no">4498</span><span id="line-4498"></span>
-<span class="source-line-no">4499</span><span id="line-4499">  private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">4500</span><span id="line-4500">    // initialize master side coprocessors before we start handling requests</span>
-<span class="source-line-no">4501</span><span id="line-4501">    this.cpHost = new MasterCoprocessorHost(this, conf);</span>
-<span class="source-line-no">4502</span><span id="line-4502">  }</span>
-<span class="source-line-no">4503</span><span id="line-4503"></span>
-<span class="source-line-no">4504</span><span id="line-4504">  @Override</span>
-<span class="source-line-no">4505</span><span id="line-4505">  public long flushTable(TableName tableName, List&lt;byte[]&gt; columnFamilies, long nonceGroup,</span>
-<span class="source-line-no">4506</span><span id="line-4506">    long nonce) throws IOException {</span>
-<span class="source-line-no">4507</span><span id="line-4507">    checkInitialized();</span>
-<span class="source-line-no">4508</span><span id="line-4508"></span>
-<span class="source-line-no">4509</span><span id="line-4509">    if (</span>
-<span class="source-line-no">4510</span><span id="line-4510">      !getConfiguration().getBoolean(MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED,</span>
-<span class="source-line-no">4511</span><span id="line-4511">        MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED_DEFAULT)</span>
-<span class="source-line-no">4512</span><span id="line-4512">    ) {</span>
-<span class="source-line-no">4513</span><span id="line-4513">      throw new DoNotRetryIOException("FlushTableProcedureV2 is DISABLED");</span>
-<span class="source-line-no">4514</span><span id="line-4514">    }</span>
-<span class="source-line-no">4515</span><span id="line-4515"></span>
-<span class="source-line-no">4516</span><span id="line-4516">    return MasterProcedureUtil</span>
-<span class="source-line-no">4517</span><span id="line-4517">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">4518</span><span id="line-4518">        @Override</span>
-<span class="source-line-no">4519</span><span id="line-4519">        protected void run() throws IOException {</span>
-<span class="source-line-no">4520</span><span id="line-4520">          getMaster().getMasterCoprocessorHost().preTableFlush(tableName);</span>
-<span class="source-line-no">4521</span><span id="line-4521">          LOG.info(getClientIdAuditPrefix() + " flush " + tableName);</span>
-<span class="source-line-no">4522</span><span id="line-4522">          submitProcedure(</span>
-<span class="source-line-no">4523</span><span id="line-4523">            new FlushTableProcedure(procedureExecutor.getEnvironment(), tableName, columnFamilies));</span>
-<span class="source-line-no">4524</span><span id="line-4524">          getMaster().getMasterCoprocessorHost().postTableFlush(tableName);</span>
-<span class="source-line-no">4525</span><span id="line-4525">        }</span>
-<span class="source-line-no">4526</span><span id="line-4526"></span>
-<span class="source-line-no">4527</span><span id="line-4527">        @Override</span>
-<span class="source-line-no">4528</span><span id="line-4528">        protected String getDescription() {</span>
-<span class="source-line-no">4529</span><span id="line-4529">          return "FlushTableProcedure";</span>
-<span class="source-line-no">4530</span><span id="line-4530">        }</span>
-<span class="source-line-no">4531</span><span id="line-4531">      });</span>
-<span class="source-line-no">4532</span><span id="line-4532">  }</span>
-<span class="source-line-no">4533</span><span id="line-4533">}</span>
+<span class="source-line-no">4473</span><span id="line-4473">  public Collection&lt;ServerName&gt; getLiveRegionServers() {</span>
+<span class="source-line-no">4474</span><span id="line-4474">    return regionServerTracker.getRegionServers();</span>
+<span class="source-line-no">4475</span><span id="line-4475">  }</span>
+<span class="source-line-no">4476</span><span id="line-4476"></span>
+<span class="source-line-no">4477</span><span id="line-4477">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4478</span><span id="line-4478">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4479</span><span id="line-4479">  void setLoadBalancer(RSGroupBasedLoadBalancer loadBalancer) {</span>
+<span class="source-line-no">4480</span><span id="line-4480">    this.balancer = loadBalancer;</span>
+<span class="source-line-no">4481</span><span id="line-4481">  }</span>
+<span class="source-line-no">4482</span><span id="line-4482"></span>
+<span class="source-line-no">4483</span><span id="line-4483">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4484</span><span id="line-4484">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4485</span><span id="line-4485">  void setAssignmentManager(AssignmentManager assignmentManager) {</span>
+<span class="source-line-no">4486</span><span id="line-4486">    this.assignmentManager = assignmentManager;</span>
+<span class="source-line-no">4487</span><span id="line-4487">  }</span>
+<span class="source-line-no">4488</span><span id="line-4488"></span>
+<span class="source-line-no">4489</span><span id="line-4489">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4490</span><span id="line-4490">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4491</span><span id="line-4491">  static void setDisableBalancerChoreForTest(boolean disable) {</span>
+<span class="source-line-no">4492</span><span id="line-4492">    disableBalancerChoreForTest = disable;</span>
+<span class="source-line-no">4493</span><span id="line-4493">  }</span>
+<span class="source-line-no">4494</span><span id="line-4494"></span>
+<span class="source-line-no">4495</span><span id="line-4495">  private void setQuotasObserver(Configuration conf) {</span>
+<span class="source-line-no">4496</span><span id="line-4496">    // Add the Observer to delete quotas on table deletion before starting all CPs by</span>
+<span class="source-line-no">4497</span><span id="line-4497">    // default with quota support, avoiding if user specifically asks to not load this Observer.</span>
+<span class="source-line-no">4498</span><span id="line-4498">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
+<span class="source-line-no">4499</span><span id="line-4499">      updateConfigurationForQuotasObserver(conf);</span>
+<span class="source-line-no">4500</span><span id="line-4500">    }</span>
+<span class="source-line-no">4501</span><span id="line-4501">  }</span>
+<span class="source-line-no">4502</span><span id="line-4502"></span>
+<span class="source-line-no">4503</span><span id="line-4503">  private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">4504</span><span id="line-4504">    // initialize master side coprocessors before we start handling requests</span>
+<span class="source-line-no">4505</span><span id="line-4505">    this.cpHost = new MasterCoprocessorHost(this, conf);</span>
+<span class="source-line-no">4506</span><span id="line-4506">  }</span>
+<span class="source-line-no">4507</span><span id="line-4507"></span>
+<span class="source-line-no">4508</span><span id="line-4508">  @Override</span>
+<span class="source-line-no">4509</span><span id="line-4509">  public long flushTable(TableName tableName, List&lt;byte[]&gt; columnFamilies, long nonceGroup,</span>
+<span class="source-line-no">4510</span><span id="line-4510">    long nonce) throws IOException {</span>
+<span class="source-line-no">4511</span><span id="line-4511">    checkInitialized();</span>
+<span class="source-line-no">4512</span><span id="line-4512"></span>
+<span class="source-line-no">4513</span><span id="line-4513">    if (</span>
+<span class="source-line-no">4514</span><span id="line-4514">      !getConfiguration().getBoolean(MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED,</span>
+<span class="source-line-no">4515</span><span id="line-4515">        MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED_DEFAULT)</span>
+<span class="source-line-no">4516</span><span id="line-4516">    ) {</span>
+<span class="source-line-no">4517</span><span id="line-4517">      throw new DoNotRetryIOException("FlushTableProcedureV2 is DISABLED");</span>
+<span class="source-line-no">4518</span><span id="line-4518">    }</span>
+<span class="source-line-no">4519</span><span id="line-4519"></span>
+<span class="source-line-no">4520</span><span id="line-4520">    return MasterProcedureUtil</span>
+<span class="source-line-no">4521</span><span id="line-4521">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">4522</span><span id="line-4522">        @Override</span>
+<span class="source-line-no">4523</span><span id="line-4523">        protected void run() throws IOException {</span>
+<span class="source-line-no">4524</span><span id="line-4524">          getMaster().getMasterCoprocessorHost().preTableFlush(tableName);</span>
+<span class="source-line-no">4525</span><span id="line-4525">          LOG.info(getClientIdAuditPrefix() + " flush " + tableName);</span>
+<span class="source-line-no">4526</span><span id="line-4526">          submitProcedure(</span>
+<span class="source-line-no">4527</span><span id="line-4527">            new FlushTableProcedure(procedureExecutor.getEnvironment(), tableName, columnFamilies));</span>
+<span class="source-line-no">4528</span><span id="line-4528">          getMaster().getMasterCoprocessorHost().postTableFlush(tableName);</span>
+<span class="source-line-no">4529</span><span id="line-4529">        }</span>
+<span class="source-line-no">4530</span><span id="line-4530"></span>
+<span class="source-line-no">4531</span><span id="line-4531">        @Override</span>
+<span class="source-line-no">4532</span><span id="line-4532">        protected String getDescription() {</span>
+<span class="source-line-no">4533</span><span id="line-4533">          return "FlushTableProcedure";</span>
+<span class="source-line-no">4534</span><span id="line-4534">        }</span>
+<span class="source-line-no">4535</span><span id="line-4535">      });</span>
+<span class="source-line-no">4536</span><span id="line-4536">  }</span>
+<span class="source-line-no">4537</span><span id="line-4537">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.html b/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.html
index 04666609a4f..d27c9fe86f8 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/master/HMaster.html
@@ -2201,2349 +2201,2353 @@
 <span class="source-line-no">2188</span><span id="line-2188">        // TODO: bulk assign</span>
 <span class="source-line-no">2189</span><span id="line-2189">        try {</span>
 <span class="source-line-no">2190</span><span id="line-2190">          this.assignmentManager.balance(plan);</span>
-<span class="source-line-no">2191</span><span id="line-2191">        } catch (HBaseIOException hioe) {</span>
-<span class="source-line-no">2192</span><span id="line-2192">          // should ignore failed plans here, avoiding the whole balance plans be aborted</span>
-<span class="source-line-no">2193</span><span id="line-2193">          // later calls of balance() can fetch up the failed and skipped plans</span>
-<span class="source-line-no">2194</span><span id="line-2194">          LOG.warn("Failed balance plan {}, skipping...", plan, hioe);</span>
-<span class="source-line-no">2195</span><span id="line-2195">        }</span>
-<span class="source-line-no">2196</span><span id="line-2196">        // rpCount records balance plans processed, does not care if a plan succeeds</span>
-<span class="source-line-no">2197</span><span id="line-2197">        rpCount++;</span>
-<span class="source-line-no">2198</span><span id="line-2198">        successRegionPlans.add(plan);</span>
-<span class="source-line-no">2199</span><span id="line-2199"></span>
-<span class="source-line-no">2200</span><span id="line-2200">        if (this.maxBalancingTime &gt; 0) {</span>
-<span class="source-line-no">2201</span><span id="line-2201">          balanceThrottling(balanceStartTime + rpCount * balanceInterval, maxRegionsInTransition,</span>
-<span class="source-line-no">2202</span><span id="line-2202">            cutoffTime);</span>
-<span class="source-line-no">2203</span><span id="line-2203">        }</span>
-<span class="source-line-no">2204</span><span id="line-2204"></span>
-<span class="source-line-no">2205</span><span id="line-2205">        // if performing next balance exceeds cutoff time, exit the loop</span>
-<span class="source-line-no">2206</span><span id="line-2206">        if (</span>
-<span class="source-line-no">2207</span><span id="line-2207">          this.maxBalancingTime &gt; 0 &amp;&amp; rpCount &lt; plans.size()</span>
-<span class="source-line-no">2208</span><span id="line-2208">            &amp;&amp; EnvironmentEdgeManager.currentTime() &gt; cutoffTime</span>
-<span class="source-line-no">2209</span><span id="line-2209">        ) {</span>
-<span class="source-line-no">2210</span><span id="line-2210">          // TODO: After balance, there should not be a cutoff time (keeping it as</span>
-<span class="source-line-no">2211</span><span id="line-2211">          // a security net for now)</span>
-<span class="source-line-no">2212</span><span id="line-2212">          LOG.debug(</span>
-<span class="source-line-no">2213</span><span id="line-2213">            "No more balancing till next balance run; maxBalanceTime=" + this.maxBalancingTime);</span>
-<span class="source-line-no">2214</span><span id="line-2214">          break;</span>
-<span class="source-line-no">2215</span><span id="line-2215">        }</span>
-<span class="source-line-no">2216</span><span id="line-2216">      }</span>
-<span class="source-line-no">2217</span><span id="line-2217">    }</span>
-<span class="source-line-no">2218</span><span id="line-2218">    LOG.debug("Balancer is going into sleep until next period in {}ms", getConfiguration()</span>
-<span class="source-line-no">2219</span><span id="line-2219">      .getInt(HConstants.HBASE_BALANCER_PERIOD, HConstants.DEFAULT_HBASE_BALANCER_PERIOD));</span>
-<span class="source-line-no">2220</span><span id="line-2220">    return successRegionPlans;</span>
-<span class="source-line-no">2221</span><span id="line-2221">  }</span>
-<span class="source-line-no">2222</span><span id="line-2222"></span>
-<span class="source-line-no">2223</span><span id="line-2223">  @Override</span>
-<span class="source-line-no">2224</span><span id="line-2224">  public RegionNormalizerManager getRegionNormalizerManager() {</span>
-<span class="source-line-no">2225</span><span id="line-2225">    return regionNormalizerManager;</span>
-<span class="source-line-no">2226</span><span id="line-2226">  }</span>
-<span class="source-line-no">2227</span><span id="line-2227"></span>
-<span class="source-line-no">2228</span><span id="line-2228">  @Override</span>
-<span class="source-line-no">2229</span><span id="line-2229">  public boolean normalizeRegions(final NormalizeTableFilterParams ntfp,</span>
-<span class="source-line-no">2230</span><span id="line-2230">    final boolean isHighPriority) throws IOException {</span>
-<span class="source-line-no">2231</span><span id="line-2231">    if (regionNormalizerManager == null || !regionNormalizerManager.isNormalizerOn()) {</span>
-<span class="source-line-no">2232</span><span id="line-2232">      LOG.debug("Region normalization is disabled, don't run region normalizer.");</span>
-<span class="source-line-no">2233</span><span id="line-2233">      return false;</span>
-<span class="source-line-no">2234</span><span id="line-2234">    }</span>
-<span class="source-line-no">2235</span><span id="line-2235">    if (skipRegionManagementAction("region normalizer")) {</span>
-<span class="source-line-no">2236</span><span id="line-2236">      return false;</span>
-<span class="source-line-no">2237</span><span id="line-2237">    }</span>
-<span class="source-line-no">2238</span><span id="line-2238">    if (assignmentManager.hasRegionsInTransition()) {</span>
-<span class="source-line-no">2239</span><span id="line-2239">      return false;</span>
-<span class="source-line-no">2240</span><span id="line-2240">    }</span>
-<span class="source-line-no">2241</span><span id="line-2241"></span>
-<span class="source-line-no">2242</span><span id="line-2242">    final Set&lt;TableName&gt; matchingTables = getTableDescriptors(new LinkedList&lt;&gt;(),</span>
-<span class="source-line-no">2243</span><span id="line-2243">      ntfp.getNamespace(), ntfp.getRegex(), ntfp.getTableNames(), false).stream()</span>
-<span class="source-line-no">2244</span><span id="line-2244">        .map(TableDescriptor::getTableName).collect(Collectors.toSet());</span>
-<span class="source-line-no">2245</span><span id="line-2245">    final Set&lt;TableName&gt; allEnabledTables =</span>
-<span class="source-line-no">2246</span><span id="line-2246">      tableStateManager.getTablesInStates(TableState.State.ENABLED);</span>
-<span class="source-line-no">2247</span><span id="line-2247">    final List&lt;TableName&gt; targetTables =</span>
-<span class="source-line-no">2248</span><span id="line-2248">      new ArrayList&lt;&gt;(Sets.intersection(matchingTables, allEnabledTables));</span>
-<span class="source-line-no">2249</span><span id="line-2249">    Collections.shuffle(targetTables);</span>
-<span class="source-line-no">2250</span><span id="line-2250">    return regionNormalizerManager.normalizeRegions(targetTables, isHighPriority);</span>
-<span class="source-line-no">2251</span><span id="line-2251">  }</span>
-<span class="source-line-no">2252</span><span id="line-2252"></span>
-<span class="source-line-no">2253</span><span id="line-2253">  /** Returns Client info for use as prefix on an audit log string; who did an action */</span>
-<span class="source-line-no">2254</span><span id="line-2254">  @Override</span>
-<span class="source-line-no">2255</span><span id="line-2255">  public String getClientIdAuditPrefix() {</span>
-<span class="source-line-no">2256</span><span id="line-2256">    return "Client=" + RpcServer.getRequestUserName().orElse(null) + "/"</span>
-<span class="source-line-no">2257</span><span id="line-2257">      + RpcServer.getRemoteAddress().orElse(null);</span>
-<span class="source-line-no">2258</span><span id="line-2258">  }</span>
-<span class="source-line-no">2259</span><span id="line-2259"></span>
-<span class="source-line-no">2260</span><span id="line-2260">  /**</span>
-<span class="source-line-no">2261</span><span id="line-2261">   * Switch for the background CatalogJanitor thread. Used for testing. The thread will continue to</span>
-<span class="source-line-no">2262</span><span id="line-2262">   * run. It will just be a noop if disabled.</span>
-<span class="source-line-no">2263</span><span id="line-2263">   * @param b If false, the catalog janitor won't do anything.</span>
-<span class="source-line-no">2264</span><span id="line-2264">   */</span>
-<span class="source-line-no">2265</span><span id="line-2265">  public void setCatalogJanitorEnabled(final boolean b) {</span>
-<span class="source-line-no">2266</span><span id="line-2266">    this.catalogJanitorChore.setEnabled(b);</span>
-<span class="source-line-no">2267</span><span id="line-2267">  }</span>
-<span class="source-line-no">2268</span><span id="line-2268"></span>
-<span class="source-line-no">2269</span><span id="line-2269">  @Override</span>
-<span class="source-line-no">2270</span><span id="line-2270">  public long mergeRegions(final RegionInfo[] regionsToMerge, final boolean forcible, final long ng,</span>
-<span class="source-line-no">2271</span><span id="line-2271">    final long nonce) throws IOException {</span>
-<span class="source-line-no">2272</span><span id="line-2272">    checkInitialized();</span>
-<span class="source-line-no">2273</span><span id="line-2273"></span>
-<span class="source-line-no">2274</span><span id="line-2274">    final String regionNamesToLog = RegionInfo.getShortNameToLog(regionsToMerge);</span>
-<span class="source-line-no">2275</span><span id="line-2275"></span>
-<span class="source-line-no">2276</span><span id="line-2276">    if (!isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {</span>
-<span class="source-line-no">2277</span><span id="line-2277">      LOG.warn("Merge switch is off! skip merge of " + regionNamesToLog);</span>
-<span class="source-line-no">2278</span><span id="line-2278">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2279</span><span id="line-2279">        "Merge of " + regionNamesToLog + " failed because merge switch is off");</span>
-<span class="source-line-no">2280</span><span id="line-2280">    }</span>
-<span class="source-line-no">2281</span><span id="line-2281"></span>
-<span class="source-line-no">2282</span><span id="line-2282">    if (!getTableDescriptors().get(regionsToMerge[0].getTable()).isMergeEnabled()) {</span>
-<span class="source-line-no">2283</span><span id="line-2283">      LOG.warn("Merge is disabled for the table! Skipping merge of {}", regionNamesToLog);</span>
-<span class="source-line-no">2284</span><span id="line-2284">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2285</span><span id="line-2285">        "Merge of " + regionNamesToLog + " failed as region merge is disabled for the table");</span>
-<span class="source-line-no">2286</span><span id="line-2286">    }</span>
-<span class="source-line-no">2287</span><span id="line-2287"></span>
-<span class="source-line-no">2288</span><span id="line-2288">    return MasterProcedureUtil.submitProcedure(new NonceProcedureRunnable(this, ng, nonce) {</span>
-<span class="source-line-no">2289</span><span id="line-2289">      @Override</span>
-<span class="source-line-no">2290</span><span id="line-2290">      protected void run() throws IOException {</span>
-<span class="source-line-no">2291</span><span id="line-2291">        getMaster().getMasterCoprocessorHost().preMergeRegions(regionsToMerge);</span>
-<span class="source-line-no">2292</span><span id="line-2292">        String aid = getClientIdAuditPrefix();</span>
-<span class="source-line-no">2293</span><span id="line-2293">        LOG.info("{} merge regions {}", aid, regionNamesToLog);</span>
-<span class="source-line-no">2294</span><span id="line-2294">        submitProcedure(new MergeTableRegionsProcedure(procedureExecutor.getEnvironment(),</span>
-<span class="source-line-no">2295</span><span id="line-2295">          regionsToMerge, forcible));</span>
-<span class="source-line-no">2296</span><span id="line-2296">        getMaster().getMasterCoprocessorHost().postMergeRegions(regionsToMerge);</span>
-<span class="source-line-no">2297</span><span id="line-2297">      }</span>
-<span class="source-line-no">2298</span><span id="line-2298"></span>
-<span class="source-line-no">2299</span><span id="line-2299">      @Override</span>
-<span class="source-line-no">2300</span><span id="line-2300">      protected String getDescription() {</span>
-<span class="source-line-no">2301</span><span id="line-2301">        return "MergeTableProcedure";</span>
-<span class="source-line-no">2302</span><span id="line-2302">      }</span>
-<span class="source-line-no">2303</span><span id="line-2303">    });</span>
-<span class="source-line-no">2304</span><span id="line-2304">  }</span>
-<span class="source-line-no">2305</span><span id="line-2305"></span>
-<span class="source-line-no">2306</span><span id="line-2306">  @Override</span>
-<span class="source-line-no">2307</span><span id="line-2307">  public long splitRegion(final RegionInfo regionInfo, final byte[] splitRow, final long nonceGroup,</span>
-<span class="source-line-no">2308</span><span id="line-2308">    final long nonce) throws IOException {</span>
-<span class="source-line-no">2309</span><span id="line-2309">    checkInitialized();</span>
-<span class="source-line-no">2310</span><span id="line-2310"></span>
-<span class="source-line-no">2311</span><span id="line-2311">    if (!isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {</span>
-<span class="source-line-no">2312</span><span id="line-2312">      LOG.warn("Split switch is off! skip split of " + regionInfo);</span>
-<span class="source-line-no">2313</span><span id="line-2313">      throw new DoNotRetryIOException(</span>
-<span class="source-line-no">2314</span><span id="line-2314">        "Split region " + regionInfo.getRegionNameAsString() + " failed due to split switch off");</span>
-<span class="source-line-no">2315</span><span id="line-2315">    }</span>
-<span class="source-line-no">2316</span><span id="line-2316"></span>
-<span class="source-line-no">2317</span><span id="line-2317">    if (!getTableDescriptors().get(regionInfo.getTable()).isSplitEnabled()) {</span>
-<span class="source-line-no">2318</span><span id="line-2318">      LOG.warn("Split is disabled for the table! Skipping split of {}", regionInfo);</span>
-<span class="source-line-no">2319</span><span id="line-2319">      throw new DoNotRetryIOException("Split region " + regionInfo.getRegionNameAsString()</span>
-<span class="source-line-no">2320</span><span id="line-2320">        + " failed as region split is disabled for the table");</span>
-<span class="source-line-no">2321</span><span id="line-2321">    }</span>
-<span class="source-line-no">2322</span><span id="line-2322"></span>
-<span class="source-line-no">2323</span><span id="line-2323">    return MasterProcedureUtil</span>
-<span class="source-line-no">2324</span><span id="line-2324">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2325</span><span id="line-2325">        @Override</span>
-<span class="source-line-no">2326</span><span id="line-2326">        protected void run() throws IOException {</span>
-<span class="source-line-no">2327</span><span id="line-2327">          getMaster().getMasterCoprocessorHost().preSplitRegion(regionInfo.getTable(), splitRow);</span>
-<span class="source-line-no">2328</span><span id="line-2328">          LOG.info(getClientIdAuditPrefix() + " split " + regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">2329</span><span id="line-2329"></span>
-<span class="source-line-no">2330</span><span id="line-2330">          // Execute the operation asynchronously</span>
-<span class="source-line-no">2331</span><span id="line-2331">          submitProcedure(getAssignmentManager().createSplitProcedure(regionInfo, splitRow));</span>
-<span class="source-line-no">2332</span><span id="line-2332">        }</span>
+<span class="source-line-no">2191</span><span id="line-2191">          this.balancer.updateClusterMetrics(getClusterMetricsWithoutCoprocessor());</span>
+<span class="source-line-no">2192</span><span id="line-2192">          this.balancer.throttle(plan);</span>
+<span class="source-line-no">2193</span><span id="line-2193">        } catch (HBaseIOException hioe) {</span>
+<span class="source-line-no">2194</span><span id="line-2194">          // should ignore failed plans here, avoiding the whole balance plans be aborted</span>
+<span class="source-line-no">2195</span><span id="line-2195">          // later calls of balance() can fetch up the failed and skipped plans</span>
+<span class="source-line-no">2196</span><span id="line-2196">          LOG.warn("Failed balance plan {}, skipping...", plan, hioe);</span>
+<span class="source-line-no">2197</span><span id="line-2197">        } catch (Exception e) {</span>
+<span class="source-line-no">2198</span><span id="line-2198">          LOG.warn("Failed throttling assigning a new plan.", e);</span>
+<span class="source-line-no">2199</span><span id="line-2199">        }</span>
+<span class="source-line-no">2200</span><span id="line-2200">        // rpCount records balance plans processed, does not care if a plan succeeds</span>
+<span class="source-line-no">2201</span><span id="line-2201">        rpCount++;</span>
+<span class="source-line-no">2202</span><span id="line-2202">        successRegionPlans.add(plan);</span>
+<span class="source-line-no">2203</span><span id="line-2203"></span>
+<span class="source-line-no">2204</span><span id="line-2204">        if (this.maxBalancingTime &gt; 0) {</span>
+<span class="source-line-no">2205</span><span id="line-2205">          balanceThrottling(balanceStartTime + rpCount * balanceInterval, maxRegionsInTransition,</span>
+<span class="source-line-no">2206</span><span id="line-2206">            cutoffTime);</span>
+<span class="source-line-no">2207</span><span id="line-2207">        }</span>
+<span class="source-line-no">2208</span><span id="line-2208"></span>
+<span class="source-line-no">2209</span><span id="line-2209">        // if performing next balance exceeds cutoff time, exit the loop</span>
+<span class="source-line-no">2210</span><span id="line-2210">        if (</span>
+<span class="source-line-no">2211</span><span id="line-2211">          this.maxBalancingTime &gt; 0 &amp;&amp; rpCount &lt; plans.size()</span>
+<span class="source-line-no">2212</span><span id="line-2212">            &amp;&amp; EnvironmentEdgeManager.currentTime() &gt; cutoffTime</span>
+<span class="source-line-no">2213</span><span id="line-2213">        ) {</span>
+<span class="source-line-no">2214</span><span id="line-2214">          // TODO: After balance, there should not be a cutoff time (keeping it as</span>
+<span class="source-line-no">2215</span><span id="line-2215">          // a security net for now)</span>
+<span class="source-line-no">2216</span><span id="line-2216">          LOG.debug(</span>
+<span class="source-line-no">2217</span><span id="line-2217">            "No more balancing till next balance run; maxBalanceTime=" + this.maxBalancingTime);</span>
+<span class="source-line-no">2218</span><span id="line-2218">          break;</span>
+<span class="source-line-no">2219</span><span id="line-2219">        }</span>
+<span class="source-line-no">2220</span><span id="line-2220">      }</span>
+<span class="source-line-no">2221</span><span id="line-2221">    }</span>
+<span class="source-line-no">2222</span><span id="line-2222">    LOG.debug("Balancer is going into sleep until next period in {}ms", getConfiguration()</span>
+<span class="source-line-no">2223</span><span id="line-2223">      .getInt(HConstants.HBASE_BALANCER_PERIOD, HConstants.DEFAULT_HBASE_BALANCER_PERIOD));</span>
+<span class="source-line-no">2224</span><span id="line-2224">    return successRegionPlans;</span>
+<span class="source-line-no">2225</span><span id="line-2225">  }</span>
+<span class="source-line-no">2226</span><span id="line-2226"></span>
+<span class="source-line-no">2227</span><span id="line-2227">  @Override</span>
+<span class="source-line-no">2228</span><span id="line-2228">  public RegionNormalizerManager getRegionNormalizerManager() {</span>
+<span class="source-line-no">2229</span><span id="line-2229">    return regionNormalizerManager;</span>
+<span class="source-line-no">2230</span><span id="line-2230">  }</span>
+<span class="source-line-no">2231</span><span id="line-2231"></span>
+<span class="source-line-no">2232</span><span id="line-2232">  @Override</span>
+<span class="source-line-no">2233</span><span id="line-2233">  public boolean normalizeRegions(final NormalizeTableFilterParams ntfp,</span>
+<span class="source-line-no">2234</span><span id="line-2234">    final boolean isHighPriority) throws IOException {</span>
+<span class="source-line-no">2235</span><span id="line-2235">    if (regionNormalizerManager == null || !regionNormalizerManager.isNormalizerOn()) {</span>
+<span class="source-line-no">2236</span><span id="line-2236">      LOG.debug("Region normalization is disabled, don't run region normalizer.");</span>
+<span class="source-line-no">2237</span><span id="line-2237">      return false;</span>
+<span class="source-line-no">2238</span><span id="line-2238">    }</span>
+<span class="source-line-no">2239</span><span id="line-2239">    if (skipRegionManagementAction("region normalizer")) {</span>
+<span class="source-line-no">2240</span><span id="line-2240">      return false;</span>
+<span class="source-line-no">2241</span><span id="line-2241">    }</span>
+<span class="source-line-no">2242</span><span id="line-2242">    if (assignmentManager.hasRegionsInTransition()) {</span>
+<span class="source-line-no">2243</span><span id="line-2243">      return false;</span>
+<span class="source-line-no">2244</span><span id="line-2244">    }</span>
+<span class="source-line-no">2245</span><span id="line-2245"></span>
+<span class="source-line-no">2246</span><span id="line-2246">    final Set&lt;TableName&gt; matchingTables = getTableDescriptors(new LinkedList&lt;&gt;(),</span>
+<span class="source-line-no">2247</span><span id="line-2247">      ntfp.getNamespace(), ntfp.getRegex(), ntfp.getTableNames(), false).stream()</span>
+<span class="source-line-no">2248</span><span id="line-2248">        .map(TableDescriptor::getTableName).collect(Collectors.toSet());</span>
+<span class="source-line-no">2249</span><span id="line-2249">    final Set&lt;TableName&gt; allEnabledTables =</span>
+<span class="source-line-no">2250</span><span id="line-2250">      tableStateManager.getTablesInStates(TableState.State.ENABLED);</span>
+<span class="source-line-no">2251</span><span id="line-2251">    final List&lt;TableName&gt; targetTables =</span>
+<span class="source-line-no">2252</span><span id="line-2252">      new ArrayList&lt;&gt;(Sets.intersection(matchingTables, allEnabledTables));</span>
+<span class="source-line-no">2253</span><span id="line-2253">    Collections.shuffle(targetTables);</span>
+<span class="source-line-no">2254</span><span id="line-2254">    return regionNormalizerManager.normalizeRegions(targetTables, isHighPriority);</span>
+<span class="source-line-no">2255</span><span id="line-2255">  }</span>
+<span class="source-line-no">2256</span><span id="line-2256"></span>
+<span class="source-line-no">2257</span><span id="line-2257">  /** Returns Client info for use as prefix on an audit log string; who did an action */</span>
+<span class="source-line-no">2258</span><span id="line-2258">  @Override</span>
+<span class="source-line-no">2259</span><span id="line-2259">  public String getClientIdAuditPrefix() {</span>
+<span class="source-line-no">2260</span><span id="line-2260">    return "Client=" + RpcServer.getRequestUserName().orElse(null) + "/"</span>
+<span class="source-line-no">2261</span><span id="line-2261">      + RpcServer.getRemoteAddress().orElse(null);</span>
+<span class="source-line-no">2262</span><span id="line-2262">  }</span>
+<span class="source-line-no">2263</span><span id="line-2263"></span>
+<span class="source-line-no">2264</span><span id="line-2264">  /**</span>
+<span class="source-line-no">2265</span><span id="line-2265">   * Switch for the background CatalogJanitor thread. Used for testing. The thread will continue to</span>
+<span class="source-line-no">2266</span><span id="line-2266">   * run. It will just be a noop if disabled.</span>
+<span class="source-line-no">2267</span><span id="line-2267">   * @param b If false, the catalog janitor won't do anything.</span>
+<span class="source-line-no">2268</span><span id="line-2268">   */</span>
+<span class="source-line-no">2269</span><span id="line-2269">  public void setCatalogJanitorEnabled(final boolean b) {</span>
+<span class="source-line-no">2270</span><span id="line-2270">    this.catalogJanitorChore.setEnabled(b);</span>
+<span class="source-line-no">2271</span><span id="line-2271">  }</span>
+<span class="source-line-no">2272</span><span id="line-2272"></span>
+<span class="source-line-no">2273</span><span id="line-2273">  @Override</span>
+<span class="source-line-no">2274</span><span id="line-2274">  public long mergeRegions(final RegionInfo[] regionsToMerge, final boolean forcible, final long ng,</span>
+<span class="source-line-no">2275</span><span id="line-2275">    final long nonce) throws IOException {</span>
+<span class="source-line-no">2276</span><span id="line-2276">    checkInitialized();</span>
+<span class="source-line-no">2277</span><span id="line-2277"></span>
+<span class="source-line-no">2278</span><span id="line-2278">    final String regionNamesToLog = RegionInfo.getShortNameToLog(regionsToMerge);</span>
+<span class="source-line-no">2279</span><span id="line-2279"></span>
+<span class="source-line-no">2280</span><span id="line-2280">    if (!isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {</span>
+<span class="source-line-no">2281</span><span id="line-2281">      LOG.warn("Merge switch is off! skip merge of " + regionNamesToLog);</span>
+<span class="source-line-no">2282</span><span id="line-2282">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2283</span><span id="line-2283">        "Merge of " + regionNamesToLog + " failed because merge switch is off");</span>
+<span class="source-line-no">2284</span><span id="line-2284">    }</span>
+<span class="source-line-no">2285</span><span id="line-2285"></span>
+<span class="source-line-no">2286</span><span id="line-2286">    if (!getTableDescriptors().get(regionsToMerge[0].getTable()).isMergeEnabled()) {</span>
+<span class="source-line-no">2287</span><span id="line-2287">      LOG.warn("Merge is disabled for the table! Skipping merge of {}", regionNamesToLog);</span>
+<span class="source-line-no">2288</span><span id="line-2288">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2289</span><span id="line-2289">        "Merge of " + regionNamesToLog + " failed as region merge is disabled for the table");</span>
+<span class="source-line-no">2290</span><span id="line-2290">    }</span>
+<span class="source-line-no">2291</span><span id="line-2291"></span>
+<span class="source-line-no">2292</span><span id="line-2292">    return MasterProcedureUtil.submitProcedure(new NonceProcedureRunnable(this, ng, nonce) {</span>
+<span class="source-line-no">2293</span><span id="line-2293">      @Override</span>
+<span class="source-line-no">2294</span><span id="line-2294">      protected void run() throws IOException {</span>
+<span class="source-line-no">2295</span><span id="line-2295">        getMaster().getMasterCoprocessorHost().preMergeRegions(regionsToMerge);</span>
+<span class="source-line-no">2296</span><span id="line-2296">        String aid = getClientIdAuditPrefix();</span>
+<span class="source-line-no">2297</span><span id="line-2297">        LOG.info("{} merge regions {}", aid, regionNamesToLog);</span>
+<span class="source-line-no">2298</span><span id="line-2298">        submitProcedure(new MergeTableRegionsProcedure(procedureExecutor.getEnvironment(),</span>
+<span class="source-line-no">2299</span><span id="line-2299">          regionsToMerge, forcible));</span>
+<span class="source-line-no">2300</span><span id="line-2300">        getMaster().getMasterCoprocessorHost().postMergeRegions(regionsToMerge);</span>
+<span class="source-line-no">2301</span><span id="line-2301">      }</span>
+<span class="source-line-no">2302</span><span id="line-2302"></span>
+<span class="source-line-no">2303</span><span id="line-2303">      @Override</span>
+<span class="source-line-no">2304</span><span id="line-2304">      protected String getDescription() {</span>
+<span class="source-line-no">2305</span><span id="line-2305">        return "MergeTableProcedure";</span>
+<span class="source-line-no">2306</span><span id="line-2306">      }</span>
+<span class="source-line-no">2307</span><span id="line-2307">    });</span>
+<span class="source-line-no">2308</span><span id="line-2308">  }</span>
+<span class="source-line-no">2309</span><span id="line-2309"></span>
+<span class="source-line-no">2310</span><span id="line-2310">  @Override</span>
+<span class="source-line-no">2311</span><span id="line-2311">  public long splitRegion(final RegionInfo regionInfo, final byte[] splitRow, final long nonceGroup,</span>
+<span class="source-line-no">2312</span><span id="line-2312">    final long nonce) throws IOException {</span>
+<span class="source-line-no">2313</span><span id="line-2313">    checkInitialized();</span>
+<span class="source-line-no">2314</span><span id="line-2314"></span>
+<span class="source-line-no">2315</span><span id="line-2315">    if (!isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {</span>
+<span class="source-line-no">2316</span><span id="line-2316">      LOG.warn("Split switch is off! skip split of " + regionInfo);</span>
+<span class="source-line-no">2317</span><span id="line-2317">      throw new DoNotRetryIOException(</span>
+<span class="source-line-no">2318</span><span id="line-2318">        "Split region " + regionInfo.getRegionNameAsString() + " failed due to split switch off");</span>
+<span class="source-line-no">2319</span><span id="line-2319">    }</span>
+<span class="source-line-no">2320</span><span id="line-2320"></span>
+<span class="source-line-no">2321</span><span id="line-2321">    if (!getTableDescriptors().get(regionInfo.getTable()).isSplitEnabled()) {</span>
+<span class="source-line-no">2322</span><span id="line-2322">      LOG.warn("Split is disabled for the table! Skipping split of {}", regionInfo);</span>
+<span class="source-line-no">2323</span><span id="line-2323">      throw new DoNotRetryIOException("Split region " + regionInfo.getRegionNameAsString()</span>
+<span class="source-line-no">2324</span><span id="line-2324">        + " failed as region split is disabled for the table");</span>
+<span class="source-line-no">2325</span><span id="line-2325">    }</span>
+<span class="source-line-no">2326</span><span id="line-2326"></span>
+<span class="source-line-no">2327</span><span id="line-2327">    return MasterProcedureUtil</span>
+<span class="source-line-no">2328</span><span id="line-2328">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2329</span><span id="line-2329">        @Override</span>
+<span class="source-line-no">2330</span><span id="line-2330">        protected void run() throws IOException {</span>
+<span class="source-line-no">2331</span><span id="line-2331">          getMaster().getMasterCoprocessorHost().preSplitRegion(regionInfo.getTable(), splitRow);</span>
+<span class="source-line-no">2332</span><span id="line-2332">          LOG.info(getClientIdAuditPrefix() + " split " + regionInfo.getRegionNameAsString());</span>
 <span class="source-line-no">2333</span><span id="line-2333"></span>
-<span class="source-line-no">2334</span><span id="line-2334">        @Override</span>
-<span class="source-line-no">2335</span><span id="line-2335">        protected String getDescription() {</span>
-<span class="source-line-no">2336</span><span id="line-2336">          return "SplitTableProcedure";</span>
-<span class="source-line-no">2337</span><span id="line-2337">        }</span>
-<span class="source-line-no">2338</span><span id="line-2338">      });</span>
-<span class="source-line-no">2339</span><span id="line-2339">  }</span>
-<span class="source-line-no">2340</span><span id="line-2340"></span>
-<span class="source-line-no">2341</span><span id="line-2341">  private void warmUpRegion(ServerName server, RegionInfo region) {</span>
-<span class="source-line-no">2342</span><span id="line-2342">    FutureUtils.addListener(asyncClusterConnection.getRegionServerAdmin(server)</span>
-<span class="source-line-no">2343</span><span id="line-2343">      .warmupRegion(RequestConverter.buildWarmupRegionRequest(region)), (r, e) -&gt; {</span>
-<span class="source-line-no">2344</span><span id="line-2344">        if (e != null) {</span>
-<span class="source-line-no">2345</span><span id="line-2345">          LOG.warn("Failed to warm up region {} on server {}", region, server, e);</span>
-<span class="source-line-no">2346</span><span id="line-2346">        }</span>
-<span class="source-line-no">2347</span><span id="line-2347">      });</span>
-<span class="source-line-no">2348</span><span id="line-2348">  }</span>
-<span class="source-line-no">2349</span><span id="line-2349"></span>
-<span class="source-line-no">2350</span><span id="line-2350">  // Public so can be accessed by tests. Blocks until move is done.</span>
-<span class="source-line-no">2351</span><span id="line-2351">  // Replace with an async implementation from which you can get</span>
-<span class="source-line-no">2352</span><span id="line-2352">  // a success/failure result.</span>
-<span class="source-line-no">2353</span><span id="line-2353">  @InterfaceAudience.Private</span>
-<span class="source-line-no">2354</span><span id="line-2354">  public void move(final byte[] encodedRegionName, byte[] destServerName) throws IOException {</span>
-<span class="source-line-no">2355</span><span id="line-2355">    RegionState regionState =</span>
-<span class="source-line-no">2356</span><span id="line-2356">      assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
-<span class="source-line-no">2357</span><span id="line-2357"></span>
-<span class="source-line-no">2358</span><span id="line-2358">    RegionInfo hri;</span>
-<span class="source-line-no">2359</span><span id="line-2359">    if (regionState != null) {</span>
-<span class="source-line-no">2360</span><span id="line-2360">      hri = regionState.getRegion();</span>
-<span class="source-line-no">2361</span><span id="line-2361">    } else {</span>
-<span class="source-line-no">2362</span><span id="line-2362">      throw new UnknownRegionException(Bytes.toStringBinary(encodedRegionName));</span>
-<span class="source-line-no">2363</span><span id="line-2363">    }</span>
-<span class="source-line-no">2364</span><span id="line-2364"></span>
-<span class="source-line-no">2365</span><span id="line-2365">    ServerName dest;</span>
-<span class="source-line-no">2366</span><span id="line-2366">    List&lt;ServerName&gt; exclude = hri.getTable().isSystemTable()</span>
-<span class="source-line-no">2367</span><span id="line-2367">      ? assignmentManager.getExcludedServersForSystemTable()</span>
-<span class="source-line-no">2368</span><span id="line-2368">      : new ArrayList&lt;&gt;(1);</span>
-<span class="source-line-no">2369</span><span id="line-2369">    if (</span>
-<span class="source-line-no">2370</span><span id="line-2370">      destServerName != null &amp;&amp; exclude.contains(ServerName.valueOf(Bytes.toString(destServerName)))</span>
-<span class="source-line-no">2371</span><span id="line-2371">    ) {</span>
-<span class="source-line-no">2372</span><span id="line-2372">      LOG.info(Bytes.toString(encodedRegionName) + " can not move to "</span>
-<span class="source-line-no">2373</span><span id="line-2373">        + Bytes.toString(destServerName) + " because the server is in exclude list");</span>
-<span class="source-line-no">2374</span><span id="line-2374">      destServerName = null;</span>
-<span class="source-line-no">2375</span><span id="line-2375">    }</span>
-<span class="source-line-no">2376</span><span id="line-2376">    if (destServerName == null || destServerName.length == 0) {</span>
-<span class="source-line-no">2377</span><span id="line-2377">      LOG.info("Passed destination servername is null/empty so " + "choosing a server at random");</span>
-<span class="source-line-no">2378</span><span id="line-2378">      exclude.add(regionState.getServerName());</span>
-<span class="source-line-no">2379</span><span id="line-2379">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList(exclude);</span>
-<span class="source-line-no">2380</span><span id="line-2380">      dest = balancer.randomAssignment(hri, destServers);</span>
-<span class="source-line-no">2381</span><span id="line-2381">      if (dest == null) {</span>
-<span class="source-line-no">2382</span><span id="line-2382">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
-<span class="source-line-no">2383</span><span id="line-2383">        return;</span>
-<span class="source-line-no">2384</span><span id="line-2384">      }</span>
-<span class="source-line-no">2385</span><span id="line-2385">    } else {</span>
-<span class="source-line-no">2386</span><span id="line-2386">      ServerName candidate = ServerName.valueOf(Bytes.toString(destServerName));</span>
-<span class="source-line-no">2387</span><span id="line-2387">      dest = balancer.randomAssignment(hri, Lists.newArrayList(candidate));</span>
-<span class="source-line-no">2388</span><span id="line-2388">      if (dest == null) {</span>
-<span class="source-line-no">2389</span><span id="line-2389">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
-<span class="source-line-no">2390</span><span id="line-2390">        return;</span>
-<span class="source-line-no">2391</span><span id="line-2391">      }</span>
-<span class="source-line-no">2392</span><span id="line-2392">      // TODO: deal with table on master for rs group.</span>
-<span class="source-line-no">2393</span><span id="line-2393">      if (dest.equals(serverName)) {</span>
-<span class="source-line-no">2394</span><span id="line-2394">        // To avoid unnecessary region moving later by balancer. Don't put user</span>
-<span class="source-line-no">2395</span><span id="line-2395">        // regions on master.</span>
-<span class="source-line-no">2396</span><span id="line-2396">        LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">2397</span><span id="line-2397">          + " to avoid unnecessary region moving later by load balancer,"</span>
-<span class="source-line-no">2398</span><span id="line-2398">          + " because it should not be on master");</span>
-<span class="source-line-no">2399</span><span id="line-2399">        return;</span>
-<span class="source-line-no">2400</span><span id="line-2400">      }</span>
-<span class="source-line-no">2401</span><span id="line-2401">    }</span>
-<span class="source-line-no">2402</span><span id="line-2402"></span>
-<span class="source-line-no">2403</span><span id="line-2403">    if (dest.equals(regionState.getServerName())) {</span>
-<span class="source-line-no">2404</span><span id="line-2404">      LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">2405</span><span id="line-2405">        + " because region already assigned to the same server " + dest + ".");</span>
-<span class="source-line-no">2406</span><span id="line-2406">      return;</span>
-<span class="source-line-no">2407</span><span id="line-2407">    }</span>
-<span class="source-line-no">2408</span><span id="line-2408"></span>
-<span class="source-line-no">2409</span><span id="line-2409">    // Now we can do the move</span>
-<span class="source-line-no">2410</span><span id="line-2410">    RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest);</span>
-<span class="source-line-no">2411</span><span id="line-2411">    assert rp.getDestination() != null : rp.toString() + " " + dest;</span>
+<span class="source-line-no">2334</span><span id="line-2334">          // Execute the operation asynchronously</span>
+<span class="source-line-no">2335</span><span id="line-2335">          submitProcedure(getAssignmentManager().createSplitProcedure(regionInfo, splitRow));</span>
+<span class="source-line-no">2336</span><span id="line-2336">        }</span>
+<span class="source-line-no">2337</span><span id="line-2337"></span>
+<span class="source-line-no">2338</span><span id="line-2338">        @Override</span>
+<span class="source-line-no">2339</span><span id="line-2339">        protected String getDescription() {</span>
+<span class="source-line-no">2340</span><span id="line-2340">          return "SplitTableProcedure";</span>
+<span class="source-line-no">2341</span><span id="line-2341">        }</span>
+<span class="source-line-no">2342</span><span id="line-2342">      });</span>
+<span class="source-line-no">2343</span><span id="line-2343">  }</span>
+<span class="source-line-no">2344</span><span id="line-2344"></span>
+<span class="source-line-no">2345</span><span id="line-2345">  private void warmUpRegion(ServerName server, RegionInfo region) {</span>
+<span class="source-line-no">2346</span><span id="line-2346">    FutureUtils.addListener(asyncClusterConnection.getRegionServerAdmin(server)</span>
+<span class="source-line-no">2347</span><span id="line-2347">      .warmupRegion(RequestConverter.buildWarmupRegionRequest(region)), (r, e) -&gt; {</span>
+<span class="source-line-no">2348</span><span id="line-2348">        if (e != null) {</span>
+<span class="source-line-no">2349</span><span id="line-2349">          LOG.warn("Failed to warm up region {} on server {}", region, server, e);</span>
+<span class="source-line-no">2350</span><span id="line-2350">        }</span>
+<span class="source-line-no">2351</span><span id="line-2351">      });</span>
+<span class="source-line-no">2352</span><span id="line-2352">  }</span>
+<span class="source-line-no">2353</span><span id="line-2353"></span>
+<span class="source-line-no">2354</span><span id="line-2354">  // Public so can be accessed by tests. Blocks until move is done.</span>
+<span class="source-line-no">2355</span><span id="line-2355">  // Replace with an async implementation from which you can get</span>
+<span class="source-line-no">2356</span><span id="line-2356">  // a success/failure result.</span>
+<span class="source-line-no">2357</span><span id="line-2357">  @InterfaceAudience.Private</span>
+<span class="source-line-no">2358</span><span id="line-2358">  public void move(final byte[] encodedRegionName, byte[] destServerName) throws IOException {</span>
+<span class="source-line-no">2359</span><span id="line-2359">    RegionState regionState =</span>
+<span class="source-line-no">2360</span><span id="line-2360">      assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
+<span class="source-line-no">2361</span><span id="line-2361"></span>
+<span class="source-line-no">2362</span><span id="line-2362">    RegionInfo hri;</span>
+<span class="source-line-no">2363</span><span id="line-2363">    if (regionState != null) {</span>
+<span class="source-line-no">2364</span><span id="line-2364">      hri = regionState.getRegion();</span>
+<span class="source-line-no">2365</span><span id="line-2365">    } else {</span>
+<span class="source-line-no">2366</span><span id="line-2366">      throw new UnknownRegionException(Bytes.toStringBinary(encodedRegionName));</span>
+<span class="source-line-no">2367</span><span id="line-2367">    }</span>
+<span class="source-line-no">2368</span><span id="line-2368"></span>
+<span class="source-line-no">2369</span><span id="line-2369">    ServerName dest;</span>
+<span class="source-line-no">2370</span><span id="line-2370">    List&lt;ServerName&gt; exclude = hri.getTable().isSystemTable()</span>
+<span class="source-line-no">2371</span><span id="line-2371">      ? assignmentManager.getExcludedServersForSystemTable()</span>
+<span class="source-line-no">2372</span><span id="line-2372">      : new ArrayList&lt;&gt;(1);</span>
+<span class="source-line-no">2373</span><span id="line-2373">    if (</span>
+<span class="source-line-no">2374</span><span id="line-2374">      destServerName != null &amp;&amp; exclude.contains(ServerName.valueOf(Bytes.toString(destServerName)))</span>
+<span class="source-line-no">2375</span><span id="line-2375">    ) {</span>
+<span class="source-line-no">2376</span><span id="line-2376">      LOG.info(Bytes.toString(encodedRegionName) + " can not move to "</span>
+<span class="source-line-no">2377</span><span id="line-2377">        + Bytes.toString(destServerName) + " because the server is in exclude list");</span>
+<span class="source-line-no">2378</span><span id="line-2378">      destServerName = null;</span>
+<span class="source-line-no">2379</span><span id="line-2379">    }</span>
+<span class="source-line-no">2380</span><span id="line-2380">    if (destServerName == null || destServerName.length == 0) {</span>
+<span class="source-line-no">2381</span><span id="line-2381">      LOG.info("Passed destination servername is null/empty so " + "choosing a server at random");</span>
+<span class="source-line-no">2382</span><span id="line-2382">      exclude.add(regionState.getServerName());</span>
+<span class="source-line-no">2383</span><span id="line-2383">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList(exclude);</span>
+<span class="source-line-no">2384</span><span id="line-2384">      dest = balancer.randomAssignment(hri, destServers);</span>
+<span class="source-line-no">2385</span><span id="line-2385">      if (dest == null) {</span>
+<span class="source-line-no">2386</span><span id="line-2386">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
+<span class="source-line-no">2387</span><span id="line-2387">        return;</span>
+<span class="source-line-no">2388</span><span id="line-2388">      }</span>
+<span class="source-line-no">2389</span><span id="line-2389">    } else {</span>
+<span class="source-line-no">2390</span><span id="line-2390">      ServerName candidate = ServerName.valueOf(Bytes.toString(destServerName));</span>
+<span class="source-line-no">2391</span><span id="line-2391">      dest = balancer.randomAssignment(hri, Lists.newArrayList(candidate));</span>
+<span class="source-line-no">2392</span><span id="line-2392">      if (dest == null) {</span>
+<span class="source-line-no">2393</span><span id="line-2393">        LOG.debug("Unable to determine a plan to assign " + hri);</span>
+<span class="source-line-no">2394</span><span id="line-2394">        return;</span>
+<span class="source-line-no">2395</span><span id="line-2395">      }</span>
+<span class="source-line-no">2396</span><span id="line-2396">      // TODO: deal with table on master for rs group.</span>
+<span class="source-line-no">2397</span><span id="line-2397">      if (dest.equals(serverName)) {</span>
+<span class="source-line-no">2398</span><span id="line-2398">        // To avoid unnecessary region moving later by balancer. Don't put user</span>
+<span class="source-line-no">2399</span><span id="line-2399">        // regions on master.</span>
+<span class="source-line-no">2400</span><span id="line-2400">        LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">2401</span><span id="line-2401">          + " to avoid unnecessary region moving later by load balancer,"</span>
+<span class="source-line-no">2402</span><span id="line-2402">          + " because it should not be on master");</span>
+<span class="source-line-no">2403</span><span id="line-2403">        return;</span>
+<span class="source-line-no">2404</span><span id="line-2404">      }</span>
+<span class="source-line-no">2405</span><span id="line-2405">    }</span>
+<span class="source-line-no">2406</span><span id="line-2406"></span>
+<span class="source-line-no">2407</span><span id="line-2407">    if (dest.equals(regionState.getServerName())) {</span>
+<span class="source-line-no">2408</span><span id="line-2408">      LOG.debug("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">2409</span><span id="line-2409">        + " because region already assigned to the same server " + dest + ".");</span>
+<span class="source-line-no">2410</span><span id="line-2410">      return;</span>
+<span class="source-line-no">2411</span><span id="line-2411">    }</span>
 <span class="source-line-no">2412</span><span id="line-2412"></span>
-<span class="source-line-no">2413</span><span id="line-2413">    try {</span>
-<span class="source-line-no">2414</span><span id="line-2414">      checkInitialized();</span>
-<span class="source-line-no">2415</span><span id="line-2415">      if (this.cpHost != null) {</span>
-<span class="source-line-no">2416</span><span id="line-2416">        this.cpHost.preMove(hri, rp.getSource(), rp.getDestination());</span>
-<span class="source-line-no">2417</span><span id="line-2417">      }</span>
-<span class="source-line-no">2418</span><span id="line-2418"></span>
-<span class="source-line-no">2419</span><span id="line-2419">      TransitRegionStateProcedure proc =</span>
-<span class="source-line-no">2420</span><span id="line-2420">        this.assignmentManager.createMoveRegionProcedure(rp.getRegionInfo(), rp.getDestination());</span>
-<span class="source-line-no">2421</span><span id="line-2421">      if (conf.getBoolean(WARMUP_BEFORE_MOVE, DEFAULT_WARMUP_BEFORE_MOVE)) {</span>
-<span class="source-line-no">2422</span><span id="line-2422">        // Warmup the region on the destination before initiating the move.</span>
-<span class="source-line-no">2423</span><span id="line-2423">        // A region server could reject the close request because it either does not</span>
-<span class="source-line-no">2424</span><span id="line-2424">        // have the specified region or the region is being split.</span>
-<span class="source-line-no">2425</span><span id="line-2425">        LOG.info(getClientIdAuditPrefix() + " move " + rp + ", warming up region on "</span>
-<span class="source-line-no">2426</span><span id="line-2426">          + rp.getDestination());</span>
-<span class="source-line-no">2427</span><span id="line-2427">        warmUpRegion(rp.getDestination(), hri);</span>
-<span class="source-line-no">2428</span><span id="line-2428">      }</span>
-<span class="source-line-no">2429</span><span id="line-2429">      LOG.info(getClientIdAuditPrefix() + " move " + rp + ", running balancer");</span>
-<span class="source-line-no">2430</span><span id="line-2430">      Future&lt;byte[]&gt; future = ProcedureSyncWait.submitProcedure(this.procedureExecutor, proc);</span>
-<span class="source-line-no">2431</span><span id="line-2431">      try {</span>
-<span class="source-line-no">2432</span><span id="line-2432">        // Is this going to work? Will we throw exception on error?</span>
-<span class="source-line-no">2433</span><span id="line-2433">        // TODO: CompletableFuture rather than this stunted Future.</span>
-<span class="source-line-no">2434</span><span id="line-2434">        future.get();</span>
-<span class="source-line-no">2435</span><span id="line-2435">      } catch (InterruptedException | ExecutionException e) {</span>
-<span class="source-line-no">2436</span><span id="line-2436">        throw new HBaseIOException(e);</span>
-<span class="source-line-no">2437</span><span id="line-2437">      }</span>
-<span class="source-line-no">2438</span><span id="line-2438">      if (this.cpHost != null) {</span>
-<span class="source-line-no">2439</span><span id="line-2439">        this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());</span>
-<span class="source-line-no">2440</span><span id="line-2440">      }</span>
-<span class="source-line-no">2441</span><span id="line-2441">    } catch (IOException ioe) {</span>
-<span class="source-line-no">2442</span><span id="line-2442">      if (ioe instanceof HBaseIOException) {</span>
-<span class="source-line-no">2443</span><span id="line-2443">        throw (HBaseIOException) ioe;</span>
+<span class="source-line-no">2413</span><span id="line-2413">    // Now we can do the move</span>
+<span class="source-line-no">2414</span><span id="line-2414">    RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest);</span>
+<span class="source-line-no">2415</span><span id="line-2415">    assert rp.getDestination() != null : rp.toString() + " " + dest;</span>
+<span class="source-line-no">2416</span><span id="line-2416"></span>
+<span class="source-line-no">2417</span><span id="line-2417">    try {</span>
+<span class="source-line-no">2418</span><span id="line-2418">      checkInitialized();</span>
+<span class="source-line-no">2419</span><span id="line-2419">      if (this.cpHost != null) {</span>
+<span class="source-line-no">2420</span><span id="line-2420">        this.cpHost.preMove(hri, rp.getSource(), rp.getDestination());</span>
+<span class="source-line-no">2421</span><span id="line-2421">      }</span>
+<span class="source-line-no">2422</span><span id="line-2422"></span>
+<span class="source-line-no">2423</span><span id="line-2423">      TransitRegionStateProcedure proc =</span>
+<span class="source-line-no">2424</span><span id="line-2424">        this.assignmentManager.createMoveRegionProcedure(rp.getRegionInfo(), rp.getDestination());</span>
+<span class="source-line-no">2425</span><span id="line-2425">      if (conf.getBoolean(WARMUP_BEFORE_MOVE, DEFAULT_WARMUP_BEFORE_MOVE)) {</span>
+<span class="source-line-no">2426</span><span id="line-2426">        // Warmup the region on the destination before initiating the move.</span>
+<span class="source-line-no">2427</span><span id="line-2427">        // A region server could reject the close request because it either does not</span>
+<span class="source-line-no">2428</span><span id="line-2428">        // have the specified region or the region is being split.</span>
+<span class="source-line-no">2429</span><span id="line-2429">        LOG.info(getClientIdAuditPrefix() + " move " + rp + ", warming up region on "</span>
+<span class="source-line-no">2430</span><span id="line-2430">          + rp.getDestination());</span>
+<span class="source-line-no">2431</span><span id="line-2431">        warmUpRegion(rp.getDestination(), hri);</span>
+<span class="source-line-no">2432</span><span id="line-2432">      }</span>
+<span class="source-line-no">2433</span><span id="line-2433">      LOG.info(getClientIdAuditPrefix() + " move " + rp + ", running balancer");</span>
+<span class="source-line-no">2434</span><span id="line-2434">      Future&lt;byte[]&gt; future = ProcedureSyncWait.submitProcedure(this.procedureExecutor, proc);</span>
+<span class="source-line-no">2435</span><span id="line-2435">      try {</span>
+<span class="source-line-no">2436</span><span id="line-2436">        // Is this going to work? Will we throw exception on error?</span>
+<span class="source-line-no">2437</span><span id="line-2437">        // TODO: CompletableFuture rather than this stunted Future.</span>
+<span class="source-line-no">2438</span><span id="line-2438">        future.get();</span>
+<span class="source-line-no">2439</span><span id="line-2439">      } catch (InterruptedException | ExecutionException e) {</span>
+<span class="source-line-no">2440</span><span id="line-2440">        throw new HBaseIOException(e);</span>
+<span class="source-line-no">2441</span><span id="line-2441">      }</span>
+<span class="source-line-no">2442</span><span id="line-2442">      if (this.cpHost != null) {</span>
+<span class="source-line-no">2443</span><span id="line-2443">        this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());</span>
 <span class="source-line-no">2444</span><span id="line-2444">      }</span>
-<span class="source-line-no">2445</span><span id="line-2445">      throw new HBaseIOException(ioe);</span>
-<span class="source-line-no">2446</span><span id="line-2446">    }</span>
-<span class="source-line-no">2447</span><span id="line-2447">  }</span>
-<span class="source-line-no">2448</span><span id="line-2448"></span>
-<span class="source-line-no">2449</span><span id="line-2449">  @Override</span>
-<span class="source-line-no">2450</span><span id="line-2450">  public long createTable(final TableDescriptor tableDescriptor, final byte[][] splitKeys,</span>
-<span class="source-line-no">2451</span><span id="line-2451">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2452</span><span id="line-2452">    checkInitialized();</span>
-<span class="source-line-no">2453</span><span id="line-2453">    TableDescriptor desc = getMasterCoprocessorHost().preCreateTableRegionsInfos(tableDescriptor);</span>
-<span class="source-line-no">2454</span><span id="line-2454">    if (desc == null) {</span>
-<span class="source-line-no">2455</span><span id="line-2455">      throw new IOException("Creation for " + tableDescriptor + " is canceled by CP");</span>
-<span class="source-line-no">2456</span><span id="line-2456">    }</span>
-<span class="source-line-no">2457</span><span id="line-2457">    String namespace = desc.getTableName().getNamespaceAsString();</span>
-<span class="source-line-no">2458</span><span id="line-2458">    this.clusterSchemaService.getNamespace(namespace);</span>
-<span class="source-line-no">2459</span><span id="line-2459"></span>
-<span class="source-line-no">2460</span><span id="line-2460">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(desc, splitKeys);</span>
-<span class="source-line-no">2461</span><span id="line-2461">    TableDescriptorChecker.sanityCheck(conf, desc);</span>
-<span class="source-line-no">2462</span><span id="line-2462"></span>
-<span class="source-line-no">2463</span><span id="line-2463">    return MasterProcedureUtil</span>
-<span class="source-line-no">2464</span><span id="line-2464">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2465</span><span id="line-2465">        @Override</span>
-<span class="source-line-no">2466</span><span id="line-2466">        protected void run() throws IOException {</span>
-<span class="source-line-no">2467</span><span id="line-2467">          getMaster().getMasterCoprocessorHost().preCreateTable(desc, newRegions);</span>
-<span class="source-line-no">2468</span><span id="line-2468"></span>
-<span class="source-line-no">2469</span><span id="line-2469">          LOG.info(getClientIdAuditPrefix() + " create " + desc);</span>
-<span class="source-line-no">2470</span><span id="line-2470"></span>
-<span class="source-line-no">2471</span><span id="line-2471">          // TODO: We can handle/merge duplicate requests, and differentiate the case of</span>
-<span class="source-line-no">2472</span><span id="line-2472">          // TableExistsException by saying if the schema is the same or not.</span>
-<span class="source-line-no">2473</span><span id="line-2473">          //</span>
-<span class="source-line-no">2474</span><span id="line-2474">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2475</span><span id="line-2475">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2476</span><span id="line-2476">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2477</span><span id="line-2477">          submitProcedure(</span>
-<span class="source-line-no">2478</span><span id="line-2478">            new CreateTableProcedure(procedureExecutor.getEnvironment(), desc, newRegions, latch));</span>
-<span class="source-line-no">2479</span><span id="line-2479">          latch.await();</span>
-<span class="source-line-no">2480</span><span id="line-2480"></span>
-<span class="source-line-no">2481</span><span id="line-2481">          getMaster().getMasterCoprocessorHost().postCreateTable(desc, newRegions);</span>
-<span class="source-line-no">2482</span><span id="line-2482">        }</span>
-<span class="source-line-no">2483</span><span id="line-2483"></span>
-<span class="source-line-no">2484</span><span id="line-2484">        @Override</span>
-<span class="source-line-no">2485</span><span id="line-2485">        protected String getDescription() {</span>
-<span class="source-line-no">2486</span><span id="line-2486">          return "CreateTableProcedure";</span>
-<span class="source-line-no">2487</span><span id="line-2487">        }</span>
-<span class="source-line-no">2488</span><span id="line-2488">      });</span>
-<span class="source-line-no">2489</span><span id="line-2489">  }</span>
-<span class="source-line-no">2490</span><span id="line-2490"></span>
-<span class="source-line-no">2491</span><span id="line-2491">  @Override</span>
-<span class="source-line-no">2492</span><span id="line-2492">  public long createSystemTable(final TableDescriptor tableDescriptor) throws IOException {</span>
-<span class="source-line-no">2493</span><span id="line-2493">    if (isStopped()) {</span>
-<span class="source-line-no">2494</span><span id="line-2494">      throw new MasterNotRunningException();</span>
-<span class="source-line-no">2495</span><span id="line-2495">    }</span>
-<span class="source-line-no">2496</span><span id="line-2496"></span>
-<span class="source-line-no">2497</span><span id="line-2497">    TableName tableName = tableDescriptor.getTableName();</span>
-<span class="source-line-no">2498</span><span id="line-2498">    if (!(tableName.isSystemTable())) {</span>
-<span class="source-line-no">2499</span><span id="line-2499">      throw new IllegalArgumentException(</span>
-<span class="source-line-no">2500</span><span id="line-2500">        "Only system table creation can use this createSystemTable API");</span>
-<span class="source-line-no">2501</span><span id="line-2501">    }</span>
-<span class="source-line-no">2502</span><span id="line-2502"></span>
-<span class="source-line-no">2503</span><span id="line-2503">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(tableDescriptor, null);</span>
-<span class="source-line-no">2504</span><span id="line-2504"></span>
-<span class="source-line-no">2505</span><span id="line-2505">    LOG.info(getClientIdAuditPrefix() + " create " + tableDescriptor);</span>
+<span class="source-line-no">2445</span><span id="line-2445">    } catch (IOException ioe) {</span>
+<span class="source-line-no">2446</span><span id="line-2446">      if (ioe instanceof HBaseIOException) {</span>
+<span class="source-line-no">2447</span><span id="line-2447">        throw (HBaseIOException) ioe;</span>
+<span class="source-line-no">2448</span><span id="line-2448">      }</span>
+<span class="source-line-no">2449</span><span id="line-2449">      throw new HBaseIOException(ioe);</span>
+<span class="source-line-no">2450</span><span id="line-2450">    }</span>
+<span class="source-line-no">2451</span><span id="line-2451">  }</span>
+<span class="source-line-no">2452</span><span id="line-2452"></span>
+<span class="source-line-no">2453</span><span id="line-2453">  @Override</span>
+<span class="source-line-no">2454</span><span id="line-2454">  public long createTable(final TableDescriptor tableDescriptor, final byte[][] splitKeys,</span>
+<span class="source-line-no">2455</span><span id="line-2455">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2456</span><span id="line-2456">    checkInitialized();</span>
+<span class="source-line-no">2457</span><span id="line-2457">    TableDescriptor desc = getMasterCoprocessorHost().preCreateTableRegionsInfos(tableDescriptor);</span>
+<span class="source-line-no">2458</span><span id="line-2458">    if (desc == null) {</span>
+<span class="source-line-no">2459</span><span id="line-2459">      throw new IOException("Creation for " + tableDescriptor + " is canceled by CP");</span>
+<span class="source-line-no">2460</span><span id="line-2460">    }</span>
+<span class="source-line-no">2461</span><span id="line-2461">    String namespace = desc.getTableName().getNamespaceAsString();</span>
+<span class="source-line-no">2462</span><span id="line-2462">    this.clusterSchemaService.getNamespace(namespace);</span>
+<span class="source-line-no">2463</span><span id="line-2463"></span>
+<span class="source-line-no">2464</span><span id="line-2464">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(desc, splitKeys);</span>
+<span class="source-line-no">2465</span><span id="line-2465">    TableDescriptorChecker.sanityCheck(conf, desc);</span>
+<span class="source-line-no">2466</span><span id="line-2466"></span>
+<span class="source-line-no">2467</span><span id="line-2467">    return MasterProcedureUtil</span>
+<span class="source-line-no">2468</span><span id="line-2468">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2469</span><span id="line-2469">        @Override</span>
+<span class="source-line-no">2470</span><span id="line-2470">        protected void run() throws IOException {</span>
+<span class="source-line-no">2471</span><span id="line-2471">          getMaster().getMasterCoprocessorHost().preCreateTable(desc, newRegions);</span>
+<span class="source-line-no">2472</span><span id="line-2472"></span>
+<span class="source-line-no">2473</span><span id="line-2473">          LOG.info(getClientIdAuditPrefix() + " create " + desc);</span>
+<span class="source-line-no">2474</span><span id="line-2474"></span>
+<span class="source-line-no">2475</span><span id="line-2475">          // TODO: We can handle/merge duplicate requests, and differentiate the case of</span>
+<span class="source-line-no">2476</span><span id="line-2476">          // TableExistsException by saying if the schema is the same or not.</span>
+<span class="source-line-no">2477</span><span id="line-2477">          //</span>
+<span class="source-line-no">2478</span><span id="line-2478">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2479</span><span id="line-2479">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2480</span><span id="line-2480">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2481</span><span id="line-2481">          submitProcedure(</span>
+<span class="source-line-no">2482</span><span id="line-2482">            new CreateTableProcedure(procedureExecutor.getEnvironment(), desc, newRegions, latch));</span>
+<span class="source-line-no">2483</span><span id="line-2483">          latch.await();</span>
+<span class="source-line-no">2484</span><span id="line-2484"></span>
+<span class="source-line-no">2485</span><span id="line-2485">          getMaster().getMasterCoprocessorHost().postCreateTable(desc, newRegions);</span>
+<span class="source-line-no">2486</span><span id="line-2486">        }</span>
+<span class="source-line-no">2487</span><span id="line-2487"></span>
+<span class="source-line-no">2488</span><span id="line-2488">        @Override</span>
+<span class="source-line-no">2489</span><span id="line-2489">        protected String getDescription() {</span>
+<span class="source-line-no">2490</span><span id="line-2490">          return "CreateTableProcedure";</span>
+<span class="source-line-no">2491</span><span id="line-2491">        }</span>
+<span class="source-line-no">2492</span><span id="line-2492">      });</span>
+<span class="source-line-no">2493</span><span id="line-2493">  }</span>
+<span class="source-line-no">2494</span><span id="line-2494"></span>
+<span class="source-line-no">2495</span><span id="line-2495">  @Override</span>
+<span class="source-line-no">2496</span><span id="line-2496">  public long createSystemTable(final TableDescriptor tableDescriptor) throws IOException {</span>
+<span class="source-line-no">2497</span><span id="line-2497">    if (isStopped()) {</span>
+<span class="source-line-no">2498</span><span id="line-2498">      throw new MasterNotRunningException();</span>
+<span class="source-line-no">2499</span><span id="line-2499">    }</span>
+<span class="source-line-no">2500</span><span id="line-2500"></span>
+<span class="source-line-no">2501</span><span id="line-2501">    TableName tableName = tableDescriptor.getTableName();</span>
+<span class="source-line-no">2502</span><span id="line-2502">    if (!(tableName.isSystemTable())) {</span>
+<span class="source-line-no">2503</span><span id="line-2503">      throw new IllegalArgumentException(</span>
+<span class="source-line-no">2504</span><span id="line-2504">        "Only system table creation can use this createSystemTable API");</span>
+<span class="source-line-no">2505</span><span id="line-2505">    }</span>
 <span class="source-line-no">2506</span><span id="line-2506"></span>
-<span class="source-line-no">2507</span><span id="line-2507">    // This special create table is called locally to master. Therefore, no RPC means no need</span>
-<span class="source-line-no">2508</span><span id="line-2508">    // to use nonce to detect duplicated RPC call.</span>
-<span class="source-line-no">2509</span><span id="line-2509">    long procId = this.procedureExecutor.submitProcedure(</span>
-<span class="source-line-no">2510</span><span id="line-2510">      new CreateTableProcedure(procedureExecutor.getEnvironment(), tableDescriptor, newRegions));</span>
-<span class="source-line-no">2511</span><span id="line-2511"></span>
-<span class="source-line-no">2512</span><span id="line-2512">    return procId;</span>
-<span class="source-line-no">2513</span><span id="line-2513">  }</span>
-<span class="source-line-no">2514</span><span id="line-2514"></span>
-<span class="source-line-no">2515</span><span id="line-2515">  private void startActiveMasterManager(int infoPort) throws KeeperException {</span>
-<span class="source-line-no">2516</span><span id="line-2516">    String backupZNode = ZNodePaths.joinZNode(zooKeeper.getZNodePaths().backupMasterAddressesZNode,</span>
-<span class="source-line-no">2517</span><span id="line-2517">      serverName.toString());</span>
-<span class="source-line-no">2518</span><span id="line-2518">    /*</span>
-<span class="source-line-no">2519</span><span id="line-2519">     * Add a ZNode for ourselves in the backup master directory since we may not become the active</span>
-<span class="source-line-no">2520</span><span id="line-2520">     * master. If so, we want the actual active master to know we are backup masters, so that it</span>
-<span class="source-line-no">2521</span><span id="line-2521">     * won't assign regions to us if so configured. If we become the active master later,</span>
-<span class="source-line-no">2522</span><span id="line-2522">     * ActiveMasterManager will delete this node explicitly. If we crash before then, ZooKeeper will</span>
-<span class="source-line-no">2523</span><span id="line-2523">     * delete this node for us since it is ephemeral.</span>
-<span class="source-line-no">2524</span><span id="line-2524">     */</span>
-<span class="source-line-no">2525</span><span id="line-2525">    LOG.info("Adding backup master ZNode " + backupZNode);</span>
-<span class="source-line-no">2526</span><span id="line-2526">    if (!MasterAddressTracker.setMasterAddress(zooKeeper, backupZNode, serverName, infoPort)) {</span>
-<span class="source-line-no">2527</span><span id="line-2527">      LOG.warn("Failed create of " + backupZNode + " by " + serverName);</span>
-<span class="source-line-no">2528</span><span id="line-2528">    }</span>
-<span class="source-line-no">2529</span><span id="line-2529">    this.activeMasterManager.setInfoPort(infoPort);</span>
-<span class="source-line-no">2530</span><span id="line-2530">    int timeout = conf.getInt(HConstants.ZK_SESSION_TIMEOUT, HConstants.DEFAULT_ZK_SESSION_TIMEOUT);</span>
-<span class="source-line-no">2531</span><span id="line-2531">    // If we're a backup master, stall until a primary to write this address</span>
-<span class="source-line-no">2532</span><span id="line-2532">    if (conf.getBoolean(HConstants.MASTER_TYPE_BACKUP, HConstants.DEFAULT_MASTER_TYPE_BACKUP)) {</span>
-<span class="source-line-no">2533</span><span id="line-2533">      LOG.debug("HMaster started in backup mode. Stalling until master znode is written.");</span>
-<span class="source-line-no">2534</span><span id="line-2534">      // This will only be a minute or so while the cluster starts up,</span>
-<span class="source-line-no">2535</span><span id="line-2535">      // so don't worry about setting watches on the parent znode</span>
-<span class="source-line-no">2536</span><span id="line-2536">      while (!activeMasterManager.hasActiveMaster()) {</span>
-<span class="source-line-no">2537</span><span id="line-2537">        LOG.debug("Waiting for master address and cluster state znode to be written.");</span>
-<span class="source-line-no">2538</span><span id="line-2538">        Threads.sleep(timeout);</span>
-<span class="source-line-no">2539</span><span id="line-2539">      }</span>
-<span class="source-line-no">2540</span><span id="line-2540">    }</span>
-<span class="source-line-no">2541</span><span id="line-2541"></span>
-<span class="source-line-no">2542</span><span id="line-2542">    // Here for the master startup process, we use TaskGroup to monitor the whole progress.</span>
-<span class="source-line-no">2543</span><span id="line-2543">    // The UI is similar to how Hadoop designed the startup page for the NameNode.</span>
-<span class="source-line-no">2544</span><span id="line-2544">    // See HBASE-21521 for more details.</span>
-<span class="source-line-no">2545</span><span id="line-2545">    // We do not cleanup the startupTaskGroup, let the startup progress information</span>
-<span class="source-line-no">2546</span><span id="line-2546">    // be permanent in the MEM.</span>
-<span class="source-line-no">2547</span><span id="line-2547">    startupTaskGroup = TaskMonitor.createTaskGroup(true, "Master startup");</span>
-<span class="source-line-no">2548</span><span id="line-2548">    try {</span>
-<span class="source-line-no">2549</span><span id="line-2549">      if (activeMasterManager.blockUntilBecomingActiveMaster(timeout, startupTaskGroup)) {</span>
-<span class="source-line-no">2550</span><span id="line-2550">        finishActiveMasterInitialization();</span>
-<span class="source-line-no">2551</span><span id="line-2551">      }</span>
-<span class="source-line-no">2552</span><span id="line-2552">    } catch (Throwable t) {</span>
-<span class="source-line-no">2553</span><span id="line-2553">      startupTaskGroup.abort("Failed to become active master due to:" + t.getMessage());</span>
-<span class="source-line-no">2554</span><span id="line-2554">      LOG.error(HBaseMarkers.FATAL, "Failed to become active master", t);</span>
-<span class="source-line-no">2555</span><span id="line-2555">      // HBASE-5680: Likely hadoop23 vs hadoop 20.x/1.x incompatibility</span>
-<span class="source-line-no">2556</span><span id="line-2556">      if (</span>
-<span class="source-line-no">2557</span><span id="line-2557">        t instanceof NoClassDefFoundError</span>
-<span class="source-line-no">2558</span><span id="line-2558">          &amp;&amp; t.getMessage().contains("org/apache/hadoop/hdfs/protocol/HdfsConstants$SafeModeAction")</span>
-<span class="source-line-no">2559</span><span id="line-2559">      ) {</span>
-<span class="source-line-no">2560</span><span id="line-2560">        // improved error message for this special case</span>
-<span class="source-line-no">2561</span><span id="line-2561">        abort("HBase is having a problem with its Hadoop jars.  You may need to recompile "</span>
-<span class="source-line-no">2562</span><span id="line-2562">          + "HBase against Hadoop version " + org.apache.hadoop.util.VersionInfo.getVersion()</span>
-<span class="source-line-no">2563</span><span id="line-2563">          + " or change your hadoop jars to start properly", t);</span>
-<span class="source-line-no">2564</span><span id="line-2564">      } else {</span>
-<span class="source-line-no">2565</span><span id="line-2565">        abort("Unhandled exception. Starting shutdown.", t);</span>
-<span class="source-line-no">2566</span><span id="line-2566">      }</span>
-<span class="source-line-no">2567</span><span id="line-2567">    }</span>
-<span class="source-line-no">2568</span><span id="line-2568">  }</span>
-<span class="source-line-no">2569</span><span id="line-2569"></span>
-<span class="source-line-no">2570</span><span id="line-2570">  private static boolean isCatalogTable(final TableName tableName) {</span>
-<span class="source-line-no">2571</span><span id="line-2571">    return tableName.equals(TableName.META_TABLE_NAME);</span>
+<span class="source-line-no">2507</span><span id="line-2507">    RegionInfo[] newRegions = ModifyRegionUtils.createRegionInfos(tableDescriptor, null);</span>
+<span class="source-line-no">2508</span><span id="line-2508"></span>
+<span class="source-line-no">2509</span><span id="line-2509">    LOG.info(getClientIdAuditPrefix() + " create " + tableDescriptor);</span>
+<span class="source-line-no">2510</span><span id="line-2510"></span>
+<span class="source-line-no">2511</span><span id="line-2511">    // This special create table is called locally to master. Therefore, no RPC means no need</span>
+<span class="source-line-no">2512</span><span id="line-2512">    // to use nonce to detect duplicated RPC call.</span>
+<span class="source-line-no">2513</span><span id="line-2513">    long procId = this.procedureExecutor.submitProcedure(</span>
+<span class="source-line-no">2514</span><span id="line-2514">      new CreateTableProcedure(procedureExecutor.getEnvironment(), tableDescriptor, newRegions));</span>
+<span class="source-line-no">2515</span><span id="line-2515"></span>
+<span class="source-line-no">2516</span><span id="line-2516">    return procId;</span>
+<span class="source-line-no">2517</span><span id="line-2517">  }</span>
+<span class="source-line-no">2518</span><span id="line-2518"></span>
+<span class="source-line-no">2519</span><span id="line-2519">  private void startActiveMasterManager(int infoPort) throws KeeperException {</span>
+<span class="source-line-no">2520</span><span id="line-2520">    String backupZNode = ZNodePaths.joinZNode(zooKeeper.getZNodePaths().backupMasterAddressesZNode,</span>
+<span class="source-line-no">2521</span><span id="line-2521">      serverName.toString());</span>
+<span class="source-line-no">2522</span><span id="line-2522">    /*</span>
+<span class="source-line-no">2523</span><span id="line-2523">     * Add a ZNode for ourselves in the backup master directory since we may not become the active</span>
+<span class="source-line-no">2524</span><span id="line-2524">     * master. If so, we want the actual active master to know we are backup masters, so that it</span>
+<span class="source-line-no">2525</span><span id="line-2525">     * won't assign regions to us if so configured. If we become the active master later,</span>
+<span class="source-line-no">2526</span><span id="line-2526">     * ActiveMasterManager will delete this node explicitly. If we crash before then, ZooKeeper will</span>
+<span class="source-line-no">2527</span><span id="line-2527">     * delete this node for us since it is ephemeral.</span>
+<span class="source-line-no">2528</span><span id="line-2528">     */</span>
+<span class="source-line-no">2529</span><span id="line-2529">    LOG.info("Adding backup master ZNode " + backupZNode);</span>
+<span class="source-line-no">2530</span><span id="line-2530">    if (!MasterAddressTracker.setMasterAddress(zooKeeper, backupZNode, serverName, infoPort)) {</span>
+<span class="source-line-no">2531</span><span id="line-2531">      LOG.warn("Failed create of " + backupZNode + " by " + serverName);</span>
+<span class="source-line-no">2532</span><span id="line-2532">    }</span>
+<span class="source-line-no">2533</span><span id="line-2533">    this.activeMasterManager.setInfoPort(infoPort);</span>
+<span class="source-line-no">2534</span><span id="line-2534">    int timeout = conf.getInt(HConstants.ZK_SESSION_TIMEOUT, HConstants.DEFAULT_ZK_SESSION_TIMEOUT);</span>
+<span class="source-line-no">2535</span><span id="line-2535">    // If we're a backup master, stall until a primary to write this address</span>
+<span class="source-line-no">2536</span><span id="line-2536">    if (conf.getBoolean(HConstants.MASTER_TYPE_BACKUP, HConstants.DEFAULT_MASTER_TYPE_BACKUP)) {</span>
+<span class="source-line-no">2537</span><span id="line-2537">      LOG.debug("HMaster started in backup mode. Stalling until master znode is written.");</span>
+<span class="source-line-no">2538</span><span id="line-2538">      // This will only be a minute or so while the cluster starts up,</span>
+<span class="source-line-no">2539</span><span id="line-2539">      // so don't worry about setting watches on the parent znode</span>
+<span class="source-line-no">2540</span><span id="line-2540">      while (!activeMasterManager.hasActiveMaster()) {</span>
+<span class="source-line-no">2541</span><span id="line-2541">        LOG.debug("Waiting for master address and cluster state znode to be written.");</span>
+<span class="source-line-no">2542</span><span id="line-2542">        Threads.sleep(timeout);</span>
+<span class="source-line-no">2543</span><span id="line-2543">      }</span>
+<span class="source-line-no">2544</span><span id="line-2544">    }</span>
+<span class="source-line-no">2545</span><span id="line-2545"></span>
+<span class="source-line-no">2546</span><span id="line-2546">    // Here for the master startup process, we use TaskGroup to monitor the whole progress.</span>
+<span class="source-line-no">2547</span><span id="line-2547">    // The UI is similar to how Hadoop designed the startup page for the NameNode.</span>
+<span class="source-line-no">2548</span><span id="line-2548">    // See HBASE-21521 for more details.</span>
+<span class="source-line-no">2549</span><span id="line-2549">    // We do not cleanup the startupTaskGroup, let the startup progress information</span>
+<span class="source-line-no">2550</span><span id="line-2550">    // be permanent in the MEM.</span>
+<span class="source-line-no">2551</span><span id="line-2551">    startupTaskGroup = TaskMonitor.createTaskGroup(true, "Master startup");</span>
+<span class="source-line-no">2552</span><span id="line-2552">    try {</span>
+<span class="source-line-no">2553</span><span id="line-2553">      if (activeMasterManager.blockUntilBecomingActiveMaster(timeout, startupTaskGroup)) {</span>
+<span class="source-line-no">2554</span><span id="line-2554">        finishActiveMasterInitialization();</span>
+<span class="source-line-no">2555</span><span id="line-2555">      }</span>
+<span class="source-line-no">2556</span><span id="line-2556">    } catch (Throwable t) {</span>
+<span class="source-line-no">2557</span><span id="line-2557">      startupTaskGroup.abort("Failed to become active master due to:" + t.getMessage());</span>
+<span class="source-line-no">2558</span><span id="line-2558">      LOG.error(HBaseMarkers.FATAL, "Failed to become active master", t);</span>
+<span class="source-line-no">2559</span><span id="line-2559">      // HBASE-5680: Likely hadoop23 vs hadoop 20.x/1.x incompatibility</span>
+<span class="source-line-no">2560</span><span id="line-2560">      if (</span>
+<span class="source-line-no">2561</span><span id="line-2561">        t instanceof NoClassDefFoundError</span>
+<span class="source-line-no">2562</span><span id="line-2562">          &amp;&amp; t.getMessage().contains("org/apache/hadoop/hdfs/protocol/HdfsConstants$SafeModeAction")</span>
+<span class="source-line-no">2563</span><span id="line-2563">      ) {</span>
+<span class="source-line-no">2564</span><span id="line-2564">        // improved error message for this special case</span>
+<span class="source-line-no">2565</span><span id="line-2565">        abort("HBase is having a problem with its Hadoop jars.  You may need to recompile "</span>
+<span class="source-line-no">2566</span><span id="line-2566">          + "HBase against Hadoop version " + org.apache.hadoop.util.VersionInfo.getVersion()</span>
+<span class="source-line-no">2567</span><span id="line-2567">          + " or change your hadoop jars to start properly", t);</span>
+<span class="source-line-no">2568</span><span id="line-2568">      } else {</span>
+<span class="source-line-no">2569</span><span id="line-2569">        abort("Unhandled exception. Starting shutdown.", t);</span>
+<span class="source-line-no">2570</span><span id="line-2570">      }</span>
+<span class="source-line-no">2571</span><span id="line-2571">    }</span>
 <span class="source-line-no">2572</span><span id="line-2572">  }</span>
 <span class="source-line-no">2573</span><span id="line-2573"></span>
-<span class="source-line-no">2574</span><span id="line-2574">  @Override</span>
-<span class="source-line-no">2575</span><span id="line-2575">  public long deleteTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2576</span><span id="line-2576">    throws IOException {</span>
-<span class="source-line-no">2577</span><span id="line-2577">    checkInitialized();</span>
-<span class="source-line-no">2578</span><span id="line-2578"></span>
-<span class="source-line-no">2579</span><span id="line-2579">    return MasterProcedureUtil</span>
-<span class="source-line-no">2580</span><span id="line-2580">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2581</span><span id="line-2581">        @Override</span>
-<span class="source-line-no">2582</span><span id="line-2582">        protected void run() throws IOException {</span>
-<span class="source-line-no">2583</span><span id="line-2583">          getMaster().getMasterCoprocessorHost().preDeleteTable(tableName);</span>
-<span class="source-line-no">2584</span><span id="line-2584"></span>
-<span class="source-line-no">2585</span><span id="line-2585">          LOG.info(getClientIdAuditPrefix() + " delete " + tableName);</span>
-<span class="source-line-no">2586</span><span id="line-2586"></span>
-<span class="source-line-no">2587</span><span id="line-2587">          // TODO: We can handle/merge duplicate request</span>
-<span class="source-line-no">2588</span><span id="line-2588">          //</span>
-<span class="source-line-no">2589</span><span id="line-2589">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2590</span><span id="line-2590">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2591</span><span id="line-2591">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2592</span><span id="line-2592">          submitProcedure(</span>
-<span class="source-line-no">2593</span><span id="line-2593">            new DeleteTableProcedure(procedureExecutor.getEnvironment(), tableName, latch));</span>
-<span class="source-line-no">2594</span><span id="line-2594">          latch.await();</span>
-<span class="source-line-no">2595</span><span id="line-2595"></span>
-<span class="source-line-no">2596</span><span id="line-2596">          getMaster().getMasterCoprocessorHost().postDeleteTable(tableName);</span>
-<span class="source-line-no">2597</span><span id="line-2597">        }</span>
-<span class="source-line-no">2598</span><span id="line-2598"></span>
-<span class="source-line-no">2599</span><span id="line-2599">        @Override</span>
-<span class="source-line-no">2600</span><span id="line-2600">        protected String getDescription() {</span>
-<span class="source-line-no">2601</span><span id="line-2601">          return "DeleteTableProcedure";</span>
-<span class="source-line-no">2602</span><span id="line-2602">        }</span>
-<span class="source-line-no">2603</span><span id="line-2603">      });</span>
-<span class="source-line-no">2604</span><span id="line-2604">  }</span>
-<span class="source-line-no">2605</span><span id="line-2605"></span>
-<span class="source-line-no">2606</span><span id="line-2606">  @Override</span>
-<span class="source-line-no">2607</span><span id="line-2607">  public long truncateTable(final TableName tableName, final boolean preserveSplits,</span>
-<span class="source-line-no">2608</span><span id="line-2608">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2609</span><span id="line-2609">    checkInitialized();</span>
-<span class="source-line-no">2610</span><span id="line-2610"></span>
-<span class="source-line-no">2611</span><span id="line-2611">    return MasterProcedureUtil</span>
-<span class="source-line-no">2612</span><span id="line-2612">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2613</span><span id="line-2613">        @Override</span>
-<span class="source-line-no">2614</span><span id="line-2614">        protected void run() throws IOException {</span>
-<span class="source-line-no">2615</span><span id="line-2615">          getMaster().getMasterCoprocessorHost().preTruncateTable(tableName);</span>
-<span class="source-line-no">2616</span><span id="line-2616"></span>
-<span class="source-line-no">2617</span><span id="line-2617">          LOG.info(getClientIdAuditPrefix() + " truncate " + tableName);</span>
-<span class="source-line-no">2618</span><span id="line-2618">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
-<span class="source-line-no">2619</span><span id="line-2619">          submitProcedure(new TruncateTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
-<span class="source-line-no">2620</span><span id="line-2620">            preserveSplits, latch));</span>
-<span class="source-line-no">2621</span><span id="line-2621">          latch.await();</span>
-<span class="source-line-no">2622</span><span id="line-2622"></span>
-<span class="source-line-no">2623</span><span id="line-2623">          getMaster().getMasterCoprocessorHost().postTruncateTable(tableName);</span>
-<span class="source-line-no">2624</span><span id="line-2624">        }</span>
-<span class="source-line-no">2625</span><span id="line-2625"></span>
-<span class="source-line-no">2626</span><span id="line-2626">        @Override</span>
-<span class="source-line-no">2627</span><span id="line-2627">        protected String getDescription() {</span>
-<span class="source-line-no">2628</span><span id="line-2628">          return "TruncateTableProcedure";</span>
-<span class="source-line-no">2629</span><span id="line-2629">        }</span>
-<span class="source-line-no">2630</span><span id="line-2630">      });</span>
-<span class="source-line-no">2631</span><span id="line-2631">  }</span>
-<span class="source-line-no">2632</span><span id="line-2632"></span>
-<span class="source-line-no">2633</span><span id="line-2633">  @Override</span>
-<span class="source-line-no">2634</span><span id="line-2634">  public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2635</span><span id="line-2635">    throws IOException {</span>
-<span class="source-line-no">2636</span><span id="line-2636">    checkInitialized();</span>
-<span class="source-line-no">2637</span><span id="line-2637"></span>
-<span class="source-line-no">2638</span><span id="line-2638">    return MasterProcedureUtil</span>
-<span class="source-line-no">2639</span><span id="line-2639">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2640</span><span id="line-2640">        @Override</span>
-<span class="source-line-no">2641</span><span id="line-2641">        protected void run() throws IOException {</span>
-<span class="source-line-no">2642</span><span id="line-2642">          getMaster().getMasterCoprocessorHost().preTruncateRegion(regionInfo);</span>
-<span class="source-line-no">2643</span><span id="line-2643"></span>
-<span class="source-line-no">2644</span><span id="line-2644">          LOG.info(</span>
-<span class="source-line-no">2645</span><span id="line-2645">            getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">2646</span><span id="line-2646"></span>
-<span class="source-line-no">2647</span><span id="line-2647">          // Execute the operation asynchronously</span>
-<span class="source-line-no">2648</span><span id="line-2648">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
-<span class="source-line-no">2649</span><span id="line-2649">          submitProcedure(</span>
-<span class="source-line-no">2650</span><span id="line-2650">            new TruncateRegionProcedure(procedureExecutor.getEnvironment(), regionInfo, latch));</span>
-<span class="source-line-no">2651</span><span id="line-2651">          latch.await();</span>
-<span class="source-line-no">2652</span><span id="line-2652"></span>
-<span class="source-line-no">2653</span><span id="line-2653">          getMaster().getMasterCoprocessorHost().postTruncateRegion(regionInfo);</span>
-<span class="source-line-no">2654</span><span id="line-2654">        }</span>
-<span class="source-line-no">2655</span><span id="line-2655"></span>
-<span class="source-line-no">2656</span><span id="line-2656">        @Override</span>
-<span class="source-line-no">2657</span><span id="line-2657">        protected String getDescription() {</span>
-<span class="source-line-no">2658</span><span id="line-2658">          return "TruncateRegionProcedure";</span>
-<span class="source-line-no">2659</span><span id="line-2659">        }</span>
-<span class="source-line-no">2660</span><span id="line-2660">      });</span>
-<span class="source-line-no">2661</span><span id="line-2661">  }</span>
-<span class="source-line-no">2662</span><span id="line-2662"></span>
-<span class="source-line-no">2663</span><span id="line-2663">  @Override</span>
-<span class="source-line-no">2664</span><span id="line-2664">  public long addColumn(final TableName tableName, final ColumnFamilyDescriptor column,</span>
-<span class="source-line-no">2665</span><span id="line-2665">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2666</span><span id="line-2666">    checkInitialized();</span>
-<span class="source-line-no">2667</span><span id="line-2667">    checkTableExists(tableName);</span>
-<span class="source-line-no">2668</span><span id="line-2668"></span>
-<span class="source-line-no">2669</span><span id="line-2669">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2670</span><span id="line-2670"></span>
-<span class="source-line-no">2671</span><span id="line-2671">      @Override</span>
-<span class="source-line-no">2672</span><span id="line-2672">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2673</span><span id="line-2673">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2674</span><span id="line-2674">        if (old.hasColumnFamily(column.getName())) {</span>
-<span class="source-line-no">2675</span><span id="line-2675">          throw new InvalidFamilyOperationException("Column family '" + column.getNameAsString()</span>
-<span class="source-line-no">2676</span><span id="line-2676">            + "' in table '" + tableName + "' already exists so cannot be added");</span>
-<span class="source-line-no">2677</span><span id="line-2677">        }</span>
-<span class="source-line-no">2678</span><span id="line-2678"></span>
-<span class="source-line-no">2679</span><span id="line-2679">        return TableDescriptorBuilder.newBuilder(old).setColumnFamily(column).build();</span>
-<span class="source-line-no">2680</span><span id="line-2680">      }</span>
-<span class="source-line-no">2681</span><span id="line-2681">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2682</span><span id="line-2682">  }</span>
-<span class="source-line-no">2683</span><span id="line-2683"></span>
-<span class="source-line-no">2684</span><span id="line-2684">  /**</span>
-<span class="source-line-no">2685</span><span id="line-2685">   * Implement to return TableDescriptor after pre-checks</span>
-<span class="source-line-no">2686</span><span id="line-2686">   */</span>
-<span class="source-line-no">2687</span><span id="line-2687">  protected interface TableDescriptorGetter {</span>
-<span class="source-line-no">2688</span><span id="line-2688">    TableDescriptor get() throws IOException;</span>
-<span class="source-line-no">2689</span><span id="line-2689">  }</span>
-<span class="source-line-no">2690</span><span id="line-2690"></span>
-<span class="source-line-no">2691</span><span id="line-2691">  @Override</span>
-<span class="source-line-no">2692</span><span id="line-2692">  public long modifyColumn(final TableName tableName, final ColumnFamilyDescriptor descriptor,</span>
-<span class="source-line-no">2693</span><span id="line-2693">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2694</span><span id="line-2694">    checkInitialized();</span>
-<span class="source-line-no">2695</span><span id="line-2695">    checkTableExists(tableName);</span>
-<span class="source-line-no">2696</span><span id="line-2696">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2697</span><span id="line-2697"></span>
-<span class="source-line-no">2698</span><span id="line-2698">      @Override</span>
-<span class="source-line-no">2699</span><span id="line-2699">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2700</span><span id="line-2700">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2701</span><span id="line-2701">        if (!old.hasColumnFamily(descriptor.getName())) {</span>
-<span class="source-line-no">2702</span><span id="line-2702">          throw new InvalidFamilyOperationException("Family '" + descriptor.getNameAsString()</span>
-<span class="source-line-no">2703</span><span id="line-2703">            + "' does not exist, so it cannot be modified");</span>
-<span class="source-line-no">2704</span><span id="line-2704">        }</span>
-<span class="source-line-no">2705</span><span id="line-2705"></span>
-<span class="source-line-no">2706</span><span id="line-2706">        return TableDescriptorBuilder.newBuilder(old).modifyColumnFamily(descriptor).build();</span>
-<span class="source-line-no">2707</span><span id="line-2707">      }</span>
-<span class="source-line-no">2708</span><span id="line-2708">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2709</span><span id="line-2709">  }</span>
-<span class="source-line-no">2710</span><span id="line-2710"></span>
-<span class="source-line-no">2711</span><span id="line-2711">  @Override</span>
-<span class="source-line-no">2712</span><span id="line-2712">  public long modifyColumnStoreFileTracker(TableName tableName, byte[] family, String dstSFT,</span>
-<span class="source-line-no">2713</span><span id="line-2713">    long nonceGroup, long nonce) throws IOException {</span>
-<span class="source-line-no">2714</span><span id="line-2714">    checkInitialized();</span>
-<span class="source-line-no">2715</span><span id="line-2715">    return MasterProcedureUtil</span>
-<span class="source-line-no">2716</span><span id="line-2716">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2717</span><span id="line-2717"></span>
-<span class="source-line-no">2718</span><span id="line-2718">        @Override</span>
-<span class="source-line-no">2719</span><span id="line-2719">        protected void run() throws IOException {</span>
-<span class="source-line-no">2720</span><span id="line-2720">          String sft = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2721</span><span id="line-2721">            .preModifyColumnFamilyStoreFileTracker(tableName, family, dstSFT);</span>
-<span class="source-line-no">2722</span><span id="line-2722">          LOG.info("{} modify column {} store file tracker of table {} to {}",</span>
-<span class="source-line-no">2723</span><span id="line-2723">            getClientIdAuditPrefix(), Bytes.toStringBinary(family), tableName, sft);</span>
-<span class="source-line-no">2724</span><span id="line-2724">          submitProcedure(new ModifyColumnFamilyStoreFileTrackerProcedure(</span>
-<span class="source-line-no">2725</span><span id="line-2725">            procedureExecutor.getEnvironment(), tableName, family, sft));</span>
-<span class="source-line-no">2726</span><span id="line-2726">          getMaster().getMasterCoprocessorHost().postModifyColumnFamilyStoreFileTracker(tableName,</span>
-<span class="source-line-no">2727</span><span id="line-2727">            family, dstSFT);</span>
-<span class="source-line-no">2728</span><span id="line-2728">        }</span>
-<span class="source-line-no">2729</span><span id="line-2729"></span>
-<span class="source-line-no">2730</span><span id="line-2730">        @Override</span>
-<span class="source-line-no">2731</span><span id="line-2731">        protected String getDescription() {</span>
-<span class="source-line-no">2732</span><span id="line-2732">          return "ModifyColumnFamilyStoreFileTrackerProcedure";</span>
-<span class="source-line-no">2733</span><span id="line-2733">        }</span>
-<span class="source-line-no">2734</span><span id="line-2734">      });</span>
-<span class="source-line-no">2735</span><span id="line-2735">  }</span>
-<span class="source-line-no">2736</span><span id="line-2736"></span>
-<span class="source-line-no">2737</span><span id="line-2737">  @Override</span>
-<span class="source-line-no">2738</span><span id="line-2738">  public long deleteColumn(final TableName tableName, final byte[] columnName,</span>
-<span class="source-line-no">2739</span><span id="line-2739">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">2740</span><span id="line-2740">    checkInitialized();</span>
-<span class="source-line-no">2741</span><span id="line-2741">    checkTableExists(tableName);</span>
-<span class="source-line-no">2742</span><span id="line-2742"></span>
-<span class="source-line-no">2743</span><span id="line-2743">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2744</span><span id="line-2744"></span>
-<span class="source-line-no">2745</span><span id="line-2745">      @Override</span>
-<span class="source-line-no">2746</span><span id="line-2746">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2747</span><span id="line-2747">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2574</span><span id="line-2574">  private static boolean isCatalogTable(final TableName tableName) {</span>
+<span class="source-line-no">2575</span><span id="line-2575">    return tableName.equals(TableName.META_TABLE_NAME);</span>
+<span class="source-line-no">2576</span><span id="line-2576">  }</span>
+<span class="source-line-no">2577</span><span id="line-2577"></span>
+<span class="source-line-no">2578</span><span id="line-2578">  @Override</span>
+<span class="source-line-no">2579</span><span id="line-2579">  public long deleteTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2580</span><span id="line-2580">    throws IOException {</span>
+<span class="source-line-no">2581</span><span id="line-2581">    checkInitialized();</span>
+<span class="source-line-no">2582</span><span id="line-2582"></span>
+<span class="source-line-no">2583</span><span id="line-2583">    return MasterProcedureUtil</span>
+<span class="source-line-no">2584</span><span id="line-2584">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2585</span><span id="line-2585">        @Override</span>
+<span class="source-line-no">2586</span><span id="line-2586">        protected void run() throws IOException {</span>
+<span class="source-line-no">2587</span><span id="line-2587">          getMaster().getMasterCoprocessorHost().preDeleteTable(tableName);</span>
+<span class="source-line-no">2588</span><span id="line-2588"></span>
+<span class="source-line-no">2589</span><span id="line-2589">          LOG.info(getClientIdAuditPrefix() + " delete " + tableName);</span>
+<span class="source-line-no">2590</span><span id="line-2590"></span>
+<span class="source-line-no">2591</span><span id="line-2591">          // TODO: We can handle/merge duplicate request</span>
+<span class="source-line-no">2592</span><span id="line-2592">          //</span>
+<span class="source-line-no">2593</span><span id="line-2593">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2594</span><span id="line-2594">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2595</span><span id="line-2595">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2596</span><span id="line-2596">          submitProcedure(</span>
+<span class="source-line-no">2597</span><span id="line-2597">            new DeleteTableProcedure(procedureExecutor.getEnvironment(), tableName, latch));</span>
+<span class="source-line-no">2598</span><span id="line-2598">          latch.await();</span>
+<span class="source-line-no">2599</span><span id="line-2599"></span>
+<span class="source-line-no">2600</span><span id="line-2600">          getMaster().getMasterCoprocessorHost().postDeleteTable(tableName);</span>
+<span class="source-line-no">2601</span><span id="line-2601">        }</span>
+<span class="source-line-no">2602</span><span id="line-2602"></span>
+<span class="source-line-no">2603</span><span id="line-2603">        @Override</span>
+<span class="source-line-no">2604</span><span id="line-2604">        protected String getDescription() {</span>
+<span class="source-line-no">2605</span><span id="line-2605">          return "DeleteTableProcedure";</span>
+<span class="source-line-no">2606</span><span id="line-2606">        }</span>
+<span class="source-line-no">2607</span><span id="line-2607">      });</span>
+<span class="source-line-no">2608</span><span id="line-2608">  }</span>
+<span class="source-line-no">2609</span><span id="line-2609"></span>
+<span class="source-line-no">2610</span><span id="line-2610">  @Override</span>
+<span class="source-line-no">2611</span><span id="line-2611">  public long truncateTable(final TableName tableName, final boolean preserveSplits,</span>
+<span class="source-line-no">2612</span><span id="line-2612">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2613</span><span id="line-2613">    checkInitialized();</span>
+<span class="source-line-no">2614</span><span id="line-2614"></span>
+<span class="source-line-no">2615</span><span id="line-2615">    return MasterProcedureUtil</span>
+<span class="source-line-no">2616</span><span id="line-2616">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2617</span><span id="line-2617">        @Override</span>
+<span class="source-line-no">2618</span><span id="line-2618">        protected void run() throws IOException {</span>
+<span class="source-line-no">2619</span><span id="line-2619">          getMaster().getMasterCoprocessorHost().preTruncateTable(tableName);</span>
+<span class="source-line-no">2620</span><span id="line-2620"></span>
+<span class="source-line-no">2621</span><span id="line-2621">          LOG.info(getClientIdAuditPrefix() + " truncate " + tableName);</span>
+<span class="source-line-no">2622</span><span id="line-2622">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
+<span class="source-line-no">2623</span><span id="line-2623">          submitProcedure(new TruncateTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
+<span class="source-line-no">2624</span><span id="line-2624">            preserveSplits, latch));</span>
+<span class="source-line-no">2625</span><span id="line-2625">          latch.await();</span>
+<span class="source-line-no">2626</span><span id="line-2626"></span>
+<span class="source-line-no">2627</span><span id="line-2627">          getMaster().getMasterCoprocessorHost().postTruncateTable(tableName);</span>
+<span class="source-line-no">2628</span><span id="line-2628">        }</span>
+<span class="source-line-no">2629</span><span id="line-2629"></span>
+<span class="source-line-no">2630</span><span id="line-2630">        @Override</span>
+<span class="source-line-no">2631</span><span id="line-2631">        protected String getDescription() {</span>
+<span class="source-line-no">2632</span><span id="line-2632">          return "TruncateTableProcedure";</span>
+<span class="source-line-no">2633</span><span id="line-2633">        }</span>
+<span class="source-line-no">2634</span><span id="line-2634">      });</span>
+<span class="source-line-no">2635</span><span id="line-2635">  }</span>
+<span class="source-line-no">2636</span><span id="line-2636"></span>
+<span class="source-line-no">2637</span><span id="line-2637">  @Override</span>
+<span class="source-line-no">2638</span><span id="line-2638">  public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2639</span><span id="line-2639">    throws IOException {</span>
+<span class="source-line-no">2640</span><span id="line-2640">    checkInitialized();</span>
+<span class="source-line-no">2641</span><span id="line-2641"></span>
+<span class="source-line-no">2642</span><span id="line-2642">    return MasterProcedureUtil</span>
+<span class="source-line-no">2643</span><span id="line-2643">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2644</span><span id="line-2644">        @Override</span>
+<span class="source-line-no">2645</span><span id="line-2645">        protected void run() throws IOException {</span>
+<span class="source-line-no">2646</span><span id="line-2646">          getMaster().getMasterCoprocessorHost().preTruncateRegion(regionInfo);</span>
+<span class="source-line-no">2647</span><span id="line-2647"></span>
+<span class="source-line-no">2648</span><span id="line-2648">          LOG.info(</span>
+<span class="source-line-no">2649</span><span id="line-2649">            getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());</span>
+<span class="source-line-no">2650</span><span id="line-2650"></span>
+<span class="source-line-no">2651</span><span id="line-2651">          // Execute the operation asynchronously</span>
+<span class="source-line-no">2652</span><span id="line-2652">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);</span>
+<span class="source-line-no">2653</span><span id="line-2653">          submitProcedure(</span>
+<span class="source-line-no">2654</span><span id="line-2654">            new TruncateRegionProcedure(procedureExecutor.getEnvironment(), regionInfo, latch));</span>
+<span class="source-line-no">2655</span><span id="line-2655">          latch.await();</span>
+<span class="source-line-no">2656</span><span id="line-2656"></span>
+<span class="source-line-no">2657</span><span id="line-2657">          getMaster().getMasterCoprocessorHost().postTruncateRegion(regionInfo);</span>
+<span class="source-line-no">2658</span><span id="line-2658">        }</span>
+<span class="source-line-no">2659</span><span id="line-2659"></span>
+<span class="source-line-no">2660</span><span id="line-2660">        @Override</span>
+<span class="source-line-no">2661</span><span id="line-2661">        protected String getDescription() {</span>
+<span class="source-line-no">2662</span><span id="line-2662">          return "TruncateRegionProcedure";</span>
+<span class="source-line-no">2663</span><span id="line-2663">        }</span>
+<span class="source-line-no">2664</span><span id="line-2664">      });</span>
+<span class="source-line-no">2665</span><span id="line-2665">  }</span>
+<span class="source-line-no">2666</span><span id="line-2666"></span>
+<span class="source-line-no">2667</span><span id="line-2667">  @Override</span>
+<span class="source-line-no">2668</span><span id="line-2668">  public long addColumn(final TableName tableName, final ColumnFamilyDescriptor column,</span>
+<span class="source-line-no">2669</span><span id="line-2669">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2670</span><span id="line-2670">    checkInitialized();</span>
+<span class="source-line-no">2671</span><span id="line-2671">    checkTableExists(tableName);</span>
+<span class="source-line-no">2672</span><span id="line-2672"></span>
+<span class="source-line-no">2673</span><span id="line-2673">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2674</span><span id="line-2674"></span>
+<span class="source-line-no">2675</span><span id="line-2675">      @Override</span>
+<span class="source-line-no">2676</span><span id="line-2676">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2677</span><span id="line-2677">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2678</span><span id="line-2678">        if (old.hasColumnFamily(column.getName())) {</span>
+<span class="source-line-no">2679</span><span id="line-2679">          throw new InvalidFamilyOperationException("Column family '" + column.getNameAsString()</span>
+<span class="source-line-no">2680</span><span id="line-2680">            + "' in table '" + tableName + "' already exists so cannot be added");</span>
+<span class="source-line-no">2681</span><span id="line-2681">        }</span>
+<span class="source-line-no">2682</span><span id="line-2682"></span>
+<span class="source-line-no">2683</span><span id="line-2683">        return TableDescriptorBuilder.newBuilder(old).setColumnFamily(column).build();</span>
+<span class="source-line-no">2684</span><span id="line-2684">      }</span>
+<span class="source-line-no">2685</span><span id="line-2685">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2686</span><span id="line-2686">  }</span>
+<span class="source-line-no">2687</span><span id="line-2687"></span>
+<span class="source-line-no">2688</span><span id="line-2688">  /**</span>
+<span class="source-line-no">2689</span><span id="line-2689">   * Implement to return TableDescriptor after pre-checks</span>
+<span class="source-line-no">2690</span><span id="line-2690">   */</span>
+<span class="source-line-no">2691</span><span id="line-2691">  protected interface TableDescriptorGetter {</span>
+<span class="source-line-no">2692</span><span id="line-2692">    TableDescriptor get() throws IOException;</span>
+<span class="source-line-no">2693</span><span id="line-2693">  }</span>
+<span class="source-line-no">2694</span><span id="line-2694"></span>
+<span class="source-line-no">2695</span><span id="line-2695">  @Override</span>
+<span class="source-line-no">2696</span><span id="line-2696">  public long modifyColumn(final TableName tableName, final ColumnFamilyDescriptor descriptor,</span>
+<span class="source-line-no">2697</span><span id="line-2697">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2698</span><span id="line-2698">    checkInitialized();</span>
+<span class="source-line-no">2699</span><span id="line-2699">    checkTableExists(tableName);</span>
+<span class="source-line-no">2700</span><span id="line-2700">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2701</span><span id="line-2701"></span>
+<span class="source-line-no">2702</span><span id="line-2702">      @Override</span>
+<span class="source-line-no">2703</span><span id="line-2703">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2704</span><span id="line-2704">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2705</span><span id="line-2705">        if (!old.hasColumnFamily(descriptor.getName())) {</span>
+<span class="source-line-no">2706</span><span id="line-2706">          throw new InvalidFamilyOperationException("Family '" + descriptor.getNameAsString()</span>
+<span class="source-line-no">2707</span><span id="line-2707">            + "' does not exist, so it cannot be modified");</span>
+<span class="source-line-no">2708</span><span id="line-2708">        }</span>
+<span class="source-line-no">2709</span><span id="line-2709"></span>
+<span class="source-line-no">2710</span><span id="line-2710">        return TableDescriptorBuilder.newBuilder(old).modifyColumnFamily(descriptor).build();</span>
+<span class="source-line-no">2711</span><span id="line-2711">      }</span>
+<span class="source-line-no">2712</span><span id="line-2712">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2713</span><span id="line-2713">  }</span>
+<span class="source-line-no">2714</span><span id="line-2714"></span>
+<span class="source-line-no">2715</span><span id="line-2715">  @Override</span>
+<span class="source-line-no">2716</span><span id="line-2716">  public long modifyColumnStoreFileTracker(TableName tableName, byte[] family, String dstSFT,</span>
+<span class="source-line-no">2717</span><span id="line-2717">    long nonceGroup, long nonce) throws IOException {</span>
+<span class="source-line-no">2718</span><span id="line-2718">    checkInitialized();</span>
+<span class="source-line-no">2719</span><span id="line-2719">    return MasterProcedureUtil</span>
+<span class="source-line-no">2720</span><span id="line-2720">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2721</span><span id="line-2721"></span>
+<span class="source-line-no">2722</span><span id="line-2722">        @Override</span>
+<span class="source-line-no">2723</span><span id="line-2723">        protected void run() throws IOException {</span>
+<span class="source-line-no">2724</span><span id="line-2724">          String sft = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2725</span><span id="line-2725">            .preModifyColumnFamilyStoreFileTracker(tableName, family, dstSFT);</span>
+<span class="source-line-no">2726</span><span id="line-2726">          LOG.info("{} modify column {} store file tracker of table {} to {}",</span>
+<span class="source-line-no">2727</span><span id="line-2727">            getClientIdAuditPrefix(), Bytes.toStringBinary(family), tableName, sft);</span>
+<span class="source-line-no">2728</span><span id="line-2728">          submitProcedure(new ModifyColumnFamilyStoreFileTrackerProcedure(</span>
+<span class="source-line-no">2729</span><span id="line-2729">            procedureExecutor.getEnvironment(), tableName, family, sft));</span>
+<span class="source-line-no">2730</span><span id="line-2730">          getMaster().getMasterCoprocessorHost().postModifyColumnFamilyStoreFileTracker(tableName,</span>
+<span class="source-line-no">2731</span><span id="line-2731">            family, dstSFT);</span>
+<span class="source-line-no">2732</span><span id="line-2732">        }</span>
+<span class="source-line-no">2733</span><span id="line-2733"></span>
+<span class="source-line-no">2734</span><span id="line-2734">        @Override</span>
+<span class="source-line-no">2735</span><span id="line-2735">        protected String getDescription() {</span>
+<span class="source-line-no">2736</span><span id="line-2736">          return "ModifyColumnFamilyStoreFileTrackerProcedure";</span>
+<span class="source-line-no">2737</span><span id="line-2737">        }</span>
+<span class="source-line-no">2738</span><span id="line-2738">      });</span>
+<span class="source-line-no">2739</span><span id="line-2739">  }</span>
+<span class="source-line-no">2740</span><span id="line-2740"></span>
+<span class="source-line-no">2741</span><span id="line-2741">  @Override</span>
+<span class="source-line-no">2742</span><span id="line-2742">  public long deleteColumn(final TableName tableName, final byte[] columnName,</span>
+<span class="source-line-no">2743</span><span id="line-2743">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">2744</span><span id="line-2744">    checkInitialized();</span>
+<span class="source-line-no">2745</span><span id="line-2745">    checkTableExists(tableName);</span>
+<span class="source-line-no">2746</span><span id="line-2746"></span>
+<span class="source-line-no">2747</span><span id="line-2747">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
 <span class="source-line-no">2748</span><span id="line-2748"></span>
-<span class="source-line-no">2749</span><span id="line-2749">        if (!old.hasColumnFamily(columnName)) {</span>
-<span class="source-line-no">2750</span><span id="line-2750">          throw new InvalidFamilyOperationException(</span>
-<span class="source-line-no">2751</span><span id="line-2751">            "Family '" + Bytes.toString(columnName) + "' does not exist, so it cannot be deleted");</span>
-<span class="source-line-no">2752</span><span id="line-2752">        }</span>
-<span class="source-line-no">2753</span><span id="line-2753">        if (old.getColumnFamilyCount() == 1) {</span>
-<span class="source-line-no">2754</span><span id="line-2754">          throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName)</span>
-<span class="source-line-no">2755</span><span id="line-2755">            + "' is the only column family in the table, so it cannot be deleted");</span>
+<span class="source-line-no">2749</span><span id="line-2749">      @Override</span>
+<span class="source-line-no">2750</span><span id="line-2750">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2751</span><span id="line-2751">        TableDescriptor old = getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2752</span><span id="line-2752"></span>
+<span class="source-line-no">2753</span><span id="line-2753">        if (!old.hasColumnFamily(columnName)) {</span>
+<span class="source-line-no">2754</span><span id="line-2754">          throw new InvalidFamilyOperationException(</span>
+<span class="source-line-no">2755</span><span id="line-2755">            "Family '" + Bytes.toString(columnName) + "' does not exist, so it cannot be deleted");</span>
 <span class="source-line-no">2756</span><span id="line-2756">        }</span>
-<span class="source-line-no">2757</span><span id="line-2757">        return TableDescriptorBuilder.newBuilder(old).removeColumnFamily(columnName).build();</span>
-<span class="source-line-no">2758</span><span id="line-2758">      }</span>
-<span class="source-line-no">2759</span><span id="line-2759">    }, nonceGroup, nonce, true);</span>
-<span class="source-line-no">2760</span><span id="line-2760">  }</span>
-<span class="source-line-no">2761</span><span id="line-2761"></span>
-<span class="source-line-no">2762</span><span id="line-2762">  @Override</span>
-<span class="source-line-no">2763</span><span id="line-2763">  public long enableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2764</span><span id="line-2764">    throws IOException {</span>
-<span class="source-line-no">2765</span><span id="line-2765">    checkInitialized();</span>
-<span class="source-line-no">2766</span><span id="line-2766"></span>
-<span class="source-line-no">2767</span><span id="line-2767">    return MasterProcedureUtil</span>
-<span class="source-line-no">2768</span><span id="line-2768">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2769</span><span id="line-2769">        @Override</span>
-<span class="source-line-no">2770</span><span id="line-2770">        protected void run() throws IOException {</span>
-<span class="source-line-no">2771</span><span id="line-2771">          getMaster().getMasterCoprocessorHost().preEnableTable(tableName);</span>
-<span class="source-line-no">2772</span><span id="line-2772"></span>
-<span class="source-line-no">2773</span><span id="line-2773">          // Normally, it would make sense for this authorization check to exist inside</span>
-<span class="source-line-no">2774</span><span id="line-2774">          // AccessController, but because the authorization check is done based on internal state</span>
-<span class="source-line-no">2775</span><span id="line-2775">          // (rather than explicit permissions) we'll do the check here instead of in the</span>
-<span class="source-line-no">2776</span><span id="line-2776">          // coprocessor.</span>
-<span class="source-line-no">2777</span><span id="line-2777">          MasterQuotaManager quotaManager = getMasterQuotaManager();</span>
-<span class="source-line-no">2778</span><span id="line-2778">          if (quotaManager != null) {</span>
-<span class="source-line-no">2779</span><span id="line-2779">            if (quotaManager.isQuotaInitialized()) {</span>
-<span class="source-line-no">2780</span><span id="line-2780">              // skip checking quotas for system tables, see:</span>
-<span class="source-line-no">2781</span><span id="line-2781">              // https://issues.apache.org/jira/browse/HBASE-28183</span>
-<span class="source-line-no">2782</span><span id="line-2782">              if (!tableName.isSystemTable()) {</span>
-<span class="source-line-no">2783</span><span id="line-2783">                SpaceQuotaSnapshot currSnapshotOfTable =</span>
-<span class="source-line-no">2784</span><span id="line-2784">                  QuotaTableUtil.getCurrentSnapshotFromQuotaTable(getConnection(), tableName);</span>
-<span class="source-line-no">2785</span><span id="line-2785">                if (currSnapshotOfTable != null) {</span>
-<span class="source-line-no">2786</span><span id="line-2786">                  SpaceQuotaStatus quotaStatus = currSnapshotOfTable.getQuotaStatus();</span>
-<span class="source-line-no">2787</span><span id="line-2787">                  if (</span>
-<span class="source-line-no">2788</span><span id="line-2788">                    quotaStatus.isInViolation()</span>
-<span class="source-line-no">2789</span><span id="line-2789">                      &amp;&amp; SpaceViolationPolicy.DISABLE == quotaStatus.getPolicy().orElse(null)</span>
-<span class="source-line-no">2790</span><span id="line-2790">                  ) {</span>
-<span class="source-line-no">2791</span><span id="line-2791">                    throw new AccessDeniedException("Enabling the table '" + tableName</span>
-<span class="source-line-no">2792</span><span id="line-2792">                      + "' is disallowed due to a violated space quota.");</span>
-<span class="source-line-no">2793</span><span id="line-2793">                  }</span>
-<span class="source-line-no">2794</span><span id="line-2794">                }</span>
-<span class="source-line-no">2795</span><span id="line-2795">              }</span>
-<span class="source-line-no">2796</span><span id="line-2796">            } else if (LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">2797</span><span id="line-2797">              LOG</span>
-<span class="source-line-no">2798</span><span id="line-2798">                .trace("Unable to check for space quotas as the MasterQuotaManager is not enabled");</span>
-<span class="source-line-no">2799</span><span id="line-2799">            }</span>
-<span class="source-line-no">2800</span><span id="line-2800">          }</span>
-<span class="source-line-no">2801</span><span id="line-2801"></span>
-<span class="source-line-no">2802</span><span id="line-2802">          LOG.info(getClientIdAuditPrefix() + " enable " + tableName);</span>
-<span class="source-line-no">2803</span><span id="line-2803"></span>
-<span class="source-line-no">2804</span><span id="line-2804">          // Execute the operation asynchronously - client will check the progress of the operation</span>
-<span class="source-line-no">2805</span><span id="line-2805">          // In case the request is from a &lt;1.1 client before returning,</span>
-<span class="source-line-no">2806</span><span id="line-2806">          // we want to make sure that the table is prepared to be</span>
-<span class="source-line-no">2807</span><span id="line-2807">          // enabled (the table is locked and the table state is set).</span>
-<span class="source-line-no">2808</span><span id="line-2808">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
-<span class="source-line-no">2809</span><span id="line-2809">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createLatch();</span>
-<span class="source-line-no">2810</span><span id="line-2810">          submitProcedure(</span>
-<span class="source-line-no">2811</span><span id="line-2811">            new EnableTableProcedure(procedureExecutor.getEnvironment(), tableName, prepareLatch));</span>
-<span class="source-line-no">2812</span><span id="line-2812">          prepareLatch.await();</span>
-<span class="source-line-no">2813</span><span id="line-2813"></span>
-<span class="source-line-no">2814</span><span id="line-2814">          getMaster().getMasterCoprocessorHost().postEnableTable(tableName);</span>
-<span class="source-line-no">2815</span><span id="line-2815">        }</span>
-<span class="source-line-no">2816</span><span id="line-2816"></span>
-<span class="source-line-no">2817</span><span id="line-2817">        @Override</span>
-<span class="source-line-no">2818</span><span id="line-2818">        protected String getDescription() {</span>
-<span class="source-line-no">2819</span><span id="line-2819">          return "EnableTableProcedure";</span>
-<span class="source-line-no">2820</span><span id="line-2820">        }</span>
-<span class="source-line-no">2821</span><span id="line-2821">      });</span>
-<span class="source-line-no">2822</span><span id="line-2822">  }</span>
-<span class="source-line-no">2823</span><span id="line-2823"></span>
-<span class="source-line-no">2824</span><span id="line-2824">  @Override</span>
-<span class="source-line-no">2825</span><span id="line-2825">  public long disableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">2826</span><span id="line-2826">    throws IOException {</span>
-<span class="source-line-no">2827</span><span id="line-2827">    checkInitialized();</span>
-<span class="source-line-no">2828</span><span id="line-2828"></span>
-<span class="source-line-no">2829</span><span id="line-2829">    return MasterProcedureUtil</span>
-<span class="source-line-no">2830</span><span id="line-2830">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2831</span><span id="line-2831">        @Override</span>
-<span class="source-line-no">2832</span><span id="line-2832">        protected void run() throws IOException {</span>
-<span class="source-line-no">2833</span><span id="line-2833">          getMaster().getMasterCoprocessorHost().preDisableTable(tableName);</span>
-<span class="source-line-no">2834</span><span id="line-2834"></span>
-<span class="source-line-no">2835</span><span id="line-2835">          LOG.info(getClientIdAuditPrefix() + " disable " + tableName);</span>
-<span class="source-line-no">2836</span><span id="line-2836"></span>
-<span class="source-line-no">2837</span><span id="line-2837">          // Execute the operation asynchronously - client will check the progress of the operation</span>
-<span class="source-line-no">2838</span><span id="line-2838">          // In case the request is from a &lt;1.1 client before returning,</span>
-<span class="source-line-no">2839</span><span id="line-2839">          // we want to make sure that the table is prepared to be</span>
-<span class="source-line-no">2840</span><span id="line-2840">          // enabled (the table is locked and the table state is set).</span>
-<span class="source-line-no">2841</span><span id="line-2841">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
-<span class="source-line-no">2842</span><span id="line-2842">          //</span>
-<span class="source-line-no">2843</span><span id="line-2843">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2844</span><span id="line-2844">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2845</span><span id="line-2845">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2846</span><span id="line-2846">          submitProcedure(new DisableTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
-<span class="source-line-no">2847</span><span id="line-2847">            false, prepareLatch));</span>
-<span class="source-line-no">2848</span><span id="line-2848">          prepareLatch.await();</span>
-<span class="source-line-no">2849</span><span id="line-2849"></span>
-<span class="source-line-no">2850</span><span id="line-2850">          getMaster().getMasterCoprocessorHost().postDisableTable(tableName);</span>
-<span class="source-line-no">2851</span><span id="line-2851">        }</span>
-<span class="source-line-no">2852</span><span id="line-2852"></span>
-<span class="source-line-no">2853</span><span id="line-2853">        @Override</span>
-<span class="source-line-no">2854</span><span id="line-2854">        protected String getDescription() {</span>
-<span class="source-line-no">2855</span><span id="line-2855">          return "DisableTableProcedure";</span>
-<span class="source-line-no">2856</span><span id="line-2856">        }</span>
-<span class="source-line-no">2857</span><span id="line-2857">      });</span>
-<span class="source-line-no">2858</span><span id="line-2858">  }</span>
-<span class="source-line-no">2859</span><span id="line-2859"></span>
-<span class="source-line-no">2860</span><span id="line-2860">  private long modifyTable(final TableName tableName,</span>
-<span class="source-line-no">2861</span><span id="line-2861">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
-<span class="source-line-no">2862</span><span id="line-2862">    final boolean shouldCheckDescriptor) throws IOException {</span>
-<span class="source-line-no">2863</span><span id="line-2863">    return modifyTable(tableName, newDescriptorGetter, nonceGroup, nonce, shouldCheckDescriptor,</span>
-<span class="source-line-no">2864</span><span id="line-2864">      true);</span>
-<span class="source-line-no">2865</span><span id="line-2865">  }</span>
-<span class="source-line-no">2866</span><span id="line-2866"></span>
-<span class="source-line-no">2867</span><span id="line-2867">  private long modifyTable(final TableName tableName,</span>
-<span class="source-line-no">2868</span><span id="line-2868">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
-<span class="source-line-no">2869</span><span id="line-2869">    final boolean shouldCheckDescriptor, final boolean reopenRegions) throws IOException {</span>
-<span class="source-line-no">2870</span><span id="line-2870">    return MasterProcedureUtil</span>
-<span class="source-line-no">2871</span><span id="line-2871">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2872</span><span id="line-2872">        @Override</span>
-<span class="source-line-no">2873</span><span id="line-2873">        protected void run() throws IOException {</span>
-<span class="source-line-no">2874</span><span id="line-2874">          TableDescriptor oldDescriptor = getMaster().getTableDescriptors().get(tableName);</span>
-<span class="source-line-no">2875</span><span id="line-2875">          TableDescriptor newDescriptor = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2876</span><span id="line-2876">            .preModifyTable(tableName, oldDescriptor, newDescriptorGetter.get());</span>
-<span class="source-line-no">2877</span><span id="line-2877">          TableDescriptorChecker.sanityCheck(conf, newDescriptor);</span>
-<span class="source-line-no">2878</span><span id="line-2878">          LOG.info("{} modify table {} from {} to {}", getClientIdAuditPrefix(), tableName,</span>
-<span class="source-line-no">2879</span><span id="line-2879">            oldDescriptor, newDescriptor);</span>
-<span class="source-line-no">2880</span><span id="line-2880"></span>
-<span class="source-line-no">2881</span><span id="line-2881">          // Execute the operation synchronously - wait for the operation completes before</span>
-<span class="source-line-no">2882</span><span id="line-2882">          // continuing.</span>
-<span class="source-line-no">2883</span><span id="line-2883">          //</span>
-<span class="source-line-no">2884</span><span id="line-2884">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">2885</span><span id="line-2885">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">2886</span><span id="line-2886">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">2887</span><span id="line-2887">          submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),</span>
-<span class="source-line-no">2888</span><span id="line-2888">            newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, reopenRegions));</span>
-<span class="source-line-no">2889</span><span id="line-2889">          latch.await();</span>
-<span class="source-line-no">2890</span><span id="line-2890"></span>
-<span class="source-line-no">2891</span><span id="line-2891">          getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,</span>
-<span class="source-line-no">2892</span><span id="line-2892">            newDescriptor);</span>
-<span class="source-line-no">2893</span><span id="line-2893">        }</span>
+<span class="source-line-no">2757</span><span id="line-2757">        if (old.getColumnFamilyCount() == 1) {</span>
+<span class="source-line-no">2758</span><span id="line-2758">          throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName)</span>
+<span class="source-line-no">2759</span><span id="line-2759">            + "' is the only column family in the table, so it cannot be deleted");</span>
+<span class="source-line-no">2760</span><span id="line-2760">        }</span>
+<span class="source-line-no">2761</span><span id="line-2761">        return TableDescriptorBuilder.newBuilder(old).removeColumnFamily(columnName).build();</span>
+<span class="source-line-no">2762</span><span id="line-2762">      }</span>
+<span class="source-line-no">2763</span><span id="line-2763">    }, nonceGroup, nonce, true);</span>
+<span class="source-line-no">2764</span><span id="line-2764">  }</span>
+<span class="source-line-no">2765</span><span id="line-2765"></span>
+<span class="source-line-no">2766</span><span id="line-2766">  @Override</span>
+<span class="source-line-no">2767</span><span id="line-2767">  public long enableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2768</span><span id="line-2768">    throws IOException {</span>
+<span class="source-line-no">2769</span><span id="line-2769">    checkInitialized();</span>
+<span class="source-line-no">2770</span><span id="line-2770"></span>
+<span class="source-line-no">2771</span><span id="line-2771">    return MasterProcedureUtil</span>
+<span class="source-line-no">2772</span><span id="line-2772">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2773</span><span id="line-2773">        @Override</span>
+<span class="source-line-no">2774</span><span id="line-2774">        protected void run() throws IOException {</span>
+<span class="source-line-no">2775</span><span id="line-2775">          getMaster().getMasterCoprocessorHost().preEnableTable(tableName);</span>
+<span class="source-line-no">2776</span><span id="line-2776"></span>
+<span class="source-line-no">2777</span><span id="line-2777">          // Normally, it would make sense for this authorization check to exist inside</span>
+<span class="source-line-no">2778</span><span id="line-2778">          // AccessController, but because the authorization check is done based on internal state</span>
+<span class="source-line-no">2779</span><span id="line-2779">          // (rather than explicit permissions) we'll do the check here instead of in the</span>
+<span class="source-line-no">2780</span><span id="line-2780">          // coprocessor.</span>
+<span class="source-line-no">2781</span><span id="line-2781">          MasterQuotaManager quotaManager = getMasterQuotaManager();</span>
+<span class="source-line-no">2782</span><span id="line-2782">          if (quotaManager != null) {</span>
+<span class="source-line-no">2783</span><span id="line-2783">            if (quotaManager.isQuotaInitialized()) {</span>
+<span class="source-line-no">2784</span><span id="line-2784">              // skip checking quotas for system tables, see:</span>
+<span class="source-line-no">2785</span><span id="line-2785">              // https://issues.apache.org/jira/browse/HBASE-28183</span>
+<span class="source-line-no">2786</span><span id="line-2786">              if (!tableName.isSystemTable()) {</span>
+<span class="source-line-no">2787</span><span id="line-2787">                SpaceQuotaSnapshot currSnapshotOfTable =</span>
+<span class="source-line-no">2788</span><span id="line-2788">                  QuotaTableUtil.getCurrentSnapshotFromQuotaTable(getConnection(), tableName);</span>
+<span class="source-line-no">2789</span><span id="line-2789">                if (currSnapshotOfTable != null) {</span>
+<span class="source-line-no">2790</span><span id="line-2790">                  SpaceQuotaStatus quotaStatus = currSnapshotOfTable.getQuotaStatus();</span>
+<span class="source-line-no">2791</span><span id="line-2791">                  if (</span>
+<span class="source-line-no">2792</span><span id="line-2792">                    quotaStatus.isInViolation()</span>
+<span class="source-line-no">2793</span><span id="line-2793">                      &amp;&amp; SpaceViolationPolicy.DISABLE == quotaStatus.getPolicy().orElse(null)</span>
+<span class="source-line-no">2794</span><span id="line-2794">                  ) {</span>
+<span class="source-line-no">2795</span><span id="line-2795">                    throw new AccessDeniedException("Enabling the table '" + tableName</span>
+<span class="source-line-no">2796</span><span id="line-2796">                      + "' is disallowed due to a violated space quota.");</span>
+<span class="source-line-no">2797</span><span id="line-2797">                  }</span>
+<span class="source-line-no">2798</span><span id="line-2798">                }</span>
+<span class="source-line-no">2799</span><span id="line-2799">              }</span>
+<span class="source-line-no">2800</span><span id="line-2800">            } else if (LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">2801</span><span id="line-2801">              LOG</span>
+<span class="source-line-no">2802</span><span id="line-2802">                .trace("Unable to check for space quotas as the MasterQuotaManager is not enabled");</span>
+<span class="source-line-no">2803</span><span id="line-2803">            }</span>
+<span class="source-line-no">2804</span><span id="line-2804">          }</span>
+<span class="source-line-no">2805</span><span id="line-2805"></span>
+<span class="source-line-no">2806</span><span id="line-2806">          LOG.info(getClientIdAuditPrefix() + " enable " + tableName);</span>
+<span class="source-line-no">2807</span><span id="line-2807"></span>
+<span class="source-line-no">2808</span><span id="line-2808">          // Execute the operation asynchronously - client will check the progress of the operation</span>
+<span class="source-line-no">2809</span><span id="line-2809">          // In case the request is from a &lt;1.1 client before returning,</span>
+<span class="source-line-no">2810</span><span id="line-2810">          // we want to make sure that the table is prepared to be</span>
+<span class="source-line-no">2811</span><span id="line-2811">          // enabled (the table is locked and the table state is set).</span>
+<span class="source-line-no">2812</span><span id="line-2812">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
+<span class="source-line-no">2813</span><span id="line-2813">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createLatch();</span>
+<span class="source-line-no">2814</span><span id="line-2814">          submitProcedure(</span>
+<span class="source-line-no">2815</span><span id="line-2815">            new EnableTableProcedure(procedureExecutor.getEnvironment(), tableName, prepareLatch));</span>
+<span class="source-line-no">2816</span><span id="line-2816">          prepareLatch.await();</span>
+<span class="source-line-no">2817</span><span id="line-2817"></span>
+<span class="source-line-no">2818</span><span id="line-2818">          getMaster().getMasterCoprocessorHost().postEnableTable(tableName);</span>
+<span class="source-line-no">2819</span><span id="line-2819">        }</span>
+<span class="source-line-no">2820</span><span id="line-2820"></span>
+<span class="source-line-no">2821</span><span id="line-2821">        @Override</span>
+<span class="source-line-no">2822</span><span id="line-2822">        protected String getDescription() {</span>
+<span class="source-line-no">2823</span><span id="line-2823">          return "EnableTableProcedure";</span>
+<span class="source-line-no">2824</span><span id="line-2824">        }</span>
+<span class="source-line-no">2825</span><span id="line-2825">      });</span>
+<span class="source-line-no">2826</span><span id="line-2826">  }</span>
+<span class="source-line-no">2827</span><span id="line-2827"></span>
+<span class="source-line-no">2828</span><span id="line-2828">  @Override</span>
+<span class="source-line-no">2829</span><span id="line-2829">  public long disableTable(final TableName tableName, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">2830</span><span id="line-2830">    throws IOException {</span>
+<span class="source-line-no">2831</span><span id="line-2831">    checkInitialized();</span>
+<span class="source-line-no">2832</span><span id="line-2832"></span>
+<span class="source-line-no">2833</span><span id="line-2833">    return MasterProcedureUtil</span>
+<span class="source-line-no">2834</span><span id="line-2834">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2835</span><span id="line-2835">        @Override</span>
+<span class="source-line-no">2836</span><span id="line-2836">        protected void run() throws IOException {</span>
+<span class="source-line-no">2837</span><span id="line-2837">          getMaster().getMasterCoprocessorHost().preDisableTable(tableName);</span>
+<span class="source-line-no">2838</span><span id="line-2838"></span>
+<span class="source-line-no">2839</span><span id="line-2839">          LOG.info(getClientIdAuditPrefix() + " disable " + tableName);</span>
+<span class="source-line-no">2840</span><span id="line-2840"></span>
+<span class="source-line-no">2841</span><span id="line-2841">          // Execute the operation asynchronously - client will check the progress of the operation</span>
+<span class="source-line-no">2842</span><span id="line-2842">          // In case the request is from a &lt;1.1 client before returning,</span>
+<span class="source-line-no">2843</span><span id="line-2843">          // we want to make sure that the table is prepared to be</span>
+<span class="source-line-no">2844</span><span id="line-2844">          // enabled (the table is locked and the table state is set).</span>
+<span class="source-line-no">2845</span><span id="line-2845">          // Note: if the procedure throws exception, we will catch it and rethrow.</span>
+<span class="source-line-no">2846</span><span id="line-2846">          //</span>
+<span class="source-line-no">2847</span><span id="line-2847">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2848</span><span id="line-2848">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2849</span><span id="line-2849">          final ProcedurePrepareLatch prepareLatch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2850</span><span id="line-2850">          submitProcedure(new DisableTableProcedure(procedureExecutor.getEnvironment(), tableName,</span>
+<span class="source-line-no">2851</span><span id="line-2851">            false, prepareLatch));</span>
+<span class="source-line-no">2852</span><span id="line-2852">          prepareLatch.await();</span>
+<span class="source-line-no">2853</span><span id="line-2853"></span>
+<span class="source-line-no">2854</span><span id="line-2854">          getMaster().getMasterCoprocessorHost().postDisableTable(tableName);</span>
+<span class="source-line-no">2855</span><span id="line-2855">        }</span>
+<span class="source-line-no">2856</span><span id="line-2856"></span>
+<span class="source-line-no">2857</span><span id="line-2857">        @Override</span>
+<span class="source-line-no">2858</span><span id="line-2858">        protected String getDescription() {</span>
+<span class="source-line-no">2859</span><span id="line-2859">          return "DisableTableProcedure";</span>
+<span class="source-line-no">2860</span><span id="line-2860">        }</span>
+<span class="source-line-no">2861</span><span id="line-2861">      });</span>
+<span class="source-line-no">2862</span><span id="line-2862">  }</span>
+<span class="source-line-no">2863</span><span id="line-2863"></span>
+<span class="source-line-no">2864</span><span id="line-2864">  private long modifyTable(final TableName tableName,</span>
+<span class="source-line-no">2865</span><span id="line-2865">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
+<span class="source-line-no">2866</span><span id="line-2866">    final boolean shouldCheckDescriptor) throws IOException {</span>
+<span class="source-line-no">2867</span><span id="line-2867">    return modifyTable(tableName, newDescriptorGetter, nonceGroup, nonce, shouldCheckDescriptor,</span>
+<span class="source-line-no">2868</span><span id="line-2868">      true);</span>
+<span class="source-line-no">2869</span><span id="line-2869">  }</span>
+<span class="source-line-no">2870</span><span id="line-2870"></span>
+<span class="source-line-no">2871</span><span id="line-2871">  private long modifyTable(final TableName tableName,</span>
+<span class="source-line-no">2872</span><span id="line-2872">    final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,</span>
+<span class="source-line-no">2873</span><span id="line-2873">    final boolean shouldCheckDescriptor, final boolean reopenRegions) throws IOException {</span>
+<span class="source-line-no">2874</span><span id="line-2874">    return MasterProcedureUtil</span>
+<span class="source-line-no">2875</span><span id="line-2875">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2876</span><span id="line-2876">        @Override</span>
+<span class="source-line-no">2877</span><span id="line-2877">        protected void run() throws IOException {</span>
+<span class="source-line-no">2878</span><span id="line-2878">          TableDescriptor oldDescriptor = getMaster().getTableDescriptors().get(tableName);</span>
+<span class="source-line-no">2879</span><span id="line-2879">          TableDescriptor newDescriptor = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2880</span><span id="line-2880">            .preModifyTable(tableName, oldDescriptor, newDescriptorGetter.get());</span>
+<span class="source-line-no">2881</span><span id="line-2881">          TableDescriptorChecker.sanityCheck(conf, newDescriptor);</span>
+<span class="source-line-no">2882</span><span id="line-2882">          LOG.info("{} modify table {} from {} to {}", getClientIdAuditPrefix(), tableName,</span>
+<span class="source-line-no">2883</span><span id="line-2883">            oldDescriptor, newDescriptor);</span>
+<span class="source-line-no">2884</span><span id="line-2884"></span>
+<span class="source-line-no">2885</span><span id="line-2885">          // Execute the operation synchronously - wait for the operation completes before</span>
+<span class="source-line-no">2886</span><span id="line-2886">          // continuing.</span>
+<span class="source-line-no">2887</span><span id="line-2887">          //</span>
+<span class="source-line-no">2888</span><span id="line-2888">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">2889</span><span id="line-2889">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">2890</span><span id="line-2890">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">2891</span><span id="line-2891">          submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),</span>
+<span class="source-line-no">2892</span><span id="line-2892">            newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, reopenRegions));</span>
+<span class="source-line-no">2893</span><span id="line-2893">          latch.await();</span>
 <span class="source-line-no">2894</span><span id="line-2894"></span>
-<span class="source-line-no">2895</span><span id="line-2895">        @Override</span>
-<span class="source-line-no">2896</span><span id="line-2896">        protected String getDescription() {</span>
-<span class="source-line-no">2897</span><span id="line-2897">          return "ModifyTableProcedure";</span>
-<span class="source-line-no">2898</span><span id="line-2898">        }</span>
-<span class="source-line-no">2899</span><span id="line-2899">      });</span>
-<span class="source-line-no">2900</span><span id="line-2900"></span>
-<span class="source-line-no">2901</span><span id="line-2901">  }</span>
-<span class="source-line-no">2902</span><span id="line-2902"></span>
-<span class="source-line-no">2903</span><span id="line-2903">  @Override</span>
-<span class="source-line-no">2904</span><span id="line-2904">  public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,</span>
-<span class="source-line-no">2905</span><span id="line-2905">    final long nonceGroup, final long nonce, final boolean reopenRegions) throws IOException {</span>
-<span class="source-line-no">2906</span><span id="line-2906">    checkInitialized();</span>
-<span class="source-line-no">2907</span><span id="line-2907">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
-<span class="source-line-no">2908</span><span id="line-2908">      @Override</span>
-<span class="source-line-no">2909</span><span id="line-2909">      public TableDescriptor get() throws IOException {</span>
-<span class="source-line-no">2910</span><span id="line-2910">        return newDescriptor;</span>
-<span class="source-line-no">2911</span><span id="line-2911">      }</span>
-<span class="source-line-no">2912</span><span id="line-2912">    }, nonceGroup, nonce, false, reopenRegions);</span>
-<span class="source-line-no">2913</span><span id="line-2913"></span>
-<span class="source-line-no">2914</span><span id="line-2914">  }</span>
-<span class="source-line-no">2915</span><span id="line-2915"></span>
-<span class="source-line-no">2916</span><span id="line-2916">  @Override</span>
-<span class="source-line-no">2917</span><span id="line-2917">  public long modifyTableStoreFileTracker(TableName tableName, String dstSFT, long nonceGroup,</span>
-<span class="source-line-no">2918</span><span id="line-2918">    long nonce) throws IOException {</span>
-<span class="source-line-no">2919</span><span id="line-2919">    checkInitialized();</span>
-<span class="source-line-no">2920</span><span id="line-2920">    return MasterProcedureUtil</span>
-<span class="source-line-no">2921</span><span id="line-2921">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2922</span><span id="line-2922"></span>
-<span class="source-line-no">2923</span><span id="line-2923">        @Override</span>
-<span class="source-line-no">2924</span><span id="line-2924">        protected void run() throws IOException {</span>
-<span class="source-line-no">2925</span><span id="line-2925">          String sft = getMaster().getMasterCoprocessorHost()</span>
-<span class="source-line-no">2926</span><span id="line-2926">            .preModifyTableStoreFileTracker(tableName, dstSFT);</span>
-<span class="source-line-no">2927</span><span id="line-2927">          LOG.info("{} modify table store file tracker of table {} to {}", getClientIdAuditPrefix(),</span>
-<span class="source-line-no">2928</span><span id="line-2928">            tableName, sft);</span>
-<span class="source-line-no">2929</span><span id="line-2929">          submitProcedure(new ModifyTableStoreFileTrackerProcedure(</span>
-<span class="source-line-no">2930</span><span id="line-2930">            procedureExecutor.getEnvironment(), tableName, sft));</span>
-<span class="source-line-no">2931</span><span id="line-2931">          getMaster().getMasterCoprocessorHost().postModifyTableStoreFileTracker(tableName, sft);</span>
-<span class="source-line-no">2932</span><span id="line-2932">        }</span>
-<span class="source-line-no">2933</span><span id="line-2933"></span>
-<span class="source-line-no">2934</span><span id="line-2934">        @Override</span>
-<span class="source-line-no">2935</span><span id="line-2935">        protected String getDescription() {</span>
-<span class="source-line-no">2936</span><span id="line-2936">          return "ModifyTableStoreFileTrackerProcedure";</span>
-<span class="source-line-no">2937</span><span id="line-2937">        }</span>
-<span class="source-line-no">2938</span><span id="line-2938">      });</span>
-<span class="source-line-no">2939</span><span id="line-2939">  }</span>
-<span class="source-line-no">2940</span><span id="line-2940"></span>
-<span class="source-line-no">2941</span><span id="line-2941">  public long restoreSnapshot(final SnapshotDescription snapshotDesc, final long nonceGroup,</span>
-<span class="source-line-no">2942</span><span id="line-2942">    final long nonce, final boolean restoreAcl, final String customSFT) throws IOException {</span>
-<span class="source-line-no">2943</span><span id="line-2943">    checkInitialized();</span>
-<span class="source-line-no">2944</span><span id="line-2944">    getSnapshotManager().checkSnapshotSupport();</span>
-<span class="source-line-no">2945</span><span id="line-2945"></span>
-<span class="source-line-no">2946</span><span id="line-2946">    // Ensure namespace exists. Will throw exception if non-known NS.</span>
-<span class="source-line-no">2947</span><span id="line-2947">    final TableName dstTable = TableName.valueOf(snapshotDesc.getTable());</span>
-<span class="source-line-no">2948</span><span id="line-2948">    getClusterSchema().getNamespace(dstTable.getNamespaceAsString());</span>
+<span class="source-line-no">2895</span><span id="line-2895">          getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,</span>
+<span class="source-line-no">2896</span><span id="line-2896">            newDescriptor);</span>
+<span class="source-line-no">2897</span><span id="line-2897">        }</span>
+<span class="source-line-no">2898</span><span id="line-2898"></span>
+<span class="source-line-no">2899</span><span id="line-2899">        @Override</span>
+<span class="source-line-no">2900</span><span id="line-2900">        protected String getDescription() {</span>
+<span class="source-line-no">2901</span><span id="line-2901">          return "ModifyTableProcedure";</span>
+<span class="source-line-no">2902</span><span id="line-2902">        }</span>
+<span class="source-line-no">2903</span><span id="line-2903">      });</span>
+<span class="source-line-no">2904</span><span id="line-2904"></span>
+<span class="source-line-no">2905</span><span id="line-2905">  }</span>
+<span class="source-line-no">2906</span><span id="line-2906"></span>
+<span class="source-line-no">2907</span><span id="line-2907">  @Override</span>
+<span class="source-line-no">2908</span><span id="line-2908">  public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,</span>
+<span class="source-line-no">2909</span><span id="line-2909">    final long nonceGroup, final long nonce, final boolean reopenRegions) throws IOException {</span>
+<span class="source-line-no">2910</span><span id="line-2910">    checkInitialized();</span>
+<span class="source-line-no">2911</span><span id="line-2911">    return modifyTable(tableName, new TableDescriptorGetter() {</span>
+<span class="source-line-no">2912</span><span id="line-2912">      @Override</span>
+<span class="source-line-no">2913</span><span id="line-2913">      public TableDescriptor get() throws IOException {</span>
+<span class="source-line-no">2914</span><span id="line-2914">        return newDescriptor;</span>
+<span class="source-line-no">2915</span><span id="line-2915">      }</span>
+<span class="source-line-no">2916</span><span id="line-2916">    }, nonceGroup, nonce, false, reopenRegions);</span>
+<span class="source-line-no">2917</span><span id="line-2917"></span>
+<span class="source-line-no">2918</span><span id="line-2918">  }</span>
+<span class="source-line-no">2919</span><span id="line-2919"></span>
+<span class="source-line-no">2920</span><span id="line-2920">  @Override</span>
+<span class="source-line-no">2921</span><span id="line-2921">  public long modifyTableStoreFileTracker(TableName tableName, String dstSFT, long nonceGroup,</span>
+<span class="source-line-no">2922</span><span id="line-2922">    long nonce) throws IOException {</span>
+<span class="source-line-no">2923</span><span id="line-2923">    checkInitialized();</span>
+<span class="source-line-no">2924</span><span id="line-2924">    return MasterProcedureUtil</span>
+<span class="source-line-no">2925</span><span id="line-2925">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2926</span><span id="line-2926"></span>
+<span class="source-line-no">2927</span><span id="line-2927">        @Override</span>
+<span class="source-line-no">2928</span><span id="line-2928">        protected void run() throws IOException {</span>
+<span class="source-line-no">2929</span><span id="line-2929">          String sft = getMaster().getMasterCoprocessorHost()</span>
+<span class="source-line-no">2930</span><span id="line-2930">            .preModifyTableStoreFileTracker(tableName, dstSFT);</span>
+<span class="source-line-no">2931</span><span id="line-2931">          LOG.info("{} modify table store file tracker of table {} to {}", getClientIdAuditPrefix(),</span>
+<span class="source-line-no">2932</span><span id="line-2932">            tableName, sft);</span>
+<span class="source-line-no">2933</span><span id="line-2933">          submitProcedure(new ModifyTableStoreFileTrackerProcedure(</span>
+<span class="source-line-no">2934</span><span id="line-2934">            procedureExecutor.getEnvironment(), tableName, sft));</span>
+<span class="source-line-no">2935</span><span id="line-2935">          getMaster().getMasterCoprocessorHost().postModifyTableStoreFileTracker(tableName, sft);</span>
+<span class="source-line-no">2936</span><span id="line-2936">        }</span>
+<span class="source-line-no">2937</span><span id="line-2937"></span>
+<span class="source-line-no">2938</span><span id="line-2938">        @Override</span>
+<span class="source-line-no">2939</span><span id="line-2939">        protected String getDescription() {</span>
+<span class="source-line-no">2940</span><span id="line-2940">          return "ModifyTableStoreFileTrackerProcedure";</span>
+<span class="source-line-no">2941</span><span id="line-2941">        }</span>
+<span class="source-line-no">2942</span><span id="line-2942">      });</span>
+<span class="source-line-no">2943</span><span id="line-2943">  }</span>
+<span class="source-line-no">2944</span><span id="line-2944"></span>
+<span class="source-line-no">2945</span><span id="line-2945">  public long restoreSnapshot(final SnapshotDescription snapshotDesc, final long nonceGroup,</span>
+<span class="source-line-no">2946</span><span id="line-2946">    final long nonce, final boolean restoreAcl, final String customSFT) throws IOException {</span>
+<span class="source-line-no">2947</span><span id="line-2947">    checkInitialized();</span>
+<span class="source-line-no">2948</span><span id="line-2948">    getSnapshotManager().checkSnapshotSupport();</span>
 <span class="source-line-no">2949</span><span id="line-2949"></span>
-<span class="source-line-no">2950</span><span id="line-2950">    return MasterProcedureUtil</span>
-<span class="source-line-no">2951</span><span id="line-2951">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">2952</span><span id="line-2952">        @Override</span>
-<span class="source-line-no">2953</span><span id="line-2953">        protected void run() throws IOException {</span>
-<span class="source-line-no">2954</span><span id="line-2954">          setProcId(getSnapshotManager().restoreOrCloneSnapshot(snapshotDesc, getNonceKey(),</span>
-<span class="source-line-no">2955</span><span id="line-2955">            restoreAcl, customSFT));</span>
-<span class="source-line-no">2956</span><span id="line-2956">        }</span>
-<span class="source-line-no">2957</span><span id="line-2957"></span>
-<span class="source-line-no">2958</span><span id="line-2958">        @Override</span>
-<span class="source-line-no">2959</span><span id="line-2959">        protected String getDescription() {</span>
-<span class="source-line-no">2960</span><span id="line-2960">          return "RestoreSnapshotProcedure";</span>
-<span class="source-line-no">2961</span><span id="line-2961">        }</span>
-<span class="source-line-no">2962</span><span id="line-2962">      });</span>
-<span class="source-line-no">2963</span><span id="line-2963">  }</span>
-<span class="source-line-no">2964</span><span id="line-2964"></span>
-<span class="source-line-no">2965</span><span id="line-2965">  private void checkTableExists(final TableName tableName)</span>
-<span class="source-line-no">2966</span><span id="line-2966">    throws IOException, TableNotFoundException {</span>
-<span class="source-line-no">2967</span><span id="line-2967">    if (!tableDescriptors.exists(tableName)) {</span>
-<span class="source-line-no">2968</span><span id="line-2968">      throw new TableNotFoundException(tableName);</span>
-<span class="source-line-no">2969</span><span id="line-2969">    }</span>
-<span class="source-line-no">2970</span><span id="line-2970">  }</span>
-<span class="source-line-no">2971</span><span id="line-2971"></span>
-<span class="source-line-no">2972</span><span id="line-2972">  @Override</span>
-<span class="source-line-no">2973</span><span id="line-2973">  public void checkTableModifiable(final TableName tableName)</span>
-<span class="source-line-no">2974</span><span id="line-2974">    throws IOException, TableNotFoundException, TableNotDisabledException {</span>
-<span class="source-line-no">2975</span><span id="line-2975">    if (isCatalogTable(tableName)) {</span>
-<span class="source-line-no">2976</span><span id="line-2976">      throw new IOException("Can't modify catalog tables");</span>
-<span class="source-line-no">2977</span><span id="line-2977">    }</span>
-<span class="source-line-no">2978</span><span id="line-2978">    checkTableExists(tableName);</span>
-<span class="source-line-no">2979</span><span id="line-2979">    TableState ts = getTableStateManager().getTableState(tableName);</span>
-<span class="source-line-no">2980</span><span id="line-2980">    if (!ts.isDisabled()) {</span>
-<span class="source-line-no">2981</span><span id="line-2981">      throw new TableNotDisabledException("Not DISABLED; " + ts);</span>
-<span class="source-line-no">2982</span><span id="line-2982">    }</span>
-<span class="source-line-no">2983</span><span id="line-2983">  }</span>
-<span class="source-line-no">2984</span><span id="line-2984"></span>
-<span class="source-line-no">2985</span><span id="line-2985">  public ClusterMetrics getClusterMetricsWithoutCoprocessor() throws InterruptedIOException {</span>
-<span class="source-line-no">2986</span><span id="line-2986">    return getClusterMetricsWithoutCoprocessor(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">2950</span><span id="line-2950">    // Ensure namespace exists. Will throw exception if non-known NS.</span>
+<span class="source-line-no">2951</span><span id="line-2951">    final TableName dstTable = TableName.valueOf(snapshotDesc.getTable());</span>
+<span class="source-line-no">2952</span><span id="line-2952">    getClusterSchema().getNamespace(dstTable.getNamespaceAsString());</span>
+<span class="source-line-no">2953</span><span id="line-2953"></span>
+<span class="source-line-no">2954</span><span id="line-2954">    return MasterProcedureUtil</span>
+<span class="source-line-no">2955</span><span id="line-2955">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">2956</span><span id="line-2956">        @Override</span>
+<span class="source-line-no">2957</span><span id="line-2957">        protected void run() throws IOException {</span>
+<span class="source-line-no">2958</span><span id="line-2958">          setProcId(getSnapshotManager().restoreOrCloneSnapshot(snapshotDesc, getNonceKey(),</span>
+<span class="source-line-no">2959</span><span id="line-2959">            restoreAcl, customSFT));</span>
+<span class="source-line-no">2960</span><span id="line-2960">        }</span>
+<span class="source-line-no">2961</span><span id="line-2961"></span>
+<span class="source-line-no">2962</span><span id="line-2962">        @Override</span>
+<span class="source-line-no">2963</span><span id="line-2963">        protected String getDescription() {</span>
+<span class="source-line-no">2964</span><span id="line-2964">          return "RestoreSnapshotProcedure";</span>
+<span class="source-line-no">2965</span><span id="line-2965">        }</span>
+<span class="source-line-no">2966</span><span id="line-2966">      });</span>
+<span class="source-line-no">2967</span><span id="line-2967">  }</span>
+<span class="source-line-no">2968</span><span id="line-2968"></span>
+<span class="source-line-no">2969</span><span id="line-2969">  private void checkTableExists(final TableName tableName)</span>
+<span class="source-line-no">2970</span><span id="line-2970">    throws IOException, TableNotFoundException {</span>
+<span class="source-line-no">2971</span><span id="line-2971">    if (!tableDescriptors.exists(tableName)) {</span>
+<span class="source-line-no">2972</span><span id="line-2972">      throw new TableNotFoundException(tableName);</span>
+<span class="source-line-no">2973</span><span id="line-2973">    }</span>
+<span class="source-line-no">2974</span><span id="line-2974">  }</span>
+<span class="source-line-no">2975</span><span id="line-2975"></span>
+<span class="source-line-no">2976</span><span id="line-2976">  @Override</span>
+<span class="source-line-no">2977</span><span id="line-2977">  public void checkTableModifiable(final TableName tableName)</span>
+<span class="source-line-no">2978</span><span id="line-2978">    throws IOException, TableNotFoundException, TableNotDisabledException {</span>
+<span class="source-line-no">2979</span><span id="line-2979">    if (isCatalogTable(tableName)) {</span>
+<span class="source-line-no">2980</span><span id="line-2980">      throw new IOException("Can't modify catalog tables");</span>
+<span class="source-line-no">2981</span><span id="line-2981">    }</span>
+<span class="source-line-no">2982</span><span id="line-2982">    checkTableExists(tableName);</span>
+<span class="source-line-no">2983</span><span id="line-2983">    TableState ts = getTableStateManager().getTableState(tableName);</span>
+<span class="source-line-no">2984</span><span id="line-2984">    if (!ts.isDisabled()) {</span>
+<span class="source-line-no">2985</span><span id="line-2985">      throw new TableNotDisabledException("Not DISABLED; " + ts);</span>
+<span class="source-line-no">2986</span><span id="line-2986">    }</span>
 <span class="source-line-no">2987</span><span id="line-2987">  }</span>
 <span class="source-line-no">2988</span><span id="line-2988"></span>
-<span class="source-line-no">2989</span><span id="line-2989">  public ClusterMetrics getClusterMetricsWithoutCoprocessor(EnumSet&lt;Option&gt; options)</span>
-<span class="source-line-no">2990</span><span id="line-2990">    throws InterruptedIOException {</span>
-<span class="source-line-no">2991</span><span id="line-2991">    ClusterMetricsBuilder builder = ClusterMetricsBuilder.newBuilder();</span>
-<span class="source-line-no">2992</span><span id="line-2992">    // given that hbase1 can't submit the request with Option,</span>
-<span class="source-line-no">2993</span><span id="line-2993">    // we return all information to client if the list of Option is empty.</span>
-<span class="source-line-no">2994</span><span id="line-2994">    if (options.isEmpty()) {</span>
-<span class="source-line-no">2995</span><span id="line-2995">      options = EnumSet.allOf(Option.class);</span>
-<span class="source-line-no">2996</span><span id="line-2996">    }</span>
-<span class="source-line-no">2997</span><span id="line-2997"></span>
-<span class="source-line-no">2998</span><span id="line-2998">    // TASKS and/or LIVE_SERVERS will populate this map, which will be given to the builder if</span>
-<span class="source-line-no">2999</span><span id="line-2999">    // not null after option processing completes.</span>
-<span class="source-line-no">3000</span><span id="line-3000">    Map&lt;ServerName, ServerMetrics&gt; serverMetricsMap = null;</span>
+<span class="source-line-no">2989</span><span id="line-2989">  public ClusterMetrics getClusterMetricsWithoutCoprocessor() throws InterruptedIOException {</span>
+<span class="source-line-no">2990</span><span id="line-2990">    return getClusterMetricsWithoutCoprocessor(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">2991</span><span id="line-2991">  }</span>
+<span class="source-line-no">2992</span><span id="line-2992"></span>
+<span class="source-line-no">2993</span><span id="line-2993">  public ClusterMetrics getClusterMetricsWithoutCoprocessor(EnumSet&lt;Option&gt; options)</span>
+<span class="source-line-no">2994</span><span id="line-2994">    throws InterruptedIOException {</span>
+<span class="source-line-no">2995</span><span id="line-2995">    ClusterMetricsBuilder builder = ClusterMetricsBuilder.newBuilder();</span>
+<span class="source-line-no">2996</span><span id="line-2996">    // given that hbase1 can't submit the request with Option,</span>
+<span class="source-line-no">2997</span><span id="line-2997">    // we return all information to client if the list of Option is empty.</span>
+<span class="source-line-no">2998</span><span id="line-2998">    if (options.isEmpty()) {</span>
+<span class="source-line-no">2999</span><span id="line-2999">      options = EnumSet.allOf(Option.class);</span>
+<span class="source-line-no">3000</span><span id="line-3000">    }</span>
 <span class="source-line-no">3001</span><span id="line-3001"></span>
-<span class="source-line-no">3002</span><span id="line-3002">    for (Option opt : options) {</span>
-<span class="source-line-no">3003</span><span id="line-3003">      switch (opt) {</span>
-<span class="source-line-no">3004</span><span id="line-3004">        case HBASE_VERSION:</span>
-<span class="source-line-no">3005</span><span id="line-3005">          builder.setHBaseVersion(VersionInfo.getVersion());</span>
-<span class="source-line-no">3006</span><span id="line-3006">          break;</span>
-<span class="source-line-no">3007</span><span id="line-3007">        case CLUSTER_ID:</span>
-<span class="source-line-no">3008</span><span id="line-3008">          builder.setClusterId(getClusterId());</span>
-<span class="source-line-no">3009</span><span id="line-3009">          break;</span>
-<span class="source-line-no">3010</span><span id="line-3010">        case MASTER:</span>
-<span class="source-line-no">3011</span><span id="line-3011">          builder.setMasterName(getServerName());</span>
-<span class="source-line-no">3012</span><span id="line-3012">          break;</span>
-<span class="source-line-no">3013</span><span id="line-3013">        case BACKUP_MASTERS:</span>
-<span class="source-line-no">3014</span><span id="line-3014">          builder.setBackerMasterNames(getBackupMasters());</span>
-<span class="source-line-no">3015</span><span id="line-3015">          break;</span>
-<span class="source-line-no">3016</span><span id="line-3016">        case TASKS: {</span>
-<span class="source-line-no">3017</span><span id="line-3017">          // Master tasks</span>
-<span class="source-line-no">3018</span><span id="line-3018">          builder.setMasterTasks(TaskMonitor.get().getTasks().stream()</span>
-<span class="source-line-no">3019</span><span id="line-3019">            .map(task -&gt; ServerTaskBuilder.newBuilder().setDescription(task.getDescription())</span>
-<span class="source-line-no">3020</span><span id="line-3020">              .setStatus(task.getStatus())</span>
-<span class="source-line-no">3021</span><span id="line-3021">              .setState(ServerTask.State.valueOf(task.getState().name()))</span>
-<span class="source-line-no">3022</span><span id="line-3022">              .setStartTime(task.getStartTime()).setCompletionTime(task.getCompletionTimestamp())</span>
-<span class="source-line-no">3023</span><span id="line-3023">              .build())</span>
-<span class="source-line-no">3024</span><span id="line-3024">            .collect(Collectors.toList()));</span>
-<span class="source-line-no">3025</span><span id="line-3025">          // TASKS is also synonymous with LIVE_SERVERS for now because task information for</span>
-<span class="source-line-no">3026</span><span id="line-3026">          // regionservers is carried in ServerLoad.</span>
-<span class="source-line-no">3027</span><span id="line-3027">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
-<span class="source-line-no">3028</span><span id="line-3028">          if (serverMetricsMap == null) {</span>
-<span class="source-line-no">3029</span><span id="line-3029">            serverMetricsMap = getOnlineServers();</span>
-<span class="source-line-no">3030</span><span id="line-3030">          }</span>
-<span class="source-line-no">3031</span><span id="line-3031">          break;</span>
-<span class="source-line-no">3032</span><span id="line-3032">        }</span>
-<span class="source-line-no">3033</span><span id="line-3033">        case LIVE_SERVERS: {</span>
-<span class="source-line-no">3034</span><span id="line-3034">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
-<span class="source-line-no">3035</span><span id="line-3035">          if (serverMetricsMap == null) {</span>
-<span class="source-line-no">3036</span><span id="line-3036">            serverMetricsMap = getOnlineServers();</span>
-<span class="source-line-no">3037</span><span id="line-3037">          }</span>
-<span class="source-line-no">3038</span><span id="line-3038">          break;</span>
-<span class="source-line-no">3039</span><span id="line-3039">        }</span>
-<span class="source-line-no">3040</span><span id="line-3040">        case DEAD_SERVERS: {</span>
-<span class="source-line-no">3041</span><span id="line-3041">          if (serverManager != null) {</span>
-<span class="source-line-no">3042</span><span id="line-3042">            builder.setDeadServerNames(</span>
-<span class="source-line-no">3043</span><span id="line-3043">              new ArrayList&lt;&gt;(serverManager.getDeadServers().copyServerNames()));</span>
-<span class="source-line-no">3044</span><span id="line-3044">          }</span>
-<span class="source-line-no">3045</span><span id="line-3045">          break;</span>
-<span class="source-line-no">3046</span><span id="line-3046">        }</span>
-<span class="source-line-no">3047</span><span id="line-3047">        case UNKNOWN_SERVERS: {</span>
-<span class="source-line-no">3048</span><span id="line-3048">          if (serverManager != null) {</span>
-<span class="source-line-no">3049</span><span id="line-3049">            builder.setUnknownServerNames(getUnknownServers());</span>
-<span class="source-line-no">3050</span><span id="line-3050">          }</span>
-<span class="source-line-no">3051</span><span id="line-3051">          break;</span>
-<span class="source-line-no">3052</span><span id="line-3052">        }</span>
-<span class="source-line-no">3053</span><span id="line-3053">        case MASTER_COPROCESSORS: {</span>
-<span class="source-line-no">3054</span><span id="line-3054">          if (cpHost != null) {</span>
-<span class="source-line-no">3055</span><span id="line-3055">            builder.setMasterCoprocessorNames(Arrays.asList(getMasterCoprocessors()));</span>
-<span class="source-line-no">3056</span><span id="line-3056">          }</span>
-<span class="source-line-no">3057</span><span id="line-3057">          break;</span>
-<span class="source-line-no">3058</span><span id="line-3058">        }</span>
-<span class="source-line-no">3059</span><span id="line-3059">        case REGIONS_IN_TRANSITION: {</span>
-<span class="source-line-no">3060</span><span id="line-3060">          if (assignmentManager != null) {</span>
-<span class="source-line-no">3061</span><span id="line-3061">            builder.setRegionsInTransition(</span>
-<span class="source-line-no">3062</span><span id="line-3062">              assignmentManager.getRegionStates().getRegionsStateInTransition());</span>
-<span class="source-line-no">3063</span><span id="line-3063">          }</span>
-<span class="source-line-no">3064</span><span id="line-3064">          break;</span>
-<span class="source-line-no">3065</span><span id="line-3065">        }</span>
-<span class="source-line-no">3066</span><span id="line-3066">        case BALANCER_ON: {</span>
-<span class="source-line-no">3067</span><span id="line-3067">          if (loadBalancerStateStore != null) {</span>
-<span class="source-line-no">3068</span><span id="line-3068">            builder.setBalancerOn(loadBalancerStateStore.get());</span>
-<span class="source-line-no">3069</span><span id="line-3069">          }</span>
-<span class="source-line-no">3070</span><span id="line-3070">          break;</span>
-<span class="source-line-no">3071</span><span id="line-3071">        }</span>
-<span class="source-line-no">3072</span><span id="line-3072">        case MASTER_INFO_PORT: {</span>
-<span class="source-line-no">3073</span><span id="line-3073">          if (infoServer != null) {</span>
-<span class="source-line-no">3074</span><span id="line-3074">            builder.setMasterInfoPort(infoServer.getPort());</span>
-<span class="source-line-no">3075</span><span id="line-3075">          }</span>
-<span class="source-line-no">3076</span><span id="line-3076">          break;</span>
-<span class="source-line-no">3077</span><span id="line-3077">        }</span>
-<span class="source-line-no">3078</span><span id="line-3078">        case SERVERS_NAME: {</span>
-<span class="source-line-no">3079</span><span id="line-3079">          if (serverManager != null) {</span>
-<span class="source-line-no">3080</span><span id="line-3080">            builder.setServerNames(serverManager.getOnlineServersList());</span>
-<span class="source-line-no">3081</span><span id="line-3081">          }</span>
-<span class="source-line-no">3082</span><span id="line-3082">          break;</span>
-<span class="source-line-no">3083</span><span id="line-3083">        }</span>
-<span class="source-line-no">3084</span><span id="line-3084">        case TABLE_TO_REGIONS_COUNT: {</span>
-<span class="source-line-no">3085</span><span id="line-3085">          if (isActiveMaster() &amp;&amp; isInitialized() &amp;&amp; assignmentManager != null) {</span>
-<span class="source-line-no">3086</span><span id="line-3086">            try {</span>
-<span class="source-line-no">3087</span><span id="line-3087">              Map&lt;TableName, RegionStatesCount&gt; tableRegionStatesCountMap = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">3088</span><span id="line-3088">              Map&lt;String, TableDescriptor&gt; tableDescriptorMap = getTableDescriptors().getAll();</span>
-<span class="source-line-no">3089</span><span id="line-3089">              for (TableDescriptor tableDescriptor : tableDescriptorMap.values()) {</span>
-<span class="source-line-no">3090</span><span id="line-3090">                TableName tableName = tableDescriptor.getTableName();</span>
-<span class="source-line-no">3091</span><span id="line-3091">                RegionStatesCount regionStatesCount =</span>
-<span class="source-line-no">3092</span><span id="line-3092">                  assignmentManager.getRegionStatesCount(tableName);</span>
-<span class="source-line-no">3093</span><span id="line-3093">                tableRegionStatesCountMap.put(tableName, regionStatesCount);</span>
-<span class="source-line-no">3094</span><span id="line-3094">              }</span>
-<span class="source-line-no">3095</span><span id="line-3095">              builder.setTableRegionStatesCount(tableRegionStatesCountMap);</span>
-<span class="source-line-no">3096</span><span id="line-3096">            } catch (IOException e) {</span>
-<span class="source-line-no">3097</span><span id="line-3097">              LOG.error("Error while populating TABLE_TO_REGIONS_COUNT for Cluster Metrics..", e);</span>
-<span class="source-line-no">3098</span><span id="line-3098">            }</span>
-<span class="source-line-no">3099</span><span id="line-3099">          }</span>
-<span class="source-line-no">3100</span><span id="line-3100">          break;</span>
-<span class="source-line-no">3101</span><span id="line-3101">        }</span>
-<span class="source-line-no">3102</span><span id="line-3102">        case DECOMMISSIONED_SERVERS: {</span>
-<span class="source-line-no">3103</span><span id="line-3103">          if (serverManager != null) {</span>
-<span class="source-line-no">3104</span><span id="line-3104">            builder.setDecommissionedServerNames(serverManager.getDrainingServersList());</span>
-<span class="source-line-no">3105</span><span id="line-3105">          }</span>
-<span class="source-line-no">3106</span><span id="line-3106">          break;</span>
-<span class="source-line-no">3107</span><span id="line-3107">        }</span>
-<span class="source-line-no">3108</span><span id="line-3108">      }</span>
-<span class="source-line-no">3109</span><span id="line-3109">    }</span>
-<span class="source-line-no">3110</span><span id="line-3110"></span>
-<span class="source-line-no">3111</span><span id="line-3111">    if (serverMetricsMap != null) {</span>
-<span class="source-line-no">3112</span><span id="line-3112">      builder.setLiveServerMetrics(serverMetricsMap);</span>
+<span class="source-line-no">3002</span><span id="line-3002">    // TASKS and/or LIVE_SERVERS will populate this map, which will be given to the builder if</span>
+<span class="source-line-no">3003</span><span id="line-3003">    // not null after option processing completes.</span>
+<span class="source-line-no">3004</span><span id="line-3004">    Map&lt;ServerName, ServerMetrics&gt; serverMetricsMap = null;</span>
+<span class="source-line-no">3005</span><span id="line-3005"></span>
+<span class="source-line-no">3006</span><span id="line-3006">    for (Option opt : options) {</span>
+<span class="source-line-no">3007</span><span id="line-3007">      switch (opt) {</span>
+<span class="source-line-no">3008</span><span id="line-3008">        case HBASE_VERSION:</span>
+<span class="source-line-no">3009</span><span id="line-3009">          builder.setHBaseVersion(VersionInfo.getVersion());</span>
+<span class="source-line-no">3010</span><span id="line-3010">          break;</span>
+<span class="source-line-no">3011</span><span id="line-3011">        case CLUSTER_ID:</span>
+<span class="source-line-no">3012</span><span id="line-3012">          builder.setClusterId(getClusterId());</span>
+<span class="source-line-no">3013</span><span id="line-3013">          break;</span>
+<span class="source-line-no">3014</span><span id="line-3014">        case MASTER:</span>
+<span class="source-line-no">3015</span><span id="line-3015">          builder.setMasterName(getServerName());</span>
+<span class="source-line-no">3016</span><span id="line-3016">          break;</span>
+<span class="source-line-no">3017</span><span id="line-3017">        case BACKUP_MASTERS:</span>
+<span class="source-line-no">3018</span><span id="line-3018">          builder.setBackerMasterNames(getBackupMasters());</span>
+<span class="source-line-no">3019</span><span id="line-3019">          break;</span>
+<span class="source-line-no">3020</span><span id="line-3020">        case TASKS: {</span>
+<span class="source-line-no">3021</span><span id="line-3021">          // Master tasks</span>
+<span class="source-line-no">3022</span><span id="line-3022">          builder.setMasterTasks(TaskMonitor.get().getTasks().stream()</span>
+<span class="source-line-no">3023</span><span id="line-3023">            .map(task -&gt; ServerTaskBuilder.newBuilder().setDescription(task.getDescription())</span>
+<span class="source-line-no">3024</span><span id="line-3024">              .setStatus(task.getStatus())</span>
+<span class="source-line-no">3025</span><span id="line-3025">              .setState(ServerTask.State.valueOf(task.getState().name()))</span>
+<span class="source-line-no">3026</span><span id="line-3026">              .setStartTime(task.getStartTime()).setCompletionTime(task.getCompletionTimestamp())</span>
+<span class="source-line-no">3027</span><span id="line-3027">              .build())</span>
+<span class="source-line-no">3028</span><span id="line-3028">            .collect(Collectors.toList()));</span>
+<span class="source-line-no">3029</span><span id="line-3029">          // TASKS is also synonymous with LIVE_SERVERS for now because task information for</span>
+<span class="source-line-no">3030</span><span id="line-3030">          // regionservers is carried in ServerLoad.</span>
+<span class="source-line-no">3031</span><span id="line-3031">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
+<span class="source-line-no">3032</span><span id="line-3032">          if (serverMetricsMap == null) {</span>
+<span class="source-line-no">3033</span><span id="line-3033">            serverMetricsMap = getOnlineServers();</span>
+<span class="source-line-no">3034</span><span id="line-3034">          }</span>
+<span class="source-line-no">3035</span><span id="line-3035">          break;</span>
+<span class="source-line-no">3036</span><span id="line-3036">        }</span>
+<span class="source-line-no">3037</span><span id="line-3037">        case LIVE_SERVERS: {</span>
+<span class="source-line-no">3038</span><span id="line-3038">          // Add entries to serverMetricsMap for all live servers, if we haven't already done so</span>
+<span class="source-line-no">3039</span><span id="line-3039">          if (serverMetricsMap == null) {</span>
+<span class="source-line-no">3040</span><span id="line-3040">            serverMetricsMap = getOnlineServers();</span>
+<span class="source-line-no">3041</span><span id="line-3041">          }</span>
+<span class="source-line-no">3042</span><span id="line-3042">          break;</span>
+<span class="source-line-no">3043</span><span id="line-3043">        }</span>
+<span class="source-line-no">3044</span><span id="line-3044">        case DEAD_SERVERS: {</span>
+<span class="source-line-no">3045</span><span id="line-3045">          if (serverManager != null) {</span>
+<span class="source-line-no">3046</span><span id="line-3046">            builder.setDeadServerNames(</span>
+<span class="source-line-no">3047</span><span id="line-3047">              new ArrayList&lt;&gt;(serverManager.getDeadServers().copyServerNames()));</span>
+<span class="source-line-no">3048</span><span id="line-3048">          }</span>
+<span class="source-line-no">3049</span><span id="line-3049">          break;</span>
+<span class="source-line-no">3050</span><span id="line-3050">        }</span>
+<span class="source-line-no">3051</span><span id="line-3051">        case UNKNOWN_SERVERS: {</span>
+<span class="source-line-no">3052</span><span id="line-3052">          if (serverManager != null) {</span>
+<span class="source-line-no">3053</span><span id="line-3053">            builder.setUnknownServerNames(getUnknownServers());</span>
+<span class="source-line-no">3054</span><span id="line-3054">          }</span>
+<span class="source-line-no">3055</span><span id="line-3055">          break;</span>
+<span class="source-line-no">3056</span><span id="line-3056">        }</span>
+<span class="source-line-no">3057</span><span id="line-3057">        case MASTER_COPROCESSORS: {</span>
+<span class="source-line-no">3058</span><span id="line-3058">          if (cpHost != null) {</span>
+<span class="source-line-no">3059</span><span id="line-3059">            builder.setMasterCoprocessorNames(Arrays.asList(getMasterCoprocessors()));</span>
+<span class="source-line-no">3060</span><span id="line-3060">          }</span>
+<span class="source-line-no">3061</span><span id="line-3061">          break;</span>
+<span class="source-line-no">3062</span><span id="line-3062">        }</span>
+<span class="source-line-no">3063</span><span id="line-3063">        case REGIONS_IN_TRANSITION: {</span>
+<span class="source-line-no">3064</span><span id="line-3064">          if (assignmentManager != null) {</span>
+<span class="source-line-no">3065</span><span id="line-3065">            builder.setRegionsInTransition(</span>
+<span class="source-line-no">3066</span><span id="line-3066">              assignmentManager.getRegionStates().getRegionsStateInTransition());</span>
+<span class="source-line-no">3067</span><span id="line-3067">          }</span>
+<span class="source-line-no">3068</span><span id="line-3068">          break;</span>
+<span class="source-line-no">3069</span><span id="line-3069">        }</span>
+<span class="source-line-no">3070</span><span id="line-3070">        case BALANCER_ON: {</span>
+<span class="source-line-no">3071</span><span id="line-3071">          if (loadBalancerStateStore != null) {</span>
+<span class="source-line-no">3072</span><span id="line-3072">            builder.setBalancerOn(loadBalancerStateStore.get());</span>
+<span class="source-line-no">3073</span><span id="line-3073">          }</span>
+<span class="source-line-no">3074</span><span id="line-3074">          break;</span>
+<span class="source-line-no">3075</span><span id="line-3075">        }</span>
+<span class="source-line-no">3076</span><span id="line-3076">        case MASTER_INFO_PORT: {</span>
+<span class="source-line-no">3077</span><span id="line-3077">          if (infoServer != null) {</span>
+<span class="source-line-no">3078</span><span id="line-3078">            builder.setMasterInfoPort(infoServer.getPort());</span>
+<span class="source-line-no">3079</span><span id="line-3079">          }</span>
+<span class="source-line-no">3080</span><span id="line-3080">          break;</span>
+<span class="source-line-no">3081</span><span id="line-3081">        }</span>
+<span class="source-line-no">3082</span><span id="line-3082">        case SERVERS_NAME: {</span>
+<span class="source-line-no">3083</span><span id="line-3083">          if (serverManager != null) {</span>
+<span class="source-line-no">3084</span><span id="line-3084">            builder.setServerNames(serverManager.getOnlineServersList());</span>
+<span class="source-line-no">3085</span><span id="line-3085">          }</span>
+<span class="source-line-no">3086</span><span id="line-3086">          break;</span>
+<span class="source-line-no">3087</span><span id="line-3087">        }</span>
+<span class="source-line-no">3088</span><span id="line-3088">        case TABLE_TO_REGIONS_COUNT: {</span>
+<span class="source-line-no">3089</span><span id="line-3089">          if (isActiveMaster() &amp;&amp; isInitialized() &amp;&amp; assignmentManager != null) {</span>
+<span class="source-line-no">3090</span><span id="line-3090">            try {</span>
+<span class="source-line-no">3091</span><span id="line-3091">              Map&lt;TableName, RegionStatesCount&gt; tableRegionStatesCountMap = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">3092</span><span id="line-3092">              Map&lt;String, TableDescriptor&gt; tableDescriptorMap = getTableDescriptors().getAll();</span>
+<span class="source-line-no">3093</span><span id="line-3093">              for (TableDescriptor tableDescriptor : tableDescriptorMap.values()) {</span>
+<span class="source-line-no">3094</span><span id="line-3094">                TableName tableName = tableDescriptor.getTableName();</span>
+<span class="source-line-no">3095</span><span id="line-3095">                RegionStatesCount regionStatesCount =</span>
+<span class="source-line-no">3096</span><span id="line-3096">                  assignmentManager.getRegionStatesCount(tableName);</span>
+<span class="source-line-no">3097</span><span id="line-3097">                tableRegionStatesCountMap.put(tableName, regionStatesCount);</span>
+<span class="source-line-no">3098</span><span id="line-3098">              }</span>
+<span class="source-line-no">3099</span><span id="line-3099">              builder.setTableRegionStatesCount(tableRegionStatesCountMap);</span>
+<span class="source-line-no">3100</span><span id="line-3100">            } catch (IOException e) {</span>
+<span class="source-line-no">3101</span><span id="line-3101">              LOG.error("Error while populating TABLE_TO_REGIONS_COUNT for Cluster Metrics..", e);</span>
+<span class="source-line-no">3102</span><span id="line-3102">            }</span>
+<span class="source-line-no">3103</span><span id="line-3103">          }</span>
+<span class="source-line-no">3104</span><span id="line-3104">          break;</span>
+<span class="source-line-no">3105</span><span id="line-3105">        }</span>
+<span class="source-line-no">3106</span><span id="line-3106">        case DECOMMISSIONED_SERVERS: {</span>
+<span class="source-line-no">3107</span><span id="line-3107">          if (serverManager != null) {</span>
+<span class="source-line-no">3108</span><span id="line-3108">            builder.setDecommissionedServerNames(serverManager.getDrainingServersList());</span>
+<span class="source-line-no">3109</span><span id="line-3109">          }</span>
+<span class="source-line-no">3110</span><span id="line-3110">          break;</span>
+<span class="source-line-no">3111</span><span id="line-3111">        }</span>
+<span class="source-line-no">3112</span><span id="line-3112">      }</span>
 <span class="source-line-no">3113</span><span id="line-3113">    }</span>
 <span class="source-line-no">3114</span><span id="line-3114"></span>
-<span class="source-line-no">3115</span><span id="line-3115">    return builder.build();</span>
-<span class="source-line-no">3116</span><span id="line-3116">  }</span>
-<span class="source-line-no">3117</span><span id="line-3117"></span>
-<span class="source-line-no">3118</span><span id="line-3118">  private List&lt;ServerName&gt; getUnknownServers() {</span>
-<span class="source-line-no">3119</span><span id="line-3119">    if (serverManager != null) {</span>
-<span class="source-line-no">3120</span><span id="line-3120">      final Set&lt;ServerName&gt; serverNames = getAssignmentManager().getRegionStates().getRegionStates()</span>
-<span class="source-line-no">3121</span><span id="line-3121">        .stream().map(RegionState::getServerName).collect(Collectors.toSet());</span>
-<span class="source-line-no">3122</span><span id="line-3122">      final List&lt;ServerName&gt; unknownServerNames = serverNames.stream()</span>
-<span class="source-line-no">3123</span><span id="line-3123">        .filter(sn -&gt; sn != null &amp;&amp; serverManager.isServerUnknown(sn)).collect(Collectors.toList());</span>
-<span class="source-line-no">3124</span><span id="line-3124">      return unknownServerNames;</span>
-<span class="source-line-no">3125</span><span id="line-3125">    }</span>
-<span class="source-line-no">3126</span><span id="line-3126">    return null;</span>
-<span class="source-line-no">3127</span><span id="line-3127">  }</span>
-<span class="source-line-no">3128</span><span id="line-3128"></span>
-<span class="source-line-no">3129</span><span id="line-3129">  private Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {</span>
-<span class="source-line-no">3130</span><span id="line-3130">    if (serverManager != null) {</span>
-<span class="source-line-no">3131</span><span id="line-3131">      final Map&lt;ServerName, ServerMetrics&gt; map = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">3132</span><span id="line-3132">      serverManager.getOnlineServers().entrySet().forEach(e -&gt; map.put(e.getKey(), e.getValue()));</span>
-<span class="source-line-no">3133</span><span id="line-3133">      return map;</span>
-<span class="source-line-no">3134</span><span id="line-3134">    }</span>
-<span class="source-line-no">3135</span><span id="line-3135">    return null;</span>
-<span class="source-line-no">3136</span><span id="line-3136">  }</span>
-<span class="source-line-no">3137</span><span id="line-3137"></span>
-<span class="source-line-no">3138</span><span id="line-3138">  /** Returns cluster status */</span>
-<span class="source-line-no">3139</span><span id="line-3139">  public ClusterMetrics getClusterMetrics() throws IOException {</span>
-<span class="source-line-no">3140</span><span id="line-3140">    return getClusterMetrics(EnumSet.allOf(Option.class));</span>
-<span class="source-line-no">3141</span><span id="line-3141">  }</span>
-<span class="source-line-no">3142</span><span id="line-3142"></span>
-<span class="source-line-no">3143</span><span id="line-3143">  public ClusterMetrics getClusterMetrics(EnumSet&lt;Option&gt; options) throws IOException {</span>
-<span class="source-line-no">3144</span><span id="line-3144">    if (cpHost != null) {</span>
-<span class="source-line-no">3145</span><span id="line-3145">      cpHost.preGetClusterMetrics();</span>
-<span class="source-line-no">3146</span><span id="line-3146">    }</span>
-<span class="source-line-no">3147</span><span id="line-3147">    ClusterMetrics status = getClusterMetricsWithoutCoprocessor(options);</span>
+<span class="source-line-no">3115</span><span id="line-3115">    if (serverMetricsMap != null) {</span>
+<span class="source-line-no">3116</span><span id="line-3116">      builder.setLiveServerMetrics(serverMetricsMap);</span>
+<span class="source-line-no">3117</span><span id="line-3117">    }</span>
+<span class="source-line-no">3118</span><span id="line-3118"></span>
+<span class="source-line-no">3119</span><span id="line-3119">    return builder.build();</span>
+<span class="source-line-no">3120</span><span id="line-3120">  }</span>
+<span class="source-line-no">3121</span><span id="line-3121"></span>
+<span class="source-line-no">3122</span><span id="line-3122">  private List&lt;ServerName&gt; getUnknownServers() {</span>
+<span class="source-line-no">3123</span><span id="line-3123">    if (serverManager != null) {</span>
+<span class="source-line-no">3124</span><span id="line-3124">      final Set&lt;ServerName&gt; serverNames = getAssignmentManager().getRegionStates().getRegionStates()</span>
+<span class="source-line-no">3125</span><span id="line-3125">        .stream().map(RegionState::getServerName).collect(Collectors.toSet());</span>
+<span class="source-line-no">3126</span><span id="line-3126">      final List&lt;ServerName&gt; unknownServerNames = serverNames.stream()</span>
+<span class="source-line-no">3127</span><span id="line-3127">        .filter(sn -&gt; sn != null &amp;&amp; serverManager.isServerUnknown(sn)).collect(Collectors.toList());</span>
+<span class="source-line-no">3128</span><span id="line-3128">      return unknownServerNames;</span>
+<span class="source-line-no">3129</span><span id="line-3129">    }</span>
+<span class="source-line-no">3130</span><span id="line-3130">    return null;</span>
+<span class="source-line-no">3131</span><span id="line-3131">  }</span>
+<span class="source-line-no">3132</span><span id="line-3132"></span>
+<span class="source-line-no">3133</span><span id="line-3133">  private Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {</span>
+<span class="source-line-no">3134</span><span id="line-3134">    if (serverManager != null) {</span>
+<span class="source-line-no">3135</span><span id="line-3135">      final Map&lt;ServerName, ServerMetrics&gt; map = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">3136</span><span id="line-3136">      serverManager.getOnlineServers().entrySet().forEach(e -&gt; map.put(e.getKey(), e.getValue()));</span>
+<span class="source-line-no">3137</span><span id="line-3137">      return map;</span>
+<span class="source-line-no">3138</span><span id="line-3138">    }</span>
+<span class="source-line-no">3139</span><span id="line-3139">    return null;</span>
+<span class="source-line-no">3140</span><span id="line-3140">  }</span>
+<span class="source-line-no">3141</span><span id="line-3141"></span>
+<span class="source-line-no">3142</span><span id="line-3142">  /** Returns cluster status */</span>
+<span class="source-line-no">3143</span><span id="line-3143">  public ClusterMetrics getClusterMetrics() throws IOException {</span>
+<span class="source-line-no">3144</span><span id="line-3144">    return getClusterMetrics(EnumSet.allOf(Option.class));</span>
+<span class="source-line-no">3145</span><span id="line-3145">  }</span>
+<span class="source-line-no">3146</span><span id="line-3146"></span>
+<span class="source-line-no">3147</span><span id="line-3147">  public ClusterMetrics getClusterMetrics(EnumSet&lt;Option&gt; options) throws IOException {</span>
 <span class="source-line-no">3148</span><span id="line-3148">    if (cpHost != null) {</span>
-<span class="source-line-no">3149</span><span id="line-3149">      cpHost.postGetClusterMetrics(status);</span>
+<span class="source-line-no">3149</span><span id="line-3149">      cpHost.preGetClusterMetrics();</span>
 <span class="source-line-no">3150</span><span id="line-3150">    }</span>
-<span class="source-line-no">3151</span><span id="line-3151">    return status;</span>
-<span class="source-line-no">3152</span><span id="line-3152">  }</span>
-<span class="source-line-no">3153</span><span id="line-3153"></span>
-<span class="source-line-no">3154</span><span id="line-3154">  /** Returns info port of active master or 0 if any exception occurs. */</span>
-<span class="source-line-no">3155</span><span id="line-3155">  public int getActiveMasterInfoPort() {</span>
-<span class="source-line-no">3156</span><span id="line-3156">    return activeMasterManager.getActiveMasterInfoPort();</span>
-<span class="source-line-no">3157</span><span id="line-3157">  }</span>
-<span class="source-line-no">3158</span><span id="line-3158"></span>
-<span class="source-line-no">3159</span><span id="line-3159">  /**</span>
-<span class="source-line-no">3160</span><span id="line-3160">   * @param sn is ServerName of the backup master</span>
-<span class="source-line-no">3161</span><span id="line-3161">   * @return info port of backup master or 0 if any exception occurs.</span>
-<span class="source-line-no">3162</span><span id="line-3162">   */</span>
-<span class="source-line-no">3163</span><span id="line-3163">  public int getBackupMasterInfoPort(final ServerName sn) {</span>
-<span class="source-line-no">3164</span><span id="line-3164">    return activeMasterManager.getBackupMasterInfoPort(sn);</span>
-<span class="source-line-no">3165</span><span id="line-3165">  }</span>
-<span class="source-line-no">3166</span><span id="line-3166"></span>
-<span class="source-line-no">3167</span><span id="line-3167">  /**</span>
-<span class="source-line-no">3168</span><span id="line-3168">   * The set of loaded coprocessors is stored in a static set. Since it's statically allocated, it</span>
-<span class="source-line-no">3169</span><span id="line-3169">   * does not require that HMaster's cpHost be initialized prior to accessing it.</span>
-<span class="source-line-no">3170</span><span id="line-3170">   * @return a String representation of the set of names of the loaded coprocessors.</span>
-<span class="source-line-no">3171</span><span id="line-3171">   */</span>
-<span class="source-line-no">3172</span><span id="line-3172">  public static String getLoadedCoprocessors() {</span>
-<span class="source-line-no">3173</span><span id="line-3173">    return CoprocessorHost.getLoadedCoprocessors().toString();</span>
-<span class="source-line-no">3174</span><span id="line-3174">  }</span>
-<span class="source-line-no">3175</span><span id="line-3175"></span>
-<span class="source-line-no">3176</span><span id="line-3176">  /** Returns timestamp in millis when HMaster was started. */</span>
-<span class="source-line-no">3177</span><span id="line-3177">  public long getMasterStartTime() {</span>
-<span class="source-line-no">3178</span><span id="line-3178">    return startcode;</span>
-<span class="source-line-no">3179</span><span id="line-3179">  }</span>
-<span class="source-line-no">3180</span><span id="line-3180"></span>
-<span class="source-line-no">3181</span><span id="line-3181">  /** Returns timestamp in millis when HMaster became the active master. */</span>
-<span class="source-line-no">3182</span><span id="line-3182">  @Override</span>
-<span class="source-line-no">3183</span><span id="line-3183">  public long getMasterActiveTime() {</span>
-<span class="source-line-no">3184</span><span id="line-3184">    return masterActiveTime;</span>
-<span class="source-line-no">3185</span><span id="line-3185">  }</span>
-<span class="source-line-no">3186</span><span id="line-3186"></span>
-<span class="source-line-no">3187</span><span id="line-3187">  /** Returns timestamp in millis when HMaster finished becoming the active master */</span>
-<span class="source-line-no">3188</span><span id="line-3188">  public long getMasterFinishedInitializationTime() {</span>
-<span class="source-line-no">3189</span><span id="line-3189">    return masterFinishedInitializationTime;</span>
-<span class="source-line-no">3190</span><span id="line-3190">  }</span>
-<span class="source-line-no">3191</span><span id="line-3191"></span>
-<span class="source-line-no">3192</span><span id="line-3192">  public int getNumWALFiles() {</span>
-<span class="source-line-no">3193</span><span id="line-3193">    return 0;</span>
+<span class="source-line-no">3151</span><span id="line-3151">    ClusterMetrics status = getClusterMetricsWithoutCoprocessor(options);</span>
+<span class="source-line-no">3152</span><span id="line-3152">    if (cpHost != null) {</span>
+<span class="source-line-no">3153</span><span id="line-3153">      cpHost.postGetClusterMetrics(status);</span>
+<span class="source-line-no">3154</span><span id="line-3154">    }</span>
+<span class="source-line-no">3155</span><span id="line-3155">    return status;</span>
+<span class="source-line-no">3156</span><span id="line-3156">  }</span>
+<span class="source-line-no">3157</span><span id="line-3157"></span>
+<span class="source-line-no">3158</span><span id="line-3158">  /** Returns info port of active master or 0 if any exception occurs. */</span>
+<span class="source-line-no">3159</span><span id="line-3159">  public int getActiveMasterInfoPort() {</span>
+<span class="source-line-no">3160</span><span id="line-3160">    return activeMasterManager.getActiveMasterInfoPort();</span>
+<span class="source-line-no">3161</span><span id="line-3161">  }</span>
+<span class="source-line-no">3162</span><span id="line-3162"></span>
+<span class="source-line-no">3163</span><span id="line-3163">  /**</span>
+<span class="source-line-no">3164</span><span id="line-3164">   * @param sn is ServerName of the backup master</span>
+<span class="source-line-no">3165</span><span id="line-3165">   * @return info port of backup master or 0 if any exception occurs.</span>
+<span class="source-line-no">3166</span><span id="line-3166">   */</span>
+<span class="source-line-no">3167</span><span id="line-3167">  public int getBackupMasterInfoPort(final ServerName sn) {</span>
+<span class="source-line-no">3168</span><span id="line-3168">    return activeMasterManager.getBackupMasterInfoPort(sn);</span>
+<span class="source-line-no">3169</span><span id="line-3169">  }</span>
+<span class="source-line-no">3170</span><span id="line-3170"></span>
+<span class="source-line-no">3171</span><span id="line-3171">  /**</span>
+<span class="source-line-no">3172</span><span id="line-3172">   * The set of loaded coprocessors is stored in a static set. Since it's statically allocated, it</span>
+<span class="source-line-no">3173</span><span id="line-3173">   * does not require that HMaster's cpHost be initialized prior to accessing it.</span>
+<span class="source-line-no">3174</span><span id="line-3174">   * @return a String representation of the set of names of the loaded coprocessors.</span>
+<span class="source-line-no">3175</span><span id="line-3175">   */</span>
+<span class="source-line-no">3176</span><span id="line-3176">  public static String getLoadedCoprocessors() {</span>
+<span class="source-line-no">3177</span><span id="line-3177">    return CoprocessorHost.getLoadedCoprocessors().toString();</span>
+<span class="source-line-no">3178</span><span id="line-3178">  }</span>
+<span class="source-line-no">3179</span><span id="line-3179"></span>
+<span class="source-line-no">3180</span><span id="line-3180">  /** Returns timestamp in millis when HMaster was started. */</span>
+<span class="source-line-no">3181</span><span id="line-3181">  public long getMasterStartTime() {</span>
+<span class="source-line-no">3182</span><span id="line-3182">    return startcode;</span>
+<span class="source-line-no">3183</span><span id="line-3183">  }</span>
+<span class="source-line-no">3184</span><span id="line-3184"></span>
+<span class="source-line-no">3185</span><span id="line-3185">  /** Returns timestamp in millis when HMaster became the active master. */</span>
+<span class="source-line-no">3186</span><span id="line-3186">  @Override</span>
+<span class="source-line-no">3187</span><span id="line-3187">  public long getMasterActiveTime() {</span>
+<span class="source-line-no">3188</span><span id="line-3188">    return masterActiveTime;</span>
+<span class="source-line-no">3189</span><span id="line-3189">  }</span>
+<span class="source-line-no">3190</span><span id="line-3190"></span>
+<span class="source-line-no">3191</span><span id="line-3191">  /** Returns timestamp in millis when HMaster finished becoming the active master */</span>
+<span class="source-line-no">3192</span><span id="line-3192">  public long getMasterFinishedInitializationTime() {</span>
+<span class="source-line-no">3193</span><span id="line-3193">    return masterFinishedInitializationTime;</span>
 <span class="source-line-no">3194</span><span id="line-3194">  }</span>
 <span class="source-line-no">3195</span><span id="line-3195"></span>
-<span class="source-line-no">3196</span><span id="line-3196">  public ProcedureStore getProcedureStore() {</span>
-<span class="source-line-no">3197</span><span id="line-3197">    return procedureStore;</span>
+<span class="source-line-no">3196</span><span id="line-3196">  public int getNumWALFiles() {</span>
+<span class="source-line-no">3197</span><span id="line-3197">    return 0;</span>
 <span class="source-line-no">3198</span><span id="line-3198">  }</span>
 <span class="source-line-no">3199</span><span id="line-3199"></span>
-<span class="source-line-no">3200</span><span id="line-3200">  public int getRegionServerInfoPort(final ServerName sn) {</span>
-<span class="source-line-no">3201</span><span id="line-3201">    int port = this.serverManager.getInfoPort(sn);</span>
-<span class="source-line-no">3202</span><span id="line-3202">    return port == 0</span>
-<span class="source-line-no">3203</span><span id="line-3203">      ? conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT)</span>
-<span class="source-line-no">3204</span><span id="line-3204">      : port;</span>
-<span class="source-line-no">3205</span><span id="line-3205">  }</span>
-<span class="source-line-no">3206</span><span id="line-3206"></span>
-<span class="source-line-no">3207</span><span id="line-3207">  @Override</span>
-<span class="source-line-no">3208</span><span id="line-3208">  public String getRegionServerVersion(ServerName sn) {</span>
-<span class="source-line-no">3209</span><span id="line-3209">    // Will return "0.0.0" if the server is not online to prevent move system region to unknown</span>
-<span class="source-line-no">3210</span><span id="line-3210">    // version RS.</span>
-<span class="source-line-no">3211</span><span id="line-3211">    return this.serverManager.getVersion(sn);</span>
-<span class="source-line-no">3212</span><span id="line-3212">  }</span>
-<span class="source-line-no">3213</span><span id="line-3213"></span>
-<span class="source-line-no">3214</span><span id="line-3214">  @Override</span>
-<span class="source-line-no">3215</span><span id="line-3215">  public void checkIfShouldMoveSystemRegionAsync() {</span>
-<span class="source-line-no">3216</span><span id="line-3216">    assignmentManager.checkIfShouldMoveSystemRegionAsync();</span>
-<span class="source-line-no">3217</span><span id="line-3217">  }</span>
-<span class="source-line-no">3218</span><span id="line-3218"></span>
-<span class="source-line-no">3219</span><span id="line-3219">  /** Returns array of coprocessor SimpleNames. */</span>
-<span class="source-line-no">3220</span><span id="line-3220">  public String[] getMasterCoprocessors() {</span>
-<span class="source-line-no">3221</span><span id="line-3221">    Set&lt;String&gt; masterCoprocessors = getMasterCoprocessorHost().getCoprocessors();</span>
-<span class="source-line-no">3222</span><span id="line-3222">    return masterCoprocessors.toArray(new String[masterCoprocessors.size()]);</span>
-<span class="source-line-no">3223</span><span id="line-3223">  }</span>
-<span class="source-line-no">3224</span><span id="line-3224"></span>
-<span class="source-line-no">3225</span><span id="line-3225">  @Override</span>
-<span class="source-line-no">3226</span><span id="line-3226">  public void abort(String reason, Throwable cause) {</span>
-<span class="source-line-no">3227</span><span id="line-3227">    if (!setAbortRequested() || isStopped()) {</span>
-<span class="source-line-no">3228</span><span id="line-3228">      LOG.debug("Abort called but aborted={}, stopped={}", isAborted(), isStopped());</span>
-<span class="source-line-no">3229</span><span id="line-3229">      return;</span>
-<span class="source-line-no">3230</span><span id="line-3230">    }</span>
-<span class="source-line-no">3231</span><span id="line-3231">    if (cpHost != null) {</span>
-<span class="source-line-no">3232</span><span id="line-3232">      // HBASE-4014: dump a list of loaded coprocessors.</span>
-<span class="source-line-no">3233</span><span id="line-3233">      LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">3234</span><span id="line-3234">        "Master server abort: loaded coprocessors are: " + getLoadedCoprocessors());</span>
-<span class="source-line-no">3235</span><span id="line-3235">    }</span>
-<span class="source-line-no">3236</span><span id="line-3236">    String msg = "***** ABORTING master " + this + ": " + reason + " *****";</span>
-<span class="source-line-no">3237</span><span id="line-3237">    if (cause != null) {</span>
-<span class="source-line-no">3238</span><span id="line-3238">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
-<span class="source-line-no">3239</span><span id="line-3239">    } else {</span>
-<span class="source-line-no">3240</span><span id="line-3240">      LOG.error(HBaseMarkers.FATAL, msg);</span>
-<span class="source-line-no">3241</span><span id="line-3241">    }</span>
-<span class="source-line-no">3242</span><span id="line-3242"></span>
-<span class="source-line-no">3243</span><span id="line-3243">    try {</span>
-<span class="source-line-no">3244</span><span id="line-3244">      stopMaster();</span>
-<span class="source-line-no">3245</span><span id="line-3245">    } catch (IOException e) {</span>
-<span class="source-line-no">3246</span><span id="line-3246">      LOG.error("Exception occurred while stopping master", e);</span>
-<span class="source-line-no">3247</span><span id="line-3247">    }</span>
-<span class="source-line-no">3248</span><span id="line-3248">  }</span>
-<span class="source-line-no">3249</span><span id="line-3249"></span>
-<span class="source-line-no">3250</span><span id="line-3250">  @Override</span>
-<span class="source-line-no">3251</span><span id="line-3251">  public MasterCoprocessorHost getMasterCoprocessorHost() {</span>
-<span class="source-line-no">3252</span><span id="line-3252">    return cpHost;</span>
-<span class="source-line-no">3253</span><span id="line-3253">  }</span>
-<span class="source-line-no">3254</span><span id="line-3254"></span>
-<span class="source-line-no">3255</span><span id="line-3255">  @Override</span>
-<span class="source-line-no">3256</span><span id="line-3256">  public MasterQuotaManager getMasterQuotaManager() {</span>
-<span class="source-line-no">3257</span><span id="line-3257">    return quotaManager;</span>
-<span class="source-line-no">3258</span><span id="line-3258">  }</span>
-<span class="source-line-no">3259</span><span id="line-3259"></span>
-<span class="source-line-no">3260</span><span id="line-3260">  @Override</span>
-<span class="source-line-no">3261</span><span id="line-3261">  public ProcedureExecutor&lt;MasterProcedureEnv&gt; getMasterProcedureExecutor() {</span>
-<span class="source-line-no">3262</span><span id="line-3262">    return procedureExecutor;</span>
-<span class="source-line-no">3263</span><span id="line-3263">  }</span>
-<span class="source-line-no">3264</span><span id="line-3264"></span>
-<span class="source-line-no">3265</span><span id="line-3265">  @Override</span>
-<span class="source-line-no">3266</span><span id="line-3266">  public ServerName getServerName() {</span>
-<span class="source-line-no">3267</span><span id="line-3267">    return this.serverName;</span>
-<span class="source-line-no">3268</span><span id="line-3268">  }</span>
-<span class="source-line-no">3269</span><span id="line-3269"></span>
-<span class="source-line-no">3270</span><span id="line-3270">  @Override</span>
-<span class="source-line-no">3271</span><span id="line-3271">  public AssignmentManager getAssignmentManager() {</span>
-<span class="source-line-no">3272</span><span id="line-3272">    return this.assignmentManager;</span>
-<span class="source-line-no">3273</span><span id="line-3273">  }</span>
-<span class="source-line-no">3274</span><span id="line-3274"></span>
-<span class="source-line-no">3275</span><span id="line-3275">  @Override</span>
-<span class="source-line-no">3276</span><span id="line-3276">  public CatalogJanitor getCatalogJanitor() {</span>
-<span class="source-line-no">3277</span><span id="line-3277">    return this.catalogJanitorChore;</span>
-<span class="source-line-no">3278</span><span id="line-3278">  }</span>
-<span class="source-line-no">3279</span><span id="line-3279"></span>
-<span class="source-line-no">3280</span><span id="line-3280">  public MemoryBoundedLogMessageBuffer getRegionServerFatalLogBuffer() {</span>
-<span class="source-line-no">3281</span><span id="line-3281">    return rsFatals;</span>
+<span class="source-line-no">3200</span><span id="line-3200">  public ProcedureStore getProcedureStore() {</span>
+<span class="source-line-no">3201</span><span id="line-3201">    return procedureStore;</span>
+<span class="source-line-no">3202</span><span id="line-3202">  }</span>
+<span class="source-line-no">3203</span><span id="line-3203"></span>
+<span class="source-line-no">3204</span><span id="line-3204">  public int getRegionServerInfoPort(final ServerName sn) {</span>
+<span class="source-line-no">3205</span><span id="line-3205">    int port = this.serverManager.getInfoPort(sn);</span>
+<span class="source-line-no">3206</span><span id="line-3206">    return port == 0</span>
+<span class="source-line-no">3207</span><span id="line-3207">      ? conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT)</span>
+<span class="source-line-no">3208</span><span id="line-3208">      : port;</span>
+<span class="source-line-no">3209</span><span id="line-3209">  }</span>
+<span class="source-line-no">3210</span><span id="line-3210"></span>
+<span class="source-line-no">3211</span><span id="line-3211">  @Override</span>
+<span class="source-line-no">3212</span><span id="line-3212">  public String getRegionServerVersion(ServerName sn) {</span>
+<span class="source-line-no">3213</span><span id="line-3213">    // Will return "0.0.0" if the server is not online to prevent move system region to unknown</span>
+<span class="source-line-no">3214</span><span id="line-3214">    // version RS.</span>
+<span class="source-line-no">3215</span><span id="line-3215">    return this.serverManager.getVersion(sn);</span>
+<span class="source-line-no">3216</span><span id="line-3216">  }</span>
+<span class="source-line-no">3217</span><span id="line-3217"></span>
+<span class="source-line-no">3218</span><span id="line-3218">  @Override</span>
+<span class="source-line-no">3219</span><span id="line-3219">  public void checkIfShouldMoveSystemRegionAsync() {</span>
+<span class="source-line-no">3220</span><span id="line-3220">    assignmentManager.checkIfShouldMoveSystemRegionAsync();</span>
+<span class="source-line-no">3221</span><span id="line-3221">  }</span>
+<span class="source-line-no">3222</span><span id="line-3222"></span>
+<span class="source-line-no">3223</span><span id="line-3223">  /** Returns array of coprocessor SimpleNames. */</span>
+<span class="source-line-no">3224</span><span id="line-3224">  public String[] getMasterCoprocessors() {</span>
+<span class="source-line-no">3225</span><span id="line-3225">    Set&lt;String&gt; masterCoprocessors = getMasterCoprocessorHost().getCoprocessors();</span>
+<span class="source-line-no">3226</span><span id="line-3226">    return masterCoprocessors.toArray(new String[masterCoprocessors.size()]);</span>
+<span class="source-line-no">3227</span><span id="line-3227">  }</span>
+<span class="source-line-no">3228</span><span id="line-3228"></span>
+<span class="source-line-no">3229</span><span id="line-3229">  @Override</span>
+<span class="source-line-no">3230</span><span id="line-3230">  public void abort(String reason, Throwable cause) {</span>
+<span class="source-line-no">3231</span><span id="line-3231">    if (!setAbortRequested() || isStopped()) {</span>
+<span class="source-line-no">3232</span><span id="line-3232">      LOG.debug("Abort called but aborted={}, stopped={}", isAborted(), isStopped());</span>
+<span class="source-line-no">3233</span><span id="line-3233">      return;</span>
+<span class="source-line-no">3234</span><span id="line-3234">    }</span>
+<span class="source-line-no">3235</span><span id="line-3235">    if (cpHost != null) {</span>
+<span class="source-line-no">3236</span><span id="line-3236">      // HBASE-4014: dump a list of loaded coprocessors.</span>
+<span class="source-line-no">3237</span><span id="line-3237">      LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">3238</span><span id="line-3238">        "Master server abort: loaded coprocessors are: " + getLoadedCoprocessors());</span>
+<span class="source-line-no">3239</span><span id="line-3239">    }</span>
+<span class="source-line-no">3240</span><span id="line-3240">    String msg = "***** ABORTING master " + this + ": " + reason + " *****";</span>
+<span class="source-line-no">3241</span><span id="line-3241">    if (cause != null) {</span>
+<span class="source-line-no">3242</span><span id="line-3242">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
+<span class="source-line-no">3243</span><span id="line-3243">    } else {</span>
+<span class="source-line-no">3244</span><span id="line-3244">      LOG.error(HBaseMarkers.FATAL, msg);</span>
+<span class="source-line-no">3245</span><span id="line-3245">    }</span>
+<span class="source-line-no">3246</span><span id="line-3246"></span>
+<span class="source-line-no">3247</span><span id="line-3247">    try {</span>
+<span class="source-line-no">3248</span><span id="line-3248">      stopMaster();</span>
+<span class="source-line-no">3249</span><span id="line-3249">    } catch (IOException e) {</span>
+<span class="source-line-no">3250</span><span id="line-3250">      LOG.error("Exception occurred while stopping master", e);</span>
+<span class="source-line-no">3251</span><span id="line-3251">    }</span>
+<span class="source-line-no">3252</span><span id="line-3252">  }</span>
+<span class="source-line-no">3253</span><span id="line-3253"></span>
+<span class="source-line-no">3254</span><span id="line-3254">  @Override</span>
+<span class="source-line-no">3255</span><span id="line-3255">  public MasterCoprocessorHost getMasterCoprocessorHost() {</span>
+<span class="source-line-no">3256</span><span id="line-3256">    return cpHost;</span>
+<span class="source-line-no">3257</span><span id="line-3257">  }</span>
+<span class="source-line-no">3258</span><span id="line-3258"></span>
+<span class="source-line-no">3259</span><span id="line-3259">  @Override</span>
+<span class="source-line-no">3260</span><span id="line-3260">  public MasterQuotaManager getMasterQuotaManager() {</span>
+<span class="source-line-no">3261</span><span id="line-3261">    return quotaManager;</span>
+<span class="source-line-no">3262</span><span id="line-3262">  }</span>
+<span class="source-line-no">3263</span><span id="line-3263"></span>
+<span class="source-line-no">3264</span><span id="line-3264">  @Override</span>
+<span class="source-line-no">3265</span><span id="line-3265">  public ProcedureExecutor&lt;MasterProcedureEnv&gt; getMasterProcedureExecutor() {</span>
+<span class="source-line-no">3266</span><span id="line-3266">    return procedureExecutor;</span>
+<span class="source-line-no">3267</span><span id="line-3267">  }</span>
+<span class="source-line-no">3268</span><span id="line-3268"></span>
+<span class="source-line-no">3269</span><span id="line-3269">  @Override</span>
+<span class="source-line-no">3270</span><span id="line-3270">  public ServerName getServerName() {</span>
+<span class="source-line-no">3271</span><span id="line-3271">    return this.serverName;</span>
+<span class="source-line-no">3272</span><span id="line-3272">  }</span>
+<span class="source-line-no">3273</span><span id="line-3273"></span>
+<span class="source-line-no">3274</span><span id="line-3274">  @Override</span>
+<span class="source-line-no">3275</span><span id="line-3275">  public AssignmentManager getAssignmentManager() {</span>
+<span class="source-line-no">3276</span><span id="line-3276">    return this.assignmentManager;</span>
+<span class="source-line-no">3277</span><span id="line-3277">  }</span>
+<span class="source-line-no">3278</span><span id="line-3278"></span>
+<span class="source-line-no">3279</span><span id="line-3279">  @Override</span>
+<span class="source-line-no">3280</span><span id="line-3280">  public CatalogJanitor getCatalogJanitor() {</span>
+<span class="source-line-no">3281</span><span id="line-3281">    return this.catalogJanitorChore;</span>
 <span class="source-line-no">3282</span><span id="line-3282">  }</span>
 <span class="source-line-no">3283</span><span id="line-3283"></span>
-<span class="source-line-no">3284</span><span id="line-3284">  public TaskGroup getStartupProgress() {</span>
-<span class="source-line-no">3285</span><span id="line-3285">    return startupTaskGroup;</span>
+<span class="source-line-no">3284</span><span id="line-3284">  public MemoryBoundedLogMessageBuffer getRegionServerFatalLogBuffer() {</span>
+<span class="source-line-no">3285</span><span id="line-3285">    return rsFatals;</span>
 <span class="source-line-no">3286</span><span id="line-3286">  }</span>
 <span class="source-line-no">3287</span><span id="line-3287"></span>
-<span class="source-line-no">3288</span><span id="line-3288">  /**</span>
-<span class="source-line-no">3289</span><span id="line-3289">   * Shutdown the cluster. Master runs a coordinated stop of all RegionServers and then itself.</span>
-<span class="source-line-no">3290</span><span id="line-3290">   */</span>
-<span class="source-line-no">3291</span><span id="line-3291">  public void shutdown() throws IOException {</span>
-<span class="source-line-no">3292</span><span id="line-3292">    TraceUtil.trace(() -&gt; {</span>
-<span class="source-line-no">3293</span><span id="line-3293">      if (cpHost != null) {</span>
-<span class="source-line-no">3294</span><span id="line-3294">        cpHost.preShutdown();</span>
-<span class="source-line-no">3295</span><span id="line-3295">      }</span>
-<span class="source-line-no">3296</span><span id="line-3296"></span>
-<span class="source-line-no">3297</span><span id="line-3297">      // Tell the servermanager cluster shutdown has been called. This makes it so when Master is</span>
-<span class="source-line-no">3298</span><span id="line-3298">      // last running server, it'll stop itself. Next, we broadcast the cluster shutdown by setting</span>
-<span class="source-line-no">3299</span><span id="line-3299">      // the cluster status as down. RegionServers will notice this change in state and will start</span>
-<span class="source-line-no">3300</span><span id="line-3300">      // shutting themselves down. When last has exited, Master can go down.</span>
-<span class="source-line-no">3301</span><span id="line-3301">      if (this.serverManager != null) {</span>
-<span class="source-line-no">3302</span><span id="line-3302">        this.serverManager.shutdownCluster();</span>
-<span class="source-line-no">3303</span><span id="line-3303">      }</span>
-<span class="source-line-no">3304</span><span id="line-3304">      if (this.clusterStatusTracker != null) {</span>
-<span class="source-line-no">3305</span><span id="line-3305">        try {</span>
-<span class="source-line-no">3306</span><span id="line-3306">          this.clusterStatusTracker.setClusterDown();</span>
-<span class="source-line-no">3307</span><span id="line-3307">        } catch (KeeperException e) {</span>
-<span class="source-line-no">3308</span><span id="line-3308">          LOG.error("ZooKeeper exception trying to set cluster as down in ZK", e);</span>
-<span class="source-line-no">3309</span><span id="line-3309">        }</span>
-<span class="source-line-no">3310</span><span id="line-3310">      }</span>
-<span class="source-line-no">3311</span><span id="line-3311">      // Stop the procedure executor. Will stop any ongoing assign, unassign, server crash etc.,</span>
-<span class="source-line-no">3312</span><span id="line-3312">      // processing so we can go down.</span>
-<span class="source-line-no">3313</span><span id="line-3313">      if (this.procedureExecutor != null) {</span>
-<span class="source-line-no">3314</span><span id="line-3314">        this.procedureExecutor.stop();</span>
-<span class="source-line-no">3315</span><span id="line-3315">      }</span>
-<span class="source-line-no">3316</span><span id="line-3316">      // Shutdown our cluster connection. This will kill any hosted RPCs that might be going on;</span>
-<span class="source-line-no">3317</span><span id="line-3317">      // this is what we want especially if the Master is in startup phase doing call outs to</span>
-<span class="source-line-no">3318</span><span id="line-3318">      // hbase:meta, etc. when cluster is down. Without ths connection close, we'd have to wait on</span>
-<span class="source-line-no">3319</span><span id="line-3319">      // the rpc to timeout.</span>
-<span class="source-line-no">3320</span><span id="line-3320">      if (this.asyncClusterConnection != null) {</span>
-<span class="source-line-no">3321</span><span id="line-3321">        this.asyncClusterConnection.close();</span>
-<span class="source-line-no">3322</span><span id="line-3322">      }</span>
-<span class="source-line-no">3323</span><span id="line-3323">    }, "HMaster.shutdown");</span>
-<span class="source-line-no">3324</span><span id="line-3324">  }</span>
-<span class="source-line-no">3325</span><span id="line-3325"></span>
-<span class="source-line-no">3326</span><span id="line-3326">  public void stopMaster() throws IOException {</span>
-<span class="source-line-no">3327</span><span id="line-3327">    if (cpHost != null) {</span>
-<span class="source-line-no">3328</span><span id="line-3328">      cpHost.preStopMaster();</span>
-<span class="source-line-no">3329</span><span id="line-3329">    }</span>
-<span class="source-line-no">3330</span><span id="line-3330">    stop("Stopped by " + Thread.currentThread().getName());</span>
-<span class="source-line-no">3331</span><span id="line-3331">  }</span>
-<span class="source-line-no">3332</span><span id="line-3332"></span>
-<span class="source-line-no">3333</span><span id="line-3333">  @Override</span>
-<span class="source-line-no">3334</span><span id="line-3334">  public void stop(String msg) {</span>
-<span class="source-line-no">3335</span><span id="line-3335">    if (!this.stopped) {</span>
-<span class="source-line-no">3336</span><span id="line-3336">      LOG.info("***** STOPPING master '" + this + "' *****");</span>
-<span class="source-line-no">3337</span><span id="line-3337">      this.stopped = true;</span>
-<span class="source-line-no">3338</span><span id="line-3338">      LOG.info("STOPPED: " + msg);</span>
-<span class="source-line-no">3339</span><span id="line-3339">      // Wakes run() if it is sleeping</span>
-<span class="source-line-no">3340</span><span id="line-3340">      sleeper.skipSleepCycle();</span>
-<span class="source-line-no">3341</span><span id="line-3341">      if (this.activeMasterManager != null) {</span>
-<span class="source-line-no">3342</span><span id="line-3342">        this.activeMasterManager.stop();</span>
-<span class="source-line-no">3343</span><span id="line-3343">      }</span>
-<span class="source-line-no">3344</span><span id="line-3344">    }</span>
-<span class="source-line-no">3345</span><span id="line-3345">  }</span>
-<span class="source-line-no">3346</span><span id="line-3346"></span>
-<span class="source-line-no">3347</span><span id="line-3347">  protected void checkServiceStarted() throws ServerNotRunningYetException {</span>
-<span class="source-line-no">3348</span><span id="line-3348">    if (!serviceStarted) {</span>
-<span class="source-line-no">3349</span><span id="line-3349">      throw new ServerNotRunningYetException("Server is not running yet");</span>
-<span class="source-line-no">3350</span><span id="line-3350">    }</span>
-<span class="source-line-no">3351</span><span id="line-3351">  }</span>
-<span class="source-line-no">3352</span><span id="line-3352"></span>
-<span class="source-line-no">3353</span><span id="line-3353">  void checkInitialized() throws PleaseHoldException, ServerNotRunningYetException,</span>
-<span class="source-line-no">3354</span><span id="line-3354">    MasterNotRunningException, MasterStoppedException {</span>
-<span class="source-line-no">3355</span><span id="line-3355">    checkServiceStarted();</span>
-<span class="source-line-no">3356</span><span id="line-3356">    if (!isInitialized()) {</span>
-<span class="source-line-no">3357</span><span id="line-3357">      throw new PleaseHoldException("Master is initializing");</span>
-<span class="source-line-no">3358</span><span id="line-3358">    }</span>
-<span class="source-line-no">3359</span><span id="line-3359">    if (isStopped()) {</span>
-<span class="source-line-no">3360</span><span id="line-3360">      throw new MasterStoppedException();</span>
-<span class="source-line-no">3361</span><span id="line-3361">    }</span>
-<span class="source-line-no">3362</span><span id="line-3362">  }</span>
-<span class="source-line-no">3363</span><span id="line-3363"></span>
-<span class="source-line-no">3364</span><span id="line-3364">  /**</span>
-<span class="source-line-no">3365</span><span id="line-3365">   * Report whether this master is currently the active master or not. If not active master, we are</span>
-<span class="source-line-no">3366</span><span id="line-3366">   * parked on ZK waiting to become active. This method is used for testing.</span>
-<span class="source-line-no">3367</span><span id="line-3367">   * @return true if active master, false if not.</span>
-<span class="source-line-no">3368</span><span id="line-3368">   */</span>
-<span class="source-line-no">3369</span><span id="line-3369">  @Override</span>
-<span class="source-line-no">3370</span><span id="line-3370">  public boolean isActiveMaster() {</span>
-<span class="source-line-no">3371</span><span id="line-3371">    return activeMaster;</span>
-<span class="source-line-no">3372</span><span id="line-3372">  }</span>
-<span class="source-line-no">3373</span><span id="line-3373"></span>
-<span class="source-line-no">3374</span><span id="line-3374">  /**</span>
-<span class="source-line-no">3375</span><span id="line-3375">   * Report whether this master has completed with its initialization and is ready. If ready, the</span>
-<span class="source-line-no">3376</span><span id="line-3376">   * master is also the active master. A standby master is never ready. This method is used for</span>
-<span class="source-line-no">3377</span><span id="line-3377">   * testing.</span>
-<span class="source-line-no">3378</span><span id="line-3378">   * @return true if master is ready to go, false if not.</span>
-<span class="source-line-no">3379</span><span id="line-3379">   */</span>
-<span class="source-line-no">3380</span><span id="line-3380">  @Override</span>
-<span class="source-line-no">3381</span><span id="line-3381">  public boolean isInitialized() {</span>
-<span class="source-line-no">3382</span><span id="line-3382">    return initialized.isReady();</span>
-<span class="source-line-no">3383</span><span id="line-3383">  }</span>
-<span class="source-line-no">3384</span><span id="line-3384"></span>
-<span class="source-line-no">3385</span><span id="line-3385">  /**</span>
-<span class="source-line-no">3386</span><span id="line-3386">   * Report whether this master is started This method is used for testing.</span>
-<span class="source-line-no">3387</span><span id="line-3387">   * @return true if master is ready to go, false if not.</span>
-<span class="source-line-no">3388</span><span id="line-3388">   */</span>
-<span class="source-line-no">3389</span><span id="line-3389">  public boolean isOnline() {</span>
-<span class="source-line-no">3390</span><span id="line-3390">    return serviceStarted;</span>
-<span class="source-line-no">3391</span><span id="line-3391">  }</span>
-<span class="source-line-no">3392</span><span id="line-3392"></span>
-<span class="source-line-no">3393</span><span id="line-3393">  /**</span>
-<span class="source-line-no">3394</span><span id="line-3394">   * Report whether this master is in maintenance mode.</span>
-<span class="source-line-no">3395</span><span id="line-3395">   * @return true if master is in maintenanceMode</span>
-<span class="source-line-no">3396</span><span id="line-3396">   */</span>
-<span class="source-line-no">3397</span><span id="line-3397">  @Override</span>
-<span class="source-line-no">3398</span><span id="line-3398">  public boolean isInMaintenanceMode() {</span>
-<span class="source-line-no">3399</span><span id="line-3399">    return maintenanceMode;</span>
-<span class="source-line-no">3400</span><span id="line-3400">  }</span>
-<span class="source-line-no">3401</span><span id="line-3401"></span>
-<span class="source-line-no">3402</span><span id="line-3402">  public void setInitialized(boolean isInitialized) {</span>
-<span class="source-line-no">3403</span><span id="line-3403">    procedureExecutor.getEnvironment().setEventReady(initialized, isInitialized);</span>
+<span class="source-line-no">3288</span><span id="line-3288">  public TaskGroup getStartupProgress() {</span>
+<span class="source-line-no">3289</span><span id="line-3289">    return startupTaskGroup;</span>
+<span class="source-line-no">3290</span><span id="line-3290">  }</span>
+<span class="source-line-no">3291</span><span id="line-3291"></span>
+<span class="source-line-no">3292</span><span id="line-3292">  /**</span>
+<span class="source-line-no">3293</span><span id="line-3293">   * Shutdown the cluster. Master runs a coordinated stop of all RegionServers and then itself.</span>
+<span class="source-line-no">3294</span><span id="line-3294">   */</span>
+<span class="source-line-no">3295</span><span id="line-3295">  public void shutdown() throws IOException {</span>
+<span class="source-line-no">3296</span><span id="line-3296">    TraceUtil.trace(() -&gt; {</span>
+<span class="source-line-no">3297</span><span id="line-3297">      if (cpHost != null) {</span>
+<span class="source-line-no">3298</span><span id="line-3298">        cpHost.preShutdown();</span>
+<span class="source-line-no">3299</span><span id="line-3299">      }</span>
+<span class="source-line-no">3300</span><span id="line-3300"></span>
+<span class="source-line-no">3301</span><span id="line-3301">      // Tell the servermanager cluster shutdown has been called. This makes it so when Master is</span>
+<span class="source-line-no">3302</span><span id="line-3302">      // last running server, it'll stop itself. Next, we broadcast the cluster shutdown by setting</span>
+<span class="source-line-no">3303</span><span id="line-3303">      // the cluster status as down. RegionServers will notice this change in state and will start</span>
+<span class="source-line-no">3304</span><span id="line-3304">      // shutting themselves down. When last has exited, Master can go down.</span>
+<span class="source-line-no">3305</span><span id="line-3305">      if (this.serverManager != null) {</span>
+<span class="source-line-no">3306</span><span id="line-3306">        this.serverManager.shutdownCluster();</span>
+<span class="source-line-no">3307</span><span id="line-3307">      }</span>
+<span class="source-line-no">3308</span><span id="line-3308">      if (this.clusterStatusTracker != null) {</span>
+<span class="source-line-no">3309</span><span id="line-3309">        try {</span>
+<span class="source-line-no">3310</span><span id="line-3310">          this.clusterStatusTracker.setClusterDown();</span>
+<span class="source-line-no">3311</span><span id="line-3311">        } catch (KeeperException e) {</span>
+<span class="source-line-no">3312</span><span id="line-3312">          LOG.error("ZooKeeper exception trying to set cluster as down in ZK", e);</span>
+<span class="source-line-no">3313</span><span id="line-3313">        }</span>
+<span class="source-line-no">3314</span><span id="line-3314">      }</span>
+<span class="source-line-no">3315</span><span id="line-3315">      // Stop the procedure executor. Will stop any ongoing assign, unassign, server crash etc.,</span>
+<span class="source-line-no">3316</span><span id="line-3316">      // processing so we can go down.</span>
+<span class="source-line-no">3317</span><span id="line-3317">      if (this.procedureExecutor != null) {</span>
+<span class="source-line-no">3318</span><span id="line-3318">        this.procedureExecutor.stop();</span>
+<span class="source-line-no">3319</span><span id="line-3319">      }</span>
+<span class="source-line-no">3320</span><span id="line-3320">      // Shutdown our cluster connection. This will kill any hosted RPCs that might be going on;</span>
+<span class="source-line-no">3321</span><span id="line-3321">      // this is what we want especially if the Master is in startup phase doing call outs to</span>
+<span class="source-line-no">3322</span><span id="line-3322">      // hbase:meta, etc. when cluster is down. Without ths connection close, we'd have to wait on</span>
+<span class="source-line-no">3323</span><span id="line-3323">      // the rpc to timeout.</span>
+<span class="source-line-no">3324</span><span id="line-3324">      if (this.asyncClusterConnection != null) {</span>
+<span class="source-line-no">3325</span><span id="line-3325">        this.asyncClusterConnection.close();</span>
+<span class="source-line-no">3326</span><span id="line-3326">      }</span>
+<span class="source-line-no">3327</span><span id="line-3327">    }, "HMaster.shutdown");</span>
+<span class="source-line-no">3328</span><span id="line-3328">  }</span>
+<span class="source-line-no">3329</span><span id="line-3329"></span>
+<span class="source-line-no">3330</span><span id="line-3330">  public void stopMaster() throws IOException {</span>
+<span class="source-line-no">3331</span><span id="line-3331">    if (cpHost != null) {</span>
+<span class="source-line-no">3332</span><span id="line-3332">      cpHost.preStopMaster();</span>
+<span class="source-line-no">3333</span><span id="line-3333">    }</span>
+<span class="source-line-no">3334</span><span id="line-3334">    stop("Stopped by " + Thread.currentThread().getName());</span>
+<span class="source-line-no">3335</span><span id="line-3335">  }</span>
+<span class="source-line-no">3336</span><span id="line-3336"></span>
+<span class="source-line-no">3337</span><span id="line-3337">  @Override</span>
+<span class="source-line-no">3338</span><span id="line-3338">  public void stop(String msg) {</span>
+<span class="source-line-no">3339</span><span id="line-3339">    if (!this.stopped) {</span>
+<span class="source-line-no">3340</span><span id="line-3340">      LOG.info("***** STOPPING master '" + this + "' *****");</span>
+<span class="source-line-no">3341</span><span id="line-3341">      this.stopped = true;</span>
+<span class="source-line-no">3342</span><span id="line-3342">      LOG.info("STOPPED: " + msg);</span>
+<span class="source-line-no">3343</span><span id="line-3343">      // Wakes run() if it is sleeping</span>
+<span class="source-line-no">3344</span><span id="line-3344">      sleeper.skipSleepCycle();</span>
+<span class="source-line-no">3345</span><span id="line-3345">      if (this.activeMasterManager != null) {</span>
+<span class="source-line-no">3346</span><span id="line-3346">        this.activeMasterManager.stop();</span>
+<span class="source-line-no">3347</span><span id="line-3347">      }</span>
+<span class="source-line-no">3348</span><span id="line-3348">    }</span>
+<span class="source-line-no">3349</span><span id="line-3349">  }</span>
+<span class="source-line-no">3350</span><span id="line-3350"></span>
+<span class="source-line-no">3351</span><span id="line-3351">  protected void checkServiceStarted() throws ServerNotRunningYetException {</span>
+<span class="source-line-no">3352</span><span id="line-3352">    if (!serviceStarted) {</span>
+<span class="source-line-no">3353</span><span id="line-3353">      throw new ServerNotRunningYetException("Server is not running yet");</span>
+<span class="source-line-no">3354</span><span id="line-3354">    }</span>
+<span class="source-line-no">3355</span><span id="line-3355">  }</span>
+<span class="source-line-no">3356</span><span id="line-3356"></span>
+<span class="source-line-no">3357</span><span id="line-3357">  void checkInitialized() throws PleaseHoldException, ServerNotRunningYetException,</span>
+<span class="source-line-no">3358</span><span id="line-3358">    MasterNotRunningException, MasterStoppedException {</span>
+<span class="source-line-no">3359</span><span id="line-3359">    checkServiceStarted();</span>
+<span class="source-line-no">3360</span><span id="line-3360">    if (!isInitialized()) {</span>
+<span class="source-line-no">3361</span><span id="line-3361">      throw new PleaseHoldException("Master is initializing");</span>
+<span class="source-line-no">3362</span><span id="line-3362">    }</span>
+<span class="source-line-no">3363</span><span id="line-3363">    if (isStopped()) {</span>
+<span class="source-line-no">3364</span><span id="line-3364">      throw new MasterStoppedException();</span>
+<span class="source-line-no">3365</span><span id="line-3365">    }</span>
+<span class="source-line-no">3366</span><span id="line-3366">  }</span>
+<span class="source-line-no">3367</span><span id="line-3367"></span>
+<span class="source-line-no">3368</span><span id="line-3368">  /**</span>
+<span class="source-line-no">3369</span><span id="line-3369">   * Report whether this master is currently the active master or not. If not active master, we are</span>
+<span class="source-line-no">3370</span><span id="line-3370">   * parked on ZK waiting to become active. This method is used for testing.</span>
+<span class="source-line-no">3371</span><span id="line-3371">   * @return true if active master, false if not.</span>
+<span class="source-line-no">3372</span><span id="line-3372">   */</span>
+<span class="source-line-no">3373</span><span id="line-3373">  @Override</span>
+<span class="source-line-no">3374</span><span id="line-3374">  public boolean isActiveMaster() {</span>
+<span class="source-line-no">3375</span><span id="line-3375">    return activeMaster;</span>
+<span class="source-line-no">3376</span><span id="line-3376">  }</span>
+<span class="source-line-no">3377</span><span id="line-3377"></span>
+<span class="source-line-no">3378</span><span id="line-3378">  /**</span>
+<span class="source-line-no">3379</span><span id="line-3379">   * Report whether this master has completed with its initialization and is ready. If ready, the</span>
+<span class="source-line-no">3380</span><span id="line-3380">   * master is also the active master. A standby master is never ready. This method is used for</span>
+<span class="source-line-no">3381</span><span id="line-3381">   * testing.</span>
+<span class="source-line-no">3382</span><span id="line-3382">   * @return true if master is ready to go, false if not.</span>
+<span class="source-line-no">3383</span><span id="line-3383">   */</span>
+<span class="source-line-no">3384</span><span id="line-3384">  @Override</span>
+<span class="source-line-no">3385</span><span id="line-3385">  public boolean isInitialized() {</span>
+<span class="source-line-no">3386</span><span id="line-3386">    return initialized.isReady();</span>
+<span class="source-line-no">3387</span><span id="line-3387">  }</span>
+<span class="source-line-no">3388</span><span id="line-3388"></span>
+<span class="source-line-no">3389</span><span id="line-3389">  /**</span>
+<span class="source-line-no">3390</span><span id="line-3390">   * Report whether this master is started This method is used for testing.</span>
+<span class="source-line-no">3391</span><span id="line-3391">   * @return true if master is ready to go, false if not.</span>
+<span class="source-line-no">3392</span><span id="line-3392">   */</span>
+<span class="source-line-no">3393</span><span id="line-3393">  public boolean isOnline() {</span>
+<span class="source-line-no">3394</span><span id="line-3394">    return serviceStarted;</span>
+<span class="source-line-no">3395</span><span id="line-3395">  }</span>
+<span class="source-line-no">3396</span><span id="line-3396"></span>
+<span class="source-line-no">3397</span><span id="line-3397">  /**</span>
+<span class="source-line-no">3398</span><span id="line-3398">   * Report whether this master is in maintenance mode.</span>
+<span class="source-line-no">3399</span><span id="line-3399">   * @return true if master is in maintenanceMode</span>
+<span class="source-line-no">3400</span><span id="line-3400">   */</span>
+<span class="source-line-no">3401</span><span id="line-3401">  @Override</span>
+<span class="source-line-no">3402</span><span id="line-3402">  public boolean isInMaintenanceMode() {</span>
+<span class="source-line-no">3403</span><span id="line-3403">    return maintenanceMode;</span>
 <span class="source-line-no">3404</span><span id="line-3404">  }</span>
 <span class="source-line-no">3405</span><span id="line-3405"></span>
-<span class="source-line-no">3406</span><span id="line-3406">  /**</span>
-<span class="source-line-no">3407</span><span id="line-3407">   * Mainly used in procedure related tests, where we will restart ProcedureExecutor and</span>
-<span class="source-line-no">3408</span><span id="line-3408">   * AssignmentManager, but we do not want to restart master(to speed up the test), so we need to</span>
-<span class="source-line-no">3409</span><span id="line-3409">   * disable rpc for a while otherwise some critical rpc requests such as</span>
-<span class="source-line-no">3410</span><span id="line-3410">   * reportRegionStateTransition could fail and cause region server to abort.</span>
-<span class="source-line-no">3411</span><span id="line-3411">   */</span>
-<span class="source-line-no">3412</span><span id="line-3412">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">3413</span><span id="line-3413">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">3414</span><span id="line-3414">  public void setServiceStarted(boolean started) {</span>
-<span class="source-line-no">3415</span><span id="line-3415">    this.serviceStarted = started;</span>
-<span class="source-line-no">3416</span><span id="line-3416">  }</span>
-<span class="source-line-no">3417</span><span id="line-3417"></span>
-<span class="source-line-no">3418</span><span id="line-3418">  @Override</span>
-<span class="source-line-no">3419</span><span id="line-3419">  public ProcedureEvent&lt;?&gt; getInitializedEvent() {</span>
-<span class="source-line-no">3420</span><span id="line-3420">    return initialized;</span>
-<span class="source-line-no">3421</span><span id="line-3421">  }</span>
-<span class="source-line-no">3422</span><span id="line-3422"></span>
-<span class="source-line-no">3423</span><span id="line-3423">  /**</span>
-<span class="source-line-no">3424</span><span id="line-3424">   * Compute the average load across all region servers. Currently, this uses a very naive</span>
-<span class="source-line-no">3425</span><span id="line-3425">   * computation - just uses the number of regions being served, ignoring stats about number of</span>
-<span class="source-line-no">3426</span><span id="line-3426">   * requests.</span>
-<span class="source-line-no">3427</span><span id="line-3427">   * @return the average load</span>
-<span class="source-line-no">3428</span><span id="line-3428">   */</span>
-<span class="source-line-no">3429</span><span id="line-3429">  public double getAverageLoad() {</span>
-<span class="source-line-no">3430</span><span id="line-3430">    if (this.assignmentManager == null) {</span>
-<span class="source-line-no">3431</span><span id="line-3431">      return 0;</span>
-<span class="source-line-no">3432</span><span id="line-3432">    }</span>
-<span class="source-line-no">3433</span><span id="line-3433"></span>
-<span class="source-line-no">3434</span><span id="line-3434">    RegionStates regionStates = this.assignmentManager.getRegionStates();</span>
-<span class="source-line-no">3435</span><span id="line-3435">    if (regionStates == null) {</span>
-<span class="source-line-no">3436</span><span id="line-3436">      return 0;</span>
-<span class="source-line-no">3437</span><span id="line-3437">    }</span>
-<span class="source-line-no">3438</span><span id="line-3438">    return regionStates.getAverageLoad();</span>
-<span class="source-line-no">3439</span><span id="line-3439">  }</span>
-<span class="source-line-no">3440</span><span id="line-3440"></span>
-<span class="source-line-no">3441</span><span id="line-3441">  @Override</span>
-<span class="source-line-no">3442</span><span id="line-3442">  public boolean registerService(Service instance) {</span>
-<span class="source-line-no">3443</span><span id="line-3443">    /*</span>
-<span class="source-line-no">3444</span><span id="line-3444">     * No stacking of instances is allowed for a single service name</span>
-<span class="source-line-no">3445</span><span id="line-3445">     */</span>
-<span class="source-line-no">3446</span><span id="line-3446">    Descriptors.ServiceDescriptor serviceDesc = instance.getDescriptorForType();</span>
-<span class="source-line-no">3447</span><span id="line-3447">    String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc);</span>
-<span class="source-line-no">3448</span><span id="line-3448">    if (coprocessorServiceHandlers.containsKey(serviceName)) {</span>
-<span class="source-line-no">3449</span><span id="line-3449">      LOG.error("Coprocessor service " + serviceName</span>
-<span class="source-line-no">3450</span><span id="line-3450">        + " already registered, rejecting request from " + instance);</span>
-<span class="source-line-no">3451</span><span id="line-3451">      return false;</span>
-<span class="source-line-no">3452</span><span id="line-3452">    }</span>
-<span class="source-line-no">3453</span><span id="line-3453"></span>
-<span class="source-line-no">3454</span><span id="line-3454">    coprocessorServiceHandlers.put(serviceName, instance);</span>
-<span class="source-line-no">3455</span><span id="line-3455">    if (LOG.isDebugEnabled()) {</span>
-<span class="source-line-no">3456</span><span id="line-3456">      LOG.debug("Registered master coprocessor service: service=" + serviceName);</span>
-<span class="source-line-no">3457</span><span id="line-3457">    }</span>
-<span class="source-line-no">3458</span><span id="line-3458">    return true;</span>
-<span class="source-line-no">3459</span><span id="line-3459">  }</span>
-<span class="source-line-no">3460</span><span id="line-3460"></span>
-<span class="source-line-no">3461</span><span id="line-3461">  /**</span>
-<span class="source-line-no">3462</span><span id="line-3462">   * Utility for constructing an instance of the passed HMaster class.</span>
-<span class="source-line-no">3463</span><span id="line-3463">   * @return HMaster instance.</span>
-<span class="source-line-no">3464</span><span id="line-3464">   */</span>
-<span class="source-line-no">3465</span><span id="line-3465">  public static HMaster constructMaster(Class&lt;? extends HMaster&gt; masterClass,</span>
-<span class="source-line-no">3466</span><span id="line-3466">    final Configuration conf) {</span>
-<span class="source-line-no">3467</span><span id="line-3467">    try {</span>
-<span class="source-line-no">3468</span><span id="line-3468">      Constructor&lt;? extends HMaster&gt; c = masterClass.getConstructor(Configuration.class);</span>
-<span class="source-line-no">3469</span><span id="line-3469">      return c.newInstance(conf);</span>
-<span class="source-line-no">3470</span><span id="line-3470">    } catch (Exception e) {</span>
-<span class="source-line-no">3471</span><span id="line-3471">      Throwable error = e;</span>
-<span class="source-line-no">3472</span><span id="line-3472">      if (</span>
-<span class="source-line-no">3473</span><span id="line-3473">        e instanceof InvocationTargetException</span>
-<span class="source-line-no">3474</span><span id="line-3474">          &amp;&amp; ((InvocationTargetException) e).getTargetException() != null</span>
-<span class="source-line-no">3475</span><span id="line-3475">      ) {</span>
-<span class="source-line-no">3476</span><span id="line-3476">        error = ((InvocationTargetException) e).getTargetException();</span>
-<span class="source-line-no">3477</span><span id="line-3477">      }</span>
-<span class="source-line-no">3478</span><span id="line-3478">      throw new RuntimeException("Failed construction of Master: " + masterClass.toString() + ". ",</span>
-<span class="source-line-no">3479</span><span id="line-3479">        error);</span>
-<span class="source-line-no">3480</span><span id="line-3480">    }</span>
-<span class="source-line-no">3481</span><span id="line-3481">  }</span>
-<span class="source-line-no">3482</span><span id="line-3482"></span>
-<span class="source-line-no">3483</span><span id="line-3483">  /**</span>
-<span class="source-line-no">3484</span><span id="line-3484">   * @see org.apache.hadoop.hbase.master.HMasterCommandLine</span>
-<span class="source-line-no">3485</span><span id="line-3485">   */</span>
-<span class="source-line-no">3486</span><span id="line-3486">  public static void main(String[] args) {</span>
-<span class="source-line-no">3487</span><span id="line-3487">    LOG.info("STARTING service " + HMaster.class.getSimpleName());</span>
-<span class="source-line-no">3488</span><span id="line-3488">    VersionInfo.logVersion();</span>
-<span class="source-line-no">3489</span><span id="line-3489">    new HMasterCommandLine(HMaster.class).doMain(args);</span>
-<span class="source-line-no">3490</span><span id="line-3490">  }</span>
-<span class="source-line-no">3491</span><span id="line-3491"></span>
-<span class="source-line-no">3492</span><span id="line-3492">  public HFileCleaner getHFileCleaner() {</span>
-<span class="source-line-no">3493</span><span id="line-3493">    return this.hfileCleaners.get(0);</span>
+<span class="source-line-no">3406</span><span id="line-3406">  public void setInitialized(boolean isInitialized) {</span>
+<span class="source-line-no">3407</span><span id="line-3407">    procedureExecutor.getEnvironment().setEventReady(initialized, isInitialized);</span>
+<span class="source-line-no">3408</span><span id="line-3408">  }</span>
+<span class="source-line-no">3409</span><span id="line-3409"></span>
+<span class="source-line-no">3410</span><span id="line-3410">  /**</span>
+<span class="source-line-no">3411</span><span id="line-3411">   * Mainly used in procedure related tests, where we will restart ProcedureExecutor and</span>
+<span class="source-line-no">3412</span><span id="line-3412">   * AssignmentManager, but we do not want to restart master(to speed up the test), so we need to</span>
+<span class="source-line-no">3413</span><span id="line-3413">   * disable rpc for a while otherwise some critical rpc requests such as</span>
+<span class="source-line-no">3414</span><span id="line-3414">   * reportRegionStateTransition could fail and cause region server to abort.</span>
+<span class="source-line-no">3415</span><span id="line-3415">   */</span>
+<span class="source-line-no">3416</span><span id="line-3416">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">3417</span><span id="line-3417">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">3418</span><span id="line-3418">  public void setServiceStarted(boolean started) {</span>
+<span class="source-line-no">3419</span><span id="line-3419">    this.serviceStarted = started;</span>
+<span class="source-line-no">3420</span><span id="line-3420">  }</span>
+<span class="source-line-no">3421</span><span id="line-3421"></span>
+<span class="source-line-no">3422</span><span id="line-3422">  @Override</span>
+<span class="source-line-no">3423</span><span id="line-3423">  public ProcedureEvent&lt;?&gt; getInitializedEvent() {</span>
+<span class="source-line-no">3424</span><span id="line-3424">    return initialized;</span>
+<span class="source-line-no">3425</span><span id="line-3425">  }</span>
+<span class="source-line-no">3426</span><span id="line-3426"></span>
+<span class="source-line-no">3427</span><span id="line-3427">  /**</span>
+<span class="source-line-no">3428</span><span id="line-3428">   * Compute the average load across all region servers. Currently, this uses a very naive</span>
+<span class="source-line-no">3429</span><span id="line-3429">   * computation - just uses the number of regions being served, ignoring stats about number of</span>
+<span class="source-line-no">3430</span><span id="line-3430">   * requests.</span>
+<span class="source-line-no">3431</span><span id="line-3431">   * @return the average load</span>
+<span class="source-line-no">3432</span><span id="line-3432">   */</span>
+<span class="source-line-no">3433</span><span id="line-3433">  public double getAverageLoad() {</span>
+<span class="source-line-no">3434</span><span id="line-3434">    if (this.assignmentManager == null) {</span>
+<span class="source-line-no">3435</span><span id="line-3435">      return 0;</span>
+<span class="source-line-no">3436</span><span id="line-3436">    }</span>
+<span class="source-line-no">3437</span><span id="line-3437"></span>
+<span class="source-line-no">3438</span><span id="line-3438">    RegionStates regionStates = this.assignmentManager.getRegionStates();</span>
+<span class="source-line-no">3439</span><span id="line-3439">    if (regionStates == null) {</span>
+<span class="source-line-no">3440</span><span id="line-3440">      return 0;</span>
+<span class="source-line-no">3441</span><span id="line-3441">    }</span>
+<span class="source-line-no">3442</span><span id="line-3442">    return regionStates.getAverageLoad();</span>
+<span class="source-line-no">3443</span><span id="line-3443">  }</span>
+<span class="source-line-no">3444</span><span id="line-3444"></span>
+<span class="source-line-no">3445</span><span id="line-3445">  @Override</span>
+<span class="source-line-no">3446</span><span id="line-3446">  public boolean registerService(Service instance) {</span>
+<span class="source-line-no">3447</span><span id="line-3447">    /*</span>
+<span class="source-line-no">3448</span><span id="line-3448">     * No stacking of instances is allowed for a single service name</span>
+<span class="source-line-no">3449</span><span id="line-3449">     */</span>
+<span class="source-line-no">3450</span><span id="line-3450">    Descriptors.ServiceDescriptor serviceDesc = instance.getDescriptorForType();</span>
+<span class="source-line-no">3451</span><span id="line-3451">    String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc);</span>
+<span class="source-line-no">3452</span><span id="line-3452">    if (coprocessorServiceHandlers.containsKey(serviceName)) {</span>
+<span class="source-line-no">3453</span><span id="line-3453">      LOG.error("Coprocessor service " + serviceName</span>
+<span class="source-line-no">3454</span><span id="line-3454">        + " already registered, rejecting request from " + instance);</span>
+<span class="source-line-no">3455</span><span id="line-3455">      return false;</span>
+<span class="source-line-no">3456</span><span id="line-3456">    }</span>
+<span class="source-line-no">3457</span><span id="line-3457"></span>
+<span class="source-line-no">3458</span><span id="line-3458">    coprocessorServiceHandlers.put(serviceName, instance);</span>
+<span class="source-line-no">3459</span><span id="line-3459">    if (LOG.isDebugEnabled()) {</span>
+<span class="source-line-no">3460</span><span id="line-3460">      LOG.debug("Registered master coprocessor service: service=" + serviceName);</span>
+<span class="source-line-no">3461</span><span id="line-3461">    }</span>
+<span class="source-line-no">3462</span><span id="line-3462">    return true;</span>
+<span class="source-line-no">3463</span><span id="line-3463">  }</span>
+<span class="source-line-no">3464</span><span id="line-3464"></span>
+<span class="source-line-no">3465</span><span id="line-3465">  /**</span>
+<span class="source-line-no">3466</span><span id="line-3466">   * Utility for constructing an instance of the passed HMaster class.</span>
+<span class="source-line-no">3467</span><span id="line-3467">   * @return HMaster instance.</span>
+<span class="source-line-no">3468</span><span id="line-3468">   */</span>
+<span class="source-line-no">3469</span><span id="line-3469">  public static HMaster constructMaster(Class&lt;? extends HMaster&gt; masterClass,</span>
+<span class="source-line-no">3470</span><span id="line-3470">    final Configuration conf) {</span>
+<span class="source-line-no">3471</span><span id="line-3471">    try {</span>
+<span class="source-line-no">3472</span><span id="line-3472">      Constructor&lt;? extends HMaster&gt; c = masterClass.getConstructor(Configuration.class);</span>
+<span class="source-line-no">3473</span><span id="line-3473">      return c.newInstance(conf);</span>
+<span class="source-line-no">3474</span><span id="line-3474">    } catch (Exception e) {</span>
+<span class="source-line-no">3475</span><span id="line-3475">      Throwable error = e;</span>
+<span class="source-line-no">3476</span><span id="line-3476">      if (</span>
+<span class="source-line-no">3477</span><span id="line-3477">        e instanceof InvocationTargetException</span>
+<span class="source-line-no">3478</span><span id="line-3478">          &amp;&amp; ((InvocationTargetException) e).getTargetException() != null</span>
+<span class="source-line-no">3479</span><span id="line-3479">      ) {</span>
+<span class="source-line-no">3480</span><span id="line-3480">        error = ((InvocationTargetException) e).getTargetException();</span>
+<span class="source-line-no">3481</span><span id="line-3481">      }</span>
+<span class="source-line-no">3482</span><span id="line-3482">      throw new RuntimeException("Failed construction of Master: " + masterClass.toString() + ". ",</span>
+<span class="source-line-no">3483</span><span id="line-3483">        error);</span>
+<span class="source-line-no">3484</span><span id="line-3484">    }</span>
+<span class="source-line-no">3485</span><span id="line-3485">  }</span>
+<span class="source-line-no">3486</span><span id="line-3486"></span>
+<span class="source-line-no">3487</span><span id="line-3487">  /**</span>
+<span class="source-line-no">3488</span><span id="line-3488">   * @see org.apache.hadoop.hbase.master.HMasterCommandLine</span>
+<span class="source-line-no">3489</span><span id="line-3489">   */</span>
+<span class="source-line-no">3490</span><span id="line-3490">  public static void main(String[] args) {</span>
+<span class="source-line-no">3491</span><span id="line-3491">    LOG.info("STARTING service " + HMaster.class.getSimpleName());</span>
+<span class="source-line-no">3492</span><span id="line-3492">    VersionInfo.logVersion();</span>
+<span class="source-line-no">3493</span><span id="line-3493">    new HMasterCommandLine(HMaster.class).doMain(args);</span>
 <span class="source-line-no">3494</span><span id="line-3494">  }</span>
 <span class="source-line-no">3495</span><span id="line-3495"></span>
-<span class="source-line-no">3496</span><span id="line-3496">  public List&lt;HFileCleaner&gt; getHFileCleaners() {</span>
-<span class="source-line-no">3497</span><span id="line-3497">    return this.hfileCleaners;</span>
+<span class="source-line-no">3496</span><span id="line-3496">  public HFileCleaner getHFileCleaner() {</span>
+<span class="source-line-no">3497</span><span id="line-3497">    return this.hfileCleaners.get(0);</span>
 <span class="source-line-no">3498</span><span id="line-3498">  }</span>
 <span class="source-line-no">3499</span><span id="line-3499"></span>
-<span class="source-line-no">3500</span><span id="line-3500">  public LogCleaner getLogCleaner() {</span>
-<span class="source-line-no">3501</span><span id="line-3501">    return this.logCleaner;</span>
+<span class="source-line-no">3500</span><span id="line-3500">  public List&lt;HFileCleaner&gt; getHFileCleaners() {</span>
+<span class="source-line-no">3501</span><span id="line-3501">    return this.hfileCleaners;</span>
 <span class="source-line-no">3502</span><span id="line-3502">  }</span>
 <span class="source-line-no">3503</span><span id="line-3503"></span>
-<span class="source-line-no">3504</span><span id="line-3504">  /** Returns the underlying snapshot manager */</span>
-<span class="source-line-no">3505</span><span id="line-3505">  @Override</span>
-<span class="source-line-no">3506</span><span id="line-3506">  public SnapshotManager getSnapshotManager() {</span>
-<span class="source-line-no">3507</span><span id="line-3507">    return this.snapshotManager;</span>
-<span class="source-line-no">3508</span><span id="line-3508">  }</span>
-<span class="source-line-no">3509</span><span id="line-3509"></span>
-<span class="source-line-no">3510</span><span id="line-3510">  /** Returns the underlying MasterProcedureManagerHost */</span>
-<span class="source-line-no">3511</span><span id="line-3511">  @Override</span>
-<span class="source-line-no">3512</span><span id="line-3512">  public MasterProcedureManagerHost getMasterProcedureManagerHost() {</span>
-<span class="source-line-no">3513</span><span id="line-3513">    return mpmHost;</span>
-<span class="source-line-no">3514</span><span id="line-3514">  }</span>
-<span class="source-line-no">3515</span><span id="line-3515"></span>
-<span class="source-line-no">3516</span><span id="line-3516">  @Override</span>
-<span class="source-line-no">3517</span><span id="line-3517">  public ClusterSchema getClusterSchema() {</span>
-<span class="source-line-no">3518</span><span id="line-3518">    return this.clusterSchemaService;</span>
-<span class="source-line-no">3519</span><span id="line-3519">  }</span>
-<span class="source-line-no">3520</span><span id="line-3520"></span>
-<span class="source-line-no">3521</span><span id="line-3521">  /**</span>
-<span class="source-line-no">3522</span><span id="line-3522">   * Create a new Namespace.</span>
-<span class="source-line-no">3523</span><span id="line-3523">   * @param namespaceDescriptor descriptor for new Namespace</span>
-<span class="source-line-no">3524</span><span id="line-3524">   * @param nonceGroup          Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3525</span><span id="line-3525">   * @param nonce               A unique identifier for this operation from the client or process</span>
-<span class="source-line-no">3526</span><span id="line-3526">   *                            identified by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each</span>
-<span class="source-line-no">3527</span><span id="line-3527">   *                            operation gets a unique id).</span>
-<span class="source-line-no">3528</span><span id="line-3528">   * @return procedure id</span>
-<span class="source-line-no">3529</span><span id="line-3529">   */</span>
-<span class="source-line-no">3530</span><span id="line-3530">  long createNamespace(final NamespaceDescriptor namespaceDescriptor, final long nonceGroup,</span>
-<span class="source-line-no">3531</span><span id="line-3531">    final long nonce) throws IOException {</span>
-<span class="source-line-no">3532</span><span id="line-3532">    checkInitialized();</span>
-<span class="source-line-no">3533</span><span id="line-3533"></span>
-<span class="source-line-no">3534</span><span id="line-3534">    TableName.isLegalNamespaceName(Bytes.toBytes(namespaceDescriptor.getName()));</span>
-<span class="source-line-no">3535</span><span id="line-3535"></span>
-<span class="source-line-no">3536</span><span id="line-3536">    return MasterProcedureUtil</span>
-<span class="source-line-no">3537</span><span id="line-3537">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3538</span><span id="line-3538">        @Override</span>
-<span class="source-line-no">3539</span><span id="line-3539">        protected void run() throws IOException {</span>
-<span class="source-line-no">3540</span><span id="line-3540">          getMaster().getMasterCoprocessorHost().preCreateNamespace(namespaceDescriptor);</span>
-<span class="source-line-no">3541</span><span id="line-3541">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3542</span><span id="line-3542">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3543</span><span id="line-3543">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3544</span><span id="line-3544">          LOG.info(getClientIdAuditPrefix() + " creating " + namespaceDescriptor);</span>
-<span class="source-line-no">3545</span><span id="line-3545">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3546</span><span id="line-3546">          // continuing.</span>
-<span class="source-line-no">3547</span><span id="line-3547">          setProcId(getClusterSchema().createNamespace(namespaceDescriptor, getNonceKey(), latch));</span>
-<span class="source-line-no">3548</span><span id="line-3548">          latch.await();</span>
-<span class="source-line-no">3549</span><span id="line-3549">          getMaster().getMasterCoprocessorHost().postCreateNamespace(namespaceDescriptor);</span>
-<span class="source-line-no">3550</span><span id="line-3550">        }</span>
-<span class="source-line-no">3551</span><span id="line-3551"></span>
-<span class="source-line-no">3552</span><span id="line-3552">        @Override</span>
-<span class="source-line-no">3553</span><span id="line-3553">        protected String getDescription() {</span>
-<span class="source-line-no">3554</span><span id="line-3554">          return "CreateNamespaceProcedure";</span>
-<span class="source-line-no">3555</span><span id="line-3555">        }</span>
-<span class="source-line-no">3556</span><span id="line-3556">      });</span>
-<span class="source-line-no">3557</span><span id="line-3557">  }</span>
-<span class="source-line-no">3558</span><span id="line-3558"></span>
-<span class="source-line-no">3559</span><span id="line-3559">  /**</span>
-<span class="source-line-no">3560</span><span id="line-3560">   * Modify an existing Namespace.</span>
-<span class="source-line-no">3561</span><span id="line-3561">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3562</span><span id="line-3562">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">3563</span><span id="line-3563">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">3564</span><span id="line-3564">   *                   unique id).</span>
-<span class="source-line-no">3565</span><span id="line-3565">   * @return procedure id</span>
-<span class="source-line-no">3566</span><span id="line-3566">   */</span>
-<span class="source-line-no">3567</span><span id="line-3567">  long modifyNamespace(final NamespaceDescriptor newNsDescriptor, final long nonceGroup,</span>
-<span class="source-line-no">3568</span><span id="line-3568">    final long nonce) throws IOException {</span>
-<span class="source-line-no">3569</span><span id="line-3569">    checkInitialized();</span>
-<span class="source-line-no">3570</span><span id="line-3570"></span>
-<span class="source-line-no">3571</span><span id="line-3571">    TableName.isLegalNamespaceName(Bytes.toBytes(newNsDescriptor.getName()));</span>
-<span class="source-line-no">3572</span><span id="line-3572"></span>
-<span class="source-line-no">3573</span><span id="line-3573">    return MasterProcedureUtil</span>
-<span class="source-line-no">3574</span><span id="line-3574">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3575</span><span id="line-3575">        @Override</span>
-<span class="source-line-no">3576</span><span id="line-3576">        protected void run() throws IOException {</span>
-<span class="source-line-no">3577</span><span id="line-3577">          NamespaceDescriptor oldNsDescriptor = getNamespace(newNsDescriptor.getName());</span>
-<span class="source-line-no">3578</span><span id="line-3578">          getMaster().getMasterCoprocessorHost().preModifyNamespace(oldNsDescriptor,</span>
-<span class="source-line-no">3579</span><span id="line-3579">            newNsDescriptor);</span>
-<span class="source-line-no">3580</span><span id="line-3580">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3581</span><span id="line-3581">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3582</span><span id="line-3582">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3583</span><span id="line-3583">          LOG.info(getClientIdAuditPrefix() + " modify " + newNsDescriptor);</span>
-<span class="source-line-no">3584</span><span id="line-3584">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3585</span><span id="line-3585">          // continuing.</span>
-<span class="source-line-no">3586</span><span id="line-3586">          setProcId(getClusterSchema().modifyNamespace(newNsDescriptor, getNonceKey(), latch));</span>
-<span class="source-line-no">3587</span><span id="line-3587">          latch.await();</span>
-<span class="source-line-no">3588</span><span id="line-3588">          getMaster().getMasterCoprocessorHost().postModifyNamespace(oldNsDescriptor,</span>
-<span class="source-line-no">3589</span><span id="line-3589">            newNsDescriptor);</span>
-<span class="source-line-no">3590</span><span id="line-3590">        }</span>
-<span class="source-line-no">3591</span><span id="line-3591"></span>
-<span class="source-line-no">3592</span><span id="line-3592">        @Override</span>
-<span class="source-line-no">3593</span><span id="line-3593">        protected String getDescription() {</span>
-<span class="source-line-no">3594</span><span id="line-3594">          return "ModifyNamespaceProcedure";</span>
-<span class="source-line-no">3595</span><span id="line-3595">        }</span>
-<span class="source-line-no">3596</span><span id="line-3596">      });</span>
-<span class="source-line-no">3597</span><span id="line-3597">  }</span>
-<span class="source-line-no">3598</span><span id="line-3598"></span>
-<span class="source-line-no">3599</span><span id="line-3599">  /**</span>
-<span class="source-line-no">3600</span><span id="line-3600">   * Delete an existing Namespace. Only empty Namespaces (no tables) can be removed.</span>
-<span class="source-line-no">3601</span><span id="line-3601">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
-<span class="source-line-no">3602</span><span id="line-3602">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">3603</span><span id="line-3603">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">3604</span><span id="line-3604">   *                   unique id).</span>
-<span class="source-line-no">3605</span><span id="line-3605">   * @return procedure id</span>
-<span class="source-line-no">3606</span><span id="line-3606">   */</span>
-<span class="source-line-no">3607</span><span id="line-3607">  long deleteNamespace(final String name, final long nonceGroup, final long nonce)</span>
-<span class="source-line-no">3608</span><span id="line-3608">    throws IOException {</span>
-<span class="source-line-no">3609</span><span id="line-3609">    checkInitialized();</span>
-<span class="source-line-no">3610</span><span id="line-3610"></span>
-<span class="source-line-no">3611</span><span id="line-3611">    return MasterProcedureUtil</span>
-<span class="source-line-no">3612</span><span id="line-3612">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">3613</span><span id="line-3613">        @Override</span>
-<span class="source-line-no">3614</span><span id="line-3614">        protected void run() throws IOException {</span>
-<span class="source-line-no">3615</span><span id="line-3615">          getMaster().getMasterCoprocessorHost().preDeleteNamespace(name);</span>
-<span class="source-line-no">3616</span><span id="line-3616">          LOG.info(getClientIdAuditPrefix() + " delete " + name);</span>
-<span class="source-line-no">3617</span><span id="line-3617">          // Execute the operation synchronously - wait for the operation to complete before</span>
-<span class="source-line-no">3618</span><span id="line-3618">          // continuing.</span>
-<span class="source-line-no">3619</span><span id="line-3619">          //</span>
-<span class="source-line-no">3620</span><span id="line-3620">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
-<span class="source-line-no">3621</span><span id="line-3621">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
-<span class="source-line-no">3622</span><span id="line-3622">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
-<span class="source-line-no">3623</span><span id="line-3623">          setProcId(submitProcedure(</span>
-<span class="source-line-no">3624</span><span id="line-3624">            new DeleteNamespaceProcedure(procedureExecutor.getEnvironment(), name, latch)));</span>
-<span class="source-line-no">3625</span><span id="line-3625">          latch.await();</span>
-<span class="source-line-no">3626</span><span id="line-3626">          // Will not be invoked in the face of Exception thrown by the Procedure's execution</span>
-<span class="source-line-no">3627</span><span id="line-3627">          getMaster().getMasterCoprocessorHost().postDeleteNamespace(name);</span>
-<span class="source-line-no">3628</span><span id="line-3628">        }</span>
-<span class="source-line-no">3629</span><span id="line-3629"></span>
-<span class="source-line-no">3630</span><span id="line-3630">        @Override</span>
-<span class="source-line-no">3631</span><span id="line-3631">        protected String getDescription() {</span>
-<span class="source-line-no">3632</span><span id="line-3632">          return "DeleteNamespaceProcedure";</span>
-<span class="source-line-no">3633</span><span id="line-3633">        }</span>
-<span class="source-line-no">3634</span><span id="line-3634">      });</span>
-<span class="source-line-no">3635</span><span id="line-3635">  }</span>
-<span class="source-line-no">3636</span><span id="line-3636"></span>
-<span class="source-line-no">3637</span><span id="line-3637">  /**</span>
-<span class="source-line-no">3638</span><span id="line-3638">   * Get a Namespace</span>
-<span class="source-line-no">3639</span><span id="line-3639">   * @param name Name of the Namespace</span>
-<span class="source-line-no">3640</span><span id="line-3640">   * @return Namespace descriptor for &lt;code&gt;name&lt;/code&gt;</span>
-<span class="source-line-no">3641</span><span id="line-3641">   */</span>
-<span class="source-line-no">3642</span><span id="line-3642">  NamespaceDescriptor getNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3643</span><span id="line-3643">    checkInitialized();</span>
-<span class="source-line-no">3644</span><span id="line-3644">    if (this.cpHost != null) this.cpHost.preGetNamespaceDescriptor(name);</span>
-<span class="source-line-no">3645</span><span id="line-3645">    NamespaceDescriptor nsd = this.clusterSchemaService.getNamespace(name);</span>
-<span class="source-line-no">3646</span><span id="line-3646">    if (this.cpHost != null) this.cpHost.postGetNamespaceDescriptor(nsd);</span>
-<span class="source-line-no">3647</span><span id="line-3647">    return nsd;</span>
-<span class="source-line-no">3648</span><span id="line-3648">  }</span>
-<span class="source-line-no">3649</span><span id="line-3649"></span>
-<span class="source-line-no">3650</span><span id="line-3650">  /**</span>
-<span class="source-line-no">3651</span><span id="line-3651">   * Get all Namespaces</span>
-<span class="source-line-no">3652</span><span id="line-3652">   * @return All Namespace descriptors</span>
-<span class="source-line-no">3653</span><span id="line-3653">   */</span>
-<span class="source-line-no">3654</span><span id="line-3654">  List&lt;NamespaceDescriptor&gt; getNamespaces() throws IOException {</span>
-<span class="source-line-no">3655</span><span id="line-3655">    checkInitialized();</span>
-<span class="source-line-no">3656</span><span id="line-3656">    final List&lt;NamespaceDescriptor&gt; nsds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3657</span><span id="line-3657">    if (cpHost != null) {</span>
-<span class="source-line-no">3658</span><span id="line-3658">      cpHost.preListNamespaceDescriptors(nsds);</span>
-<span class="source-line-no">3659</span><span id="line-3659">    }</span>
-<span class="source-line-no">3660</span><span id="line-3660">    nsds.addAll(this.clusterSchemaService.getNamespaces());</span>
-<span class="source-line-no">3661</span><span id="line-3661">    if (this.cpHost != null) {</span>
-<span class="source-line-no">3662</span><span id="line-3662">      this.cpHost.postListNamespaceDescriptors(nsds);</span>
+<span class="source-line-no">3504</span><span id="line-3504">  public LogCleaner getLogCleaner() {</span>
+<span class="source-line-no">3505</span><span id="line-3505">    return this.logCleaner;</span>
+<span class="source-line-no">3506</span><span id="line-3506">  }</span>
+<span class="source-line-no">3507</span><span id="line-3507"></span>
+<span class="source-line-no">3508</span><span id="line-3508">  /** Returns the underlying snapshot manager */</span>
+<span class="source-line-no">3509</span><span id="line-3509">  @Override</span>
+<span class="source-line-no">3510</span><span id="line-3510">  public SnapshotManager getSnapshotManager() {</span>
+<span class="source-line-no">3511</span><span id="line-3511">    return this.snapshotManager;</span>
+<span class="source-line-no">3512</span><span id="line-3512">  }</span>
+<span class="source-line-no">3513</span><span id="line-3513"></span>
+<span class="source-line-no">3514</span><span id="line-3514">  /** Returns the underlying MasterProcedureManagerHost */</span>
+<span class="source-line-no">3515</span><span id="line-3515">  @Override</span>
+<span class="source-line-no">3516</span><span id="line-3516">  public MasterProcedureManagerHost getMasterProcedureManagerHost() {</span>
+<span class="source-line-no">3517</span><span id="line-3517">    return mpmHost;</span>
+<span class="source-line-no">3518</span><span id="line-3518">  }</span>
+<span class="source-line-no">3519</span><span id="line-3519"></span>
+<span class="source-line-no">3520</span><span id="line-3520">  @Override</span>
+<span class="source-line-no">3521</span><span id="line-3521">  public ClusterSchema getClusterSchema() {</span>
+<span class="source-line-no">3522</span><span id="line-3522">    return this.clusterSchemaService;</span>
+<span class="source-line-no">3523</span><span id="line-3523">  }</span>
+<span class="source-line-no">3524</span><span id="line-3524"></span>
+<span class="source-line-no">3525</span><span id="line-3525">  /**</span>
+<span class="source-line-no">3526</span><span id="line-3526">   * Create a new Namespace.</span>
+<span class="source-line-no">3527</span><span id="line-3527">   * @param namespaceDescriptor descriptor for new Namespace</span>
+<span class="source-line-no">3528</span><span id="line-3528">   * @param nonceGroup          Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3529</span><span id="line-3529">   * @param nonce               A unique identifier for this operation from the client or process</span>
+<span class="source-line-no">3530</span><span id="line-3530">   *                            identified by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each</span>
+<span class="source-line-no">3531</span><span id="line-3531">   *                            operation gets a unique id).</span>
+<span class="source-line-no">3532</span><span id="line-3532">   * @return procedure id</span>
+<span class="source-line-no">3533</span><span id="line-3533">   */</span>
+<span class="source-line-no">3534</span><span id="line-3534">  long createNamespace(final NamespaceDescriptor namespaceDescriptor, final long nonceGroup,</span>
+<span class="source-line-no">3535</span><span id="line-3535">    final long nonce) throws IOException {</span>
+<span class="source-line-no">3536</span><span id="line-3536">    checkInitialized();</span>
+<span class="source-line-no">3537</span><span id="line-3537"></span>
+<span class="source-line-no">3538</span><span id="line-3538">    TableName.isLegalNamespaceName(Bytes.toBytes(namespaceDescriptor.getName()));</span>
+<span class="source-line-no">3539</span><span id="line-3539"></span>
+<span class="source-line-no">3540</span><span id="line-3540">    return MasterProcedureUtil</span>
+<span class="source-line-no">3541</span><span id="line-3541">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3542</span><span id="line-3542">        @Override</span>
+<span class="source-line-no">3543</span><span id="line-3543">        protected void run() throws IOException {</span>
+<span class="source-line-no">3544</span><span id="line-3544">          getMaster().getMasterCoprocessorHost().preCreateNamespace(namespaceDescriptor);</span>
+<span class="source-line-no">3545</span><span id="line-3545">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3546</span><span id="line-3546">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3547</span><span id="line-3547">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3548</span><span id="line-3548">          LOG.info(getClientIdAuditPrefix() + " creating " + namespaceDescriptor);</span>
+<span class="source-line-no">3549</span><span id="line-3549">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3550</span><span id="line-3550">          // continuing.</span>
+<span class="source-line-no">3551</span><span id="line-3551">          setProcId(getClusterSchema().createNamespace(namespaceDescriptor, getNonceKey(), latch));</span>
+<span class="source-line-no">3552</span><span id="line-3552">          latch.await();</span>
+<span class="source-line-no">3553</span><span id="line-3553">          getMaster().getMasterCoprocessorHost().postCreateNamespace(namespaceDescriptor);</span>
+<span class="source-line-no">3554</span><span id="line-3554">        }</span>
+<span class="source-line-no">3555</span><span id="line-3555"></span>
+<span class="source-line-no">3556</span><span id="line-3556">        @Override</span>
+<span class="source-line-no">3557</span><span id="line-3557">        protected String getDescription() {</span>
+<span class="source-line-no">3558</span><span id="line-3558">          return "CreateNamespaceProcedure";</span>
+<span class="source-line-no">3559</span><span id="line-3559">        }</span>
+<span class="source-line-no">3560</span><span id="line-3560">      });</span>
+<span class="source-line-no">3561</span><span id="line-3561">  }</span>
+<span class="source-line-no">3562</span><span id="line-3562"></span>
+<span class="source-line-no">3563</span><span id="line-3563">  /**</span>
+<span class="source-line-no">3564</span><span id="line-3564">   * Modify an existing Namespace.</span>
+<span class="source-line-no">3565</span><span id="line-3565">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3566</span><span id="line-3566">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">3567</span><span id="line-3567">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">3568</span><span id="line-3568">   *                   unique id).</span>
+<span class="source-line-no">3569</span><span id="line-3569">   * @return procedure id</span>
+<span class="source-line-no">3570</span><span id="line-3570">   */</span>
+<span class="source-line-no">3571</span><span id="line-3571">  long modifyNamespace(final NamespaceDescriptor newNsDescriptor, final long nonceGroup,</span>
+<span class="source-line-no">3572</span><span id="line-3572">    final long nonce) throws IOException {</span>
+<span class="source-line-no">3573</span><span id="line-3573">    checkInitialized();</span>
+<span class="source-line-no">3574</span><span id="line-3574"></span>
+<span class="source-line-no">3575</span><span id="line-3575">    TableName.isLegalNamespaceName(Bytes.toBytes(newNsDescriptor.getName()));</span>
+<span class="source-line-no">3576</span><span id="line-3576"></span>
+<span class="source-line-no">3577</span><span id="line-3577">    return MasterProcedureUtil</span>
+<span class="source-line-no">3578</span><span id="line-3578">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3579</span><span id="line-3579">        @Override</span>
+<span class="source-line-no">3580</span><span id="line-3580">        protected void run() throws IOException {</span>
+<span class="source-line-no">3581</span><span id="line-3581">          NamespaceDescriptor oldNsDescriptor = getNamespace(newNsDescriptor.getName());</span>
+<span class="source-line-no">3582</span><span id="line-3582">          getMaster().getMasterCoprocessorHost().preModifyNamespace(oldNsDescriptor,</span>
+<span class="source-line-no">3583</span><span id="line-3583">            newNsDescriptor);</span>
+<span class="source-line-no">3584</span><span id="line-3584">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3585</span><span id="line-3585">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3586</span><span id="line-3586">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3587</span><span id="line-3587">          LOG.info(getClientIdAuditPrefix() + " modify " + newNsDescriptor);</span>
+<span class="source-line-no">3588</span><span id="line-3588">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3589</span><span id="line-3589">          // continuing.</span>
+<span class="source-line-no">3590</span><span id="line-3590">          setProcId(getClusterSchema().modifyNamespace(newNsDescriptor, getNonceKey(), latch));</span>
+<span class="source-line-no">3591</span><span id="line-3591">          latch.await();</span>
+<span class="source-line-no">3592</span><span id="line-3592">          getMaster().getMasterCoprocessorHost().postModifyNamespace(oldNsDescriptor,</span>
+<span class="source-line-no">3593</span><span id="line-3593">            newNsDescriptor);</span>
+<span class="source-line-no">3594</span><span id="line-3594">        }</span>
+<span class="source-line-no">3595</span><span id="line-3595"></span>
+<span class="source-line-no">3596</span><span id="line-3596">        @Override</span>
+<span class="source-line-no">3597</span><span id="line-3597">        protected String getDescription() {</span>
+<span class="source-line-no">3598</span><span id="line-3598">          return "ModifyNamespaceProcedure";</span>
+<span class="source-line-no">3599</span><span id="line-3599">        }</span>
+<span class="source-line-no">3600</span><span id="line-3600">      });</span>
+<span class="source-line-no">3601</span><span id="line-3601">  }</span>
+<span class="source-line-no">3602</span><span id="line-3602"></span>
+<span class="source-line-no">3603</span><span id="line-3603">  /**</span>
+<span class="source-line-no">3604</span><span id="line-3604">   * Delete an existing Namespace. Only empty Namespaces (no tables) can be removed.</span>
+<span class="source-line-no">3605</span><span id="line-3605">   * @param nonceGroup Identifier for the source of the request, a client or process.</span>
+<span class="source-line-no">3606</span><span id="line-3606">   * @param nonce      A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">3607</span><span id="line-3607">   *                   by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">3608</span><span id="line-3608">   *                   unique id).</span>
+<span class="source-line-no">3609</span><span id="line-3609">   * @return procedure id</span>
+<span class="source-line-no">3610</span><span id="line-3610">   */</span>
+<span class="source-line-no">3611</span><span id="line-3611">  long deleteNamespace(final String name, final long nonceGroup, final long nonce)</span>
+<span class="source-line-no">3612</span><span id="line-3612">    throws IOException {</span>
+<span class="source-line-no">3613</span><span id="line-3613">    checkInitialized();</span>
+<span class="source-line-no">3614</span><span id="line-3614"></span>
+<span class="source-line-no">3615</span><span id="line-3615">    return MasterProcedureUtil</span>
+<span class="source-line-no">3616</span><span id="line-3616">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">3617</span><span id="line-3617">        @Override</span>
+<span class="source-line-no">3618</span><span id="line-3618">        protected void run() throws IOException {</span>
+<span class="source-line-no">3619</span><span id="line-3619">          getMaster().getMasterCoprocessorHost().preDeleteNamespace(name);</span>
+<span class="source-line-no">3620</span><span id="line-3620">          LOG.info(getClientIdAuditPrefix() + " delete " + name);</span>
+<span class="source-line-no">3621</span><span id="line-3621">          // Execute the operation synchronously - wait for the operation to complete before</span>
+<span class="source-line-no">3622</span><span id="line-3622">          // continuing.</span>
+<span class="source-line-no">3623</span><span id="line-3623">          //</span>
+<span class="source-line-no">3624</span><span id="line-3624">          // We need to wait for the procedure to potentially fail due to "prepare" sanity</span>
+<span class="source-line-no">3625</span><span id="line-3625">          // checks. This will block only the beginning of the procedure. See HBASE-19953.</span>
+<span class="source-line-no">3626</span><span id="line-3626">          ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();</span>
+<span class="source-line-no">3627</span><span id="line-3627">          setProcId(submitProcedure(</span>
+<span class="source-line-no">3628</span><span id="line-3628">            new DeleteNamespaceProcedure(procedureExecutor.getEnvironment(), name, latch)));</span>
+<span class="source-line-no">3629</span><span id="line-3629">          latch.await();</span>
+<span class="source-line-no">3630</span><span id="line-3630">          // Will not be invoked in the face of Exception thrown by the Procedure's execution</span>
+<span class="source-line-no">3631</span><span id="line-3631">          getMaster().getMasterCoprocessorHost().postDeleteNamespace(name);</span>
+<span class="source-line-no">3632</span><span id="line-3632">        }</span>
+<span class="source-line-no">3633</span><span id="line-3633"></span>
+<span class="source-line-no">3634</span><span id="line-3634">        @Override</span>
+<span class="source-line-no">3635</span><span id="line-3635">        protected String getDescription() {</span>
+<span class="source-line-no">3636</span><span id="line-3636">          return "DeleteNamespaceProcedure";</span>
+<span class="source-line-no">3637</span><span id="line-3637">        }</span>
+<span class="source-line-no">3638</span><span id="line-3638">      });</span>
+<span class="source-line-no">3639</span><span id="line-3639">  }</span>
+<span class="source-line-no">3640</span><span id="line-3640"></span>
+<span class="source-line-no">3641</span><span id="line-3641">  /**</span>
+<span class="source-line-no">3642</span><span id="line-3642">   * Get a Namespace</span>
+<span class="source-line-no">3643</span><span id="line-3643">   * @param name Name of the Namespace</span>
+<span class="source-line-no">3644</span><span id="line-3644">   * @return Namespace descriptor for &lt;code&gt;name&lt;/code&gt;</span>
+<span class="source-line-no">3645</span><span id="line-3645">   */</span>
+<span class="source-line-no">3646</span><span id="line-3646">  NamespaceDescriptor getNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3647</span><span id="line-3647">    checkInitialized();</span>
+<span class="source-line-no">3648</span><span id="line-3648">    if (this.cpHost != null) this.cpHost.preGetNamespaceDescriptor(name);</span>
+<span class="source-line-no">3649</span><span id="line-3649">    NamespaceDescriptor nsd = this.clusterSchemaService.getNamespace(name);</span>
+<span class="source-line-no">3650</span><span id="line-3650">    if (this.cpHost != null) this.cpHost.postGetNamespaceDescriptor(nsd);</span>
+<span class="source-line-no">3651</span><span id="line-3651">    return nsd;</span>
+<span class="source-line-no">3652</span><span id="line-3652">  }</span>
+<span class="source-line-no">3653</span><span id="line-3653"></span>
+<span class="source-line-no">3654</span><span id="line-3654">  /**</span>
+<span class="source-line-no">3655</span><span id="line-3655">   * Get all Namespaces</span>
+<span class="source-line-no">3656</span><span id="line-3656">   * @return All Namespace descriptors</span>
+<span class="source-line-no">3657</span><span id="line-3657">   */</span>
+<span class="source-line-no">3658</span><span id="line-3658">  List&lt;NamespaceDescriptor&gt; getNamespaces() throws IOException {</span>
+<span class="source-line-no">3659</span><span id="line-3659">    checkInitialized();</span>
+<span class="source-line-no">3660</span><span id="line-3660">    final List&lt;NamespaceDescriptor&gt; nsds = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">3661</span><span id="line-3661">    if (cpHost != null) {</span>
+<span class="source-line-no">3662</span><span id="line-3662">      cpHost.preListNamespaceDescriptors(nsds);</span>
 <span class="source-line-no">3663</span><span id="line-3663">    }</span>
-<span class="source-line-no">3664</span><span id="line-3664">    return nsds;</span>
-<span class="source-line-no">3665</span><span id="line-3665">  }</span>
-<span class="source-line-no">3666</span><span id="line-3666"></span>
-<span class="source-line-no">3667</span><span id="line-3667">  /**</span>
-<span class="source-line-no">3668</span><span id="line-3668">   * List namespace names</span>
-<span class="source-line-no">3669</span><span id="line-3669">   * @return All namespace names</span>
-<span class="source-line-no">3670</span><span id="line-3670">   */</span>
-<span class="source-line-no">3671</span><span id="line-3671">  public List&lt;String&gt; listNamespaces() throws IOException {</span>
-<span class="source-line-no">3672</span><span id="line-3672">    checkInitialized();</span>
-<span class="source-line-no">3673</span><span id="line-3673">    List&lt;String&gt; namespaces = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3674</span><span id="line-3674">    if (cpHost != null) {</span>
-<span class="source-line-no">3675</span><span id="line-3675">      cpHost.preListNamespaces(namespaces);</span>
-<span class="source-line-no">3676</span><span id="line-3676">    }</span>
-<span class="source-line-no">3677</span><span id="line-3677">    for (NamespaceDescriptor namespace : clusterSchemaService.getNamespaces()) {</span>
-<span class="source-line-no">3678</span><span id="line-3678">      namespaces.add(namespace.getName());</span>
-<span class="source-line-no">3679</span><span id="line-3679">    }</span>
-<span class="source-line-no">3680</span><span id="line-3680">    if (cpHost != null) {</span>
-<span class="source-line-no">3681</span><span id="line-3681">      cpHost.postListNamespaces(namespaces);</span>
-<span class="source-line-no">3682</span><span id="line-3682">    }</span>
-<span class="source-line-no">3683</span><span id="line-3683">    return namespaces;</span>
-<span class="source-line-no">3684</span><span id="line-3684">  }</span>
-<span class="source-line-no">3685</span><span id="line-3685"></span>
-<span class="source-line-no">3686</span><span id="line-3686">  @Override</span>
-<span class="source-line-no">3687</span><span id="line-3687">  public List&lt;TableName&gt; listTableNamesByNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3688</span><span id="line-3688">    checkInitialized();</span>
-<span class="source-line-no">3689</span><span id="line-3689">    return listTableNames(name, null, true);</span>
-<span class="source-line-no">3690</span><span id="line-3690">  }</span>
-<span class="source-line-no">3691</span><span id="line-3691"></span>
-<span class="source-line-no">3692</span><span id="line-3692">  @Override</span>
-<span class="source-line-no">3693</span><span id="line-3693">  public List&lt;TableDescriptor&gt; listTableDescriptorsByNamespace(String name) throws IOException {</span>
-<span class="source-line-no">3694</span><span id="line-3694">    checkInitialized();</span>
-<span class="source-line-no">3695</span><span id="line-3695">    return listTableDescriptors(name, null, null, true);</span>
-<span class="source-line-no">3696</span><span id="line-3696">  }</span>
-<span class="source-line-no">3697</span><span id="line-3697"></span>
-<span class="source-line-no">3698</span><span id="line-3698">  @Override</span>
-<span class="source-line-no">3699</span><span id="line-3699">  public boolean abortProcedure(final long procId, final boolean mayInterruptIfRunning)</span>
-<span class="source-line-no">3700</span><span id="line-3700">    throws IOException {</span>
-<span class="source-line-no">3701</span><span id="line-3701">    if (cpHost != null) {</span>
-<span class="source-line-no">3702</span><span id="line-3702">      cpHost.preAbortProcedure(this.procedureExecutor, procId);</span>
-<span class="source-line-no">3703</span><span id="line-3703">    }</span>
-<span class="source-line-no">3704</span><span id="line-3704"></span>
-<span class="source-line-no">3705</span><span id="line-3705">    final boolean result = this.procedureExecutor.abort(procId, mayInterruptIfRunning);</span>
-<span class="source-line-no">3706</span><span id="line-3706"></span>
-<span class="source-line-no">3707</span><span id="line-3707">    if (cpHost != null) {</span>
-<span class="source-line-no">3708</span><span id="line-3708">      cpHost.postAbortProcedure();</span>
-<span class="source-line-no">3709</span><span id="line-3709">    }</span>
+<span class="source-line-no">3664</span><span id="line-3664">    nsds.addAll(this.clusterSchemaService.getNamespaces());</span>
+<span class="source-line-no">3665</span><span id="line-3665">    if (this.cpHost != null) {</span>
+<span class="source-line-no">3666</span><span id="line-3666">      this.cpHost.postListNamespaceDescriptors(nsds);</span>
+<span class="source-line-no">3667</span><span id="line-3667">    }</span>
+<span class="source-line-no">3668</span><span id="line-3668">    return nsds;</span>
+<span class="source-line-no">3669</span><span id="line-3669">  }</span>
+<span class="source-line-no">3670</span><span id="line-3670"></span>
+<span class="source-line-no">3671</span><span id="line-3671">  /**</span>
+<span class="source-line-no">3672</span><span id="line-3672">   * List namespace names</span>
+<span class="source-line-no">3673</span><span id="line-3673">   * @return All namespace names</span>
+<span class="source-line-no">3674</span><span id="line-3674">   */</span>
+<span class="source-line-no">3675</span><span id="line-3675">  public List&lt;String&gt; listNamespaces() throws IOException {</span>
+<span class="source-line-no">3676</span><span id="line-3676">    checkInitialized();</span>
+<span class="source-line-no">3677</span><span id="line-3677">    List&lt;String&gt; namespaces = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">3678</span><span id="line-3678">    if (cpHost != null) {</span>
+<span class="source-line-no">3679</span><span id="line-3679">      cpHost.preListNamespaces(namespaces);</span>
+<span class="source-line-no">3680</span><span id="line-3680">    }</span>
+<span class="source-line-no">3681</span><span id="line-3681">    for (NamespaceDescriptor namespace : clusterSchemaService.getNamespaces()) {</span>
+<span class="source-line-no">3682</span><span id="line-3682">      namespaces.add(namespace.getName());</span>
+<span class="source-line-no">3683</span><span id="line-3683">    }</span>
+<span class="source-line-no">3684</span><span id="line-3684">    if (cpHost != null) {</span>
+<span class="source-line-no">3685</span><span id="line-3685">      cpHost.postListNamespaces(namespaces);</span>
+<span class="source-line-no">3686</span><span id="line-3686">    }</span>
+<span class="source-line-no">3687</span><span id="line-3687">    return namespaces;</span>
+<span class="source-line-no">3688</span><span id="line-3688">  }</span>
+<span class="source-line-no">3689</span><span id="line-3689"></span>
+<span class="source-line-no">3690</span><span id="line-3690">  @Override</span>
+<span class="source-line-no">3691</span><span id="line-3691">  public List&lt;TableName&gt; listTableNamesByNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3692</span><span id="line-3692">    checkInitialized();</span>
+<span class="source-line-no">3693</span><span id="line-3693">    return listTableNames(name, null, true);</span>
+<span class="source-line-no">3694</span><span id="line-3694">  }</span>
+<span class="source-line-no">3695</span><span id="line-3695"></span>
+<span class="source-line-no">3696</span><span id="line-3696">  @Override</span>
+<span class="source-line-no">3697</span><span id="line-3697">  public List&lt;TableDescriptor&gt; listTableDescriptorsByNamespace(String name) throws IOException {</span>
+<span class="source-line-no">3698</span><span id="line-3698">    checkInitialized();</span>
+<span class="source-line-no">3699</span><span id="line-3699">    return listTableDescriptors(name, null, null, true);</span>
+<span class="source-line-no">3700</span><span id="line-3700">  }</span>
+<span class="source-line-no">3701</span><span id="line-3701"></span>
+<span class="source-line-no">3702</span><span id="line-3702">  @Override</span>
+<span class="source-line-no">3703</span><span id="line-3703">  public boolean abortProcedure(final long procId, final boolean mayInterruptIfRunning)</span>
+<span class="source-line-no">3704</span><span id="line-3704">    throws IOException {</span>
+<span class="source-line-no">3705</span><span id="line-3705">    if (cpHost != null) {</span>
+<span class="source-line-no">3706</span><span id="line-3706">      cpHost.preAbortProcedure(this.procedureExecutor, procId);</span>
+<span class="source-line-no">3707</span><span id="line-3707">    }</span>
+<span class="source-line-no">3708</span><span id="line-3708"></span>
+<span class="source-line-no">3709</span><span id="line-3709">    final boolean result = this.procedureExecutor.abort(procId, mayInterruptIfRunning);</span>
 <span class="source-line-no">3710</span><span id="line-3710"></span>
-<span class="source-line-no">3711</span><span id="line-3711">    return result;</span>
-<span class="source-line-no">3712</span><span id="line-3712">  }</span>
-<span class="source-line-no">3713</span><span id="line-3713"></span>
-<span class="source-line-no">3714</span><span id="line-3714">  @Override</span>
-<span class="source-line-no">3715</span><span id="line-3715">  public List&lt;Procedure&lt;?&gt;&gt; getProcedures() throws IOException {</span>
-<span class="source-line-no">3716</span><span id="line-3716">    if (cpHost != null) {</span>
-<span class="source-line-no">3717</span><span id="line-3717">      cpHost.preGetProcedures();</span>
-<span class="source-line-no">3718</span><span id="line-3718">    }</span>
-<span class="source-line-no">3719</span><span id="line-3719"></span>
-<span class="source-line-no">3720</span><span id="line-3720">    @SuppressWarnings({ "unchecked", "rawtypes" })</span>
-<span class="source-line-no">3721</span><span id="line-3721">    List&lt;Procedure&lt;?&gt;&gt; procList = (List) this.procedureExecutor.getProcedures();</span>
-<span class="source-line-no">3722</span><span id="line-3722"></span>
-<span class="source-line-no">3723</span><span id="line-3723">    if (cpHost != null) {</span>
-<span class="source-line-no">3724</span><span id="line-3724">      cpHost.postGetProcedures(procList);</span>
-<span class="source-line-no">3725</span><span id="line-3725">    }</span>
+<span class="source-line-no">3711</span><span id="line-3711">    if (cpHost != null) {</span>
+<span class="source-line-no">3712</span><span id="line-3712">      cpHost.postAbortProcedure();</span>
+<span class="source-line-no">3713</span><span id="line-3713">    }</span>
+<span class="source-line-no">3714</span><span id="line-3714"></span>
+<span class="source-line-no">3715</span><span id="line-3715">    return result;</span>
+<span class="source-line-no">3716</span><span id="line-3716">  }</span>
+<span class="source-line-no">3717</span><span id="line-3717"></span>
+<span class="source-line-no">3718</span><span id="line-3718">  @Override</span>
+<span class="source-line-no">3719</span><span id="line-3719">  public List&lt;Procedure&lt;?&gt;&gt; getProcedures() throws IOException {</span>
+<span class="source-line-no">3720</span><span id="line-3720">    if (cpHost != null) {</span>
+<span class="source-line-no">3721</span><span id="line-3721">      cpHost.preGetProcedures();</span>
+<span class="source-line-no">3722</span><span id="line-3722">    }</span>
+<span class="source-line-no">3723</span><span id="line-3723"></span>
+<span class="source-line-no">3724</span><span id="line-3724">    @SuppressWarnings({ "unchecked", "rawtypes" })</span>
+<span class="source-line-no">3725</span><span id="line-3725">    List&lt;Procedure&lt;?&gt;&gt; procList = (List) this.procedureExecutor.getProcedures();</span>
 <span class="source-line-no">3726</span><span id="line-3726"></span>
-<span class="source-line-no">3727</span><span id="line-3727">    return procList;</span>
-<span class="source-line-no">3728</span><span id="line-3728">  }</span>
-<span class="source-line-no">3729</span><span id="line-3729"></span>
-<span class="source-line-no">3730</span><span id="line-3730">  @Override</span>
-<span class="source-line-no">3731</span><span id="line-3731">  public List&lt;LockedResource&gt; getLocks() throws IOException {</span>
-<span class="source-line-no">3732</span><span id="line-3732">    if (cpHost != null) {</span>
-<span class="source-line-no">3733</span><span id="line-3733">      cpHost.preGetLocks();</span>
-<span class="source-line-no">3734</span><span id="line-3734">    }</span>
-<span class="source-line-no">3735</span><span id="line-3735"></span>
-<span class="source-line-no">3736</span><span id="line-3736">    MasterProcedureScheduler procedureScheduler =</span>
-<span class="source-line-no">3737</span><span id="line-3737">      procedureExecutor.getEnvironment().getProcedureScheduler();</span>
-<span class="source-line-no">3738</span><span id="line-3738"></span>
-<span class="source-line-no">3739</span><span id="line-3739">    final List&lt;LockedResource&gt; lockedResources = procedureScheduler.getLocks();</span>
-<span class="source-line-no">3740</span><span id="line-3740"></span>
-<span class="source-line-no">3741</span><span id="line-3741">    if (cpHost != null) {</span>
-<span class="source-line-no">3742</span><span id="line-3742">      cpHost.postGetLocks(lockedResources);</span>
-<span class="source-line-no">3743</span><span id="line-3743">    }</span>
+<span class="source-line-no">3727</span><span id="line-3727">    if (cpHost != null) {</span>
+<span class="source-line-no">3728</span><span id="line-3728">      cpHost.postGetProcedures(procList);</span>
+<span class="source-line-no">3729</span><span id="line-3729">    }</span>
+<span class="source-line-no">3730</span><span id="line-3730"></span>
+<span class="source-line-no">3731</span><span id="line-3731">    return procList;</span>
+<span class="source-line-no">3732</span><span id="line-3732">  }</span>
+<span class="source-line-no">3733</span><span id="line-3733"></span>
+<span class="source-line-no">3734</span><span id="line-3734">  @Override</span>
+<span class="source-line-no">3735</span><span id="line-3735">  public List&lt;LockedResource&gt; getLocks() throws IOException {</span>
+<span class="source-line-no">3736</span><span id="line-3736">    if (cpHost != null) {</span>
+<span class="source-line-no">3737</span><span id="line-3737">      cpHost.preGetLocks();</span>
+<span class="source-line-no">3738</span><span id="line-3738">    }</span>
+<span class="source-line-no">3739</span><span id="line-3739"></span>
+<span class="source-line-no">3740</span><span id="line-3740">    MasterProcedureScheduler procedureScheduler =</span>
+<span class="source-line-no">3741</span><span id="line-3741">      procedureExecutor.getEnvironment().getProcedureScheduler();</span>
+<span class="source-line-no">3742</span><span id="line-3742"></span>
+<span class="source-line-no">3743</span><span id="line-3743">    final List&lt;LockedResource&gt; lockedResources = procedureScheduler.getLocks();</span>
 <span class="source-line-no">3744</span><span id="line-3744"></span>
-<span class="source-line-no">3745</span><span id="line-3745">    return lockedResources;</span>
-<span class="source-line-no">3746</span><span id="line-3746">  }</span>
-<span class="source-line-no">3747</span><span id="line-3747"></span>
-<span class="source-line-no">3748</span><span id="line-3748">  /**</span>
-<span class="source-line-no">3749</span><span id="line-3749">   * Returns the list of table descriptors that match the specified request</span>
-<span class="source-line-no">3750</span><span id="line-3750">   * @param namespace        the namespace to query, or null if querying for all</span>
-<span class="source-line-no">3751</span><span id="line-3751">   * @param regex            The regular expression to match against, or null if querying for all</span>
-<span class="source-line-no">3752</span><span id="line-3752">   * @param tableNameList    the list of table names, or null if querying for all</span>
-<span class="source-line-no">3753</span><span id="line-3753">   * @param includeSysTables False to match only against userspace tables</span>
-<span class="source-line-no">3754</span><span id="line-3754">   * @return the list of table descriptors</span>
-<span class="source-line-no">3755</span><span id="line-3755">   */</span>
-<span class="source-line-no">3756</span><span id="line-3756">  public List&lt;TableDescriptor&gt; listTableDescriptors(final String namespace, final String regex,</span>
-<span class="source-line-no">3757</span><span id="line-3757">    final List&lt;TableName&gt; tableNameList, final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3758</span><span id="line-3758">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3759</span><span id="line-3759">    if (cpHost != null) {</span>
-<span class="source-line-no">3760</span><span id="line-3760">      cpHost.preGetTableDescriptors(tableNameList, htds, regex);</span>
-<span class="source-line-no">3761</span><span id="line-3761">    }</span>
-<span class="source-line-no">3762</span><span id="line-3762">    htds = getTableDescriptors(htds, namespace, regex, tableNameList, includeSysTables);</span>
+<span class="source-line-no">3745</span><span id="line-3745">    if (cpHost != null) {</span>
+<span class="source-line-no">3746</span><span id="line-3746">      cpHost.postGetLocks(lockedResources);</span>
+<span class="source-line-no">3747</span><span id="line-3747">    }</span>
+<span class="source-line-no">3748</span><span id="line-3748"></span>
+<span class="source-line-no">3749</span><span id="line-3749">    return lockedResources;</span>
+<span class="source-line-no">3750</span><span id="line-3750">  }</span>
+<span class="source-line-no">3751</span><span id="line-3751"></span>
+<span class="source-line-no">3752</span><span id="line-3752">  /**</span>
+<span class="source-line-no">3753</span><span id="line-3753">   * Returns the list of table descriptors that match the specified request</span>
+<span class="source-line-no">3754</span><span id="line-3754">   * @param namespace        the namespace to query, or null if querying for all</span>
+<span class="source-line-no">3755</span><span id="line-3755">   * @param regex            The regular expression to match against, or null if querying for all</span>
+<span class="source-line-no">3756</span><span id="line-3756">   * @param tableNameList    the list of table names, or null if querying for all</span>
+<span class="source-line-no">3757</span><span id="line-3757">   * @param includeSysTables False to match only against userspace tables</span>
+<span class="source-line-no">3758</span><span id="line-3758">   * @return the list of table descriptors</span>
+<span class="source-line-no">3759</span><span id="line-3759">   */</span>
+<span class="source-line-no">3760</span><span id="line-3760">  public List&lt;TableDescriptor&gt; listTableDescriptors(final String namespace, final String regex,</span>
+<span class="source-line-no">3761</span><span id="line-3761">    final List&lt;TableName&gt; tableNameList, final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3762</span><span id="line-3762">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
 <span class="source-line-no">3763</span><span id="line-3763">    if (cpHost != null) {</span>
-<span class="source-line-no">3764</span><span id="line-3764">      cpHost.postGetTableDescriptors(tableNameList, htds, regex);</span>
+<span class="source-line-no">3764</span><span id="line-3764">      cpHost.preGetTableDescriptors(tableNameList, htds, regex);</span>
 <span class="source-line-no">3765</span><span id="line-3765">    }</span>
-<span class="source-line-no">3766</span><span id="line-3766">    return htds;</span>
-<span class="source-line-no">3767</span><span id="line-3767">  }</span>
-<span class="source-line-no">3768</span><span id="line-3768"></span>
-<span class="source-line-no">3769</span><span id="line-3769">  /**</span>
-<span class="source-line-no">3770</span><span id="line-3770">   * Returns the list of table names that match the specified request</span>
-<span class="source-line-no">3771</span><span id="line-3771">   * @param regex            The regular expression to match against, or null if querying for all</span>
-<span class="source-line-no">3772</span><span id="line-3772">   * @param namespace        the namespace to query, or null if querying for all</span>
-<span class="source-line-no">3773</span><span id="line-3773">   * @param includeSysTables False to match only against userspace tables</span>
-<span class="source-line-no">3774</span><span id="line-3774">   * @return the list of table names</span>
-<span class="source-line-no">3775</span><span id="line-3775">   */</span>
-<span class="source-line-no">3776</span><span id="line-3776">  public List&lt;TableName&gt; listTableNames(final String namespace, final String regex,</span>
-<span class="source-line-no">3777</span><span id="line-3777">    final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3778</span><span id="line-3778">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">3779</span><span id="line-3779">    if (cpHost != null) {</span>
-<span class="source-line-no">3780</span><span id="line-3780">      cpHost.preGetTableNames(htds, regex);</span>
-<span class="source-line-no">3781</span><span id="line-3781">    }</span>
-<span class="source-line-no">3782</span><span id="line-3782">    htds = getTableDescriptors(htds, namespace, regex, null, includeSysTables);</span>
+<span class="source-line-no">3766</span><span id="line-3766">    htds = getTableDescriptors(htds, namespace, regex, tableNameList, includeSysTables);</span>
+<span class="source-line-no">3767</span><span id="line-3767">    if (cpHost != null) {</span>
+<span class="source-line-no">3768</span><span id="line-3768">      cpHost.postGetTableDescriptors(tableNameList, htds, regex);</span>
+<span class="source-line-no">3769</span><span id="line-3769">    }</span>
+<span class="source-line-no">3770</span><span id="line-3770">    return htds;</span>
+<span class="source-line-no">3771</span><span id="line-3771">  }</span>
+<span class="source-line-no">3772</span><span id="line-3772"></span>
+<span class="source-line-no">3773</span><span id="line-3773">  /**</span>
+<span class="source-line-no">3774</span><span id="line-3774">   * Returns the list of table names that match the specified request</span>
+<span class="source-line-no">3775</span><span id="line-3775">   * @param regex            The regular expression to match against, or null if querying for all</span>
+<span class="source-line-no">3776</span><span id="line-3776">   * @param namespace        the namespace to query, or null if querying for all</span>
+<span class="source-line-no">3777</span><span id="line-3777">   * @param includeSysTables False to match only against userspace tables</span>
+<span class="source-line-no">3778</span><span id="line-3778">   * @return the list of table names</span>
+<span class="source-line-no">3779</span><span id="line-3779">   */</span>
+<span class="source-line-no">3780</span><span id="line-3780">  public List&lt;TableName&gt; listTableNames(final String namespace, final String regex,</span>
+<span class="source-line-no">3781</span><span id="line-3781">    final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3782</span><span id="line-3782">    List&lt;TableDescriptor&gt; htds = new ArrayList&lt;&gt;();</span>
 <span class="source-line-no">3783</span><span id="line-3783">    if (cpHost != null) {</span>
-<span class="source-line-no">3784</span><span id="line-3784">      cpHost.postGetTableNames(htds, regex);</span>
+<span class="source-line-no">3784</span><span id="line-3784">      cpHost.preGetTableNames(htds, regex);</span>
 <span class="source-line-no">3785</span><span id="line-3785">    }</span>
-<span class="source-line-no">3786</span><span id="line-3786">    List&lt;TableName&gt; result = new ArrayList&lt;&gt;(htds.size());</span>
-<span class="source-line-no">3787</span><span id="line-3787">    for (TableDescriptor htd : htds)</span>
-<span class="source-line-no">3788</span><span id="line-3788">      result.add(htd.getTableName());</span>
-<span class="source-line-no">3789</span><span id="line-3789">    return result;</span>
-<span class="source-line-no">3790</span><span id="line-3790">  }</span>
-<span class="source-line-no">3791</span><span id="line-3791"></span>
-<span class="source-line-no">3792</span><span id="line-3792">  /**</span>
-<span class="source-line-no">3793</span><span id="line-3793">   * Return a list of table table descriptors after applying any provided filter parameters. Note</span>
-<span class="source-line-no">3794</span><span id="line-3794">   * that the user-facing description of this filter logic is presented on the class-level javadoc</span>
-<span class="source-line-no">3795</span><span id="line-3795">   * of {@link NormalizeTableFilterParams}.</span>
-<span class="source-line-no">3796</span><span id="line-3796">   */</span>
-<span class="source-line-no">3797</span><span id="line-3797">  private List&lt;TableDescriptor&gt; getTableDescriptors(final List&lt;TableDescriptor&gt; htds,</span>
-<span class="source-line-no">3798</span><span id="line-3798">    final String namespace, final String regex, final List&lt;TableName&gt; tableNameList,</span>
-<span class="source-line-no">3799</span><span id="line-3799">    final boolean includeSysTables) throws IOException {</span>
-<span class="source-line-no">3800</span><span id="line-3800">    if (tableNameList == null || tableNameList.isEmpty()) {</span>
-<span class="source-line-no">3801</span><span id="line-3801">      // request for all TableDescriptors</span>
-<span class="source-line-no">3802</span><span id="line-3802">      Collection&lt;TableDescriptor&gt; allHtds;</span>
-<span class="source-line-no">3803</span><span id="line-3803">      if (namespace != null &amp;&amp; namespace.length() &gt; 0) {</span>
-<span class="source-line-no">3804</span><span id="line-3804">        // Do a check on the namespace existence. Will fail if does not exist.</span>
-<span class="source-line-no">3805</span><span id="line-3805">        this.clusterSchemaService.getNamespace(namespace);</span>
-<span class="source-line-no">3806</span><span id="line-3806">        allHtds = tableDescriptors.getByNamespace(namespace).values();</span>
-<span class="source-line-no">3807</span><span id="line-3807">      } else {</span>
-<span class="source-line-no">3808</span><span id="line-3808">        allHtds = tableDescriptors.getAll().values();</span>
-<span class="source-line-no">3809</span><span id="line-3809">      }</span>
-<span class="source-line-no">3810</span><span id="line-3810">      for (TableDescriptor desc : allHtds) {</span>
-<span class="source-line-no">3811</span><span id="line-3811">        if (</span>
-<span class="source-line-no">3812</span><span id="line-3812">          tableStateManager.isTablePresent(desc.getTableName())</span>
-<span class="source-line-no">3813</span><span id="line-3813">            &amp;&amp; (includeSysTables || !desc.getTableName().isSystemTable())</span>
-<span class="source-line-no">3814</span><span id="line-3814">        ) {</span>
-<span class="source-line-no">3815</span><span id="line-3815">          htds.add(desc);</span>
-<span class="source-line-no">3816</span><span id="line-3816">        }</span>
-<span class="source-line-no">3817</span><span id="line-3817">      }</span>
-<span class="source-line-no">3818</span><span id="line-3818">    } else {</span>
-<span class="source-line-no">3819</span><span id="line-3819">      for (TableName s : tableNameList) {</span>
-<span class="source-line-no">3820</span><span id="line-3820">        if (tableStateManager.isTablePresent(s)) {</span>
-<span class="source-line-no">3821</span><span id="line-3821">          TableDescriptor desc = tableDescriptors.get(s);</span>
-<span class="source-line-no">3822</span><span id="line-3822">          if (desc != null) {</span>
-<span class="source-line-no">3823</span><span id="line-3823">            htds.add(desc);</span>
-<span class="source-line-no">3824</span><span id="line-3824">          }</span>
-<span class="source-line-no">3825</span><span id="line-3825">        }</span>
-<span class="source-line-no">3826</span><span id="line-3826">      }</span>
-<span class="source-line-no">3827</span><span id="line-3827">    }</span>
-<span class="source-line-no">3828</span><span id="line-3828"></span>
-<span class="source-line-no">3829</span><span id="line-3829">    // Retains only those matched by regular expression.</span>
-<span class="source-line-no">3830</span><span id="line-3830">    if (regex != null) filterTablesByRegex(htds, Pattern.compile(regex));</span>
-<span class="source-line-no">3831</span><span id="line-3831">    return htds;</span>
-<span class="source-line-no">3832</span><span id="line-3832">  }</span>
-<span class="source-line-no">3833</span><span id="line-3833"></span>
-<span class="source-line-no">3834</span><span id="line-3834">  /**</span>
-<span class="source-line-no">3835</span><span id="line-3835">   * Removes the table descriptors that don't match the pattern.</span>
-<span class="source-line-no">3836</span><span id="line-3836">   * @param descriptors list of table descriptors to filter</span>
-<span class="source-line-no">3837</span><span id="line-3837">   * @param pattern     the regex to use</span>
-<span class="source-line-no">3838</span><span id="line-3838">   */</span>
-<span class="source-line-no">3839</span><span id="line-3839">  private static void filterTablesByRegex(final Collection&lt;TableDescriptor&gt; descriptors,</span>
-<span class="source-line-no">3840</span><span id="line-3840">    final Pattern pattern) {</span>
-<span class="source-line-no">3841</span><span id="line-3841">    final String defaultNS = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;</span>
-<span class="source-line-no">3842</span><span id="line-3842">    Iterator&lt;TableDescriptor&gt; itr = descriptors.iterator();</span>
-<span class="source-line-no">3843</span><span id="line-3843">    while (itr.hasNext()) {</span>
-<span class="source-line-no">3844</span><span id="line-3844">      TableDescriptor htd = itr.next();</span>
-<span class="source-line-no">3845</span><span id="line-3845">      String tableName = htd.getTableName().getNameAsString();</span>
-<span class="source-line-no">3846</span><span id="line-3846">      boolean matched = pattern.matcher(tableName).matches();</span>
-<span class="source-line-no">3847</span><span id="line-3847">      if (!matched &amp;&amp; htd.getTableName().getNamespaceAsString().equals(defaultNS)) {</span>
-<span class="source-line-no">3848</span><span id="line-3848">        matched = pattern.matcher(defaultNS + TableName.NAMESPACE_DELIM + tableName).matches();</span>
-<span class="source-line-no">3849</span><span id="line-3849">      }</span>
-<span class="source-line-no">3850</span><span id="line-3850">      if (!matched) {</span>
-<span class="source-line-no">3851</span><span id="line-3851">        itr.remove();</span>
-<span class="source-line-no">3852</span><span id="line-3852">      }</span>
-<span class="source-line-no">3853</span><span id="line-3853">    }</span>
-<span class="source-line-no">3854</span><span id="line-3854">  }</span>
-<span class="source-line-no">3855</span><span id="line-3855"></span>
-<span class="source-line-no">3856</span><span id="line-3856">  @Override</span>
-<span class="source-line-no">3857</span><span id="line-3857">  public long getLastMajorCompactionTimestamp(TableName table) throws IOException {</span>
-<span class="source-line-no">3858</span><span id="line-3858">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
-<span class="source-line-no">3859</span><span id="line-3859">      .getLastMajorCompactionTimestamp(table);</span>
-<span class="source-line-no">3860</span><span id="line-3860">  }</span>
-<span class="source-line-no">3861</span><span id="line-3861"></span>
-<span class="source-line-no">3862</span><span id="line-3862">  @Override</span>
-<span class="source-line-no">3863</span><span id="line-3863">  public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {</span>
-<span class="source-line-no">3864</span><span id="line-3864">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
-<span class="source-line-no">3865</span><span id="line-3865">      .getLastMajorCompactionTimestamp(regionName);</span>
-<span class="source-line-no">3866</span><span id="line-3866">  }</span>
-<span class="source-line-no">3867</span><span id="line-3867"></span>
-<span class="source-line-no">3868</span><span id="line-3868">  /**</span>
-<span class="source-line-no">3869</span><span id="line-3869">   * Gets the mob file compaction state for a specific table. Whether all the mob files are selected</span>
-<span class="source-line-no">3870</span><span id="line-3870">   * is known during the compaction execution, but the statistic is done just before compaction</span>
-<span class="source-line-no">3871</span><span id="line-3871">   * starts, it is hard to know the compaction type at that time, so the rough statistics are chosen</span>
-<span class="source-line-no">3872</span><span id="line-3872">   * for the mob file compaction. Only two compaction states are available,</span>
-<span class="source-line-no">3873</span><span id="line-3873">   * CompactionState.MAJOR_AND_MINOR and CompactionState.NONE.</span>
-<span class="source-line-no">3874</span><span id="line-3874">   * @param tableName The current table name.</span>
-<span class="source-line-no">3875</span><span id="line-3875">   * @return If a given table is in mob file compaction now.</span>
-<span class="source-line-no">3876</span><span id="line-3876">   */</span>
-<span class="source-line-no">3877</span><span id="line-3877">  public GetRegionInfoResponse.CompactionState getMobCompactionState(TableName tableName) {</span>
-<span class="source-line-no">3878</span><span id="line-3878">    AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3879</span><span id="line-3879">    if (compactionsCount != null &amp;&amp; compactionsCount.get() != 0) {</span>
-<span class="source-line-no">3880</span><span id="line-3880">      return GetRegionInfoResponse.CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">3881</span><span id="line-3881">    }</span>
-<span class="source-line-no">3882</span><span id="line-3882">    return GetRegionInfoResponse.CompactionState.NONE;</span>
-<span class="source-line-no">3883</span><span id="line-3883">  }</span>
-<span class="source-line-no">3884</span><span id="line-3884"></span>
-<span class="source-line-no">3885</span><span id="line-3885">  public void reportMobCompactionStart(TableName tableName) throws IOException {</span>
-<span class="source-line-no">3886</span><span id="line-3886">    IdLock.Entry lockEntry = null;</span>
-<span class="source-line-no">3887</span><span id="line-3887">    try {</span>
-<span class="source-line-no">3888</span><span id="line-3888">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
-<span class="source-line-no">3889</span><span id="line-3889">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3890</span><span id="line-3890">      if (compactionsCount == null) {</span>
-<span class="source-line-no">3891</span><span id="line-3891">        compactionsCount = new AtomicInteger(0);</span>
-<span class="source-line-no">3892</span><span id="line-3892">        mobCompactionStates.put(tableName, compactionsCount);</span>
-<span class="source-line-no">3893</span><span id="line-3893">      }</span>
-<span class="source-line-no">3894</span><span id="line-3894">      compactionsCount.incrementAndGet();</span>
-<span class="source-line-no">3895</span><span id="line-3895">    } finally {</span>
-<span class="source-line-no">3896</span><span id="line-3896">      if (lockEntry != null) {</span>
-<span class="source-line-no">3897</span><span id="line-3897">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
-<span class="source-line-no">3898</span><span id="line-3898">      }</span>
-<span class="source-line-no">3899</span><span id="line-3899">    }</span>
-<span class="source-line-no">3900</span><span id="line-3900">  }</span>
-<span class="source-line-no">3901</span><span id="line-3901"></span>
-<span class="source-line-no">3902</span><span id="line-3902">  public void reportMobCompactionEnd(TableName tableName) throws IOException {</span>
-<span class="source-line-no">3903</span><span id="line-3903">    IdLock.Entry lockEntry = null;</span>
-<span class="source-line-no">3904</span><span id="line-3904">    try {</span>
-<span class="source-line-no">3905</span><span id="line-3905">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
-<span class="source-line-no">3906</span><span id="line-3906">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
-<span class="source-line-no">3907</span><span id="line-3907">      if (compactionsCount != null) {</span>
-<span class="source-line-no">3908</span><span id="line-3908">        int count = compactionsCount.decrementAndGet();</span>
-<span class="source-line-no">3909</span><span id="line-3909">        // remove the entry if the count is 0.</span>
-<span class="source-line-no">3910</span><span id="line-3910">        if (count == 0) {</span>
-<span class="source-line-no">3911</span><span id="line-3911">          mobCompactionStates.remove(tableName);</span>
-<span class="source-line-no">3912</span><span id="line-3912">        }</span>
-<span class="source-line-no">3913</span><span id="line-3913">      }</span>
-<span class="source-line-no">3914</span><span id="line-3914">    } finally {</span>
-<span class="source-line-no">3915</span><span id="line-3915">      if (lockEntry != null) {</span>
-<span class="source-line-no">3916</span><span id="line-3916">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3786</span><span id="line-3786">    htds = getTableDescriptors(htds, namespace, regex, null, includeSysTables);</span>
+<span class="source-line-no">3787</span><span id="line-3787">    if (cpHost != null) {</span>
+<span class="source-line-no">3788</span><span id="line-3788">      cpHost.postGetTableNames(htds, regex);</span>
+<span class="source-line-no">3789</span><span id="line-3789">    }</span>
+<span class="source-line-no">3790</span><span id="line-3790">    List&lt;TableName&gt; result = new ArrayList&lt;&gt;(htds.size());</span>
+<span class="source-line-no">3791</span><span id="line-3791">    for (TableDescriptor htd : htds)</span>
+<span class="source-line-no">3792</span><span id="line-3792">      result.add(htd.getTableName());</span>
+<span class="source-line-no">3793</span><span id="line-3793">    return result;</span>
+<span class="source-line-no">3794</span><span id="line-3794">  }</span>
+<span class="source-line-no">3795</span><span id="line-3795"></span>
+<span class="source-line-no">3796</span><span id="line-3796">  /**</span>
+<span class="source-line-no">3797</span><span id="line-3797">   * Return a list of table table descriptors after applying any provided filter parameters. Note</span>
+<span class="source-line-no">3798</span><span id="line-3798">   * that the user-facing description of this filter logic is presented on the class-level javadoc</span>
+<span class="source-line-no">3799</span><span id="line-3799">   * of {@link NormalizeTableFilterParams}.</span>
+<span class="source-line-no">3800</span><span id="line-3800">   */</span>
+<span class="source-line-no">3801</span><span id="line-3801">  private List&lt;TableDescriptor&gt; getTableDescriptors(final List&lt;TableDescriptor&gt; htds,</span>
+<span class="source-line-no">3802</span><span id="line-3802">    final String namespace, final String regex, final List&lt;TableName&gt; tableNameList,</span>
+<span class="source-line-no">3803</span><span id="line-3803">    final boolean includeSysTables) throws IOException {</span>
+<span class="source-line-no">3804</span><span id="line-3804">    if (tableNameList == null || tableNameList.isEmpty()) {</span>
+<span class="source-line-no">3805</span><span id="line-3805">      // request for all TableDescriptors</span>
+<span class="source-line-no">3806</span><span id="line-3806">      Collection&lt;TableDescriptor&gt; allHtds;</span>
+<span class="source-line-no">3807</span><span id="line-3807">      if (namespace != null &amp;&amp; namespace.length() &gt; 0) {</span>
+<span class="source-line-no">3808</span><span id="line-3808">        // Do a check on the namespace existence. Will fail if does not exist.</span>
+<span class="source-line-no">3809</span><span id="line-3809">        this.clusterSchemaService.getNamespace(namespace);</span>
+<span class="source-line-no">3810</span><span id="line-3810">        allHtds = tableDescriptors.getByNamespace(namespace).values();</span>
+<span class="source-line-no">3811</span><span id="line-3811">      } else {</span>
+<span class="source-line-no">3812</span><span id="line-3812">        allHtds = tableDescriptors.getAll().values();</span>
+<span class="source-line-no">3813</span><span id="line-3813">      }</span>
+<span class="source-line-no">3814</span><span id="line-3814">      for (TableDescriptor desc : allHtds) {</span>
+<span class="source-line-no">3815</span><span id="line-3815">        if (</span>
+<span class="source-line-no">3816</span><span id="line-3816">          tableStateManager.isTablePresent(desc.getTableName())</span>
+<span class="source-line-no">3817</span><span id="line-3817">            &amp;&amp; (includeSysTables || !desc.getTableName().isSystemTable())</span>
+<span class="source-line-no">3818</span><span id="line-3818">        ) {</span>
+<span class="source-line-no">3819</span><span id="line-3819">          htds.add(desc);</span>
+<span class="source-line-no">3820</span><span id="line-3820">        }</span>
+<span class="source-line-no">3821</span><span id="line-3821">      }</span>
+<span class="source-line-no">3822</span><span id="line-3822">    } else {</span>
+<span class="source-line-no">3823</span><span id="line-3823">      for (TableName s : tableNameList) {</span>
+<span class="source-line-no">3824</span><span id="line-3824">        if (tableStateManager.isTablePresent(s)) {</span>
+<span class="source-line-no">3825</span><span id="line-3825">          TableDescriptor desc = tableDescriptors.get(s);</span>
+<span class="source-line-no">3826</span><span id="line-3826">          if (desc != null) {</span>
+<span class="source-line-no">3827</span><span id="line-3827">            htds.add(desc);</span>
+<span class="source-line-no">3828</span><span id="line-3828">          }</span>
+<span class="source-line-no">3829</span><span id="line-3829">        }</span>
+<span class="source-line-no">3830</span><span id="line-3830">      }</span>
+<span class="source-line-no">3831</span><span id="line-3831">    }</span>
+<span class="source-line-no">3832</span><span id="line-3832"></span>
+<span class="source-line-no">3833</span><span id="line-3833">    // Retains only those matched by regular expression.</span>
+<span class="source-line-no">3834</span><span id="line-3834">    if (regex != null) filterTablesByRegex(htds, Pattern.compile(regex));</span>
+<span class="source-line-no">3835</span><span id="line-3835">    return htds;</span>
+<span class="source-line-no">3836</span><span id="line-3836">  }</span>
+<span class="source-line-no">3837</span><span id="line-3837"></span>
+<span class="source-line-no">3838</span><span id="line-3838">  /**</span>
+<span class="source-line-no">3839</span><span id="line-3839">   * Removes the table descriptors that don't match the pattern.</span>
+<span class="source-line-no">3840</span><span id="line-3840">   * @param descriptors list of table descriptors to filter</span>
+<span class="source-line-no">3841</span><span id="line-3841">   * @param pattern     the regex to use</span>
+<span class="source-line-no">3842</span><span id="line-3842">   */</span>
+<span class="source-line-no">3843</span><span id="line-3843">  private static void filterTablesByRegex(final Collection&lt;TableDescriptor&gt; descriptors,</span>
+<span class="source-line-no">3844</span><span id="line-3844">    final Pattern pattern) {</span>
+<span class="source-line-no">3845</span><span id="line-3845">    final String defaultNS = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;</span>
+<span class="source-line-no">3846</span><span id="line-3846">    Iterator&lt;TableDescriptor&gt; itr = descriptors.iterator();</span>
+<span class="source-line-no">3847</span><span id="line-3847">    while (itr.hasNext()) {</span>
+<span class="source-line-no">3848</span><span id="line-3848">      TableDescriptor htd = itr.next();</span>
+<span class="source-line-no">3849</span><span id="line-3849">      String tableName = htd.getTableName().getNameAsString();</span>
+<span class="source-line-no">3850</span><span id="line-3850">      boolean matched = pattern.matcher(tableName).matches();</span>
+<span class="source-line-no">3851</span><span id="line-3851">      if (!matched &amp;&amp; htd.getTableName().getNamespaceAsString().equals(defaultNS)) {</span>
+<span class="source-line-no">3852</span><span id="line-3852">        matched = pattern.matcher(defaultNS + TableName.NAMESPACE_DELIM + tableName).matches();</span>
+<span class="source-line-no">3853</span><span id="line-3853">      }</span>
+<span class="source-line-no">3854</span><span id="line-3854">      if (!matched) {</span>
+<span class="source-line-no">3855</span><span id="line-3855">        itr.remove();</span>
+<span class="source-line-no">3856</span><span id="line-3856">      }</span>
+<span class="source-line-no">3857</span><span id="line-3857">    }</span>
+<span class="source-line-no">3858</span><span id="line-3858">  }</span>
+<span class="source-line-no">3859</span><span id="line-3859"></span>
+<span class="source-line-no">3860</span><span id="line-3860">  @Override</span>
+<span class="source-line-no">3861</span><span id="line-3861">  public long getLastMajorCompactionTimestamp(TableName table) throws IOException {</span>
+<span class="source-line-no">3862</span><span id="line-3862">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
+<span class="source-line-no">3863</span><span id="line-3863">      .getLastMajorCompactionTimestamp(table);</span>
+<span class="source-line-no">3864</span><span id="line-3864">  }</span>
+<span class="source-line-no">3865</span><span id="line-3865"></span>
+<span class="source-line-no">3866</span><span id="line-3866">  @Override</span>
+<span class="source-line-no">3867</span><span id="line-3867">  public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {</span>
+<span class="source-line-no">3868</span><span id="line-3868">    return getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))</span>
+<span class="source-line-no">3869</span><span id="line-3869">      .getLastMajorCompactionTimestamp(regionName);</span>
+<span class="source-line-no">3870</span><span id="line-3870">  }</span>
+<span class="source-line-no">3871</span><span id="line-3871"></span>
+<span class="source-line-no">3872</span><span id="line-3872">  /**</span>
+<span class="source-line-no">3873</span><span id="line-3873">   * Gets the mob file compaction state for a specific table. Whether all the mob files are selected</span>
+<span class="source-line-no">3874</span><span id="line-3874">   * is known during the compaction execution, but the statistic is done just before compaction</span>
+<span class="source-line-no">3875</span><span id="line-3875">   * starts, it is hard to know the compaction type at that time, so the rough statistics are chosen</span>
+<span class="source-line-no">3876</span><span id="line-3876">   * for the mob file compaction. Only two compaction states are available,</span>
+<span class="source-line-no">3877</span><span id="line-3877">   * CompactionState.MAJOR_AND_MINOR and CompactionState.NONE.</span>
+<span class="source-line-no">3878</span><span id="line-3878">   * @param tableName The current table name.</span>
+<span class="source-line-no">3879</span><span id="line-3879">   * @return If a given table is in mob file compaction now.</span>
+<span class="source-line-no">3880</span><span id="line-3880">   */</span>
+<span class="source-line-no">3881</span><span id="line-3881">  public GetRegionInfoResponse.CompactionState getMobCompactionState(TableName tableName) {</span>
+<span class="source-line-no">3882</span><span id="line-3882">    AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3883</span><span id="line-3883">    if (compactionsCount != null &amp;&amp; compactionsCount.get() != 0) {</span>
+<span class="source-line-no">3884</span><span id="line-3884">      return GetRegionInfoResponse.CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">3885</span><span id="line-3885">    }</span>
+<span class="source-line-no">3886</span><span id="line-3886">    return GetRegionInfoResponse.CompactionState.NONE;</span>
+<span class="source-line-no">3887</span><span id="line-3887">  }</span>
+<span class="source-line-no">3888</span><span id="line-3888"></span>
+<span class="source-line-no">3889</span><span id="line-3889">  public void reportMobCompactionStart(TableName tableName) throws IOException {</span>
+<span class="source-line-no">3890</span><span id="line-3890">    IdLock.Entry lockEntry = null;</span>
+<span class="source-line-no">3891</span><span id="line-3891">    try {</span>
+<span class="source-line-no">3892</span><span id="line-3892">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
+<span class="source-line-no">3893</span><span id="line-3893">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3894</span><span id="line-3894">      if (compactionsCount == null) {</span>
+<span class="source-line-no">3895</span><span id="line-3895">        compactionsCount = new AtomicInteger(0);</span>
+<span class="source-line-no">3896</span><span id="line-3896">        mobCompactionStates.put(tableName, compactionsCount);</span>
+<span class="source-line-no">3897</span><span id="line-3897">      }</span>
+<span class="source-line-no">3898</span><span id="line-3898">      compactionsCount.incrementAndGet();</span>
+<span class="source-line-no">3899</span><span id="line-3899">    } finally {</span>
+<span class="source-line-no">3900</span><span id="line-3900">      if (lockEntry != null) {</span>
+<span class="source-line-no">3901</span><span id="line-3901">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3902</span><span id="line-3902">      }</span>
+<span class="source-line-no">3903</span><span id="line-3903">    }</span>
+<span class="source-line-no">3904</span><span id="line-3904">  }</span>
+<span class="source-line-no">3905</span><span id="line-3905"></span>
+<span class="source-line-no">3906</span><span id="line-3906">  public void reportMobCompactionEnd(TableName tableName) throws IOException {</span>
+<span class="source-line-no">3907</span><span id="line-3907">    IdLock.Entry lockEntry = null;</span>
+<span class="source-line-no">3908</span><span id="line-3908">    try {</span>
+<span class="source-line-no">3909</span><span id="line-3909">      lockEntry = mobCompactionLock.getLockEntry(tableName.hashCode());</span>
+<span class="source-line-no">3910</span><span id="line-3910">      AtomicInteger compactionsCount = mobCompactionStates.get(tableName);</span>
+<span class="source-line-no">3911</span><span id="line-3911">      if (compactionsCount != null) {</span>
+<span class="source-line-no">3912</span><span id="line-3912">        int count = compactionsCount.decrementAndGet();</span>
+<span class="source-line-no">3913</span><span id="line-3913">        // remove the entry if the count is 0.</span>
+<span class="source-line-no">3914</span><span id="line-3914">        if (count == 0) {</span>
+<span class="source-line-no">3915</span><span id="line-3915">          mobCompactionStates.remove(tableName);</span>
+<span class="source-line-no">3916</span><span id="line-3916">        }</span>
 <span class="source-line-no">3917</span><span id="line-3917">      }</span>
-<span class="source-line-no">3918</span><span id="line-3918">    }</span>
-<span class="source-line-no">3919</span><span id="line-3919">  }</span>
-<span class="source-line-no">3920</span><span id="line-3920"></span>
-<span class="source-line-no">3921</span><span id="line-3921">  /**</span>
-<span class="source-line-no">3922</span><span id="line-3922">   * Queries the state of the {@link LoadBalancerStateStore}. If the balancer is not initialized,</span>
-<span class="source-line-no">3923</span><span id="line-3923">   * false is returned.</span>
-<span class="source-line-no">3924</span><span id="line-3924">   * @return The state of the load balancer, or false if the load balancer isn't defined.</span>
-<span class="source-line-no">3925</span><span id="line-3925">   */</span>
-<span class="source-line-no">3926</span><span id="line-3926">  public boolean isBalancerOn() {</span>
-<span class="source-line-no">3927</span><span id="line-3927">    return !isInMaintenanceMode() &amp;&amp; loadBalancerStateStore != null &amp;&amp; loadBalancerStateStore.get();</span>
-<span class="source-line-no">3928</span><span id="line-3928">  }</span>
-<span class="source-line-no">3929</span><span id="line-3929"></span>
-<span class="source-line-no">3930</span><span id="line-3930">  /**</span>
-<span class="source-line-no">3931</span><span id="line-3931">   * Queries the state of the {@link RegionNormalizerStateStore}. If it's not initialized, false is</span>
-<span class="source-line-no">3932</span><span id="line-3932">   * returned.</span>
-<span class="source-line-no">3933</span><span id="line-3933">   */</span>
-<span class="source-line-no">3934</span><span id="line-3934">  public boolean isNormalizerOn() {</span>
-<span class="source-line-no">3935</span><span id="line-3935">    return !isInMaintenanceMode() &amp;&amp; getRegionNormalizerManager().isNormalizerOn();</span>
-<span class="source-line-no">3936</span><span id="line-3936">  }</span>
-<span class="source-line-no">3937</span><span id="line-3937"></span>
-<span class="source-line-no">3938</span><span id="line-3938">  /**</span>
-<span class="source-line-no">3939</span><span id="line-3939">   * Queries the state of the {@link SplitOrMergeStateStore}. If it is not initialized, false is</span>
-<span class="source-line-no">3940</span><span id="line-3940">   * returned. If switchType is illegal, false will return.</span>
-<span class="source-line-no">3941</span><span id="line-3941">   * @param switchType see {@link org.apache.hadoop.hbase.client.MasterSwitchType}</span>
-<span class="source-line-no">3942</span><span id="line-3942">   * @return The state of the switch</span>
-<span class="source-line-no">3943</span><span id="line-3943">   */</span>
-<span class="source-line-no">3944</span><span id="line-3944">  @Override</span>
-<span class="source-line-no">3945</span><span id="line-3945">  public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) {</span>
-<span class="source-line-no">3946</span><span id="line-3946">    return !isInMaintenanceMode() &amp;&amp; splitOrMergeStateStore != null</span>
-<span class="source-line-no">3947</span><span id="line-3947">      &amp;&amp; splitOrMergeStateStore.isSplitOrMergeEnabled(switchType);</span>
-<span class="source-line-no">3948</span><span id="line-3948">  }</span>
-<span class="source-line-no">3949</span><span id="line-3949"></span>
-<span class="source-line-no">3950</span><span id="line-3950">  /**</span>
-<span class="source-line-no">3951</span><span id="line-3951">   * Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned.</span>
-<span class="source-line-no">3952</span><span id="line-3952">   * &lt;p/&gt;</span>
-<span class="source-line-no">3953</span><span id="line-3953">   * Notice that, the base load balancer will always be {@link RSGroupBasedLoadBalancer} now, so</span>
-<span class="source-line-no">3954</span><span id="line-3954">   * this method will return the balancer used inside each rs group.</span>
-<span class="source-line-no">3955</span><span id="line-3955">   * @return The name of the {@link LoadBalancer} in use.</span>
-<span class="source-line-no">3956</span><span id="line-3956">   */</span>
-<span class="source-line-no">3957</span><span id="line-3957">  public String getLoadBalancerClassName() {</span>
-<span class="source-line-no">3958</span><span id="line-3958">    return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,</span>
-<span class="source-line-no">3959</span><span id="line-3959">      LoadBalancerFactory.getDefaultLoadBalancerClass().getName());</span>
-<span class="source-line-no">3960</span><span id="line-3960">  }</span>
-<span class="source-line-no">3961</span><span id="line-3961"></span>
-<span class="source-line-no">3962</span><span id="line-3962">  public SplitOrMergeStateStore getSplitOrMergeStateStore() {</span>
-<span class="source-line-no">3963</span><span id="line-3963">    return splitOrMergeStateStore;</span>
+<span class="source-line-no">3918</span><span id="line-3918">    } finally {</span>
+<span class="source-line-no">3919</span><span id="line-3919">      if (lockEntry != null) {</span>
+<span class="source-line-no">3920</span><span id="line-3920">        mobCompactionLock.releaseLockEntry(lockEntry);</span>
+<span class="source-line-no">3921</span><span id="line-3921">      }</span>
+<span class="source-line-no">3922</span><span id="line-3922">    }</span>
+<span class="source-line-no">3923</span><span id="line-3923">  }</span>
+<span class="source-line-no">3924</span><span id="line-3924"></span>
+<span class="source-line-no">3925</span><span id="line-3925">  /**</span>
+<span class="source-line-no">3926</span><span id="line-3926">   * Queries the state of the {@link LoadBalancerStateStore}. If the balancer is not initialized,</span>
+<span class="source-line-no">3927</span><span id="line-3927">   * false is returned.</span>
+<span class="source-line-no">3928</span><span id="line-3928">   * @return The state of the load balancer, or false if the load balancer isn't defined.</span>
+<span class="source-line-no">3929</span><span id="line-3929">   */</span>
+<span class="source-line-no">3930</span><span id="line-3930">  public boolean isBalancerOn() {</span>
+<span class="source-line-no">3931</span><span id="line-3931">    return !isInMaintenanceMode() &amp;&amp; loadBalancerStateStore != null &amp;&amp; loadBalancerStateStore.get();</span>
+<span class="source-line-no">3932</span><span id="line-3932">  }</span>
+<span class="source-line-no">3933</span><span id="line-3933"></span>
+<span class="source-line-no">3934</span><span id="line-3934">  /**</span>
+<span class="source-line-no">3935</span><span id="line-3935">   * Queries the state of the {@link RegionNormalizerStateStore}. If it's not initialized, false is</span>
+<span class="source-line-no">3936</span><span id="line-3936">   * returned.</span>
+<span class="source-line-no">3937</span><span id="line-3937">   */</span>
+<span class="source-line-no">3938</span><span id="line-3938">  public boolean isNormalizerOn() {</span>
+<span class="source-line-no">3939</span><span id="line-3939">    return !isInMaintenanceMode() &amp;&amp; getRegionNormalizerManager().isNormalizerOn();</span>
+<span class="source-line-no">3940</span><span id="line-3940">  }</span>
+<span class="source-line-no">3941</span><span id="line-3941"></span>
+<span class="source-line-no">3942</span><span id="line-3942">  /**</span>
+<span class="source-line-no">3943</span><span id="line-3943">   * Queries the state of the {@link SplitOrMergeStateStore}. If it is not initialized, false is</span>
+<span class="source-line-no">3944</span><span id="line-3944">   * returned. If switchType is illegal, false will return.</span>
+<span class="source-line-no">3945</span><span id="line-3945">   * @param switchType see {@link org.apache.hadoop.hbase.client.MasterSwitchType}</span>
+<span class="source-line-no">3946</span><span id="line-3946">   * @return The state of the switch</span>
+<span class="source-line-no">3947</span><span id="line-3947">   */</span>
+<span class="source-line-no">3948</span><span id="line-3948">  @Override</span>
+<span class="source-line-no">3949</span><span id="line-3949">  public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) {</span>
+<span class="source-line-no">3950</span><span id="line-3950">    return !isInMaintenanceMode() &amp;&amp; splitOrMergeStateStore != null</span>
+<span class="source-line-no">3951</span><span id="line-3951">      &amp;&amp; splitOrMergeStateStore.isSplitOrMergeEnabled(switchType);</span>
+<span class="source-line-no">3952</span><span id="line-3952">  }</span>
+<span class="source-line-no">3953</span><span id="line-3953"></span>
+<span class="source-line-no">3954</span><span id="line-3954">  /**</span>
+<span class="source-line-no">3955</span><span id="line-3955">   * Fetch the configured {@link LoadBalancer} class name. If none is set, a default is returned.</span>
+<span class="source-line-no">3956</span><span id="line-3956">   * &lt;p/&gt;</span>
+<span class="source-line-no">3957</span><span id="line-3957">   * Notice that, the base load balancer will always be {@link RSGroupBasedLoadBalancer} now, so</span>
+<span class="source-line-no">3958</span><span id="line-3958">   * this method will return the balancer used inside each rs group.</span>
+<span class="source-line-no">3959</span><span id="line-3959">   * @return The name of the {@link LoadBalancer} in use.</span>
+<span class="source-line-no">3960</span><span id="line-3960">   */</span>
+<span class="source-line-no">3961</span><span id="line-3961">  public String getLoadBalancerClassName() {</span>
+<span class="source-line-no">3962</span><span id="line-3962">    return conf.get(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,</span>
+<span class="source-line-no">3963</span><span id="line-3963">      LoadBalancerFactory.getDefaultLoadBalancerClass().getName());</span>
 <span class="source-line-no">3964</span><span id="line-3964">  }</span>
 <span class="source-line-no">3965</span><span id="line-3965"></span>
-<span class="source-line-no">3966</span><span id="line-3966">  @Override</span>
-<span class="source-line-no">3967</span><span id="line-3967">  public RSGroupBasedLoadBalancer getLoadBalancer() {</span>
-<span class="source-line-no">3968</span><span id="line-3968">    return balancer;</span>
-<span class="source-line-no">3969</span><span id="line-3969">  }</span>
-<span class="source-line-no">3970</span><span id="line-3970"></span>
-<span class="source-line-no">3971</span><span id="line-3971">  @Override</span>
-<span class="source-line-no">3972</span><span id="line-3972">  public FavoredNodesManager getFavoredNodesManager() {</span>
-<span class="source-line-no">3973</span><span id="line-3973">    return balancer.getFavoredNodesManager();</span>
-<span class="source-line-no">3974</span><span id="line-3974">  }</span>
-<span class="source-line-no">3975</span><span id="line-3975"></span>
-<span class="source-line-no">3976</span><span id="line-3976">  private long executePeerProcedure(AbstractPeerProcedure&lt;?&gt; procedure) throws IOException {</span>
-<span class="source-line-no">3977</span><span id="line-3977">    if (!isReplicationPeerModificationEnabled()) {</span>
-<span class="source-line-no">3978</span><span id="line-3978">      throw new IOException("Replication peer modification disabled");</span>
-<span class="source-line-no">3979</span><span id="line-3979">    }</span>
-<span class="source-line-no">3980</span><span id="line-3980">    long procId = procedureExecutor.submitProcedure(procedure);</span>
-<span class="source-line-no">3981</span><span id="line-3981">    procedure.getLatch().await();</span>
-<span class="source-line-no">3982</span><span id="line-3982">    return procId;</span>
-<span class="source-line-no">3983</span><span id="line-3983">  }</span>
-<span class="source-line-no">3984</span><span id="line-3984"></span>
-<span class="source-line-no">3985</span><span id="line-3985">  @Override</span>
-<span class="source-line-no">3986</span><span id="line-3986">  public long addReplicationPeer(String peerId, ReplicationPeerConfig peerConfig, boolean enabled)</span>
-<span class="source-line-no">3987</span><span id="line-3987">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">3988</span><span id="line-3988">    LOG.info(getClientIdAuditPrefix() + " creating replication peer, id=" + peerId + ", config="</span>
-<span class="source-line-no">3989</span><span id="line-3989">      + peerConfig + ", state=" + (enabled ? "ENABLED" : "DISABLED"));</span>
-<span class="source-line-no">3990</span><span id="line-3990">    return executePeerProcedure(new AddPeerProcedure(peerId, peerConfig, enabled));</span>
-<span class="source-line-no">3991</span><span id="line-3991">  }</span>
-<span class="source-line-no">3992</span><span id="line-3992"></span>
-<span class="source-line-no">3993</span><span id="line-3993">  @Override</span>
-<span class="source-line-no">3994</span><span id="line-3994">  public long removeReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">3995</span><span id="line-3995">    LOG.info(getClientIdAuditPrefix() + " removing replication peer, id=" + peerId);</span>
-<span class="source-line-no">3996</span><span id="line-3996">    return executePeerProcedure(new RemovePeerProcedure(peerId));</span>
-<span class="source-line-no">3997</span><span id="line-3997">  }</span>
-<span class="source-line-no">3998</span><span id="line-3998"></span>
-<span class="source-line-no">3999</span><span id="line-3999">  @Override</span>
-<span class="source-line-no">4000</span><span id="line-4000">  public long enableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">4001</span><span id="line-4001">    LOG.info(getClientIdAuditPrefix() + " enable replication peer, id=" + peerId);</span>
-<span class="source-line-no">4002</span><span id="line-4002">    return executePeerProcedure(new EnablePeerProcedure(peerId));</span>
-<span class="source-line-no">4003</span><span id="line-4003">  }</span>
-<span class="source-line-no">4004</span><span id="line-4004"></span>
-<span class="source-line-no">4005</span><span id="line-4005">  @Override</span>
-<span class="source-line-no">4006</span><span id="line-4006">  public long disableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
-<span class="source-line-no">4007</span><span id="line-4007">    LOG.info(getClientIdAuditPrefix() + " disable replication peer, id=" + peerId);</span>
-<span class="source-line-no">4008</span><span id="line-4008">    return executePeerProcedure(new DisablePeerProcedure(peerId));</span>
-<span class="source-line-no">4009</span><span id="line-4009">  }</span>
-<span class="source-line-no">4010</span><span id="line-4010"></span>
-<span class="source-line-no">4011</span><span id="line-4011">  @Override</span>
-<span class="source-line-no">4012</span><span id="line-4012">  public ReplicationPeerConfig getReplicationPeerConfig(String peerId)</span>
-<span class="source-line-no">4013</span><span id="line-4013">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4014</span><span id="line-4014">    if (cpHost != null) {</span>
-<span class="source-line-no">4015</span><span id="line-4015">      cpHost.preGetReplicationPeerConfig(peerId);</span>
-<span class="source-line-no">4016</span><span id="line-4016">    }</span>
-<span class="source-line-no">4017</span><span id="line-4017">    LOG.info(getClientIdAuditPrefix() + " get replication peer config, id=" + peerId);</span>
-<span class="source-line-no">4018</span><span id="line-4018">    ReplicationPeerConfig peerConfig = this.replicationPeerManager.getPeerConfig(peerId)</span>
-<span class="source-line-no">4019</span><span id="line-4019">      .orElseThrow(() -&gt; new ReplicationPeerNotFoundException(peerId));</span>
-<span class="source-line-no">4020</span><span id="line-4020">    if (cpHost != null) {</span>
-<span class="source-line-no">4021</span><span id="line-4021">      cpHost.postGetReplicationPeerConfig(peerId);</span>
-<span class="source-line-no">4022</span><span id="line-4022">    }</span>
-<span class="source-line-no">4023</span><span id="line-4023">    return peerConfig;</span>
-<span class="source-line-no">4024</span><span id="line-4024">  }</span>
-<span class="source-line-no">4025</span><span id="line-4025"></span>
-<span class="source-line-no">4026</span><span id="line-4026">  @Override</span>
-<span class="source-line-no">4027</span><span id="line-4027">  public long updateReplicationPeerConfig(String peerId, ReplicationPeerConfig peerConfig)</span>
-<span class="source-line-no">4028</span><span id="line-4028">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4029</span><span id="line-4029">    LOG.info(getClientIdAuditPrefix() + " update replication peer config, id=" + peerId</span>
-<span class="source-line-no">4030</span><span id="line-4030">      + ", config=" + peerConfig);</span>
-<span class="source-line-no">4031</span><span id="line-4031">    return executePeerProcedure(new UpdatePeerConfigProcedure(peerId, peerConfig));</span>
-<span class="source-line-no">4032</span><span id="line-4032">  }</span>
-<span class="source-line-no">4033</span><span id="line-4033"></span>
-<span class="source-line-no">4034</span><span id="line-4034">  @Override</span>
-<span class="source-line-no">4035</span><span id="line-4035">  public List&lt;ReplicationPeerDescription&gt; listReplicationPeers(String regex)</span>
-<span class="source-line-no">4036</span><span id="line-4036">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4037</span><span id="line-4037">    if (cpHost != null) {</span>
-<span class="source-line-no">4038</span><span id="line-4038">      cpHost.preListReplicationPeers(regex);</span>
-<span class="source-line-no">4039</span><span id="line-4039">    }</span>
-<span class="source-line-no">4040</span><span id="line-4040">    LOG.debug("{} list replication peers, regex={}", getClientIdAuditPrefix(), regex);</span>
-<span class="source-line-no">4041</span><span id="line-4041">    Pattern pattern = regex == null ? null : Pattern.compile(regex);</span>
-<span class="source-line-no">4042</span><span id="line-4042">    List&lt;ReplicationPeerDescription&gt; peers = this.replicationPeerManager.listPeers(pattern);</span>
-<span class="source-line-no">4043</span><span id="line-4043">    if (cpHost != null) {</span>
-<span class="source-line-no">4044</span><span id="line-4044">      cpHost.postListReplicationPeers(regex);</span>
-<span class="source-line-no">4045</span><span id="line-4045">    }</span>
-<span class="source-line-no">4046</span><span id="line-4046">    return peers;</span>
-<span class="source-line-no">4047</span><span id="line-4047">  }</span>
-<span class="source-line-no">4048</span><span id="line-4048"></span>
-<span class="source-line-no">4049</span><span id="line-4049">  @Override</span>
-<span class="source-line-no">4050</span><span id="line-4050">  public long transitReplicationPeerSyncReplicationState(String peerId, SyncReplicationState state)</span>
-<span class="source-line-no">4051</span><span id="line-4051">    throws ReplicationException, IOException {</span>
-<span class="source-line-no">4052</span><span id="line-4052">    LOG.info(</span>
-<span class="source-line-no">4053</span><span id="line-4053">      getClientIdAuditPrefix()</span>
-<span class="source-line-no">4054</span><span id="line-4054">        + " transit current cluster state to {} in a synchronous replication peer id={}",</span>
-<span class="source-line-no">4055</span><span id="line-4055">      state, peerId);</span>
-<span class="source-line-no">4056</span><span id="line-4056">    return executePeerProcedure(new TransitPeerSyncReplicationStateProcedure(peerId, state));</span>
-<span class="source-line-no">4057</span><span id="line-4057">  }</span>
-<span class="source-line-no">4058</span><span id="line-4058"></span>
-<span class="source-line-no">4059</span><span id="line-4059">  @Override</span>
-<span class="source-line-no">4060</span><span id="line-4060">  public boolean replicationPeerModificationSwitch(boolean on) throws IOException {</span>
-<span class="source-line-no">4061</span><span id="line-4061">    return replicationPeerModificationStateStore.set(on);</span>
-<span class="source-line-no">4062</span><span id="line-4062">  }</span>
-<span class="source-line-no">4063</span><span id="line-4063"></span>
-<span class="source-line-no">4064</span><span id="line-4064">  @Override</span>
-<span class="source-line-no">4065</span><span id="line-4065">  public boolean isReplicationPeerModificationEnabled() {</span>
-<span class="source-line-no">4066</span><span id="line-4066">    return replicationPeerModificationStateStore.get();</span>
-<span class="source-line-no">4067</span><span id="line-4067">  }</span>
-<span class="source-line-no">4068</span><span id="line-4068"></span>
-<span class="source-line-no">4069</span><span id="line-4069">  /**</span>
-<span class="source-line-no">4070</span><span id="line-4070">   * Mark region server(s) as decommissioned (previously called 'draining') to prevent additional</span>
-<span class="source-line-no">4071</span><span id="line-4071">   * regions from getting assigned to them. Also unload the regions on the servers asynchronously.0</span>
-<span class="source-line-no">4072</span><span id="line-4072">   * @param servers Region servers to decommission.</span>
-<span class="source-line-no">4073</span><span id="line-4073">   */</span>
-<span class="source-line-no">4074</span><span id="line-4074">  public void decommissionRegionServers(final List&lt;ServerName&gt; servers, final boolean offload)</span>
-<span class="source-line-no">4075</span><span id="line-4075">    throws IOException {</span>
-<span class="source-line-no">4076</span><span id="line-4076">    List&lt;ServerName&gt; serversAdded = new ArrayList&lt;&gt;(servers.size());</span>
-<span class="source-line-no">4077</span><span id="line-4077">    // Place the decommission marker first.</span>
-<span class="source-line-no">4078</span><span id="line-4078">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
-<span class="source-line-no">4079</span><span id="line-4079">    for (ServerName server : servers) {</span>
-<span class="source-line-no">4080</span><span id="line-4080">      try {</span>
-<span class="source-line-no">4081</span><span id="line-4081">        String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
-<span class="source-line-no">4082</span><span id="line-4082">        ZKUtil.createAndFailSilent(getZooKeeper(), node);</span>
-<span class="source-line-no">4083</span><span id="line-4083">      } catch (KeeperException ke) {</span>
-<span class="source-line-no">4084</span><span id="line-4084">        throw new HBaseIOException(</span>
-<span class="source-line-no">4085</span><span id="line-4085">          this.zooKeeper.prefix("Unable to decommission '" + server.getServerName() + "'."), ke);</span>
-<span class="source-line-no">4086</span><span id="line-4086">      }</span>
-<span class="source-line-no">4087</span><span id="line-4087">      if (this.serverManager.addServerToDrainList(server)) {</span>
-<span class="source-line-no">4088</span><span id="line-4088">        serversAdded.add(server);</span>
-<span class="source-line-no">4089</span><span id="line-4089">      }</span>
-<span class="source-line-no">4090</span><span id="line-4090">    }</span>
-<span class="source-line-no">4091</span><span id="line-4091">    // Move the regions off the decommissioned servers.</span>
-<span class="source-line-no">4092</span><span id="line-4092">    if (offload) {</span>
-<span class="source-line-no">4093</span><span id="line-4093">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList();</span>
-<span class="source-line-no">4094</span><span id="line-4094">      for (ServerName server : serversAdded) {</span>
-<span class="source-line-no">4095</span><span id="line-4095">        final List&lt;RegionInfo&gt; regionsOnServer = this.assignmentManager.getRegionsOnServer(server);</span>
-<span class="source-line-no">4096</span><span id="line-4096">        for (RegionInfo hri : regionsOnServer) {</span>
-<span class="source-line-no">4097</span><span id="line-4097">          ServerName dest = balancer.randomAssignment(hri, destServers);</span>
-<span class="source-line-no">4098</span><span id="line-4098">          if (dest == null) {</span>
-<span class="source-line-no">4099</span><span id="line-4099">            throw new HBaseIOException("Unable to determine a plan to move " + hri);</span>
-<span class="source-line-no">4100</span><span id="line-4100">          }</span>
-<span class="source-line-no">4101</span><span id="line-4101">          RegionPlan rp = new RegionPlan(hri, server, dest);</span>
-<span class="source-line-no">4102</span><span id="line-4102">          this.assignmentManager.moveAsync(rp);</span>
-<span class="source-line-no">4103</span><span id="line-4103">        }</span>
-<span class="source-line-no">4104</span><span id="line-4104">      }</span>
-<span class="source-line-no">4105</span><span id="line-4105">    }</span>
-<span class="source-line-no">4106</span><span id="line-4106">  }</span>
-<span class="source-line-no">4107</span><span id="line-4107"></span>
-<span class="source-line-no">4108</span><span id="line-4108">  /**</span>
-<span class="source-line-no">4109</span><span id="line-4109">   * List region servers marked as decommissioned (previously called 'draining') to not get regions</span>
-<span class="source-line-no">4110</span><span id="line-4110">   * assigned to them.</span>
-<span class="source-line-no">4111</span><span id="line-4111">   * @return List of decommissioned servers.</span>
-<span class="source-line-no">4112</span><span id="line-4112">   */</span>
-<span class="source-line-no">4113</span><span id="line-4113">  public List&lt;ServerName&gt; listDecommissionedRegionServers() {</span>
-<span class="source-line-no">4114</span><span id="line-4114">    return this.serverManager.getDrainingServersList();</span>
-<span class="source-line-no">4115</span><span id="line-4115">  }</span>
-<span class="source-line-no">4116</span><span id="line-4116"></span>
-<span class="source-line-no">4117</span><span id="line-4117">  /**</span>
-<span class="source-line-no">4118</span><span id="line-4118">   * Remove decommission marker (previously called 'draining') from a region server to allow regions</span>
-<span class="source-line-no">4119</span><span id="line-4119">   * assignments. Load regions onto the server asynchronously if a list of regions is given</span>
-<span class="source-line-no">4120</span><span id="line-4120">   * @param server Region server to remove decommission marker from.</span>
-<span class="source-line-no">4121</span><span id="line-4121">   */</span>
-<span class="source-line-no">4122</span><span id="line-4122">  public void recommissionRegionServer(final ServerName server,</span>
-<span class="source-line-no">4123</span><span id="line-4123">    final List&lt;byte[]&gt; encodedRegionNames) throws IOException {</span>
-<span class="source-line-no">4124</span><span id="line-4124">    // Remove the server from decommissioned (draining) server list.</span>
-<span class="source-line-no">4125</span><span id="line-4125">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
-<span class="source-line-no">4126</span><span id="line-4126">    String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
-<span class="source-line-no">4127</span><span id="line-4127">    try {</span>
-<span class="source-line-no">4128</span><span id="line-4128">      ZKUtil.deleteNodeFailSilent(getZooKeeper(), node);</span>
-<span class="source-line-no">4129</span><span id="line-4129">    } catch (KeeperException ke) {</span>
-<span class="source-line-no">4130</span><span id="line-4130">      throw new HBaseIOException(</span>
-<span class="source-line-no">4131</span><span id="line-4131">        this.zooKeeper.prefix("Unable to recommission '" + server.getServerName() + "'."), ke);</span>
-<span class="source-line-no">4132</span><span id="line-4132">    }</span>
-<span class="source-line-no">4133</span><span id="line-4133">    this.serverManager.removeServerFromDrainList(server);</span>
-<span class="source-line-no">4134</span><span id="line-4134"></span>
-<span class="source-line-no">4135</span><span id="line-4135">    // Load the regions onto the server if we are given a list of regions.</span>
-<span class="source-line-no">4136</span><span id="line-4136">    if (encodedRegionNames == null || encodedRegionNames.isEmpty()) {</span>
-<span class="source-line-no">4137</span><span id="line-4137">      return;</span>
-<span class="source-line-no">4138</span><span id="line-4138">    }</span>
-<span class="source-line-no">4139</span><span id="line-4139">    if (!this.serverManager.isServerOnline(server)) {</span>
-<span class="source-line-no">4140</span><span id="line-4140">      return;</span>
-<span class="source-line-no">4141</span><span id="line-4141">    }</span>
-<span class="source-line-no">4142</span><span id="line-4142">    for (byte[] encodedRegionName : encodedRegionNames) {</span>
-<span class="source-line-no">4143</span><span id="line-4143">      RegionState regionState =</span>
-<span class="source-line-no">4144</span><span id="line-4144">        assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
-<span class="source-line-no">4145</span><span id="line-4145">      if (regionState == null) {</span>
-<span class="source-line-no">4146</span><span id="line-4146">        LOG.warn("Unknown region " + Bytes.toStringBinary(encodedRegionName));</span>
-<span class="source-line-no">4147</span><span id="line-4147">        continue;</span>
-<span class="source-line-no">4148</span><span id="line-4148">      }</span>
-<span class="source-line-no">4149</span><span id="line-4149">      RegionInfo hri = regionState.getRegion();</span>
-<span class="source-line-no">4150</span><span id="line-4150">      if (server.equals(regionState.getServerName())) {</span>
-<span class="source-line-no">4151</span><span id="line-4151">        LOG.info("Skipping move of region " + hri.getRegionNameAsString()</span>
-<span class="source-line-no">4152</span><span id="line-4152">          + " because region already assigned to the same server " + server + ".");</span>
-<span class="source-line-no">4153</span><span id="line-4153">        continue;</span>
-<span class="source-line-no">4154</span><span id="line-4154">      }</span>
-<span class="source-line-no">4155</span><span id="line-4155">      RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), server);</span>
-<span class="source-line-no">4156</span><span id="line-4156">      this.assignmentManager.moveAsync(rp);</span>
-<span class="source-line-no">4157</span><span id="line-4157">    }</span>
-<span class="source-line-no">4158</span><span id="line-4158">  }</span>
-<span class="source-line-no">4159</span><span id="line-4159"></span>
-<span class="source-line-no">4160</span><span id="line-4160">  @Override</span>
-<span class="source-line-no">4161</span><span id="line-4161">  public LockManager getLockManager() {</span>
-<span class="source-line-no">4162</span><span id="line-4162">    return lockManager;</span>
-<span class="source-line-no">4163</span><span id="line-4163">  }</span>
-<span class="source-line-no">4164</span><span id="line-4164"></span>
-<span class="source-line-no">4165</span><span id="line-4165">  public QuotaObserverChore getQuotaObserverChore() {</span>
-<span class="source-line-no">4166</span><span id="line-4166">    return this.quotaObserverChore;</span>
+<span class="source-line-no">3966</span><span id="line-3966">  public SplitOrMergeStateStore getSplitOrMergeStateStore() {</span>
+<span class="source-line-no">3967</span><span id="line-3967">    return splitOrMergeStateStore;</span>
+<span class="source-line-no">3968</span><span id="line-3968">  }</span>
+<span class="source-line-no">3969</span><span id="line-3969"></span>
+<span class="source-line-no">3970</span><span id="line-3970">  @Override</span>
+<span class="source-line-no">3971</span><span id="line-3971">  public RSGroupBasedLoadBalancer getLoadBalancer() {</span>
+<span class="source-line-no">3972</span><span id="line-3972">    return balancer;</span>
+<span class="source-line-no">3973</span><span id="line-3973">  }</span>
+<span class="source-line-no">3974</span><span id="line-3974"></span>
+<span class="source-line-no">3975</span><span id="line-3975">  @Override</span>
+<span class="source-line-no">3976</span><span id="line-3976">  public FavoredNodesManager getFavoredNodesManager() {</span>
+<span class="source-line-no">3977</span><span id="line-3977">    return balancer.getFavoredNodesManager();</span>
+<span class="source-line-no">3978</span><span id="line-3978">  }</span>
+<span class="source-line-no">3979</span><span id="line-3979"></span>
+<span class="source-line-no">3980</span><span id="line-3980">  private long executePeerProcedure(AbstractPeerProcedure&lt;?&gt; procedure) throws IOException {</span>
+<span class="source-line-no">3981</span><span id="line-3981">    if (!isReplicationPeerModificationEnabled()) {</span>
+<span class="source-line-no">3982</span><span id="line-3982">      throw new IOException("Replication peer modification disabled");</span>
+<span class="source-line-no">3983</span><span id="line-3983">    }</span>
+<span class="source-line-no">3984</span><span id="line-3984">    long procId = procedureExecutor.submitProcedure(procedure);</span>
+<span class="source-line-no">3985</span><span id="line-3985">    procedure.getLatch().await();</span>
+<span class="source-line-no">3986</span><span id="line-3986">    return procId;</span>
+<span class="source-line-no">3987</span><span id="line-3987">  }</span>
+<span class="source-line-no">3988</span><span id="line-3988"></span>
+<span class="source-line-no">3989</span><span id="line-3989">  @Override</span>
+<span class="source-line-no">3990</span><span id="line-3990">  public long addReplicationPeer(String peerId, ReplicationPeerConfig peerConfig, boolean enabled)</span>
+<span class="source-line-no">3991</span><span id="line-3991">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">3992</span><span id="line-3992">    LOG.info(getClientIdAuditPrefix() + " creating replication peer, id=" + peerId + ", config="</span>
+<span class="source-line-no">3993</span><span id="line-3993">      + peerConfig + ", state=" + (enabled ? "ENABLED" : "DISABLED"));</span>
+<span class="source-line-no">3994</span><span id="line-3994">    return executePeerProcedure(new AddPeerProcedure(peerId, peerConfig, enabled));</span>
+<span class="source-line-no">3995</span><span id="line-3995">  }</span>
+<span class="source-line-no">3996</span><span id="line-3996"></span>
+<span class="source-line-no">3997</span><span id="line-3997">  @Override</span>
+<span class="source-line-no">3998</span><span id="line-3998">  public long removeReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">3999</span><span id="line-3999">    LOG.info(getClientIdAuditPrefix() + " removing replication peer, id=" + peerId);</span>
+<span class="source-line-no">4000</span><span id="line-4000">    return executePeerProcedure(new RemovePeerProcedure(peerId));</span>
+<span class="source-line-no">4001</span><span id="line-4001">  }</span>
+<span class="source-line-no">4002</span><span id="line-4002"></span>
+<span class="source-line-no">4003</span><span id="line-4003">  @Override</span>
+<span class="source-line-no">4004</span><span id="line-4004">  public long enableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">4005</span><span id="line-4005">    LOG.info(getClientIdAuditPrefix() + " enable replication peer, id=" + peerId);</span>
+<span class="source-line-no">4006</span><span id="line-4006">    return executePeerProcedure(new EnablePeerProcedure(peerId));</span>
+<span class="source-line-no">4007</span><span id="line-4007">  }</span>
+<span class="source-line-no">4008</span><span id="line-4008"></span>
+<span class="source-line-no">4009</span><span id="line-4009">  @Override</span>
+<span class="source-line-no">4010</span><span id="line-4010">  public long disableReplicationPeer(String peerId) throws ReplicationException, IOException {</span>
+<span class="source-line-no">4011</span><span id="line-4011">    LOG.info(getClientIdAuditPrefix() + " disable replication peer, id=" + peerId);</span>
+<span class="source-line-no">4012</span><span id="line-4012">    return executePeerProcedure(new DisablePeerProcedure(peerId));</span>
+<span class="source-line-no">4013</span><span id="line-4013">  }</span>
+<span class="source-line-no">4014</span><span id="line-4014"></span>
+<span class="source-line-no">4015</span><span id="line-4015">  @Override</span>
+<span class="source-line-no">4016</span><span id="line-4016">  public ReplicationPeerConfig getReplicationPeerConfig(String peerId)</span>
+<span class="source-line-no">4017</span><span id="line-4017">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4018</span><span id="line-4018">    if (cpHost != null) {</span>
+<span class="source-line-no">4019</span><span id="line-4019">      cpHost.preGetReplicationPeerConfig(peerId);</span>
+<span class="source-line-no">4020</span><span id="line-4020">    }</span>
+<span class="source-line-no">4021</span><span id="line-4021">    LOG.info(getClientIdAuditPrefix() + " get replication peer config, id=" + peerId);</span>
+<span class="source-line-no">4022</span><span id="line-4022">    ReplicationPeerConfig peerConfig = this.replicationPeerManager.getPeerConfig(peerId)</span>
+<span class="source-line-no">4023</span><span id="line-4023">      .orElseThrow(() -&gt; new ReplicationPeerNotFoundException(peerId));</span>
+<span class="source-line-no">4024</span><span id="line-4024">    if (cpHost != null) {</span>
+<span class="source-line-no">4025</span><span id="line-4025">      cpHost.postGetReplicationPeerConfig(peerId);</span>
+<span class="source-line-no">4026</span><span id="line-4026">    }</span>
+<span class="source-line-no">4027</span><span id="line-4027">    return peerConfig;</span>
+<span class="source-line-no">4028</span><span id="line-4028">  }</span>
+<span class="source-line-no">4029</span><span id="line-4029"></span>
+<span class="source-line-no">4030</span><span id="line-4030">  @Override</span>
+<span class="source-line-no">4031</span><span id="line-4031">  public long updateReplicationPeerConfig(String peerId, ReplicationPeerConfig peerConfig)</span>
+<span class="source-line-no">4032</span><span id="line-4032">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4033</span><span id="line-4033">    LOG.info(getClientIdAuditPrefix() + " update replication peer config, id=" + peerId</span>
+<span class="source-line-no">4034</span><span id="line-4034">      + ", config=" + peerConfig);</span>
+<span class="source-line-no">4035</span><span id="line-4035">    return executePeerProcedure(new UpdatePeerConfigProcedure(peerId, peerConfig));</span>
+<span class="source-line-no">4036</span><span id="line-4036">  }</span>
+<span class="source-line-no">4037</span><span id="line-4037"></span>
+<span class="source-line-no">4038</span><span id="line-4038">  @Override</span>
+<span class="source-line-no">4039</span><span id="line-4039">  public List&lt;ReplicationPeerDescription&gt; listReplicationPeers(String regex)</span>
+<span class="source-line-no">4040</span><span id="line-4040">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4041</span><span id="line-4041">    if (cpHost != null) {</span>
+<span class="source-line-no">4042</span><span id="line-4042">      cpHost.preListReplicationPeers(regex);</span>
+<span class="source-line-no">4043</span><span id="line-4043">    }</span>
+<span class="source-line-no">4044</span><span id="line-4044">    LOG.debug("{} list replication peers, regex={}", getClientIdAuditPrefix(), regex);</span>
+<span class="source-line-no">4045</span><span id="line-4045">    Pattern pattern = regex == null ? null : Pattern.compile(regex);</span>
+<span class="source-line-no">4046</span><span id="line-4046">    List&lt;ReplicationPeerDescription&gt; peers = this.replicationPeerManager.listPeers(pattern);</span>
+<span class="source-line-no">4047</span><span id="line-4047">    if (cpHost != null) {</span>
+<span class="source-line-no">4048</span><span id="line-4048">      cpHost.postListReplicationPeers(regex);</span>
+<span class="source-line-no">4049</span><span id="line-4049">    }</span>
+<span class="source-line-no">4050</span><span id="line-4050">    return peers;</span>
+<span class="source-line-no">4051</span><span id="line-4051">  }</span>
+<span class="source-line-no">4052</span><span id="line-4052"></span>
+<span class="source-line-no">4053</span><span id="line-4053">  @Override</span>
+<span class="source-line-no">4054</span><span id="line-4054">  public long transitReplicationPeerSyncReplicationState(String peerId, SyncReplicationState state)</span>
+<span class="source-line-no">4055</span><span id="line-4055">    throws ReplicationException, IOException {</span>
+<span class="source-line-no">4056</span><span id="line-4056">    LOG.info(</span>
+<span class="source-line-no">4057</span><span id="line-4057">      getClientIdAuditPrefix()</span>
+<span class="source-line-no">4058</span><span id="line-4058">        + " transit current cluster state to {} in a synchronous replication peer id={}",</span>
+<span class="source-line-no">4059</span><span id="line-4059">      state, peerId);</span>
+<span class="source-line-no">4060</span><span id="line-4060">    return executePeerProcedure(new TransitPeerSyncReplicationStateProcedure(peerId, state));</span>
+<span class="source-line-no">4061</span><span id="line-4061">  }</span>
+<span class="source-line-no">4062</span><span id="line-4062"></span>
+<span class="source-line-no">4063</span><span id="line-4063">  @Override</span>
+<span class="source-line-no">4064</span><span id="line-4064">  public boolean replicationPeerModificationSwitch(boolean on) throws IOException {</span>
+<span class="source-line-no">4065</span><span id="line-4065">    return replicationPeerModificationStateStore.set(on);</span>
+<span class="source-line-no">4066</span><span id="line-4066">  }</span>
+<span class="source-line-no">4067</span><span id="line-4067"></span>
+<span class="source-line-no">4068</span><span id="line-4068">  @Override</span>
+<span class="source-line-no">4069</span><span id="line-4069">  public boolean isReplicationPeerModificationEnabled() {</span>
+<span class="source-line-no">4070</span><span id="line-4070">    return replicationPeerModificationStateStore.get();</span>
+<span class="source-line-no">4071</span><span id="line-4071">  }</span>
+<span class="source-line-no">4072</span><span id="line-4072"></span>
+<span class="source-line-no">4073</span><span id="line-4073">  /**</span>
+<span class="source-line-no">4074</span><span id="line-4074">   * Mark region server(s) as decommissioned (previously called 'draining') to prevent additional</span>
+<span class="source-line-no">4075</span><span id="line-4075">   * regions from getting assigned to them. Also unload the regions on the servers asynchronously.0</span>
+<span class="source-line-no">4076</span><span id="line-4076">   * @param servers Region servers to decommission.</span>
+<span class="source-line-no">4077</span><span id="line-4077">   */</span>
+<span class="source-line-no">4078</span><span id="line-4078">  public void decommissionRegionServers(final List&lt;ServerName&gt; servers, final boolean offload)</span>
+<span class="source-line-no">4079</span><span id="line-4079">    throws IOException {</span>
+<span class="source-line-no">4080</span><span id="line-4080">    List&lt;ServerName&gt; serversAdded = new ArrayList&lt;&gt;(servers.size());</span>
+<span class="source-line-no">4081</span><span id="line-4081">    // Place the decommission marker first.</span>
+<span class="source-line-no">4082</span><span id="line-4082">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
+<span class="source-line-no">4083</span><span id="line-4083">    for (ServerName server : servers) {</span>
+<span class="source-line-no">4084</span><span id="line-4084">      try {</span>
+<span class="source-line-no">4085</span><span id="line-4085">        String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
+<span class="source-line-no">4086</span><span id="line-4086">        ZKUtil.createAndFailSilent(getZooKeeper(), node);</span>
+<span class="source-line-no">4087</span><span id="line-4087">      } catch (KeeperException ke) {</span>
+<span class="source-line-no">4088</span><span id="line-4088">        throw new HBaseIOException(</span>
+<span class="source-line-no">4089</span><span id="line-4089">          this.zooKeeper.prefix("Unable to decommission '" + server.getServerName() + "'."), ke);</span>
+<span class="source-line-no">4090</span><span id="line-4090">      }</span>
+<span class="source-line-no">4091</span><span id="line-4091">      if (this.serverManager.addServerToDrainList(server)) {</span>
+<span class="source-line-no">4092</span><span id="line-4092">        serversAdded.add(server);</span>
+<span class="source-line-no">4093</span><span id="line-4093">      }</span>
+<span class="source-line-no">4094</span><span id="line-4094">    }</span>
+<span class="source-line-no">4095</span><span id="line-4095">    // Move the regions off the decommissioned servers.</span>
+<span class="source-line-no">4096</span><span id="line-4096">    if (offload) {</span>
+<span class="source-line-no">4097</span><span id="line-4097">      final List&lt;ServerName&gt; destServers = this.serverManager.createDestinationServersList();</span>
+<span class="source-line-no">4098</span><span id="line-4098">      for (ServerName server : serversAdded) {</span>
+<span class="source-line-no">4099</span><span id="line-4099">        final List&lt;RegionInfo&gt; regionsOnServer = this.assignmentManager.getRegionsOnServer(server);</span>
+<span class="source-line-no">4100</span><span id="line-4100">        for (RegionInfo hri : regionsOnServer) {</span>
+<span class="source-line-no">4101</span><span id="line-4101">          ServerName dest = balancer.randomAssignment(hri, destServers);</span>
+<span class="source-line-no">4102</span><span id="line-4102">          if (dest == null) {</span>
+<span class="source-line-no">4103</span><span id="line-4103">            throw new HBaseIOException("Unable to determine a plan to move " + hri);</span>
+<span class="source-line-no">4104</span><span id="line-4104">          }</span>
+<span class="source-line-no">4105</span><span id="line-4105">          RegionPlan rp = new RegionPlan(hri, server, dest);</span>
+<span class="source-line-no">4106</span><span id="line-4106">          this.assignmentManager.moveAsync(rp);</span>
+<span class="source-line-no">4107</span><span id="line-4107">        }</span>
+<span class="source-line-no">4108</span><span id="line-4108">      }</span>
+<span class="source-line-no">4109</span><span id="line-4109">    }</span>
+<span class="source-line-no">4110</span><span id="line-4110">  }</span>
+<span class="source-line-no">4111</span><span id="line-4111"></span>
+<span class="source-line-no">4112</span><span id="line-4112">  /**</span>
+<span class="source-line-no">4113</span><span id="line-4113">   * List region servers marked as decommissioned (previously called 'draining') to not get regions</span>
+<span class="source-line-no">4114</span><span id="line-4114">   * assigned to them.</span>
+<span class="source-line-no">4115</span><span id="line-4115">   * @return List of decommissioned servers.</span>
+<span class="source-line-no">4116</span><span id="line-4116">   */</span>
+<span class="source-line-no">4117</span><span id="line-4117">  public List&lt;ServerName&gt; listDecommissionedRegionServers() {</span>
+<span class="source-line-no">4118</span><span id="line-4118">    return this.serverManager.getDrainingServersList();</span>
+<span class="source-line-no">4119</span><span id="line-4119">  }</span>
+<span class="source-line-no">4120</span><span id="line-4120"></span>
+<span class="source-line-no">4121</span><span id="line-4121">  /**</span>
+<span class="source-line-no">4122</span><span id="line-4122">   * Remove decommission marker (previously called 'draining') from a region server to allow regions</span>
+<span class="source-line-no">4123</span><span id="line-4123">   * assignments. Load regions onto the server asynchronously if a list of regions is given</span>
+<span class="source-line-no">4124</span><span id="line-4124">   * @param server Region server to remove decommission marker from.</span>
+<span class="source-line-no">4125</span><span id="line-4125">   */</span>
+<span class="source-line-no">4126</span><span id="line-4126">  public void recommissionRegionServer(final ServerName server,</span>
+<span class="source-line-no">4127</span><span id="line-4127">    final List&lt;byte[]&gt; encodedRegionNames) throws IOException {</span>
+<span class="source-line-no">4128</span><span id="line-4128">    // Remove the server from decommissioned (draining) server list.</span>
+<span class="source-line-no">4129</span><span id="line-4129">    String parentZnode = getZooKeeper().getZNodePaths().drainingZNode;</span>
+<span class="source-line-no">4130</span><span id="line-4130">    String node = ZNodePaths.joinZNode(parentZnode, server.getServerName());</span>
+<span class="source-line-no">4131</span><span id="line-4131">    try {</span>
+<span class="source-line-no">4132</span><span id="line-4132">      ZKUtil.deleteNodeFailSilent(getZooKeeper(), node);</span>
+<span class="source-line-no">4133</span><span id="line-4133">    } catch (KeeperException ke) {</span>
+<span class="source-line-no">4134</span><span id="line-4134">      throw new HBaseIOException(</span>
+<span class="source-line-no">4135</span><span id="line-4135">        this.zooKeeper.prefix("Unable to recommission '" + server.getServerName() + "'."), ke);</span>
+<span class="source-line-no">4136</span><span id="line-4136">    }</span>
+<span class="source-line-no">4137</span><span id="line-4137">    this.serverManager.removeServerFromDrainList(server);</span>
+<span class="source-line-no">4138</span><span id="line-4138"></span>
+<span class="source-line-no">4139</span><span id="line-4139">    // Load the regions onto the server if we are given a list of regions.</span>
+<span class="source-line-no">4140</span><span id="line-4140">    if (encodedRegionNames == null || encodedRegionNames.isEmpty()) {</span>
+<span class="source-line-no">4141</span><span id="line-4141">      return;</span>
+<span class="source-line-no">4142</span><span id="line-4142">    }</span>
+<span class="source-line-no">4143</span><span id="line-4143">    if (!this.serverManager.isServerOnline(server)) {</span>
+<span class="source-line-no">4144</span><span id="line-4144">      return;</span>
+<span class="source-line-no">4145</span><span id="line-4145">    }</span>
+<span class="source-line-no">4146</span><span id="line-4146">    for (byte[] encodedRegionName : encodedRegionNames) {</span>
+<span class="source-line-no">4147</span><span id="line-4147">      RegionState regionState =</span>
+<span class="source-line-no">4148</span><span id="line-4148">        assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));</span>
+<span class="source-line-no">4149</span><span id="line-4149">      if (regionState == null) {</span>
+<span class="source-line-no">4150</span><span id="line-4150">        LOG.warn("Unknown region " + Bytes.toStringBinary(encodedRegionName));</span>
+<span class="source-line-no">4151</span><span id="line-4151">        continue;</span>
+<span class="source-line-no">4152</span><span id="line-4152">      }</span>
+<span class="source-line-no">4153</span><span id="line-4153">      RegionInfo hri = regionState.getRegion();</span>
+<span class="source-line-no">4154</span><span id="line-4154">      if (server.equals(regionState.getServerName())) {</span>
+<span class="source-line-no">4155</span><span id="line-4155">        LOG.info("Skipping move of region " + hri.getRegionNameAsString()</span>
+<span class="source-line-no">4156</span><span id="line-4156">          + " because region already assigned to the same server " + server + ".");</span>
+<span class="source-line-no">4157</span><span id="line-4157">        continue;</span>
+<span class="source-line-no">4158</span><span id="line-4158">      }</span>
+<span class="source-line-no">4159</span><span id="line-4159">      RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), server);</span>
+<span class="source-line-no">4160</span><span id="line-4160">      this.assignmentManager.moveAsync(rp);</span>
+<span class="source-line-no">4161</span><span id="line-4161">    }</span>
+<span class="source-line-no">4162</span><span id="line-4162">  }</span>
+<span class="source-line-no">4163</span><span id="line-4163"></span>
+<span class="source-line-no">4164</span><span id="line-4164">  @Override</span>
+<span class="source-line-no">4165</span><span id="line-4165">  public LockManager getLockManager() {</span>
+<span class="source-line-no">4166</span><span id="line-4166">    return lockManager;</span>
 <span class="source-line-no">4167</span><span id="line-4167">  }</span>
 <span class="source-line-no">4168</span><span id="line-4168"></span>
-<span class="source-line-no">4169</span><span id="line-4169">  public SpaceQuotaSnapshotNotifier getSpaceQuotaSnapshotNotifier() {</span>
-<span class="source-line-no">4170</span><span id="line-4170">    return this.spaceQuotaSnapshotNotifier;</span>
+<span class="source-line-no">4169</span><span id="line-4169">  public QuotaObserverChore getQuotaObserverChore() {</span>
+<span class="source-line-no">4170</span><span id="line-4170">    return this.quotaObserverChore;</span>
 <span class="source-line-no">4171</span><span id="line-4171">  }</span>
 <span class="source-line-no">4172</span><span id="line-4172"></span>
-<span class="source-line-no">4173</span><span id="line-4173">  @SuppressWarnings("unchecked")</span>
-<span class="source-line-no">4174</span><span id="line-4174">  private RemoteProcedure&lt;MasterProcedureEnv, ?&gt; getRemoteProcedure(long procId) {</span>
-<span class="source-line-no">4175</span><span id="line-4175">    Procedure&lt;?&gt; procedure = procedureExecutor.getProcedure(procId);</span>
-<span class="source-line-no">4176</span><span id="line-4176">    if (procedure == null) {</span>
-<span class="source-line-no">4177</span><span id="line-4177">      return null;</span>
-<span class="source-line-no">4178</span><span id="line-4178">    }</span>
-<span class="source-line-no">4179</span><span id="line-4179">    assert procedure instanceof RemoteProcedure;</span>
-<span class="source-line-no">4180</span><span id="line-4180">    return (RemoteProcedure&lt;MasterProcedureEnv, ?&gt;) procedure;</span>
-<span class="source-line-no">4181</span><span id="line-4181">  }</span>
-<span class="source-line-no">4182</span><span id="line-4182"></span>
-<span class="source-line-no">4183</span><span id="line-4183">  public void remoteProcedureCompleted(long procId) {</span>
-<span class="source-line-no">4184</span><span id="line-4184">    LOG.debug("Remote procedure done, pid={}", procId);</span>
-<span class="source-line-no">4185</span><span id="line-4185">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
-<span class="source-line-no">4186</span><span id="line-4186">    if (procedure != null) {</span>
-<span class="source-line-no">4187</span><span id="line-4187">      procedure.remoteOperationCompleted(procedureExecutor.getEnvironment());</span>
-<span class="source-line-no">4188</span><span id="line-4188">    }</span>
-<span class="source-line-no">4189</span><span id="line-4189">  }</span>
-<span class="source-line-no">4190</span><span id="line-4190"></span>
-<span class="source-line-no">4191</span><span id="line-4191">  public void remoteProcedureFailed(long procId, RemoteProcedureException error) {</span>
-<span class="source-line-no">4192</span><span id="line-4192">    LOG.debug("Remote procedure failed, pid={}", procId, error);</span>
-<span class="source-line-no">4193</span><span id="line-4193">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
-<span class="source-line-no">4194</span><span id="line-4194">    if (procedure != null) {</span>
-<span class="source-line-no">4195</span><span id="line-4195">      procedure.remoteOperationFailed(procedureExecutor.getEnvironment(), error);</span>
-<span class="source-line-no">4196</span><span id="line-4196">    }</span>
-<span class="source-line-no">4197</span><span id="line-4197">  }</span>
-<span class="source-line-no">4198</span><span id="line-4198"></span>
-<span class="source-line-no">4199</span><span id="line-4199">  /**</span>
-<span class="source-line-no">4200</span><span id="line-4200">   * Reopen regions provided in the argument</span>
-<span class="source-line-no">4201</span><span id="line-4201">   * @param tableName   The current table name</span>
-<span class="source-line-no">4202</span><span id="line-4202">   * @param regionNames The region names of the regions to reopen</span>
-<span class="source-line-no">4203</span><span id="line-4203">   * @param nonceGroup  Identifier for the source of the request, a client or process</span>
-<span class="source-line-no">4204</span><span id="line-4204">   * @param nonce       A unique identifier for this operation from the client or process identified</span>
-<span class="source-line-no">4205</span><span id="line-4205">   *                    by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
-<span class="source-line-no">4206</span><span id="line-4206">   *                    unique id).</span>
-<span class="source-line-no">4207</span><span id="line-4207">   * @return procedure Id</span>
-<span class="source-line-no">4208</span><span id="line-4208">   * @throws IOException if reopening region fails while running procedure</span>
-<span class="source-line-no">4209</span><span id="line-4209">   */</span>
-<span class="source-line-no">4210</span><span id="line-4210">  long reopenRegions(final TableName tableName, final List&lt;byte[]&gt; regionNames,</span>
-<span class="source-line-no">4211</span><span id="line-4211">    final long nonceGroup, final long nonce) throws IOException {</span>
-<span class="source-line-no">4212</span><span id="line-4212"></span>
-<span class="source-line-no">4213</span><span id="line-4213">    return MasterProcedureUtil</span>
-<span class="source-line-no">4214</span><span id="line-4214">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">4215</span><span id="line-4215"></span>
-<span class="source-line-no">4216</span><span id="line-4216">        @Override</span>
-<span class="source-line-no">4217</span><span id="line-4217">        protected void run() throws IOException {</span>
-<span class="source-line-no">4218</span><span id="line-4218">          submitProcedure(new ReopenTableRegionsProcedure(tableName, regionNames));</span>
-<span class="source-line-no">4219</span><span id="line-4219">        }</span>
-<span class="source-line-no">4220</span><span id="line-4220"></span>
-<span class="source-line-no">4221</span><span id="line-4221">        @Override</span>
-<span class="source-line-no">4222</span><span id="line-4222">        protected String getDescription() {</span>
-<span class="source-line-no">4223</span><span id="line-4223">          return "ReopenTableRegionsProcedure";</span>
-<span class="source-line-no">4224</span><span id="line-4224">        }</span>
-<span class="source-line-no">4225</span><span id="line-4225"></span>
-<span class="source-line-no">4226</span><span id="line-4226">      });</span>
-<span class="source-line-no">4227</span><span id="line-4227"></span>
-<span class="source-line-no">4228</span><span id="line-4228">  }</span>
+<span class="source-line-no">4173</span><span id="line-4173">  public SpaceQuotaSnapshotNotifier getSpaceQuotaSnapshotNotifier() {</span>
+<span class="source-line-no">4174</span><span id="line-4174">    return this.spaceQuotaSnapshotNotifier;</span>
+<span class="source-line-no">4175</span><span id="line-4175">  }</span>
+<span class="source-line-no">4176</span><span id="line-4176"></span>
+<span class="source-line-no">4177</span><span id="line-4177">  @SuppressWarnings("unchecked")</span>
+<span class="source-line-no">4178</span><span id="line-4178">  private RemoteProcedure&lt;MasterProcedureEnv, ?&gt; getRemoteProcedure(long procId) {</span>
+<span class="source-line-no">4179</span><span id="line-4179">    Procedure&lt;?&gt; procedure = procedureExecutor.getProcedure(procId);</span>
+<span class="source-line-no">4180</span><span id="line-4180">    if (procedure == null) {</span>
+<span class="source-line-no">4181</span><span id="line-4181">      return null;</span>
+<span class="source-line-no">4182</span><span id="line-4182">    }</span>
+<span class="source-line-no">4183</span><span id="line-4183">    assert procedure instanceof RemoteProcedure;</span>
+<span class="source-line-no">4184</span><span id="line-4184">    return (RemoteProcedure&lt;MasterProcedureEnv, ?&gt;) procedure;</span>
+<span class="source-line-no">4185</span><span id="line-4185">  }</span>
+<span class="source-line-no">4186</span><span id="line-4186"></span>
+<span class="source-line-no">4187</span><span id="line-4187">  public void remoteProcedureCompleted(long procId) {</span>
+<span class="source-line-no">4188</span><span id="line-4188">    LOG.debug("Remote procedure done, pid={}", procId);</span>
+<span class="source-line-no">4189</span><span id="line-4189">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
+<span class="source-line-no">4190</span><span id="line-4190">    if (procedure != null) {</span>
+<span class="source-line-no">4191</span><span id="line-4191">      procedure.remoteOperationCompleted(procedureExecutor.getEnvironment());</span>
+<span class="source-line-no">4192</span><span id="line-4192">    }</span>
+<span class="source-line-no">4193</span><span id="line-4193">  }</span>
+<span class="source-line-no">4194</span><span id="line-4194"></span>
+<span class="source-line-no">4195</span><span id="line-4195">  public void remoteProcedureFailed(long procId, RemoteProcedureException error) {</span>
+<span class="source-line-no">4196</span><span id="line-4196">    LOG.debug("Remote procedure failed, pid={}", procId, error);</span>
+<span class="source-line-no">4197</span><span id="line-4197">    RemoteProcedure&lt;MasterProcedureEnv, ?&gt; procedure = getRemoteProcedure(procId);</span>
+<span class="source-line-no">4198</span><span id="line-4198">    if (procedure != null) {</span>
+<span class="source-line-no">4199</span><span id="line-4199">      procedure.remoteOperationFailed(procedureExecutor.getEnvironment(), error);</span>
+<span class="source-line-no">4200</span><span id="line-4200">    }</span>
+<span class="source-line-no">4201</span><span id="line-4201">  }</span>
+<span class="source-line-no">4202</span><span id="line-4202"></span>
+<span class="source-line-no">4203</span><span id="line-4203">  /**</span>
+<span class="source-line-no">4204</span><span id="line-4204">   * Reopen regions provided in the argument</span>
+<span class="source-line-no">4205</span><span id="line-4205">   * @param tableName   The current table name</span>
+<span class="source-line-no">4206</span><span id="line-4206">   * @param regionNames The region names of the regions to reopen</span>
+<span class="source-line-no">4207</span><span id="line-4207">   * @param nonceGroup  Identifier for the source of the request, a client or process</span>
+<span class="source-line-no">4208</span><span id="line-4208">   * @param nonce       A unique identifier for this operation from the client or process identified</span>
+<span class="source-line-no">4209</span><span id="line-4209">   *                    by &lt;code&gt;nonceGroup&lt;/code&gt; (the source must ensure each operation gets a</span>
+<span class="source-line-no">4210</span><span id="line-4210">   *                    unique id).</span>
+<span class="source-line-no">4211</span><span id="line-4211">   * @return procedure Id</span>
+<span class="source-line-no">4212</span><span id="line-4212">   * @throws IOException if reopening region fails while running procedure</span>
+<span class="source-line-no">4213</span><span id="line-4213">   */</span>
+<span class="source-line-no">4214</span><span id="line-4214">  long reopenRegions(final TableName tableName, final List&lt;byte[]&gt; regionNames,</span>
+<span class="source-line-no">4215</span><span id="line-4215">    final long nonceGroup, final long nonce) throws IOException {</span>
+<span class="source-line-no">4216</span><span id="line-4216"></span>
+<span class="source-line-no">4217</span><span id="line-4217">    return MasterProcedureUtil</span>
+<span class="source-line-no">4218</span><span id="line-4218">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">4219</span><span id="line-4219"></span>
+<span class="source-line-no">4220</span><span id="line-4220">        @Override</span>
+<span class="source-line-no">4221</span><span id="line-4221">        protected void run() throws IOException {</span>
+<span class="source-line-no">4222</span><span id="line-4222">          submitProcedure(new ReopenTableRegionsProcedure(tableName, regionNames));</span>
+<span class="source-line-no">4223</span><span id="line-4223">        }</span>
+<span class="source-line-no">4224</span><span id="line-4224"></span>
+<span class="source-line-no">4225</span><span id="line-4225">        @Override</span>
+<span class="source-line-no">4226</span><span id="line-4226">        protected String getDescription() {</span>
+<span class="source-line-no">4227</span><span id="line-4227">          return "ReopenTableRegionsProcedure";</span>
+<span class="source-line-no">4228</span><span id="line-4228">        }</span>
 <span class="source-line-no">4229</span><span id="line-4229"></span>
-<span class="source-line-no">4230</span><span id="line-4230">  @Override</span>
-<span class="source-line-no">4231</span><span id="line-4231">  public ReplicationPeerManager getReplicationPeerManager() {</span>
-<span class="source-line-no">4232</span><span id="line-4232">    return replicationPeerManager;</span>
-<span class="source-line-no">4233</span><span id="line-4233">  }</span>
-<span class="source-line-no">4234</span><span id="line-4234"></span>
-<span class="source-line-no">4235</span><span id="line-4235">  @Override</span>
-<span class="source-line-no">4236</span><span id="line-4236">  public ReplicationLogCleanerBarrier getReplicationLogCleanerBarrier() {</span>
-<span class="source-line-no">4237</span><span id="line-4237">    return replicationLogCleanerBarrier;</span>
-<span class="source-line-no">4238</span><span id="line-4238">  }</span>
-<span class="source-line-no">4239</span><span id="line-4239"></span>
-<span class="source-line-no">4240</span><span id="line-4240">  @Override</span>
-<span class="source-line-no">4241</span><span id="line-4241">  public Semaphore getSyncReplicationPeerLock() {</span>
-<span class="source-line-no">4242</span><span id="line-4242">    return syncReplicationPeerLock;</span>
-<span class="source-line-no">4243</span><span id="line-4243">  }</span>
-<span class="source-line-no">4244</span><span id="line-4244"></span>
-<span class="source-line-no">4245</span><span id="line-4245">  public HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt;</span>
-<span class="source-line-no">4246</span><span id="line-4246">    getReplicationLoad(ServerName[] serverNames) {</span>
-<span class="source-line-no">4247</span><span id="line-4247">    List&lt;ReplicationPeerDescription&gt; peerList = this.getReplicationPeerManager().listPeers(null);</span>
-<span class="source-line-no">4248</span><span id="line-4248">    if (peerList == null) {</span>
-<span class="source-line-no">4249</span><span id="line-4249">      return null;</span>
-<span class="source-line-no">4250</span><span id="line-4250">    }</span>
-<span class="source-line-no">4251</span><span id="line-4251">    HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt; replicationLoadSourceMap =</span>
-<span class="source-line-no">4252</span><span id="line-4252">      new HashMap&lt;&gt;(peerList.size());</span>
-<span class="source-line-no">4253</span><span id="line-4253">    peerList.stream()</span>
-<span class="source-line-no">4254</span><span id="line-4254">      .forEach(peer -&gt; replicationLoadSourceMap.put(peer.getPeerId(), new ArrayList&lt;&gt;()));</span>
-<span class="source-line-no">4255</span><span id="line-4255">    for (ServerName serverName : serverNames) {</span>
-<span class="source-line-no">4256</span><span id="line-4256">      List&lt;ReplicationLoadSource&gt; replicationLoadSources =</span>
-<span class="source-line-no">4257</span><span id="line-4257">        getServerManager().getLoad(serverName).getReplicationLoadSourceList();</span>
-<span class="source-line-no">4258</span><span id="line-4258">      for (ReplicationLoadSource replicationLoadSource : replicationLoadSources) {</span>
-<span class="source-line-no">4259</span><span id="line-4259">        List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; replicationLoadSourceList =</span>
-<span class="source-line-no">4260</span><span id="line-4260">          replicationLoadSourceMap.get(replicationLoadSource.getPeerID());</span>
-<span class="source-line-no">4261</span><span id="line-4261">        if (replicationLoadSourceList == null) {</span>
-<span class="source-line-no">4262</span><span id="line-4262">          LOG.debug("{} does not exist, but it exists "</span>
-<span class="source-line-no">4263</span><span id="line-4263">            + "in znode(/hbase/replication/rs). when the rs restarts, peerId is deleted, so "</span>
-<span class="source-line-no">4264</span><span id="line-4264">            + "we just need to ignore it", replicationLoadSource.getPeerID());</span>
-<span class="source-line-no">4265</span><span id="line-4265">          continue;</span>
-<span class="source-line-no">4266</span><span id="line-4266">        }</span>
-<span class="source-line-no">4267</span><span id="line-4267">        replicationLoadSourceList.add(new Pair&lt;&gt;(serverName, replicationLoadSource));</span>
-<span class="source-line-no">4268</span><span id="line-4268">      }</span>
-<span class="source-line-no">4269</span><span id="line-4269">    }</span>
-<span class="source-line-no">4270</span><span id="line-4270">    for (List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; loads : replicationLoadSourceMap.values()) {</span>
-<span class="source-line-no">4271</span><span id="line-4271">      if (loads.size() &gt; 0) {</span>
-<span class="source-line-no">4272</span><span id="line-4272">        loads.sort(Comparator.comparingLong(load -&gt; (-1) * load.getSecond().getReplicationLag()));</span>
-<span class="source-line-no">4273</span><span id="line-4273">      }</span>
-<span class="source-line-no">4274</span><span id="line-4274">    }</span>
-<span class="source-line-no">4275</span><span id="line-4275">    return replicationLoadSourceMap;</span>
-<span class="source-line-no">4276</span><span id="line-4276">  }</span>
-<span class="source-line-no">4277</span><span id="line-4277"></span>
-<span class="source-line-no">4278</span><span id="line-4278">  /**</span>
-<span class="source-line-no">4279</span><span id="line-4279">   * This method modifies the master's configuration in order to inject replication-related features</span>
-<span class="source-line-no">4280</span><span id="line-4280">   */</span>
-<span class="source-line-no">4281</span><span id="line-4281">  @InterfaceAudience.Private</span>
-<span class="source-line-no">4282</span><span id="line-4282">  public static void decorateMasterConfiguration(Configuration conf) {</span>
-<span class="source-line-no">4283</span><span id="line-4283">    String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);</span>
-<span class="source-line-no">4284</span><span id="line-4284">    String cleanerClass = ReplicationLogCleaner.class.getCanonicalName();</span>
-<span class="source-line-no">4285</span><span id="line-4285">    if (plugins == null || !plugins.contains(cleanerClass)) {</span>
-<span class="source-line-no">4286</span><span id="line-4286">      conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
-<span class="source-line-no">4287</span><span id="line-4287">    }</span>
-<span class="source-line-no">4288</span><span id="line-4288">    if (ReplicationUtils.isReplicationForBulkLoadDataEnabled(conf)) {</span>
-<span class="source-line-no">4289</span><span id="line-4289">      plugins = conf.get(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS);</span>
-<span class="source-line-no">4290</span><span id="line-4290">      cleanerClass = ReplicationHFileCleaner.class.getCanonicalName();</span>
-<span class="source-line-no">4291</span><span id="line-4291">      if (!plugins.contains(cleanerClass)) {</span>
-<span class="source-line-no">4292</span><span id="line-4292">        conf.set(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
-<span class="source-line-no">4293</span><span id="line-4293">      }</span>
-<span class="source-line-no">4294</span><span id="line-4294">    }</span>
-<span class="source-line-no">4295</span><span id="line-4295">  }</span>
-<span class="source-line-no">4296</span><span id="line-4296"></span>
-<span class="source-line-no">4297</span><span id="line-4297">  public SnapshotQuotaObserverChore getSnapshotQuotaObserverChore() {</span>
-<span class="source-line-no">4298</span><span id="line-4298">    return this.snapshotQuotaChore;</span>
+<span class="source-line-no">4230</span><span id="line-4230">      });</span>
+<span class="source-line-no">4231</span><span id="line-4231"></span>
+<span class="source-line-no">4232</span><span id="line-4232">  }</span>
+<span class="source-line-no">4233</span><span id="line-4233"></span>
+<span class="source-line-no">4234</span><span id="line-4234">  @Override</span>
+<span class="source-line-no">4235</span><span id="line-4235">  public ReplicationPeerManager getReplicationPeerManager() {</span>
+<span class="source-line-no">4236</span><span id="line-4236">    return replicationPeerManager;</span>
+<span class="source-line-no">4237</span><span id="line-4237">  }</span>
+<span class="source-line-no">4238</span><span id="line-4238"></span>
+<span class="source-line-no">4239</span><span id="line-4239">  @Override</span>
+<span class="source-line-no">4240</span><span id="line-4240">  public ReplicationLogCleanerBarrier getReplicationLogCleanerBarrier() {</span>
+<span class="source-line-no">4241</span><span id="line-4241">    return replicationLogCleanerBarrier;</span>
+<span class="source-line-no">4242</span><span id="line-4242">  }</span>
+<span class="source-line-no">4243</span><span id="line-4243"></span>
+<span class="source-line-no">4244</span><span id="line-4244">  @Override</span>
+<span class="source-line-no">4245</span><span id="line-4245">  public Semaphore getSyncReplicationPeerLock() {</span>
+<span class="source-line-no">4246</span><span id="line-4246">    return syncReplicationPeerLock;</span>
+<span class="source-line-no">4247</span><span id="line-4247">  }</span>
+<span class="source-line-no">4248</span><span id="line-4248"></span>
+<span class="source-line-no">4249</span><span id="line-4249">  public HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt;</span>
+<span class="source-line-no">4250</span><span id="line-4250">    getReplicationLoad(ServerName[] serverNames) {</span>
+<span class="source-line-no">4251</span><span id="line-4251">    List&lt;ReplicationPeerDescription&gt; peerList = this.getReplicationPeerManager().listPeers(null);</span>
+<span class="source-line-no">4252</span><span id="line-4252">    if (peerList == null) {</span>
+<span class="source-line-no">4253</span><span id="line-4253">      return null;</span>
+<span class="source-line-no">4254</span><span id="line-4254">    }</span>
+<span class="source-line-no">4255</span><span id="line-4255">    HashMap&lt;String, List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt;&gt; replicationLoadSourceMap =</span>
+<span class="source-line-no">4256</span><span id="line-4256">      new HashMap&lt;&gt;(peerList.size());</span>
+<span class="source-line-no">4257</span><span id="line-4257">    peerList.stream()</span>
+<span class="source-line-no">4258</span><span id="line-4258">      .forEach(peer -&gt; replicationLoadSourceMap.put(peer.getPeerId(), new ArrayList&lt;&gt;()));</span>
+<span class="source-line-no">4259</span><span id="line-4259">    for (ServerName serverName : serverNames) {</span>
+<span class="source-line-no">4260</span><span id="line-4260">      List&lt;ReplicationLoadSource&gt; replicationLoadSources =</span>
+<span class="source-line-no">4261</span><span id="line-4261">        getServerManager().getLoad(serverName).getReplicationLoadSourceList();</span>
+<span class="source-line-no">4262</span><span id="line-4262">      for (ReplicationLoadSource replicationLoadSource : replicationLoadSources) {</span>
+<span class="source-line-no">4263</span><span id="line-4263">        List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; replicationLoadSourceList =</span>
+<span class="source-line-no">4264</span><span id="line-4264">          replicationLoadSourceMap.get(replicationLoadSource.getPeerID());</span>
+<span class="source-line-no">4265</span><span id="line-4265">        if (replicationLoadSourceList == null) {</span>
+<span class="source-line-no">4266</span><span id="line-4266">          LOG.debug("{} does not exist, but it exists "</span>
+<span class="source-line-no">4267</span><span id="line-4267">            + "in znode(/hbase/replication/rs). when the rs restarts, peerId is deleted, so "</span>
+<span class="source-line-no">4268</span><span id="line-4268">            + "we just need to ignore it", replicationLoadSource.getPeerID());</span>
+<span class="source-line-no">4269</span><span id="line-4269">          continue;</span>
+<span class="source-line-no">4270</span><span id="line-4270">        }</span>
+<span class="source-line-no">4271</span><span id="line-4271">        replicationLoadSourceList.add(new Pair&lt;&gt;(serverName, replicationLoadSource));</span>
+<span class="source-line-no">4272</span><span id="line-4272">      }</span>
+<span class="source-line-no">4273</span><span id="line-4273">    }</span>
+<span class="source-line-no">4274</span><span id="line-4274">    for (List&lt;Pair&lt;ServerName, ReplicationLoadSource&gt;&gt; loads : replicationLoadSourceMap.values()) {</span>
+<span class="source-line-no">4275</span><span id="line-4275">      if (loads.size() &gt; 0) {</span>
+<span class="source-line-no">4276</span><span id="line-4276">        loads.sort(Comparator.comparingLong(load -&gt; (-1) * load.getSecond().getReplicationLag()));</span>
+<span class="source-line-no">4277</span><span id="line-4277">      }</span>
+<span class="source-line-no">4278</span><span id="line-4278">    }</span>
+<span class="source-line-no">4279</span><span id="line-4279">    return replicationLoadSourceMap;</span>
+<span class="source-line-no">4280</span><span id="line-4280">  }</span>
+<span class="source-line-no">4281</span><span id="line-4281"></span>
+<span class="source-line-no">4282</span><span id="line-4282">  /**</span>
+<span class="source-line-no">4283</span><span id="line-4283">   * This method modifies the master's configuration in order to inject replication-related features</span>
+<span class="source-line-no">4284</span><span id="line-4284">   */</span>
+<span class="source-line-no">4285</span><span id="line-4285">  @InterfaceAudience.Private</span>
+<span class="source-line-no">4286</span><span id="line-4286">  public static void decorateMasterConfiguration(Configuration conf) {</span>
+<span class="source-line-no">4287</span><span id="line-4287">    String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);</span>
+<span class="source-line-no">4288</span><span id="line-4288">    String cleanerClass = ReplicationLogCleaner.class.getCanonicalName();</span>
+<span class="source-line-no">4289</span><span id="line-4289">    if (plugins == null || !plugins.contains(cleanerClass)) {</span>
+<span class="source-line-no">4290</span><span id="line-4290">      conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
+<span class="source-line-no">4291</span><span id="line-4291">    }</span>
+<span class="source-line-no">4292</span><span id="line-4292">    if (ReplicationUtils.isReplicationForBulkLoadDataEnabled(conf)) {</span>
+<span class="source-line-no">4293</span><span id="line-4293">      plugins = conf.get(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS);</span>
+<span class="source-line-no">4294</span><span id="line-4294">      cleanerClass = ReplicationHFileCleaner.class.getCanonicalName();</span>
+<span class="source-line-no">4295</span><span id="line-4295">      if (!plugins.contains(cleanerClass)) {</span>
+<span class="source-line-no">4296</span><span id="line-4296">        conf.set(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS, plugins + "," + cleanerClass);</span>
+<span class="source-line-no">4297</span><span id="line-4297">      }</span>
+<span class="source-line-no">4298</span><span id="line-4298">    }</span>
 <span class="source-line-no">4299</span><span id="line-4299">  }</span>
 <span class="source-line-no">4300</span><span id="line-4300"></span>
-<span class="source-line-no">4301</span><span id="line-4301">  public ActiveMasterManager getActiveMasterManager() {</span>
-<span class="source-line-no">4302</span><span id="line-4302">    return activeMasterManager;</span>
+<span class="source-line-no">4301</span><span id="line-4301">  public SnapshotQuotaObserverChore getSnapshotQuotaObserverChore() {</span>
+<span class="source-line-no">4302</span><span id="line-4302">    return this.snapshotQuotaChore;</span>
 <span class="source-line-no">4303</span><span id="line-4303">  }</span>
 <span class="source-line-no">4304</span><span id="line-4304"></span>
-<span class="source-line-no">4305</span><span id="line-4305">  @Override</span>
-<span class="source-line-no">4306</span><span id="line-4306">  public SyncReplicationReplayWALManager getSyncReplicationReplayWALManager() {</span>
-<span class="source-line-no">4307</span><span id="line-4307">    return this.syncReplicationReplayWALManager;</span>
-<span class="source-line-no">4308</span><span id="line-4308">  }</span>
-<span class="source-line-no">4309</span><span id="line-4309"></span>
-<span class="source-line-no">4310</span><span id="line-4310">  @Override</span>
-<span class="source-line-no">4311</span><span id="line-4311">  public HbckChore getHbckChore() {</span>
-<span class="source-line-no">4312</span><span id="line-4312">    return this.hbckChore;</span>
-<span class="source-line-no">4313</span><span id="line-4313">  }</span>
-<span class="source-line-no">4314</span><span id="line-4314"></span>
-<span class="source-line-no">4315</span><span id="line-4315">  @Override</span>
-<span class="source-line-no">4316</span><span id="line-4316">  public void runReplicationBarrierCleaner() {</span>
-<span class="source-line-no">4317</span><span id="line-4317">    ReplicationBarrierCleaner rbc = this.replicationBarrierCleaner;</span>
-<span class="source-line-no">4318</span><span id="line-4318">    if (rbc != null) {</span>
-<span class="source-line-no">4319</span><span id="line-4319">      rbc.chore();</span>
-<span class="source-line-no">4320</span><span id="line-4320">    }</span>
-<span class="source-line-no">4321</span><span id="line-4321">  }</span>
-<span class="source-line-no">4322</span><span id="line-4322"></span>
-<span class="source-line-no">4323</span><span id="line-4323">  @Override</span>
-<span class="source-line-no">4324</span><span id="line-4324">  public RSGroupInfoManager getRSGroupInfoManager() {</span>
-<span class="source-line-no">4325</span><span id="line-4325">    return rsGroupInfoManager;</span>
-<span class="source-line-no">4326</span><span id="line-4326">  }</span>
-<span class="source-line-no">4327</span><span id="line-4327"></span>
-<span class="source-line-no">4328</span><span id="line-4328">  /**</span>
-<span class="source-line-no">4329</span><span id="line-4329">   * Get the compaction state of the table</span>
-<span class="source-line-no">4330</span><span id="line-4330">   * @param tableName The table name</span>
-<span class="source-line-no">4331</span><span id="line-4331">   * @return CompactionState Compaction state of the table</span>
-<span class="source-line-no">4332</span><span id="line-4332">   */</span>
-<span class="source-line-no">4333</span><span id="line-4333">  public CompactionState getCompactionState(final TableName tableName) {</span>
-<span class="source-line-no">4334</span><span id="line-4334">    CompactionState compactionState = CompactionState.NONE;</span>
-<span class="source-line-no">4335</span><span id="line-4335">    try {</span>
-<span class="source-line-no">4336</span><span id="line-4336">      List&lt;RegionInfo&gt; regions = assignmentManager.getRegionStates().getRegionsOfTable(tableName);</span>
-<span class="source-line-no">4337</span><span id="line-4337">      for (RegionInfo regionInfo : regions) {</span>
-<span class="source-line-no">4338</span><span id="line-4338">        ServerName serverName =</span>
-<span class="source-line-no">4339</span><span id="line-4339">          assignmentManager.getRegionStates().getRegionServerOfRegion(regionInfo);</span>
-<span class="source-line-no">4340</span><span id="line-4340">        if (serverName == null) {</span>
-<span class="source-line-no">4341</span><span id="line-4341">          continue;</span>
-<span class="source-line-no">4342</span><span id="line-4342">        }</span>
-<span class="source-line-no">4343</span><span id="line-4343">        ServerMetrics sl = serverManager.getLoad(serverName);</span>
-<span class="source-line-no">4344</span><span id="line-4344">        if (sl == null) {</span>
+<span class="source-line-no">4305</span><span id="line-4305">  public ActiveMasterManager getActiveMasterManager() {</span>
+<span class="source-line-no">4306</span><span id="line-4306">    return activeMasterManager;</span>
+<span class="source-line-no">4307</span><span id="line-4307">  }</span>
+<span class="source-line-no">4308</span><span id="line-4308"></span>
+<span class="source-line-no">4309</span><span id="line-4309">  @Override</span>
+<span class="source-line-no">4310</span><span id="line-4310">  public SyncReplicationReplayWALManager getSyncReplicationReplayWALManager() {</span>
+<span class="source-line-no">4311</span><span id="line-4311">    return this.syncReplicationReplayWALManager;</span>
+<span class="source-line-no">4312</span><span id="line-4312">  }</span>
+<span class="source-line-no">4313</span><span id="line-4313"></span>
+<span class="source-line-no">4314</span><span id="line-4314">  @Override</span>
+<span class="source-line-no">4315</span><span id="line-4315">  public HbckChore getHbckChore() {</span>
+<span class="source-line-no">4316</span><span id="line-4316">    return this.hbckChore;</span>
+<span class="source-line-no">4317</span><span id="line-4317">  }</span>
+<span class="source-line-no">4318</span><span id="line-4318"></span>
+<span class="source-line-no">4319</span><span id="line-4319">  @Override</span>
+<span class="source-line-no">4320</span><span id="line-4320">  public void runReplicationBarrierCleaner() {</span>
+<span class="source-line-no">4321</span><span id="line-4321">    ReplicationBarrierCleaner rbc = this.replicationBarrierCleaner;</span>
+<span class="source-line-no">4322</span><span id="line-4322">    if (rbc != null) {</span>
+<span class="source-line-no">4323</span><span id="line-4323">      rbc.chore();</span>
+<span class="source-line-no">4324</span><span id="line-4324">    }</span>
+<span class="source-line-no">4325</span><span id="line-4325">  }</span>
+<span class="source-line-no">4326</span><span id="line-4326"></span>
+<span class="source-line-no">4327</span><span id="line-4327">  @Override</span>
+<span class="source-line-no">4328</span><span id="line-4328">  public RSGroupInfoManager getRSGroupInfoManager() {</span>
+<span class="source-line-no">4329</span><span id="line-4329">    return rsGroupInfoManager;</span>
+<span class="source-line-no">4330</span><span id="line-4330">  }</span>
+<span class="source-line-no">4331</span><span id="line-4331"></span>
+<span class="source-line-no">4332</span><span id="line-4332">  /**</span>
+<span class="source-line-no">4333</span><span id="line-4333">   * Get the compaction state of the table</span>
+<span class="source-line-no">4334</span><span id="line-4334">   * @param tableName The table name</span>
+<span class="source-line-no">4335</span><span id="line-4335">   * @return CompactionState Compaction state of the table</span>
+<span class="source-line-no">4336</span><span id="line-4336">   */</span>
+<span class="source-line-no">4337</span><span id="line-4337">  public CompactionState getCompactionState(final TableName tableName) {</span>
+<span class="source-line-no">4338</span><span id="line-4338">    CompactionState compactionState = CompactionState.NONE;</span>
+<span class="source-line-no">4339</span><span id="line-4339">    try {</span>
+<span class="source-line-no">4340</span><span id="line-4340">      List&lt;RegionInfo&gt; regions = assignmentManager.getRegionStates().getRegionsOfTable(tableName);</span>
+<span class="source-line-no">4341</span><span id="line-4341">      for (RegionInfo regionInfo : regions) {</span>
+<span class="source-line-no">4342</span><span id="line-4342">        ServerName serverName =</span>
+<span class="source-line-no">4343</span><span id="line-4343">          assignmentManager.getRegionStates().getRegionServerOfRegion(regionInfo);</span>
+<span class="source-line-no">4344</span><span id="line-4344">        if (serverName == null) {</span>
 <span class="source-line-no">4345</span><span id="line-4345">          continue;</span>
 <span class="source-line-no">4346</span><span id="line-4346">        }</span>
-<span class="source-line-no">4347</span><span id="line-4347">        RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());</span>
-<span class="source-line-no">4348</span><span id="line-4348">        if (regionMetrics == null) {</span>
-<span class="source-line-no">4349</span><span id="line-4349">          LOG.warn("Can not get compaction details for the region: {} , it may be not online.",</span>
-<span class="source-line-no">4350</span><span id="line-4350">            regionInfo.getRegionNameAsString());</span>
-<span class="source-line-no">4351</span><span id="line-4351">          continue;</span>
-<span class="source-line-no">4352</span><span id="line-4352">        }</span>
-<span class="source-line-no">4353</span><span id="line-4353">        if (regionMetrics.getCompactionState() == CompactionState.MAJOR) {</span>
-<span class="source-line-no">4354</span><span id="line-4354">          if (compactionState == CompactionState.MINOR) {</span>
-<span class="source-line-no">4355</span><span id="line-4355">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">4356</span><span id="line-4356">          } else {</span>
-<span class="source-line-no">4357</span><span id="line-4357">            compactionState = CompactionState.MAJOR;</span>
-<span class="source-line-no">4358</span><span id="line-4358">          }</span>
-<span class="source-line-no">4359</span><span id="line-4359">        } else if (regionMetrics.getCompactionState() == CompactionState.MINOR) {</span>
-<span class="source-line-no">4360</span><span id="line-4360">          if (compactionState == CompactionState.MAJOR) {</span>
-<span class="source-line-no">4361</span><span id="line-4361">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
-<span class="source-line-no">4362</span><span id="line-4362">          } else {</span>
-<span class="source-line-no">4363</span><span id="line-4363">            compactionState = CompactionState.MINOR;</span>
-<span class="source-line-no">4364</span><span id="line-4364">          }</span>
-<span class="source-line-no">4365</span><span id="line-4365">        }</span>
-<span class="source-line-no">4366</span><span id="line-4366">      }</span>
-<span class="source-line-no">4367</span><span id="line-4367">    } catch (Exception e) {</span>
-<span class="source-line-no">4368</span><span id="line-4368">      compactionState = null;</span>
-<span class="source-line-no">4369</span><span id="line-4369">      LOG.error("Exception when get compaction state for " + tableName.getNameAsString(), e);</span>
-<span class="source-line-no">4370</span><span id="line-4370">    }</span>
-<span class="source-line-no">4371</span><span id="line-4371">    return compactionState;</span>
-<span class="source-line-no">4372</span><span id="line-4372">  }</span>
-<span class="source-line-no">4373</span><span id="line-4373"></span>
-<span class="source-line-no">4374</span><span id="line-4374">  @Override</span>
-<span class="source-line-no">4375</span><span id="line-4375">  public MetaLocationSyncer getMetaLocationSyncer() {</span>
-<span class="source-line-no">4376</span><span id="line-4376">    return metaLocationSyncer;</span>
-<span class="source-line-no">4377</span><span id="line-4377">  }</span>
-<span class="source-line-no">4378</span><span id="line-4378"></span>
-<span class="source-line-no">4379</span><span id="line-4379">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4380</span><span id="line-4380">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4381</span><span id="line-4381">  public MasterRegion getMasterRegion() {</span>
-<span class="source-line-no">4382</span><span id="line-4382">    return masterRegion;</span>
-<span class="source-line-no">4383</span><span id="line-4383">  }</span>
-<span class="source-line-no">4384</span><span id="line-4384"></span>
-<span class="source-line-no">4385</span><span id="line-4385">  @Override</span>
-<span class="source-line-no">4386</span><span id="line-4386">  public void onConfigurationChange(Configuration newConf) {</span>
-<span class="source-line-no">4387</span><span id="line-4387">    try {</span>
-<span class="source-line-no">4388</span><span id="line-4388">      Superusers.initialize(newConf);</span>
-<span class="source-line-no">4389</span><span id="line-4389">    } catch (IOException e) {</span>
-<span class="source-line-no">4390</span><span id="line-4390">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
-<span class="source-line-no">4391</span><span id="line-4391">    }</span>
-<span class="source-line-no">4392</span><span id="line-4392">    // append the quotas observer back to the master coprocessor key</span>
-<span class="source-line-no">4393</span><span id="line-4393">    setQuotasObserver(newConf);</span>
-<span class="source-line-no">4394</span><span id="line-4394">    // update region server coprocessor if the configuration has changed.</span>
-<span class="source-line-no">4395</span><span id="line-4395">    if (</span>
-<span class="source-line-no">4396</span><span id="line-4396">      CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,</span>
-<span class="source-line-no">4397</span><span id="line-4397">        CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) &amp;&amp; !maintenanceMode</span>
-<span class="source-line-no">4398</span><span id="line-4398">    ) {</span>
-<span class="source-line-no">4399</span><span id="line-4399">      LOG.info("Update the master coprocessor(s) because the configuration has changed");</span>
-<span class="source-line-no">4400</span><span id="line-4400">      initializeCoprocessorHost(newConf);</span>
-<span class="source-line-no">4401</span><span id="line-4401">    }</span>
-<span class="source-line-no">4402</span><span id="line-4402">  }</span>
-<span class="source-line-no">4403</span><span id="line-4403"></span>
-<span class="source-line-no">4404</span><span id="line-4404">  @Override</span>
-<span class="source-line-no">4405</span><span id="line-4405">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
-<span class="source-line-no">4406</span><span id="line-4406">    final boolean isBalancerDecisionRecording =</span>
-<span class="source-line-no">4407</span><span id="line-4407">      conf.getBoolean(BaseLoadBalancer.BALANCER_DECISION_BUFFER_ENABLED,</span>
-<span class="source-line-no">4408</span><span id="line-4408">        BaseLoadBalancer.DEFAULT_BALANCER_DECISION_BUFFER_ENABLED);</span>
-<span class="source-line-no">4409</span><span id="line-4409">    final boolean isBalancerRejectionRecording =</span>
-<span class="source-line-no">4410</span><span id="line-4410">      conf.getBoolean(BaseLoadBalancer.BALANCER_REJECTION_BUFFER_ENABLED,</span>
-<span class="source-line-no">4411</span><span id="line-4411">        BaseLoadBalancer.DEFAULT_BALANCER_REJECTION_BUFFER_ENABLED);</span>
-<span class="source-line-no">4412</span><span id="line-4412">    if (isBalancerDecisionRecording || isBalancerRejectionRecording) {</span>
-<span class="source-line-no">4413</span><span id="line-4413">      return NamedQueueRecorder.getInstance(conf);</span>
-<span class="source-line-no">4414</span><span id="line-4414">    } else {</span>
-<span class="source-line-no">4415</span><span id="line-4415">      return null;</span>
-<span class="source-line-no">4416</span><span id="line-4416">    }</span>
-<span class="source-line-no">4417</span><span id="line-4417">  }</span>
-<span class="source-line-no">4418</span><span id="line-4418"></span>
-<span class="source-line-no">4419</span><span id="line-4419">  @Override</span>
-<span class="source-line-no">4420</span><span id="line-4420">  protected boolean clusterMode() {</span>
-<span class="source-line-no">4421</span><span id="line-4421">    return true;</span>
-<span class="source-line-no">4422</span><span id="line-4422">  }</span>
-<span class="source-line-no">4423</span><span id="line-4423"></span>
-<span class="source-line-no">4424</span><span id="line-4424">  public String getClusterId() {</span>
-<span class="source-line-no">4425</span><span id="line-4425">    if (activeMaster) {</span>
-<span class="source-line-no">4426</span><span id="line-4426">      return clusterId;</span>
-<span class="source-line-no">4427</span><span id="line-4427">    }</span>
-<span class="source-line-no">4428</span><span id="line-4428">    return cachedClusterId.getFromCacheOrFetch();</span>
-<span class="source-line-no">4429</span><span id="line-4429">  }</span>
-<span class="source-line-no">4430</span><span id="line-4430"></span>
-<span class="source-line-no">4431</span><span id="line-4431">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
-<span class="source-line-no">4432</span><span id="line-4432">    return activeMasterManager.getActiveMasterServerName();</span>
+<span class="source-line-no">4347</span><span id="line-4347">        ServerMetrics sl = serverManager.getLoad(serverName);</span>
+<span class="source-line-no">4348</span><span id="line-4348">        if (sl == null) {</span>
+<span class="source-line-no">4349</span><span id="line-4349">          continue;</span>
+<span class="source-line-no">4350</span><span id="line-4350">        }</span>
+<span class="source-line-no">4351</span><span id="line-4351">        RegionMetrics regionMetrics = sl.getRegionMetrics().get(regionInfo.getRegionName());</span>
+<span class="source-line-no">4352</span><span id="line-4352">        if (regionMetrics == null) {</span>
+<span class="source-line-no">4353</span><span id="line-4353">          LOG.warn("Can not get compaction details for the region: {} , it may be not online.",</span>
+<span class="source-line-no">4354</span><span id="line-4354">            regionInfo.getRegionNameAsString());</span>
+<span class="source-line-no">4355</span><span id="line-4355">          continue;</span>
+<span class="source-line-no">4356</span><span id="line-4356">        }</span>
+<span class="source-line-no">4357</span><span id="line-4357">        if (regionMetrics.getCompactionState() == CompactionState.MAJOR) {</span>
+<span class="source-line-no">4358</span><span id="line-4358">          if (compactionState == CompactionState.MINOR) {</span>
+<span class="source-line-no">4359</span><span id="line-4359">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">4360</span><span id="line-4360">          } else {</span>
+<span class="source-line-no">4361</span><span id="line-4361">            compactionState = CompactionState.MAJOR;</span>
+<span class="source-line-no">4362</span><span id="line-4362">          }</span>
+<span class="source-line-no">4363</span><span id="line-4363">        } else if (regionMetrics.getCompactionState() == CompactionState.MINOR) {</span>
+<span class="source-line-no">4364</span><span id="line-4364">          if (compactionState == CompactionState.MAJOR) {</span>
+<span class="source-line-no">4365</span><span id="line-4365">            compactionState = CompactionState.MAJOR_AND_MINOR;</span>
+<span class="source-line-no">4366</span><span id="line-4366">          } else {</span>
+<span class="source-line-no">4367</span><span id="line-4367">            compactionState = CompactionState.MINOR;</span>
+<span class="source-line-no">4368</span><span id="line-4368">          }</span>
+<span class="source-line-no">4369</span><span id="line-4369">        }</span>
+<span class="source-line-no">4370</span><span id="line-4370">      }</span>
+<span class="source-line-no">4371</span><span id="line-4371">    } catch (Exception e) {</span>
+<span class="source-line-no">4372</span><span id="line-4372">      compactionState = null;</span>
+<span class="source-line-no">4373</span><span id="line-4373">      LOG.error("Exception when get compaction state for " + tableName.getNameAsString(), e);</span>
+<span class="source-line-no">4374</span><span id="line-4374">    }</span>
+<span class="source-line-no">4375</span><span id="line-4375">    return compactionState;</span>
+<span class="source-line-no">4376</span><span id="line-4376">  }</span>
+<span class="source-line-no">4377</span><span id="line-4377"></span>
+<span class="source-line-no">4378</span><span id="line-4378">  @Override</span>
+<span class="source-line-no">4379</span><span id="line-4379">  public MetaLocationSyncer getMetaLocationSyncer() {</span>
+<span class="source-line-no">4380</span><span id="line-4380">    return metaLocationSyncer;</span>
+<span class="source-line-no">4381</span><span id="line-4381">  }</span>
+<span class="source-line-no">4382</span><span id="line-4382"></span>
+<span class="source-line-no">4383</span><span id="line-4383">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4384</span><span id="line-4384">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4385</span><span id="line-4385">  public MasterRegion getMasterRegion() {</span>
+<span class="source-line-no">4386</span><span id="line-4386">    return masterRegion;</span>
+<span class="source-line-no">4387</span><span id="line-4387">  }</span>
+<span class="source-line-no">4388</span><span id="line-4388"></span>
+<span class="source-line-no">4389</span><span id="line-4389">  @Override</span>
+<span class="source-line-no">4390</span><span id="line-4390">  public void onConfigurationChange(Configuration newConf) {</span>
+<span class="source-line-no">4391</span><span id="line-4391">    try {</span>
+<span class="source-line-no">4392</span><span id="line-4392">      Superusers.initialize(newConf);</span>
+<span class="source-line-no">4393</span><span id="line-4393">    } catch (IOException e) {</span>
+<span class="source-line-no">4394</span><span id="line-4394">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
+<span class="source-line-no">4395</span><span id="line-4395">    }</span>
+<span class="source-line-no">4396</span><span id="line-4396">    // append the quotas observer back to the master coprocessor key</span>
+<span class="source-line-no">4397</span><span id="line-4397">    setQuotasObserver(newConf);</span>
+<span class="source-line-no">4398</span><span id="line-4398">    // update region server coprocessor if the configuration has changed.</span>
+<span class="source-line-no">4399</span><span id="line-4399">    if (</span>
+<span class="source-line-no">4400</span><span id="line-4400">      CoprocessorConfigurationUtil.checkConfigurationChange(getConfiguration(), newConf,</span>
+<span class="source-line-no">4401</span><span id="line-4401">        CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY) &amp;&amp; !maintenanceMode</span>
+<span class="source-line-no">4402</span><span id="line-4402">    ) {</span>
+<span class="source-line-no">4403</span><span id="line-4403">      LOG.info("Update the master coprocessor(s) because the configuration has changed");</span>
+<span class="source-line-no">4404</span><span id="line-4404">      initializeCoprocessorHost(newConf);</span>
+<span class="source-line-no">4405</span><span id="line-4405">    }</span>
+<span class="source-line-no">4406</span><span id="line-4406">  }</span>
+<span class="source-line-no">4407</span><span id="line-4407"></span>
+<span class="source-line-no">4408</span><span id="line-4408">  @Override</span>
+<span class="source-line-no">4409</span><span id="line-4409">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
+<span class="source-line-no">4410</span><span id="line-4410">    final boolean isBalancerDecisionRecording =</span>
+<span class="source-line-no">4411</span><span id="line-4411">      conf.getBoolean(BaseLoadBalancer.BALANCER_DECISION_BUFFER_ENABLED,</span>
+<span class="source-line-no">4412</span><span id="line-4412">        BaseLoadBalancer.DEFAULT_BALANCER_DECISION_BUFFER_ENABLED);</span>
+<span class="source-line-no">4413</span><span id="line-4413">    final boolean isBalancerRejectionRecording =</span>
+<span class="source-line-no">4414</span><span id="line-4414">      conf.getBoolean(BaseLoadBalancer.BALANCER_REJECTION_BUFFER_ENABLED,</span>
+<span class="source-line-no">4415</span><span id="line-4415">        BaseLoadBalancer.DEFAULT_BALANCER_REJECTION_BUFFER_ENABLED);</span>
+<span class="source-line-no">4416</span><span id="line-4416">    if (isBalancerDecisionRecording || isBalancerRejectionRecording) {</span>
+<span class="source-line-no">4417</span><span id="line-4417">      return NamedQueueRecorder.getInstance(conf);</span>
+<span class="source-line-no">4418</span><span id="line-4418">    } else {</span>
+<span class="source-line-no">4419</span><span id="line-4419">      return null;</span>
+<span class="source-line-no">4420</span><span id="line-4420">    }</span>
+<span class="source-line-no">4421</span><span id="line-4421">  }</span>
+<span class="source-line-no">4422</span><span id="line-4422"></span>
+<span class="source-line-no">4423</span><span id="line-4423">  @Override</span>
+<span class="source-line-no">4424</span><span id="line-4424">  protected boolean clusterMode() {</span>
+<span class="source-line-no">4425</span><span id="line-4425">    return true;</span>
+<span class="source-line-no">4426</span><span id="line-4426">  }</span>
+<span class="source-line-no">4427</span><span id="line-4427"></span>
+<span class="source-line-no">4428</span><span id="line-4428">  public String getClusterId() {</span>
+<span class="source-line-no">4429</span><span id="line-4429">    if (activeMaster) {</span>
+<span class="source-line-no">4430</span><span id="line-4430">      return clusterId;</span>
+<span class="source-line-no">4431</span><span id="line-4431">    }</span>
+<span class="source-line-no">4432</span><span id="line-4432">    return cachedClusterId.getFromCacheOrFetch();</span>
 <span class="source-line-no">4433</span><span id="line-4433">  }</span>
 <span class="source-line-no">4434</span><span id="line-4434"></span>
-<span class="source-line-no">4435</span><span id="line-4435">  public List&lt;ServerName&gt; getBackupMasters() {</span>
-<span class="source-line-no">4436</span><span id="line-4436">    return activeMasterManager.getBackupMasters();</span>
+<span class="source-line-no">4435</span><span id="line-4435">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
+<span class="source-line-no">4436</span><span id="line-4436">    return activeMasterManager.getActiveMasterServerName();</span>
 <span class="source-line-no">4437</span><span id="line-4437">  }</span>
 <span class="source-line-no">4438</span><span id="line-4438"></span>
-<span class="source-line-no">4439</span><span id="line-4439">  @Override</span>
-<span class="source-line-no">4440</span><span id="line-4440">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
-<span class="source-line-no">4441</span><span id="line-4441">    return regionServerTracker.getRegionServers().iterator();</span>
-<span class="source-line-no">4442</span><span id="line-4442">  }</span>
-<span class="source-line-no">4443</span><span id="line-4443"></span>
-<span class="source-line-no">4444</span><span id="line-4444">  @Override</span>
-<span class="source-line-no">4445</span><span id="line-4445">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
-<span class="source-line-no">4446</span><span id="line-4446">    return metaRegionLocationCache.getMetaRegionLocations();</span>
-<span class="source-line-no">4447</span><span id="line-4447">  }</span>
-<span class="source-line-no">4448</span><span id="line-4448"></span>
-<span class="source-line-no">4449</span><span id="line-4449">  @Override</span>
-<span class="source-line-no">4450</span><span id="line-4450">  public void flushMasterStore() throws IOException {</span>
-<span class="source-line-no">4451</span><span id="line-4451">    LOG.info("Force flush master local region.");</span>
-<span class="source-line-no">4452</span><span id="line-4452">    if (this.cpHost != null) {</span>
-<span class="source-line-no">4453</span><span id="line-4453">      try {</span>
-<span class="source-line-no">4454</span><span id="line-4454">        cpHost.preMasterStoreFlush();</span>
-<span class="source-line-no">4455</span><span id="line-4455">      } catch (IOException ioe) {</span>
-<span class="source-line-no">4456</span><span id="line-4456">        LOG.error("Error invoking master coprocessor preMasterStoreFlush()", ioe);</span>
-<span class="source-line-no">4457</span><span id="line-4457">      }</span>
-<span class="source-line-no">4458</span><span id="line-4458">    }</span>
-<span class="source-line-no">4459</span><span id="line-4459">    masterRegion.flush(true);</span>
-<span class="source-line-no">4460</span><span id="line-4460">    if (this.cpHost != null) {</span>
-<span class="source-line-no">4461</span><span id="line-4461">      try {</span>
-<span class="source-line-no">4462</span><span id="line-4462">        cpHost.postMasterStoreFlush();</span>
-<span class="source-line-no">4463</span><span id="line-4463">      } catch (IOException ioe) {</span>
-<span class="source-line-no">4464</span><span id="line-4464">        LOG.error("Error invoking master coprocessor postMasterStoreFlush()", ioe);</span>
-<span class="source-line-no">4465</span><span id="line-4465">      }</span>
-<span class="source-line-no">4466</span><span id="line-4466">    }</span>
-<span class="source-line-no">4467</span><span id="line-4467">  }</span>
-<span class="source-line-no">4468</span><span id="line-4468"></span>
-<span class="source-line-no">4469</span><span id="line-4469">  public Collection&lt;ServerName&gt; getLiveRegionServers() {</span>
-<span class="source-line-no">4470</span><span id="line-4470">    return regionServerTracker.getRegionServers();</span>
+<span class="source-line-no">4439</span><span id="line-4439">  public List&lt;ServerName&gt; getBackupMasters() {</span>
+<span class="source-line-no">4440</span><span id="line-4440">    return activeMasterManager.getBackupMasters();</span>
+<span class="source-line-no">4441</span><span id="line-4441">  }</span>
+<span class="source-line-no">4442</span><span id="line-4442"></span>
+<span class="source-line-no">4443</span><span id="line-4443">  @Override</span>
+<span class="source-line-no">4444</span><span id="line-4444">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
+<span class="source-line-no">4445</span><span id="line-4445">    return regionServerTracker.getRegionServers().iterator();</span>
+<span class="source-line-no">4446</span><span id="line-4446">  }</span>
+<span class="source-line-no">4447</span><span id="line-4447"></span>
+<span class="source-line-no">4448</span><span id="line-4448">  @Override</span>
+<span class="source-line-no">4449</span><span id="line-4449">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
+<span class="source-line-no">4450</span><span id="line-4450">    return metaRegionLocationCache.getMetaRegionLocations();</span>
+<span class="source-line-no">4451</span><span id="line-4451">  }</span>
+<span class="source-line-no">4452</span><span id="line-4452"></span>
+<span class="source-line-no">4453</span><span id="line-4453">  @Override</span>
+<span class="source-line-no">4454</span><span id="line-4454">  public void flushMasterStore() throws IOException {</span>
+<span class="source-line-no">4455</span><span id="line-4455">    LOG.info("Force flush master local region.");</span>
+<span class="source-line-no">4456</span><span id="line-4456">    if (this.cpHost != null) {</span>
+<span class="source-line-no">4457</span><span id="line-4457">      try {</span>
+<span class="source-line-no">4458</span><span id="line-4458">        cpHost.preMasterStoreFlush();</span>
+<span class="source-line-no">4459</span><span id="line-4459">      } catch (IOException ioe) {</span>
+<span class="source-line-no">4460</span><span id="line-4460">        LOG.error("Error invoking master coprocessor preMasterStoreFlush()", ioe);</span>
+<span class="source-line-no">4461</span><span id="line-4461">      }</span>
+<span class="source-line-no">4462</span><span id="line-4462">    }</span>
+<span class="source-line-no">4463</span><span id="line-4463">    masterRegion.flush(true);</span>
+<span class="source-line-no">4464</span><span id="line-4464">    if (this.cpHost != null) {</span>
+<span class="source-line-no">4465</span><span id="line-4465">      try {</span>
+<span class="source-line-no">4466</span><span id="line-4466">        cpHost.postMasterStoreFlush();</span>
+<span class="source-line-no">4467</span><span id="line-4467">      } catch (IOException ioe) {</span>
+<span class="source-line-no">4468</span><span id="line-4468">        LOG.error("Error invoking master coprocessor postMasterStoreFlush()", ioe);</span>
+<span class="source-line-no">4469</span><span id="line-4469">      }</span>
+<span class="source-line-no">4470</span><span id="line-4470">    }</span>
 <span class="source-line-no">4471</span><span id="line-4471">  }</span>
 <span class="source-line-no">4472</span><span id="line-4472"></span>
-<span class="source-line-no">4473</span><span id="line-4473">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4474</span><span id="line-4474">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4475</span><span id="line-4475">  void setLoadBalancer(RSGroupBasedLoadBalancer loadBalancer) {</span>
-<span class="source-line-no">4476</span><span id="line-4476">    this.balancer = loadBalancer;</span>
-<span class="source-line-no">4477</span><span id="line-4477">  }</span>
-<span class="source-line-no">4478</span><span id="line-4478"></span>
-<span class="source-line-no">4479</span><span id="line-4479">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4480</span><span id="line-4480">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4481</span><span id="line-4481">  void setAssignmentManager(AssignmentManager assignmentManager) {</span>
-<span class="source-line-no">4482</span><span id="line-4482">    this.assignmentManager = assignmentManager;</span>
-<span class="source-line-no">4483</span><span id="line-4483">  }</span>
-<span class="source-line-no">4484</span><span id="line-4484"></span>
-<span class="source-line-no">4485</span><span id="line-4485">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">4486</span><span id="line-4486">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">4487</span><span id="line-4487">  static void setDisableBalancerChoreForTest(boolean disable) {</span>
-<span class="source-line-no">4488</span><span id="line-4488">    disableBalancerChoreForTest = disable;</span>
-<span class="source-line-no">4489</span><span id="line-4489">  }</span>
-<span class="source-line-no">4490</span><span id="line-4490"></span>
-<span class="source-line-no">4491</span><span id="line-4491">  private void setQuotasObserver(Configuration conf) {</span>
-<span class="source-line-no">4492</span><span id="line-4492">    // Add the Observer to delete quotas on table deletion before starting all CPs by</span>
-<span class="source-line-no">4493</span><span id="line-4493">    // default with quota support, avoiding if user specifically asks to not load this Observer.</span>
-<span class="source-line-no">4494</span><span id="line-4494">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
-<span class="source-line-no">4495</span><span id="line-4495">      updateConfigurationForQuotasObserver(conf);</span>
-<span class="source-line-no">4496</span><span id="line-4496">    }</span>
-<span class="source-line-no">4497</span><span id="line-4497">  }</span>
-<span class="source-line-no">4498</span><span id="line-4498"></span>
-<span class="source-line-no">4499</span><span id="line-4499">  private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">4500</span><span id="line-4500">    // initialize master side coprocessors before we start handling requests</span>
-<span class="source-line-no">4501</span><span id="line-4501">    this.cpHost = new MasterCoprocessorHost(this, conf);</span>
-<span class="source-line-no">4502</span><span id="line-4502">  }</span>
-<span class="source-line-no">4503</span><span id="line-4503"></span>
-<span class="source-line-no">4504</span><span id="line-4504">  @Override</span>
-<span class="source-line-no">4505</span><span id="line-4505">  public long flushTable(TableName tableName, List&lt;byte[]&gt; columnFamilies, long nonceGroup,</span>
-<span class="source-line-no">4506</span><span id="line-4506">    long nonce) throws IOException {</span>
-<span class="source-line-no">4507</span><span id="line-4507">    checkInitialized();</span>
-<span class="source-line-no">4508</span><span id="line-4508"></span>
-<span class="source-line-no">4509</span><span id="line-4509">    if (</span>
-<span class="source-line-no">4510</span><span id="line-4510">      !getConfiguration().getBoolean(MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED,</span>
-<span class="source-line-no">4511</span><span id="line-4511">        MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED_DEFAULT)</span>
-<span class="source-line-no">4512</span><span id="line-4512">    ) {</span>
-<span class="source-line-no">4513</span><span id="line-4513">      throw new DoNotRetryIOException("FlushTableProcedureV2 is DISABLED");</span>
-<span class="source-line-no">4514</span><span id="line-4514">    }</span>
-<span class="source-line-no">4515</span><span id="line-4515"></span>
-<span class="source-line-no">4516</span><span id="line-4516">    return MasterProcedureUtil</span>
-<span class="source-line-no">4517</span><span id="line-4517">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
-<span class="source-line-no">4518</span><span id="line-4518">        @Override</span>
-<span class="source-line-no">4519</span><span id="line-4519">        protected void run() throws IOException {</span>
-<span class="source-line-no">4520</span><span id="line-4520">          getMaster().getMasterCoprocessorHost().preTableFlush(tableName);</span>
-<span class="source-line-no">4521</span><span id="line-4521">          LOG.info(getClientIdAuditPrefix() + " flush " + tableName);</span>
-<span class="source-line-no">4522</span><span id="line-4522">          submitProcedure(</span>
-<span class="source-line-no">4523</span><span id="line-4523">            new FlushTableProcedure(procedureExecutor.getEnvironment(), tableName, columnFamilies));</span>
-<span class="source-line-no">4524</span><span id="line-4524">          getMaster().getMasterCoprocessorHost().postTableFlush(tableName);</span>
-<span class="source-line-no">4525</span><span id="line-4525">        }</span>
-<span class="source-line-no">4526</span><span id="line-4526"></span>
-<span class="source-line-no">4527</span><span id="line-4527">        @Override</span>
-<span class="source-line-no">4528</span><span id="line-4528">        protected String getDescription() {</span>
-<span class="source-line-no">4529</span><span id="line-4529">          return "FlushTableProcedure";</span>
-<span class="source-line-no">4530</span><span id="line-4530">        }</span>
-<span class="source-line-no">4531</span><span id="line-4531">      });</span>
-<span class="source-line-no">4532</span><span id="line-4532">  }</span>
-<span class="source-line-no">4533</span><span id="line-4533">}</span>
+<span class="source-line-no">4473</span><span id="line-4473">  public Collection&lt;ServerName&gt; getLiveRegionServers() {</span>
+<span class="source-line-no">4474</span><span id="line-4474">    return regionServerTracker.getRegionServers();</span>
+<span class="source-line-no">4475</span><span id="line-4475">  }</span>
+<span class="source-line-no">4476</span><span id="line-4476"></span>
+<span class="source-line-no">4477</span><span id="line-4477">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4478</span><span id="line-4478">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4479</span><span id="line-4479">  void setLoadBalancer(RSGroupBasedLoadBalancer loadBalancer) {</span>
+<span class="source-line-no">4480</span><span id="line-4480">    this.balancer = loadBalancer;</span>
+<span class="source-line-no">4481</span><span id="line-4481">  }</span>
+<span class="source-line-no">4482</span><span id="line-4482"></span>
+<span class="source-line-no">4483</span><span id="line-4483">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4484</span><span id="line-4484">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4485</span><span id="line-4485">  void setAssignmentManager(AssignmentManager assignmentManager) {</span>
+<span class="source-line-no">4486</span><span id="line-4486">    this.assignmentManager = assignmentManager;</span>
+<span class="source-line-no">4487</span><span id="line-4487">  }</span>
+<span class="source-line-no">4488</span><span id="line-4488"></span>
+<span class="source-line-no">4489</span><span id="line-4489">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">4490</span><span id="line-4490">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">4491</span><span id="line-4491">  static void setDisableBalancerChoreForTest(boolean disable) {</span>
+<span class="source-line-no">4492</span><span id="line-4492">    disableBalancerChoreForTest = disable;</span>
+<span class="source-line-no">4493</span><span id="line-4493">  }</span>
+<span class="source-line-no">4494</span><span id="line-4494"></span>
+<span class="source-line-no">4495</span><span id="line-4495">  private void setQuotasObserver(Configuration conf) {</span>
+<span class="source-line-no">4496</span><span id="line-4496">    // Add the Observer to delete quotas on table deletion before starting all CPs by</span>
+<span class="source-line-no">4497</span><span id="line-4497">    // default with quota support, avoiding if user specifically asks to not load this Observer.</span>
+<span class="source-line-no">4498</span><span id="line-4498">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
+<span class="source-line-no">4499</span><span id="line-4499">      updateConfigurationForQuotasObserver(conf);</span>
+<span class="source-line-no">4500</span><span id="line-4500">    }</span>
+<span class="source-line-no">4501</span><span id="line-4501">  }</span>
+<span class="source-line-no">4502</span><span id="line-4502"></span>
+<span class="source-line-no">4503</span><span id="line-4503">  private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">4504</span><span id="line-4504">    // initialize master side coprocessors before we start handling requests</span>
+<span class="source-line-no">4505</span><span id="line-4505">    this.cpHost = new MasterCoprocessorHost(this, conf);</span>
+<span class="source-line-no">4506</span><span id="line-4506">  }</span>
+<span class="source-line-no">4507</span><span id="line-4507"></span>
+<span class="source-line-no">4508</span><span id="line-4508">  @Override</span>
+<span class="source-line-no">4509</span><span id="line-4509">  public long flushTable(TableName tableName, List&lt;byte[]&gt; columnFamilies, long nonceGroup,</span>
+<span class="source-line-no">4510</span><span id="line-4510">    long nonce) throws IOException {</span>
+<span class="source-line-no">4511</span><span id="line-4511">    checkInitialized();</span>
+<span class="source-line-no">4512</span><span id="line-4512"></span>
+<span class="source-line-no">4513</span><span id="line-4513">    if (</span>
+<span class="source-line-no">4514</span><span id="line-4514">      !getConfiguration().getBoolean(MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED,</span>
+<span class="source-line-no">4515</span><span id="line-4515">        MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED_DEFAULT)</span>
+<span class="source-line-no">4516</span><span id="line-4516">    ) {</span>
+<span class="source-line-no">4517</span><span id="line-4517">      throw new DoNotRetryIOException("FlushTableProcedureV2 is DISABLED");</span>
+<span class="source-line-no">4518</span><span id="line-4518">    }</span>
+<span class="source-line-no">4519</span><span id="line-4519"></span>
+<span class="source-line-no">4520</span><span id="line-4520">    return MasterProcedureUtil</span>
+<span class="source-line-no">4521</span><span id="line-4521">      .submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {</span>
+<span class="source-line-no">4522</span><span id="line-4522">        @Override</span>
+<span class="source-line-no">4523</span><span id="line-4523">        protected void run() throws IOException {</span>
+<span class="source-line-no">4524</span><span id="line-4524">          getMaster().getMasterCoprocessorHost().preTableFlush(tableName);</span>
+<span class="source-line-no">4525</span><span id="line-4525">          LOG.info(getClientIdAuditPrefix() + " flush " + tableName);</span>
+<span class="source-line-no">4526</span><span id="line-4526">          submitProcedure(</span>
+<span class="source-line-no">4527</span><span id="line-4527">            new FlushTableProcedure(procedureExecutor.getEnvironment(), tableName, columnFamilies));</span>
+<span class="source-line-no">4528</span><span id="line-4528">          getMaster().getMasterCoprocessorHost().postTableFlush(tableName);</span>
+<span class="source-line-no">4529</span><span id="line-4529">        }</span>
+<span class="source-line-no">4530</span><span id="line-4530"></span>
+<span class="source-line-no">4531</span><span id="line-4531">        @Override</span>
+<span class="source-line-no">4532</span><span id="line-4532">        protected String getDescription() {</span>
+<span class="source-line-no">4533</span><span id="line-4533">          return "FlushTableProcedure";</span>
+<span class="source-line-no">4534</span><span id="line-4534">        }</span>
+<span class="source-line-no">4535</span><span id="line-4535">      });</span>
+<span class="source-line-no">4536</span><span id="line-4536">  }</span>
+<span class="source-line-no">4537</span><span id="line-4537">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/master/LoadBalancer.html b/apidocs/src-html/org/apache/hadoop/hbase/master/LoadBalancer.html
index 6489bdedda7..6c12d6f051a 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/master/LoadBalancer.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/master/LoadBalancer.html
@@ -32,142 +32,159 @@
 <span class="source-line-no">019</span><span id="line-19"></span>
 <span class="source-line-no">020</span><span id="line-20">import edu.umd.cs.findbugs.annotations.NonNull;</span>
 <span class="source-line-no">021</span><span id="line-21">import java.io.IOException;</span>
-<span class="source-line-no">022</span><span id="line-22">import java.util.List;</span>
-<span class="source-line-no">023</span><span id="line-23">import java.util.Map;</span>
-<span class="source-line-no">024</span><span id="line-24">import org.apache.hadoop.conf.Configuration;</span>
-<span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.hbase.ClusterMetrics;</span>
-<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.ServerName;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.Stoppable;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.TableName;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.client.RegionInfo;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.conf.ConfigurationObserver;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.master.balancer.ClusterInfoProvider;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.yetus.audience.InterfaceAudience;</span>
-<span class="source-line-no">033</span><span id="line-33"></span>
-<span class="source-line-no">034</span><span id="line-34">/**</span>
-<span class="source-line-no">035</span><span id="line-35"> * Makes decisions about the placement and movement of Regions across RegionServers.</span>
-<span class="source-line-no">036</span><span id="line-36"> * &lt;p/&gt;</span>
-<span class="source-line-no">037</span><span id="line-37"> * Cluster-wide load balancing will occur only when there are no regions in transition and according</span>
-<span class="source-line-no">038</span><span id="line-38"> * to a fixed period of a time using {@link #balanceCluster(Map)}.</span>
-<span class="source-line-no">039</span><span id="line-39"> * &lt;p/&gt;</span>
-<span class="source-line-no">040</span><span id="line-40"> * On cluster startup, bulk assignment can be used to determine locations for all Regions in a</span>
-<span class="source-line-no">041</span><span id="line-41"> * cluster.</span>
-<span class="source-line-no">042</span><span id="line-42"> * &lt;p/&gt;</span>
-<span class="source-line-no">043</span><span id="line-43"> * This class produces plans for the {@code AssignmentManager} to execute.</span>
-<span class="source-line-no">044</span><span id="line-44"> * &lt;p/&gt;</span>
-<span class="source-line-no">045</span><span id="line-45"> * About locking:</span>
-<span class="source-line-no">046</span><span id="line-46"> * &lt;ul&gt;</span>
-<span class="source-line-no">047</span><span id="line-47"> * &lt;li&gt;We will first call {@link #setClusterInfoProvider(ClusterInfoProvider)} and then</span>
-<span class="source-line-no">048</span><span id="line-48"> * {@link #initialize()} to initialize the balancer, and before calling {@link #initialize()}, we</span>
-<span class="source-line-no">049</span><span id="line-49"> * will never call any methods of this balancer. So these two methods do not need to be</span>
-<span class="source-line-no">050</span><span id="line-50"> * synchronized.&lt;/li&gt;</span>
-<span class="source-line-no">051</span><span id="line-51"> * &lt;li&gt;The {@link #balanceCluster(Map)} method will use the {@link ClusterMetrics} which is set by</span>
-<span class="source-line-no">052</span><span id="line-52"> * {@link #updateClusterMetrics(ClusterMetrics)}, and also lots of configurations, which could be</span>
-<span class="source-line-no">053</span><span id="line-53"> * changed by {@link #onConfigurationChange(Configuration)}, so the easier way is to make these</span>
-<span class="source-line-no">054</span><span id="line-54"> * three methods synchronized. And since there will be only one balancing thread, this will not</span>
-<span class="source-line-no">055</span><span id="line-55"> * impact performance too much.&lt;/li&gt;</span>
-<span class="source-line-no">056</span><span id="line-56"> * &lt;li&gt;The {@link #roundRobinAssignment(List, List)}, {@link #retainAssignment(Map, List)} and</span>
-<span class="source-line-no">057</span><span id="line-57"> * {@link #randomAssignment(RegionInfo, List)} could be called from multiple threads concurrently,</span>
-<span class="source-line-no">058</span><span id="line-58"> * so these three methods should not be synchronized, the implementation classes need to make sure</span>
-<span class="source-line-no">059</span><span id="line-59"> * that they are thread safe.&lt;/li&gt;</span>
-<span class="source-line-no">060</span><span id="line-60"> * &lt;/ul&gt;</span>
-<span class="source-line-no">061</span><span id="line-61"> */</span>
-<span class="source-line-no">062</span><span id="line-62">@InterfaceAudience.Private</span>
-<span class="source-line-no">063</span><span id="line-63">public interface LoadBalancer extends Stoppable, ConfigurationObserver {</span>
-<span class="source-line-no">064</span><span id="line-64"></span>
-<span class="source-line-no">065</span><span id="line-65">  // Used to signal to the caller that the region(s) cannot be assigned</span>
-<span class="source-line-no">066</span><span id="line-66">  // We deliberately use 'localhost' so the operation will fail fast</span>
-<span class="source-line-no">067</span><span id="line-67">  ServerName BOGUS_SERVER_NAME = ServerName.valueOf("localhost,1,1");</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  /**</span>
-<span class="source-line-no">070</span><span id="line-70">   * Config for pluggable load balancers.</span>
-<span class="source-line-no">071</span><span id="line-71">   * @deprecated since 3.0.0, will be removed in 4.0.0. In the new implementation, as the base load</span>
-<span class="source-line-no">072</span><span id="line-72">   *             balancer will always be the rs group based one, you should just use</span>
-<span class="source-line-no">073</span><span id="line-73">   *             {@link org.apache.hadoop.hbase.HConstants#HBASE_MASTER_LOADBALANCER_CLASS} to</span>
-<span class="source-line-no">074</span><span id="line-74">   *             config the per group load balancer.</span>
-<span class="source-line-no">075</span><span id="line-75">   */</span>
-<span class="source-line-no">076</span><span id="line-76">  @Deprecated</span>
-<span class="source-line-no">077</span><span id="line-77">  String HBASE_RSGROUP_LOADBALANCER_CLASS = "hbase.rsgroup.grouploadbalancer.class";</span>
-<span class="source-line-no">078</span><span id="line-78"></span>
-<span class="source-line-no">079</span><span id="line-79">  /**</span>
-<span class="source-line-no">080</span><span id="line-80">   * Set the current cluster status. This allows a LoadBalancer to map host name to a server</span>
-<span class="source-line-no">081</span><span id="line-81">   */</span>
-<span class="source-line-no">082</span><span id="line-82">  void updateClusterMetrics(ClusterMetrics metrics);</span>
-<span class="source-line-no">083</span><span id="line-83"></span>
-<span class="source-line-no">084</span><span id="line-84">  /**</span>
-<span class="source-line-no">085</span><span id="line-85">   * Set the cluster info provider. Usually it is just a wrapper of master.</span>
-<span class="source-line-no">086</span><span id="line-86">   */</span>
-<span class="source-line-no">087</span><span id="line-87">  void setClusterInfoProvider(ClusterInfoProvider provider);</span>
-<span class="source-line-no">088</span><span id="line-88"></span>
-<span class="source-line-no">089</span><span id="line-89">  /**</span>
-<span class="source-line-no">090</span><span id="line-90">   * Perform the major balance operation for cluster.</span>
-<span class="source-line-no">091</span><span id="line-91">   * @param loadOfAllTable region load of servers for all table</span>
-<span class="source-line-no">092</span><span id="line-92">   * @return a list of regions to be moved, including source and destination, or null if cluster is</span>
-<span class="source-line-no">093</span><span id="line-93">   *         already balanced</span>
+<span class="source-line-no">022</span><span id="line-22">import java.time.Duration;</span>
+<span class="source-line-no">023</span><span id="line-23">import java.util.List;</span>
+<span class="source-line-no">024</span><span id="line-24">import java.util.Map;</span>
+<span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.conf.Configuration;</span>
+<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.ClusterMetrics;</span>
+<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.Stoppable;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.TableName;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.client.RegionInfo;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.conf.ConfigurationObserver;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.master.balancer.ClusterInfoProvider;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">034</span><span id="line-34"></span>
+<span class="source-line-no">035</span><span id="line-35">/**</span>
+<span class="source-line-no">036</span><span id="line-36"> * Makes decisions about the placement and movement of Regions across RegionServers.</span>
+<span class="source-line-no">037</span><span id="line-37"> * &lt;p/&gt;</span>
+<span class="source-line-no">038</span><span id="line-38"> * Cluster-wide load balancing will occur only when there are no regions in transition and according</span>
+<span class="source-line-no">039</span><span id="line-39"> * to a fixed period of a time using {@link #balanceCluster(Map)}.</span>
+<span class="source-line-no">040</span><span id="line-40"> * &lt;p/&gt;</span>
+<span class="source-line-no">041</span><span id="line-41"> * On cluster startup, bulk assignment can be used to determine locations for all Regions in a</span>
+<span class="source-line-no">042</span><span id="line-42"> * cluster.</span>
+<span class="source-line-no">043</span><span id="line-43"> * &lt;p/&gt;</span>
+<span class="source-line-no">044</span><span id="line-44"> * This class produces plans for the {@code AssignmentManager} to execute.</span>
+<span class="source-line-no">045</span><span id="line-45"> * &lt;p/&gt;</span>
+<span class="source-line-no">046</span><span id="line-46"> * About locking:</span>
+<span class="source-line-no">047</span><span id="line-47"> * &lt;ul&gt;</span>
+<span class="source-line-no">048</span><span id="line-48"> * &lt;li&gt;We will first call {@link #setClusterInfoProvider(ClusterInfoProvider)} and then</span>
+<span class="source-line-no">049</span><span id="line-49"> * {@link #initialize()} to initialize the balancer, and before calling {@link #initialize()}, we</span>
+<span class="source-line-no">050</span><span id="line-50"> * will never call any methods of this balancer. So these two methods do not need to be</span>
+<span class="source-line-no">051</span><span id="line-51"> * synchronized.&lt;/li&gt;</span>
+<span class="source-line-no">052</span><span id="line-52"> * &lt;li&gt;The {@link #balanceCluster(Map)} method will use the {@link ClusterMetrics} which is set by</span>
+<span class="source-line-no">053</span><span id="line-53"> * {@link #updateClusterMetrics(ClusterMetrics)}, and also lots of configurations, which could be</span>
+<span class="source-line-no">054</span><span id="line-54"> * changed by {@link #onConfigurationChange(Configuration)}, so the easier way is to make these</span>
+<span class="source-line-no">055</span><span id="line-55"> * three methods synchronized. And since there will be only one balancing thread, this will not</span>
+<span class="source-line-no">056</span><span id="line-56"> * impact performance too much.&lt;/li&gt;</span>
+<span class="source-line-no">057</span><span id="line-57"> * &lt;li&gt;The {@link #roundRobinAssignment(List, List)}, {@link #retainAssignment(Map, List)} and</span>
+<span class="source-line-no">058</span><span id="line-58"> * {@link #randomAssignment(RegionInfo, List)} could be called from multiple threads concurrently,</span>
+<span class="source-line-no">059</span><span id="line-59"> * so these three methods should not be synchronized, the implementation classes need to make sure</span>
+<span class="source-line-no">060</span><span id="line-60"> * that they are thread safe.&lt;/li&gt;</span>
+<span class="source-line-no">061</span><span id="line-61"> * &lt;/ul&gt;</span>
+<span class="source-line-no">062</span><span id="line-62"> */</span>
+<span class="source-line-no">063</span><span id="line-63">@InterfaceAudience.Private</span>
+<span class="source-line-no">064</span><span id="line-64">public interface LoadBalancer extends Stoppable, ConfigurationObserver {</span>
+<span class="source-line-no">065</span><span id="line-65"></span>
+<span class="source-line-no">066</span><span id="line-66">  // Used to signal to the caller that the region(s) cannot be assigned</span>
+<span class="source-line-no">067</span><span id="line-67">  // We deliberately use 'localhost' so the operation will fail fast</span>
+<span class="source-line-no">068</span><span id="line-68">  ServerName BOGUS_SERVER_NAME = ServerName.valueOf("localhost,1,1");</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">  /**</span>
+<span class="source-line-no">071</span><span id="line-71">   * Config for pluggable load balancers.</span>
+<span class="source-line-no">072</span><span id="line-72">   * @deprecated since 3.0.0, will be removed in 4.0.0. In the new implementation, as the base load</span>
+<span class="source-line-no">073</span><span id="line-73">   *             balancer will always be the rs group based one, you should just use</span>
+<span class="source-line-no">074</span><span id="line-74">   *             {@link org.apache.hadoop.hbase.HConstants#HBASE_MASTER_LOADBALANCER_CLASS} to</span>
+<span class="source-line-no">075</span><span id="line-75">   *             config the per group load balancer.</span>
+<span class="source-line-no">076</span><span id="line-76">   */</span>
+<span class="source-line-no">077</span><span id="line-77">  @Deprecated</span>
+<span class="source-line-no">078</span><span id="line-78">  String HBASE_RSGROUP_LOADBALANCER_CLASS = "hbase.rsgroup.grouploadbalancer.class";</span>
+<span class="source-line-no">079</span><span id="line-79"></span>
+<span class="source-line-no">080</span><span id="line-80">  /**</span>
+<span class="source-line-no">081</span><span id="line-81">   * Configuration to determine the time to sleep when throttling (if throttling is implemented by</span>
+<span class="source-line-no">082</span><span id="line-82">   * the underlying implementation).</span>
+<span class="source-line-no">083</span><span id="line-83">   */</span>
+<span class="source-line-no">084</span><span id="line-84">  String MOVE_THROTTLING = "hbase.master.balancer.move.throttlingMillis";</span>
+<span class="source-line-no">085</span><span id="line-85"></span>
+<span class="source-line-no">086</span><span id="line-86">  /**</span>
+<span class="source-line-no">087</span><span id="line-87">   * The default value, in milliseconds, for the hbase.master.balancer.move.throttlingMillis if</span>
+<span class="source-line-no">088</span><span id="line-88">   * throttling is implemented.</span>
+<span class="source-line-no">089</span><span id="line-89">   */</span>
+<span class="source-line-no">090</span><span id="line-90">  Duration MOVE_THROTTLING_DEFAULT = Duration.ofMillis(60 * 1000);</span>
+<span class="source-line-no">091</span><span id="line-91"></span>
+<span class="source-line-no">092</span><span id="line-92">  /**</span>
+<span class="source-line-no">093</span><span id="line-93">   * Set the current cluster status. This allows a LoadBalancer to map host name to a server</span>
 <span class="source-line-no">094</span><span id="line-94">   */</span>
-<span class="source-line-no">095</span><span id="line-95">  List&lt;RegionPlan&gt; balanceCluster(Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; loadOfAllTable)</span>
-<span class="source-line-no">096</span><span id="line-96">    throws IOException;</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">  /**</span>
-<span class="source-line-no">099</span><span id="line-99">   * Perform a Round Robin assignment of regions.</span>
-<span class="source-line-no">100</span><span id="line-100">   * @return Map of servername to regioninfos</span>
-<span class="source-line-no">101</span><span id="line-101">   */</span>
-<span class="source-line-no">102</span><span id="line-102">  @NonNull</span>
-<span class="source-line-no">103</span><span id="line-103">  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; roundRobinAssignment(List&lt;RegionInfo&gt; regions,</span>
-<span class="source-line-no">104</span><span id="line-104">    List&lt;ServerName&gt; servers) throws IOException;</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">  /**</span>
-<span class="source-line-no">107</span><span id="line-107">   * Assign regions to the previously hosting region server</span>
-<span class="source-line-no">108</span><span id="line-108">   * @return List of plans</span>
-<span class="source-line-no">109</span><span id="line-109">   */</span>
-<span class="source-line-no">110</span><span id="line-110">  @NonNull</span>
-<span class="source-line-no">111</span><span id="line-111">  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; retainAssignment(Map&lt;RegionInfo, ServerName&gt; regions,</span>
-<span class="source-line-no">112</span><span id="line-112">    List&lt;ServerName&gt; servers) throws IOException;</span>
-<span class="source-line-no">113</span><span id="line-113"></span>
-<span class="source-line-no">114</span><span id="line-114">  /**</span>
-<span class="source-line-no">115</span><span id="line-115">   * Get a random region server from the list</span>
-<span class="source-line-no">116</span><span id="line-116">   * @param regionInfo Region for which this selection is being done.</span>
-<span class="source-line-no">117</span><span id="line-117">   */</span>
-<span class="source-line-no">118</span><span id="line-118">  ServerName randomAssignment(RegionInfo regionInfo, List&lt;ServerName&gt; servers) throws IOException;</span>
-<span class="source-line-no">119</span><span id="line-119"></span>
-<span class="source-line-no">120</span><span id="line-120">  /**</span>
-<span class="source-line-no">121</span><span id="line-121">   * Initialize the load balancer. Must be called after setters.</span>
+<span class="source-line-no">095</span><span id="line-95">  void updateClusterMetrics(ClusterMetrics metrics);</span>
+<span class="source-line-no">096</span><span id="line-96"></span>
+<span class="source-line-no">097</span><span id="line-97">  /**</span>
+<span class="source-line-no">098</span><span id="line-98">   * Set the cluster info provider. Usually it is just a wrapper of master.</span>
+<span class="source-line-no">099</span><span id="line-99">   */</span>
+<span class="source-line-no">100</span><span id="line-100">  void setClusterInfoProvider(ClusterInfoProvider provider);</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  /**</span>
+<span class="source-line-no">103</span><span id="line-103">   * Perform the major balance operation for cluster.</span>
+<span class="source-line-no">104</span><span id="line-104">   * @param loadOfAllTable region load of servers for all table</span>
+<span class="source-line-no">105</span><span id="line-105">   * @return a list of regions to be moved, including source and destination, or null if cluster is</span>
+<span class="source-line-no">106</span><span id="line-106">   *         already balanced</span>
+<span class="source-line-no">107</span><span id="line-107">   */</span>
+<span class="source-line-no">108</span><span id="line-108">  List&lt;RegionPlan&gt; balanceCluster(Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; loadOfAllTable)</span>
+<span class="source-line-no">109</span><span id="line-109">    throws IOException;</span>
+<span class="source-line-no">110</span><span id="line-110"></span>
+<span class="source-line-no">111</span><span id="line-111">  /**</span>
+<span class="source-line-no">112</span><span id="line-112">   * Perform a Round Robin assignment of regions.</span>
+<span class="source-line-no">113</span><span id="line-113">   * @return Map of servername to regioninfos</span>
+<span class="source-line-no">114</span><span id="line-114">   */</span>
+<span class="source-line-no">115</span><span id="line-115">  @NonNull</span>
+<span class="source-line-no">116</span><span id="line-116">  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; roundRobinAssignment(List&lt;RegionInfo&gt; regions,</span>
+<span class="source-line-no">117</span><span id="line-117">    List&lt;ServerName&gt; servers) throws IOException;</span>
+<span class="source-line-no">118</span><span id="line-118"></span>
+<span class="source-line-no">119</span><span id="line-119">  /**</span>
+<span class="source-line-no">120</span><span id="line-120">   * Assign regions to the previously hosting region server</span>
+<span class="source-line-no">121</span><span id="line-121">   * @return List of plans</span>
 <span class="source-line-no">122</span><span id="line-122">   */</span>
-<span class="source-line-no">123</span><span id="line-123">  void initialize() throws IOException;</span>
-<span class="source-line-no">124</span><span id="line-124"></span>
-<span class="source-line-no">125</span><span id="line-125">  /**</span>
-<span class="source-line-no">126</span><span id="line-126">   * Marks the region as online at balancer.</span>
-<span class="source-line-no">127</span><span id="line-127">   */</span>
-<span class="source-line-no">128</span><span id="line-128">  void regionOnline(RegionInfo regionInfo, ServerName sn);</span>
-<span class="source-line-no">129</span><span id="line-129"></span>
-<span class="source-line-no">130</span><span id="line-130">  /**</span>
-<span class="source-line-no">131</span><span id="line-131">   * Marks the region as offline at balancer.</span>
-<span class="source-line-no">132</span><span id="line-132">   */</span>
-<span class="source-line-no">133</span><span id="line-133">  void regionOffline(RegionInfo regionInfo);</span>
-<span class="source-line-no">134</span><span id="line-134"></span>
-<span class="source-line-no">135</span><span id="line-135">  /**</span>
-<span class="source-line-no">136</span><span id="line-136">   * Notification that config has changed</span>
-<span class="source-line-no">137</span><span id="line-137">   */</span>
-<span class="source-line-no">138</span><span id="line-138">  @Override</span>
-<span class="source-line-no">139</span><span id="line-139">  void onConfigurationChange(Configuration conf);</span>
-<span class="source-line-no">140</span><span id="line-140"></span>
-<span class="source-line-no">141</span><span id="line-141">  /**</span>
-<span class="source-line-no">142</span><span id="line-142">   * If balancer needs to do initialization after Master has started up, lets do that here.</span>
-<span class="source-line-no">143</span><span id="line-143">   */</span>
-<span class="source-line-no">144</span><span id="line-144">  void postMasterStartupInitialize();</span>
-<span class="source-line-no">145</span><span id="line-145"></span>
-<span class="source-line-no">146</span><span id="line-146">  /* Updates balancer status tag reported to JMX */</span>
-<span class="source-line-no">147</span><span id="line-147">  void updateBalancerStatus(boolean status);</span>
-<span class="source-line-no">148</span><span id="line-148"></span>
-<span class="source-line-no">149</span><span id="line-149">  /**</span>
-<span class="source-line-no">150</span><span id="line-150">   * In some scenarios, Balancer needs to update internal status or information according to the</span>
-<span class="source-line-no">151</span><span id="line-151">   * current tables load</span>
-<span class="source-line-no">152</span><span id="line-152">   * @param loadOfAllTable region load of servers for all table</span>
-<span class="source-line-no">153</span><span id="line-153">   */</span>
-<span class="source-line-no">154</span><span id="line-154">  default void</span>
-<span class="source-line-no">155</span><span id="line-155">    updateBalancerLoadInfo(Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; loadOfAllTable) {</span>
-<span class="source-line-no">156</span><span id="line-156">  }</span>
-<span class="source-line-no">157</span><span id="line-157">}</span>
+<span class="source-line-no">123</span><span id="line-123">  @NonNull</span>
+<span class="source-line-no">124</span><span id="line-124">  Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; retainAssignment(Map&lt;RegionInfo, ServerName&gt; regions,</span>
+<span class="source-line-no">125</span><span id="line-125">    List&lt;ServerName&gt; servers) throws IOException;</span>
+<span class="source-line-no">126</span><span id="line-126"></span>
+<span class="source-line-no">127</span><span id="line-127">  /**</span>
+<span class="source-line-no">128</span><span id="line-128">   * Get a random region server from the list</span>
+<span class="source-line-no">129</span><span id="line-129">   * @param regionInfo Region for which this selection is being done.</span>
+<span class="source-line-no">130</span><span id="line-130">   */</span>
+<span class="source-line-no">131</span><span id="line-131">  ServerName randomAssignment(RegionInfo regionInfo, List&lt;ServerName&gt; servers) throws IOException;</span>
+<span class="source-line-no">132</span><span id="line-132"></span>
+<span class="source-line-no">133</span><span id="line-133">  /**</span>
+<span class="source-line-no">134</span><span id="line-134">   * Initialize the load balancer. Must be called after setters.</span>
+<span class="source-line-no">135</span><span id="line-135">   */</span>
+<span class="source-line-no">136</span><span id="line-136">  void initialize() throws IOException;</span>
+<span class="source-line-no">137</span><span id="line-137"></span>
+<span class="source-line-no">138</span><span id="line-138">  /**</span>
+<span class="source-line-no">139</span><span id="line-139">   * Marks the region as online at balancer.</span>
+<span class="source-line-no">140</span><span id="line-140">   */</span>
+<span class="source-line-no">141</span><span id="line-141">  void regionOnline(RegionInfo regionInfo, ServerName sn);</span>
+<span class="source-line-no">142</span><span id="line-142"></span>
+<span class="source-line-no">143</span><span id="line-143">  /**</span>
+<span class="source-line-no">144</span><span id="line-144">   * Marks the region as offline at balancer.</span>
+<span class="source-line-no">145</span><span id="line-145">   */</span>
+<span class="source-line-no">146</span><span id="line-146">  void regionOffline(RegionInfo regionInfo);</span>
+<span class="source-line-no">147</span><span id="line-147"></span>
+<span class="source-line-no">148</span><span id="line-148">  /**</span>
+<span class="source-line-no">149</span><span id="line-149">   * Notification that config has changed</span>
+<span class="source-line-no">150</span><span id="line-150">   */</span>
+<span class="source-line-no">151</span><span id="line-151">  @Override</span>
+<span class="source-line-no">152</span><span id="line-152">  void onConfigurationChange(Configuration conf);</span>
+<span class="source-line-no">153</span><span id="line-153"></span>
+<span class="source-line-no">154</span><span id="line-154">  /**</span>
+<span class="source-line-no">155</span><span id="line-155">   * If balancer needs to do initialization after Master has started up, lets do that here.</span>
+<span class="source-line-no">156</span><span id="line-156">   */</span>
+<span class="source-line-no">157</span><span id="line-157">  void postMasterStartupInitialize();</span>
+<span class="source-line-no">158</span><span id="line-158"></span>
+<span class="source-line-no">159</span><span id="line-159">  /* Updates balancer status tag reported to JMX */</span>
+<span class="source-line-no">160</span><span id="line-160">  void updateBalancerStatus(boolean status);</span>
+<span class="source-line-no">161</span><span id="line-161"></span>
+<span class="source-line-no">162</span><span id="line-162">  /**</span>
+<span class="source-line-no">163</span><span id="line-163">   * In some scenarios, Balancer needs to update internal status or information according to the</span>
+<span class="source-line-no">164</span><span id="line-164">   * current tables load</span>
+<span class="source-line-no">165</span><span id="line-165">   * @param loadOfAllTable region load of servers for all table</span>
+<span class="source-line-no">166</span><span id="line-166">   */</span>
+<span class="source-line-no">167</span><span id="line-167">  default void</span>
+<span class="source-line-no">168</span><span id="line-168">    updateBalancerLoadInfo(Map&lt;TableName, Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;&gt; loadOfAllTable) {</span>
+<span class="source-line-no">169</span><span id="line-169">  }</span>
+<span class="source-line-no">170</span><span id="line-170"></span>
+<span class="source-line-no">171</span><span id="line-171">  default void throttle(RegionPlan plan) throws Exception {</span>
+<span class="source-line-no">172</span><span id="line-172">    // noop</span>
+<span class="source-line-no">173</span><span id="line-173">  }</span>
+<span class="source-line-no">174</span><span id="line-174">}</span>
 
 
 
diff --git a/book.html b/book.html
index a62ef024580..16d2db4352b 100644
--- a/book.html
+++ b/book.html
@@ -49812,7 +49812,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 4.0.0-alpha-1-SNAPSHOT<br>
-Last updated 2025-03-26 14:30:37 UTC
+Last updated 2025-03-27 14:31:26 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/bulk-loads.html b/bulk-loads.html
index f7f50e56bc9..c1655a2c3e4 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -185,7 +185,7 @@
         All other marks mentioned may be trademarks or registered trademarks of their respective owners.
       </div>
       <div style="float: right">
-        Last Published: 2025-03-26
+        Last Published: 2025-03-27
       </div>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 1b5a8c4476f..69d6c466f76 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -177,7 +177,7 @@
 <td>5082</td>
 <td>0</td>
 <td>0</td>
-<td>1712</td></tr></table></section><section>
+<td>1713</td></tr></table></section><section>
 <h2><a name="Files"></a>Files</h2>
 <table border="0" class="table table-striped">
 <tr class="a">
@@ -1639,7 +1639,7 @@
 <td><a href="#org.apache.hadoop.hbase.master.balancer.CacheAwareLoadBalancer.java">org/apache/hadoop/hbase/master/balancer/CacheAwareLoadBalancer.java</a></td>
 <td>0</td>
 <td>0</td>
-<td>2</td></tr>
+<td>3</td></tr>
 <tr class="a">
 <td><a href="#org.apache.hadoop.hbase.master.balancer.ClusterLoadState.java">org/apache/hadoop/hbase/master/balancer/ClusterLoadState.java</a></td>
 <td>0</td>
@@ -3299,7 +3299,7 @@
 <li>protectedAllowed: <code>&quot;true&quot;</code></li>
 <li>packageAllowed: <code>&quot;true&quot;</code></li>
 <li>allowPublicImmutableFields: <code>&quot;true&quot;</code></li></ul></td>
-<td>105</td>
+<td>106</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
 <tr class="b">
 <td>imports</td>
@@ -3319,27 +3319,20 @@
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
 <tr class="b">
 <td>javadoc</td>
-<td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#JavadocTagContinuationIndentation">JavadocTagContinuationIndentation</a>
-<ul>
-<li>offset: <code>&quot;2&quot;</code></li></ul></td>
-<td>3</td>
-<td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="a">
-<td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#NonEmptyAtclauseDescription">NonEmptyAtclauseDescription</a></td>
-<td>46</td>
+<td>49</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>misc</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_misc.html#ArrayTypeStyle">ArrayTypeStyle</a></td>
 <td>110</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_misc.html#UpperEll">UpperEll</a></td>
 <td>23</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>sizes</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_sizes.html#LineLength">LineLength</a>
 <ul>
@@ -3347,12 +3340,12 @@
 <li>ignorePattern: <code>&quot;^package.*|^import.*|a href|href|http://|https://|ftp://|org.apache.thrift.|com.google.protobuf.|hbase.protobuf.generated&quot;</code></li></ul></td>
 <td>141</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="a">
+<tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_sizes.html#MethodLength">MethodLength</a></td>
 <td>61</td>
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td></tr>
-<tr class="b">
+<tr class="a">
 <td>whitespace</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_whitespace.html#FileTabCharacter">FileTabCharacter</a></td>
 <td>1</td>
@@ -3360,19 +3353,19 @@
 <h2><a name="Details"></a>Details</h2><section>
 <h3 id="log4j2.properties">log4j2.properties</h3>
 <table border="0" class="table table-striped">
-<tr class="a">
+<tr class="b">
 <th>Severity</th>
 <th>Category</th>
 <th>Rule</th>
 <th>Message</th>
 <th>Line</th></tr>
-<tr class="b">
+<tr class="a">
 <td><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Error</td>
 <td>sizes</td>
 <td>LineLength</td>
 <td>Line is longer than 100 characters (found 105).</td>
... 63501 lines suppressed ...