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 2023/03/19 14:45:48 UTC

[hbase-site] branch asf-site updated: Published site at e6977a95975580831a31d122c800d01cadac007a.

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 a51b995c8e2 Published site at e6977a95975580831a31d122c800d01cadac007a.
a51b995c8e2 is described below

commit a51b995c8e2a6de309513cf7c00e0c44ac0e0719
Author: jenkins <bu...@apache.org>
AuthorDate: Sun Mar 19 14:45:35 2023 +0000

    Published site at e6977a95975580831a31d122c800d01cadac007a.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          |    4 +-
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/index-all.html                          |    2 -
 .../apache/hadoop/hbase/backup/package-tree.html   |    4 +-
 .../apache/hadoop/hbase/chaos/package-tree.html    |    2 +-
 .../hadoop/hbase/client/class-use/RegionInfo.html  |   34 +-
 .../apache/hadoop/hbase/client/package-tree.html   |   24 +-
 .../hadoop/hbase/coprocessor/package-tree.html     |    2 +-
 .../apache/hadoop/hbase/filter/package-tree.html   |    8 +-
 .../org/apache/hadoop/hbase/http/package-tree.html |    2 +-
 .../hadoop/hbase/io/crypto/tls/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/io/hfile/package-tree.html |    6 +-
 .../org/apache/hadoop/hbase/io/package-tree.html   |    2 +-
 .../org/apache/hadoop/hbase/ipc/package-tree.html  |    2 +-
 .../hadoop/hbase/mapreduce/package-tree.html       |    4 +-
 ...ignmentManager.DeadServerMetricRegionChore.html |    6 +-
 .../AssignmentManager.RegionInTransitionChore.html |    6 +-
 .../AssignmentManager.RegionInTransitionStat.html  |   40 +-
 ...AssignmentManager.RegionMetaLoadingVisitor.html |    6 +-
 .../hbase/master/assignment/AssignmentManager.html |  126 +-
 .../assignment/RegionStates.RegionFailedOpen.html  |   22 +-
 .../hbase/master/assignment/RegionStates.html      |   43 +-
 .../hadoop/hbase/master/balancer/package-tree.html |    2 +-
 .../apache/hadoop/hbase/master/package-tree.html   |    6 +-
 .../hbase/master/procedure/package-tree.html       |    4 +-
 .../hadoop/hbase/monitoring/package-tree.html      |    2 +-
 .../org/apache/hadoop/hbase/package-tree.html      |   20 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    4 +-
 .../hbase/procedure2/store/wal/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/quotas/package-tree.html   |    8 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   22 +-
 .../hbase/regionserver/wal/package-tree.html       |    4 +-
 .../hadoop/hbase/replication/package-tree.html     |    2 +-
 .../replication/regionserver/package-tree.html     |    2 +-
 .../hadoop/hbase/security/access/package-tree.html |    8 +-
 .../apache/hadoop/hbase/security/package-tree.html |    2 +-
 .../apache/hadoop/hbase/thrift/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/trace/package-tree.html    |    2 +-
 .../org/apache/hadoop/hbase/util/package-tree.html |    8 +-
 .../org/apache/hadoop/hbase/wal/package-tree.html  |    2 +-
 ...ignmentManager.DeadServerMetricRegionChore.html | 2790 ++++++++++----------
 .../AssignmentManager.RegionInTransitionChore.html | 2790 ++++++++++----------
 .../AssignmentManager.RegionInTransitionStat.html  | 2790 ++++++++++----------
 ...AssignmentManager.RegionMetaLoadingVisitor.html | 2790 ++++++++++----------
 .../hbase/master/assignment/AssignmentManager.html | 2790 ++++++++++----------
 .../assignment/RegionStates.RegionFailedOpen.html  |  249 +-
 .../RegionStates.RegionStateStampComparator.html   |  249 +-
 .../hbase/master/assignment/RegionStates.html      |  249 +-
 .../storefiletracker/StoreFileListFile.html        |    9 +-
 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 +-
 78 files changed, 7587 insertions(+), 7630 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 8dbd0b66084..1e464d77e2d 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -464,7 +464,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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 ce00980ec1a..540a39c000e 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:20230318143034+00'00')
-/CreationDate (D:20230318144318+00'00')
+/ModDate (D:20230319143034+00'00')
+/CreationDate (D:20230319144313+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index e03d559ea35..4b12e4eec80 100644
--- a/book.html
+++ b/book.html
@@ -48195,7 +48195,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 3.0.0-alpha-4-SNAPSHOT<br>
-Last updated 2023-03-18 14:30:34 UTC
+Last updated 2023-03-19 14:30:34 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/bulk-loads.html b/bulk-loads.html
index 324233898ea..5da2d395361 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -180,7 +180,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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 4c6b4fed34a..3f11f803824 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -10631,7 +10631,7 @@
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>740</td></tr></table></section><section>
+<td>735</td></tr></table></section><section>
 <h3 id="org.apache.hadoop.hbase.master.assignment.TestAssignmentOnRSCrash.java">org/apache/hadoop/hbase/master/assignment/TestAssignmentOnRSCrash.java</h3>
 <table border="0" class="table table-striped">
 <tr class="b">
@@ -18598,7 +18598,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/coc.html b/coc.html
index aea4d54580e..d199553e0ba 100644
--- a/coc.html
+++ b/coc.html
@@ -248,7 +248,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/dependencies.html b/dependencies.html
index a21c06dbb93..d48756fa19f 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -313,7 +313,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/dependency-convergence.html b/dependency-convergence.html
index e5a165b5c7b..b020b3a1087 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -1007,7 +1007,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/dependency-info.html b/dependency-info.html
index 6ecf9569725..32bb0a5ad78 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -195,7 +195,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/dependency-management.html b/dependency-management.html
index 05fd305edb7..87e4f578641 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1192,7 +1192,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2023
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-18</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2023-03-19</li>
 </p>
         </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/devapidocs/index-all.html b/devapidocs/index-all.html
index aa3f33e3932..f7d9ab29bcc 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -108681,8 +108681,6 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/namespace/NamespaceAuditor.html#removeFromNamespaceUsage-org.apache.hadoop.hbase.TableName-">removeFromNamespaceUsage(TableName)</a></span> - Method in class org.apache.hadoop.hbase.namespace.<a href="org/apache/hadoop/hbase/namespace/NamespaceAuditor.html" title="class in org.apache.hadoop.hbase.namespace">NamespaceAuditor</a></dt>
 <dd>&nbsp;</dd>
-<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeFromOfflineRegions-org.apache.hadoop.hbase.client.RegionInfo-">removeFromOfflineRegions(RegionInfo)</a></span> - Method in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/RegionStates.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates</a></dt>
-<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.html#removeFromRamCache-org.apache.hadoop.hbase.io.hfile.BlockCacheKey-">removeFromRamCache(BlockCacheKey)</a></span> - Method in class org.apache.hadoop.hbase.io.hfile.bucket.<a href="org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.html" title="class in org.apache.hadoop.hbase.io.hfile.bucket">BucketCache</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.html#removeFromRunQueue-org.apache.hadoop.hbase.master.procedure.FairQueue-org.apache.hadoop.hbase.master.procedure.Queue-java.util.function.Supplier-">removeFromRunQueue(FairQueue&lt;T&gt;, Queue&lt;T&gt;, Supplier&lt;String&gt;)</a></span> - Static method in class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/MasterProcedureScheduler.h [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
index 9849e3f56fc..cc50b4ddf5c 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
@@ -166,10 +166,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html b/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
index 0a0fcc3460b..192324858b4 100644
--- a/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
@@ -103,8 +103,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ChaosServiceName.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ChaosServiceName</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ExecutorAction.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ExecutorAction</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ChaosServiceName.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ChaosServiceName</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html b/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
index a444f60603e..51482459d05 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/class-use/RegionInfo.html
@@ -3483,30 +3483,26 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
 <td class="colLast"><span class="typeNameLabel">RegionStates.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeFromFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">removeFromFailedOpen</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
 </tr>
 <tr class="altColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><span class="typeNameLabel">RegionStates.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeFromOfflineRegions-org.apache.hadoop.hbase.client.RegionInfo-">removeFromOfflineRegions</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
-</tr>
-<tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TransitRegionStateProcedure.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#reopen-org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv-org.apache.hadoop.hbase.client.RegionInfo-">reopen</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.pro [...]
       <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#setMetaAssigned-org.apache.hadoop.hbase.client.RegionInfo-boolean-">setMetaAssigned</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;metaRegionInfo,
                boolean&nbsp;assigned)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionTransitionProcedure.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionTransitionProcedure.html#setRegionInfo-org.apache.hadoop.hbase.client.RegionInfo-">setRegionInfo</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>
 <div class="block"><span class="deprecatedLabel">Deprecated.</span>&nbsp;</div>
 &nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#shouldAssignFavoredNodes-org.apache.hadoop.hbase.client.RegionInfo-">shouldAssignFavoredNodes</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionStateStore.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateStore.html#splitRegion-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.client.TableDescriptor-">splitRegion</a></span>(<a href="../../../../../../org/apache/hadoop/hbas [...]
            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;splitA,
@@ -3516,27 +3512,27 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
 <div class="block">Splits the region into two in an atomic operation.</div>
 </td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TransitRegionStateProcedure.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#unassign-org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv-org.apache.hadoop.hbase.client.RegionInfo-">unassign</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master [...]
         <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>long</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#unassign-org.apache.hadoop.hbase.client.RegionInfo-">unassign</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a></code></td>
 <td class="colLast"><span class="typeNameLabel">TransitRegionStateProcedure.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#unassignSplitMerge-org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv-org.apache.hadoop.hbase.client.RegionInfo-">unassignSplitMerge</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache [...]
                   <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionStateStore.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateStore.html#updateRegionLocation-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State-org.apache.hadoop.hbase.client.Put-">updateRegionLocation</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop. [...]
                     <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;state,
                     <a href="../../../../../../org/apache/hadoop/hbase/client/Put.html" title="class in org.apache.hadoop.hbase.client">Put</a>&nbsp;put)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#updateRegionMergeTransition-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.Re [...]
                            org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
@@ -3544,7 +3540,7 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
                            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriA,
                            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriB)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#updateRegionSplitTransition-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.client.Re [...]
                            org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
@@ -3552,12 +3548,12 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
                            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriA,
                            <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriB)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionStates.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#updateRegionState-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State-">updateRegionState</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                  <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;state)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#updateRegionTransition-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode-org.apache.hadoop.hbase.client.RegionInfo-long-long-">updateRegionTransition</a></span>(<a href="../../../../../../org/apa [...]
                       org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
@@ -3565,7 +3561,7 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
                       long&nbsp;seqId,
                       long&nbsp;procId)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.RegionMetaLoadingVisitor.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html#visitRegionState-org.apache.hadoop.hbase.client.Result-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.ServerName-long-">visitRegionState</a [...]
                 <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
@@ -3574,7 +3570,7 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
                 <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;lastHost,
                 long&nbsp;openSeqNum)</code>&nbsp;</td>
 </tr>
-<tr class="rowColor">
+<tr class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><span class="typeNameLabel">RegionStateStore.RegionStateVisitor.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateStore.RegionStateVisitor.html#visitRegionState-org.apache.hadoop.hbase.client.Result-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.ServerName-long-">visitRegionState</a></span>(<a hr [...]
                 <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
@@ -3583,7 +3579,7 @@ Input/OutputFormats, a table indexing MapReduce job, and utility methods.</div>
                 <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;lastHost,
                 long&nbsp;openSeqNum)</code>&nbsp;</td>
 </tr>
-<tr class="altColor">
+<tr class="rowColor">
 <td class="colFirst"><code>boolean</code></td>
 <td class="colLast"><span class="typeNameLabel">AssignmentManager.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#waitMetaAssigned-org.apache.hadoop.hbase.procedure2.Procedure-org.apache.hadoop.hbase.client.RegionInfo-">waitMetaAssigned</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>&lt;?&gt;&nbsp;proc,
                 <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>
diff --git a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
index 04015aea5ee..159a05a79ac 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
@@ -470,24 +470,24 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RequestController.ReturnCode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RequestController.ReturnCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/ServerType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">ServerType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RequestController.ReturnCode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RequestController.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
index 77729296ff4..1578c9ced30 100644
--- a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
@@ -176,8 +176,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/RegionObserver.MutationType.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">RegionObserver.MutationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/MetaTableMetrics.MetaTableOps.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">MetaTableMetrics.MetaTableOps</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/RegionObserver.MutationType.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">RegionObserver.MutationType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
index eb256996c60..5a436f1e304 100644
--- a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
@@ -190,13 +190,13 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.SatisfiesCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.SatisfiesCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/BitComparator.BitwiseOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">BitComparator.BitwiseOp</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/BitComparator.BitwiseOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">BitComparator.BitwiseOp</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.SatisfiesCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.SatisfiesCode</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
index f057548c31e..a589de3108b 100644
--- a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
@@ -141,9 +141,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Output.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Output</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/HttpConfig.Policy.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">HttpConfig.Policy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Event.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Event</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Output.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Output</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/crypto/tls/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/crypto/tls/package-tree.html
index 66a78162776..12c6eaf4422 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/crypto/tls/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/crypto/tls/package-tree.html
@@ -125,8 +125,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.io.crypto.tls.<a href="../../../../../../../org/apache/hadoop/hbase/io/crypto/tls/X509Util.ClientAuth.html" title="enum in org.apache.hadoop.hbase.io.crypto.tls"><span class="typeNameLink">X509Util.ClientAuth</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.crypto.tls.<a href="../../../../../../../org/apache/hadoop/hbase/io/crypto/tls/KeyStoreFileType.html" title="enum in org.apache.hadoop.hbase.io.crypto.tls"><span class="typeNameLink">KeyStoreFileType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.crypto.tls.<a href="../../../../../../../org/apache/hadoop/hbase/io/crypto/tls/StandardTypeFileKeyStoreLoader.SupportedStandardKeyFormat.html" title="enum in org.apache.hadoop.hbase.io.crypto.tls"><span class="typeNameLink">StandardTypeFileKeyStoreLoader.SupportedStandardKeyFormat</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.crypto.tls.<a href="../../../../../../../org/apache/hadoop/hbase/io/crypto/tls/KeyStoreFileType.html" title="enum in org.apache.hadoop.hbase.io.crypto.tls"><span class="typeNameLink">KeyStoreFileType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
index 842f7d406af..892632eaed1 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -320,12 +320,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockCacheFactory.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockCacheFactory.ExternalBlockCaches</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.BlockCategory.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType.BlockCategory</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/ReaderContext.ReaderType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">ReaderContext.ReaderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/package-tree.html
index d95233284fb..4210045ae6e 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/package-tree.html
@@ -193,8 +193,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.<a href="../../../../../org/apache/hadoop/hbase/io/Reference.Range.html" title="enum in org.apache.hadoop.hbase.io"><span class="typeNameLink">Reference.Range</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.<a href="../../../../../org/apache/hadoop/hbase/io/FileChangeWatcher.State.html" title="enum in org.apache.hadoop.hbase.io"><span class="typeNameLink">FileChangeWatcher.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.<a href="../../../../../org/apache/hadoop/hbase/io/Reference.Range.html" title="enum in org.apache.hadoop.hbase.io"><span class="typeNameLink">Reference.Range</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index 05615d07379..cc2772928f3 100644
--- a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -368,9 +368,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/BufferCallBeforeInitHandler.BufferCallAction.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">BufferCallBeforeInitHandler.BufferCallAction</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
index 999a3e5f3c3..1e8f105890d 100644
--- a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
@@ -303,9 +303,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/WALPlayer.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">WALPlayer.Counter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/WALPlayer.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">WALPlayer.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/SyncTable.SyncMapper.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">SyncTable.SyncMapper.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/RowCounter.RowCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">RowCounter.RowCounterMapper.Counters</span></a></li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
index 39a6a614b94..18f5554a4f9 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
@@ -127,7 +127,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1454">AssignmentManager.DeadServerMetricRegionChore</a>
+<pre>private static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1452">AssignmentManager.DeadServerMetricRegionChore</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&gt;</pre>
 </li>
 </ul>
@@ -240,7 +240,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureI
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DeadServerMetricRegionChore</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html#line.1456">DeadServerMetricRegionChore</a>(int&nbsp;timeoutMsec)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html#line.1454">DeadServerMetricRegionChore</a>(int&nbsp;timeoutMsec)</pre>
 </li>
 </ul>
 </li>
@@ -257,7 +257,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureI
 <ul class="blockListLast">
 <li class="blockList">
 <h4>periodicExecute</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html#line.1461">periodicExecute</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html#line.1459">periodicExecute</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html#periodicExecute-TEnvironment-">periodicExecute</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mas [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
index 81144aa8def..a470297de82 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
@@ -127,7 +127,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1433">AssignmentManager.RegionInTransitionChore</a>
+<pre>private static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1431">AssignmentManager.RegionInTransitionChore</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&gt;</pre>
 </li>
 </ul>
@@ -240,7 +240,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureI
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionInTransitionChore</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html#line.1434">RegionInTransitionChore</a>(int&nbsp;timeoutMsec)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html#line.1432">RegionInTransitionChore</a>(int&nbsp;timeoutMsec)</pre>
 </li>
 </ul>
 </li>
@@ -257,7 +257,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureI
 <ul class="blockListLast">
 <li class="blockList">
 <h4>periodicExecute</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html#line.1439">periodicExecute</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html#line.1437">periodicExecute</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env)</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html#periodicExecute-TEnvironment-">periodicExecute</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureInMemoryChore.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureInMemoryChore</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mas [...]
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
index 23b87e78eac..f30acc15554 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1518">AssignmentManager.RegionInTransitionStat</a>
+<pre>public static class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1516">AssignmentManager.RegionInTransitionStat</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 </li>
 </ul>
@@ -266,7 +266,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>ritThreshold</h4>
-<pre>private final&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1519">ritThreshold</a></pre>
+<pre>private final&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1517">ritThreshold</a></pre>
 </li>
 </ul>
 <a name="ritsOverThreshold">
@@ -275,7 +275,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>ritsOverThreshold</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt; <a href="../../../../../../src-html/org/a [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>,<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt; <a href="../../../../../../src-html/org/a [...]
 </li>
 </ul>
 <a name="statTimestamp">
@@ -284,7 +284,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>statTimestamp</h4>
-<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1522">statTimestamp</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1520">statTimestamp</a></pre>
 </li>
 </ul>
 <a name="oldestRITTime">
@@ -293,7 +293,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>oldestRITTime</h4>
-<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1523">oldestRITTime</a></pre>
+<pre>private&nbsp;long <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1521">oldestRITTime</a></pre>
 </li>
 </ul>
 <a name="totalRITsTwiceThreshold">
@@ -302,7 +302,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>totalRITsTwiceThreshold</h4>
-<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1524">totalRITsTwiceThreshold</a></pre>
+<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1522">totalRITsTwiceThreshold</a></pre>
 </li>
 </ul>
 <a name="totalRITs">
@@ -311,7 +311,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>totalRITs</h4>
-<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1525">totalRITs</a></pre>
+<pre>private&nbsp;int <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1523">totalRITs</a></pre>
 </li>
 </ul>
 </li>
@@ -328,7 +328,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionInTransitionStat</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1527">RegionInTransitionStat</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1525">RegionInTransitionStat</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 </li>
@@ -345,7 +345,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRITThreshold</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1532">getRITThreshold</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1530">getRITThreshold</a>()</pre>
 </li>
 </ul>
 <a name="getTimestamp--">
@@ -354,7 +354,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getTimestamp</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1536">getTimestamp</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1534">getTimestamp</a>()</pre>
 </li>
 </ul>
 <a name="getTotalRITs--">
@@ -363,7 +363,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getTotalRITs</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1540">getTotalRITs</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1538">getTotalRITs</a>()</pre>
 </li>
 </ul>
 <a name="getOldestRITTime--">
@@ -372,7 +372,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOldestRITTime</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1544">getOldestRITTime</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1542">getOldestRITTime</a>()</pre>
 </li>
 </ul>
 <a name="getTotalRITsOverThreshold--">
@@ -381,7 +381,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getTotalRITsOverThreshold</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1548">getTotalRITsOverThreshold</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1546">getTotalRITsOverThreshold</a>()</pre>
 </li>
 </ul>
 <a name="hasRegionsTwiceOverThreshold--">
@@ -390,7 +390,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRegionsTwiceOverThreshold</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1553">hasRegionsTwiceOverThreshold</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1551">hasRegionsTwiceOverThreshold</a>()</pre>
 </li>
 </ul>
 <a name="hasRegionsOverThreshold--">
@@ -399,7 +399,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRegionsOverThreshold</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1557">hasRegionsOverThreshold</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1555">hasRegionsOverThreshold</a>()</pre>
 </li>
 </ul>
 <a name="getRegionOverThreshold--">
@@ -408,7 +408,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionOverThreshold</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1562">getRegionOverThreshold</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1560">getRegionOverThreshold</a>()</pre>
 </li>
 </ul>
 <a name="isRegionOverThreshold-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -417,7 +417,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionOverThreshold</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1567">isRegionOverThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1565">isRegionOverThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="isRegionTwiceOverThreshold-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -426,7 +426,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionTwiceOverThreshold</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1572">isRegionTwiceOverThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1570">isRegionTwiceOverThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="update-org.apache.hadoop.hbase.master.assignment.AssignmentManager-">
@@ -435,7 +435,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>update</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1584">update</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager</a>&nbsp;am)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1582">update</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager</a>&nbsp;am)</pre>
 </li>
 </ul>
 <a name="update-java.util.Collection-long-">
@@ -444,7 +444,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>update</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1598">update</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;regions,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html#line.1596">update</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;regions,
                     long&nbsp;currentTime)</pre>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html
index fdfd63a57c2..8e6320757bc 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html
@@ -117,7 +117,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1706">AssignmentManager.RegionMetaLoadingVisitor</a>
+<pre>private class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1704">AssignmentManager.RegionMetaLoadingVisitor</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a>
 implements <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateStore.RegionStateVisitor.html" title="interface in org.apache.hadoop.hbase.master.assignment">RegionStateStore.RegionStateVisitor</a></pre>
 </li>
@@ -194,7 +194,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionMetaLoadingVisitor</h4>
-<pre>private&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html#line.1706">RegionMetaLoadingVisitor</a>()</pre>
+<pre>private&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html#line.1704">RegionMetaLoadingVisitor</a>()</pre>
 </li>
 </ul>
 </li>
@@ -211,7 +211,7 @@ implements <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/
 <ul class="blockListLast">
 <li class="blockList">
 <h4>visitRegionState</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html#line.1709">visitRegionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/Result.html" title="class in org.apache.hadoop.hbase.client">Result</a>&nbsp;result,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionMetaLoadingVisitor.html#line.1707">visitRegionState</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/Result.html" title="class in org.apache.hadoop.hbase.client">Result</a>&nbsp;result,
                              <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                              <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;state,
                              <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;regionLocation,
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html
index cb1cd266471..e72026a4824 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html
@@ -1654,7 +1654,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>STATES_EXPECTED_ON_OPEN</h4>
-<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1952">STATES_EXPECTED_ON_OPEN</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1950">STATES_EXPECTED_ON_OPEN</a></pre>
 </li>
 </ul>
 <a name="STATES_EXPECTED_ON_CLOSING">
@@ -1663,7 +1663,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>STATES_EXPECTED_ON_CLOSING</h4>
-<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1956">STATES_EXPECTED_ON_CLOSING</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1954">STATES_EXPECTED_ON_CLOSING</a></pre>
 </li>
 </ul>
 <a name="STATES_EXPECTED_ON_CLOSED">
@@ -1672,7 +1672,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>STATES_EXPECTED_ON_CLOSED</h4>
-<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1962">STATES_EXPECTED_ON_CLOSED</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1960">STATES_EXPECTED_ON_CLOSED</a></pre>
 </li>
 </ul>
 <a name="STATES_EXPECTED_ON_ASSIGN">
@@ -1681,7 +1681,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>STATES_EXPECTED_ON_ASSIGN</h4>
-<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1968">STATES_EXPECTED_ON_ASSIGN</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1966">STATES_EXPECTED_ON_ASSIGN</a></pre>
 </li>
 </ul>
 <a name="STATES_EXPECTED_ON_UNASSIGN_OR_MOVE">
@@ -1690,7 +1690,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>STATES_EXPECTED_ON_UNASSIGN_OR_MOVE</h4>
-<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1971">STATES_EXPECTED_ON_UNASSIGN_OR_MOVE</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>[] <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1969">STATES_EXPECTED_ON_UNASSIGN_OR_MOVE</a></pre>
 </li>
 </ul>
 <a name="pendingAssignQueue">
@@ -1699,7 +1699,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>pendingAssignQueue</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">ArrayList</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2175">pendingAssignQueue</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html?is-external=true" title="class or interface in java.util">ArrayList</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt; <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2173">pendingAssignQueue</a></pre>
 </li>
 </ul>
 <a name="assignQueueLock">
@@ -1708,7 +1708,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>assignQueueLock</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html?is-external=true" title="class or interface in java.util.concurrent.locks">ReentrantLock</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2176">assignQueueLock</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html?is-external=true" title="class or interface in java.util.concurrent.locks">ReentrantLock</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2174">assignQueueLock</a></pre>
 </li>
 </ul>
 <a name="assignQueueFullCond">
@@ -1717,7 +1717,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>assignQueueFullCond</h4>
-<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html?is-external=true" title="class or interface in java.util.concurrent.locks">Condition</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2177">assignQueueFullCond</a></pre>
+<pre>private final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html?is-external=true" title="class or interface in java.util.concurrent.locks">Condition</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2175">assignQueueFullCond</a></pre>
 </li>
 </ul>
 </li>
@@ -2614,7 +2614,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>reportRegionStateTransition</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1106">reportRegionStateTransition</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse.Builder&nbsp;builder,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1104">reportRegionStateTransition</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse.Builder&nbsp;builder,
                                          <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                          <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition&gt;&nbsp;transitionList)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -2630,7 +2630,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>reportRegionStateTransition</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1144">reportRegionStateTransition</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest&nbsp;req)
+<pre>public&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1142">reportRegionStateTransition</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest&nbsp;req)
                                                                                                                                            throws <a href="../../../../../../org/apache/hadoop/hbase/PleaseHoldException.html" title="class in org.apache.hadoop.hbase">PleaseHoldException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -2644,7 +2644,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionTransition</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1184">updateRegionTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1182">updateRegionTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                     org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
                                     <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                                     long&nbsp;seqId,
@@ -2662,7 +2662,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>reportTransition</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1224">reportTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1222">reportTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
                                  <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;serverNode,
                                  org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
                                  long&nbsp;seqId,
@@ -2680,7 +2680,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionSplitTransition</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1236">updateRegionSplitTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1234">updateRegionSplitTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                          org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
                                          <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;parent,
                                          <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriA,
@@ -2698,7 +2698,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionMergeTransition</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1289">updateRegionMergeTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1287">updateRegionMergeTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                          org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;state,
                                          <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;merged,
                                          <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hriA,
@@ -2716,7 +2716,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>reportOnlineRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1332">reportOnlineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1330">reportOnlineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                 <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;byte[]&gt;&nbsp;regionNames)</pre>
 <div class="block">The master will call this method when the RS send the regionServerReport(). The report will
  contains the "online regions". This method will check the the online regions against the
@@ -2734,7 +2734,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>closeRegionSilently</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1374">closeRegionSilently</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1372">closeRegionSilently</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
                                  byte[]&nbsp;regionName)</pre>
 <div class="block">Close <code>regionName</code> on <code>sn</code> silently and immediately without using a
  Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not
@@ -2748,7 +2748,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>checkOnlineRegionsReport</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1388">checkOnlineRegionsReport</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;serverNode,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1386">checkOnlineRegionsReport</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;serverNode,
                                       <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;byte[]&gt;&nbsp;regionNames)</pre>
 <div class="block">Check that what the RegionServer reports aligns with the Master's image. If disagreement, we
  will tell the RegionServer to expediently close a Region we do not think it should have.</div>
@@ -2760,7 +2760,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>computeRegionInTransitionStat</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager.RegionInTransitionStat</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1512">computeRegionInTransitionStat</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager.RegionInTransitionStat</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1510">computeRegionInTransitionStat</a>()</pre>
 </li>
 </ul>
 <a name="updateRegionsInTransitionMetrics-org.apache.hadoop.hbase.master.assignment.AssignmentManager.RegionInTransitionStat-">
@@ -2769,7 +2769,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateRegionsInTransitionMetrics</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1622">updateRegionsInTransitionMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager.RegionInTransitionStat</a>&nbsp;ritStat)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1620">updateRegionsInTransitionMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager.RegionInTransitionStat</a>&nbsp;ritStat)</pre>
 </li>
 </ul>
 <a name="updateDeadServerRegionMetrics-int-int-">
@@ -2778,7 +2778,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateDeadServerRegionMetrics</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1628">updateDeadServerRegionMetrics</a>(int&nbsp;deadRegions,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1626">updateDeadServerRegionMetrics</a>(int&nbsp;deadRegions,
                                            int&nbsp;unknownRegions)</pre>
 </li>
 </ul>
@@ -2788,7 +2788,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>handleRegionOverStuckWarningThreshold</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1633">handleRegionOverStuckWarningThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1631">handleRegionOverStuckWarningThreshold</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="joinCluster--">
@@ -2797,7 +2797,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>joinCluster</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1642">joinCluster</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1640">joinCluster</a>()
                  throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -2811,7 +2811,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>processOfflineRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1677">processOfflineRegions</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1675">processOfflineRegions</a>()</pre>
 <div class="block">Create assign procedure for offline regions. Just follow the old
  processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead
  server any more, we only deal with the regions in OFFLINE state in this method. And this is a
@@ -2827,7 +2827,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>populateRegionStatesFromMeta</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1759">populateRegionStatesFromMeta</a>(@NonNull
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1757">populateRegionStatesFromMeta</a>(@NonNull
                                          <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Attempt to load <code>regionInfo</code> from META, adding any results to the
@@ -2846,7 +2846,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>populateRegionStatesFromMeta</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1774">populateRegionStatesFromMeta</a>(@NonNull
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1772">populateRegionStatesFromMeta</a>(@NonNull
                                          <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;regionEncodedName)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Attempt to load <code>regionEncodedName</code> from META, adding any results to the
@@ -2865,7 +2865,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>loadMeta</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1779">loadMeta</a>()
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1777">loadMeta</a>()
                throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -2879,7 +2879,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>checkMetaLoaded</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1791">checkMetaLoaded</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1789">checkMetaLoaded</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)
                       throws <a href="../../../../../../org/apache/hadoop/hbase/PleaseHoldException.html" title="class in org.apache.hadoop.hbase">PleaseHoldException</a></pre>
 <div class="block">Used to check if the meta loading is done.
  <p/>
@@ -2898,7 +2898,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getNumRegionsOpened</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1806">getNumRegionsOpened</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1804">getNumRegionsOpened</a>()</pre>
 </li>
 </ul>
 <a name="submitServerCrash-org.apache.hadoop.hbase.ServerName-boolean-boolean-">
@@ -2907,7 +2907,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>submitServerCrash</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1821">submitServerCrash</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>public&nbsp;long&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1819">submitServerCrash</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                               boolean&nbsp;shouldSplitWal,
                               boolean&nbsp;force)</pre>
 <div class="block">Usually run by the Master in reaction to server crash during normal processing. Can also be
@@ -2930,7 +2930,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>offlineRegion</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1876">offlineRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1874">offlineRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="onlineRegion-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-">
@@ -2939,7 +2939,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>onlineRegion</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1884">onlineRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1882">onlineRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                          <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
@@ -2949,7 +2949,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getSnapShotOfAssignment</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.ht [...]
 </li>
 </ul>
 <a name="getReopenStatus-org.apache.hadoop.hbase.TableName-">
@@ -2958,7 +2958,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getReopenStatus</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/util/Pair.html" title="class in org.apache.hadoop.hbase.util">Pair</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop [...]
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/util/Pair.html" title="class in org.apache.hadoop.hbase.util">Pair</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html?is-external=true" title="class or interface in java.lang">Integer</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop [...]
 <div class="block">Used by the client (via master) to identify if all regions have the schema updates</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -2972,7 +2972,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hasRegionsInTransition</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1918">hasRegionsInTransition</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1916">hasRegionsInTransition</a>()</pre>
 </li>
 </ul>
 <a name="getRegionsInTransition--">
@@ -2981,7 +2981,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsInTransition</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1922">getRegionsInTransition</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1920">getRegionsInTransition</a>()</pre>
 </li>
 </ul>
 <a name="getAssignedRegions--">
@@ -2990,7 +2990,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAssignedRegions</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1926">getAssignedRegions</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1924">getAssignedRegions</a>()</pre>
 </li>
 </ul>
 <a name="getRegionInfo-byte:A-">
@@ -2999,7 +2999,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionInfo</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1933">getRegionInfo</a>(byte[]&nbsp;regionName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1931">getRegionInfo</a>(byte[]&nbsp;regionName)</pre>
 <div class="block">Resolve a cached <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client"><code>RegionInfo</code></a> from the region name as a <code>byte[]</code>.</div>
 </li>
 </ul>
@@ -3009,7 +3009,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionInfo</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1941">getRegionInfo</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;encodedRegionName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1939">getRegionInfo</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;encodedRegionName)</pre>
 <div class="block">Resolve a cached <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client"><code>RegionInfo</code></a> from the encoded region name as a <code>String</code>.</div>
 </li>
 </ul>
@@ -3019,7 +3019,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>transitStateAndUpdate</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1978">transitStateAndUpdate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1976">transitStateAndUpdate</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
                                    <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;newState,
                                    <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>...&nbsp;expectedStates)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -3035,7 +3035,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionOpening</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1995">regionOpening</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.1993">regionOpening</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3049,7 +3049,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionFailedOpen</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2008">regionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2006">regionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode,
                       boolean&nbsp;giveUp)
                throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
@@ -3064,7 +3064,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionClosing</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2032">regionClosing</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2030">regionClosing</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3078,7 +3078,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionOpenedWithoutPersistingToMeta</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2051">regionOpenedWithoutPersistingToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2049">regionOpenedWithoutPersistingToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3092,7 +3092,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionClosedWithoutPersistingToMeta</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2059">regionClosedWithoutPersistingToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2057">regionClosedWithoutPersistingToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3106,7 +3106,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionClosedAbnormally</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2071">regionClosedAbnormally</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2069">regionClosedAbnormally</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3120,7 +3120,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>persistToMeta</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2093">persistToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2091">persistToMeta</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)
             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -3134,7 +3134,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>markRegionAsSplit</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2109">markRegionAsSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;parent,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2107">markRegionAsSplit</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;parent,
                               <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                               <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;daughterA,
                               <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;daughterB)
@@ -3151,7 +3151,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>markRegionAsMerged</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2149">markRegionAsMerged</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;child,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2147">markRegionAsMerged</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;child,
                                <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>[]&nbsp;mergeParents)
                         throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -3174,7 +3174,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>shouldAssignFavoredNodes</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2167">shouldAssignFavoredNodes</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</pre>
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2165">shouldAssignFavoredNodes</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</pre>
 </li>
 </ul>
 <a name="queueAssign-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">
@@ -3183,7 +3183,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>queueAssign</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2183">queueAssign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2181">queueAssign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
 <div class="block">Add the assign operation to the assignment queue. The pending assignment operation will be
  processed, and each region will be assigned by a server using the balancer.</div>
 </li>
@@ -3194,7 +3194,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>startAssignmentThread</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2201">startAssignmentThread</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2199">startAssignmentThread</a>()</pre>
 </li>
 </ul>
 <a name="stopAssignmentThread--">
@@ -3203,7 +3203,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>stopAssignmentThread</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2215">stopAssignmentThread</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2213">stopAssignmentThread</a>()</pre>
 </li>
 </ul>
 <a name="assignQueueSignal--">
@@ -3212,7 +3212,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>assignQueueSignal</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2228">assignQueueSignal</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2226">assignQueueSignal</a>()</pre>
 </li>
 </ul>
 <a name="waitOnAssignQueue--">
@@ -3221,7 +3221,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>waitOnAssignQueue</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt;&nbsp;<a hre [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&gt;&nbsp;<a hre [...]
 </li>
 </ul>
 <a name="processAssignQueue--">
@@ -3230,7 +3230,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>processAssignQueue</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2265">processAssignQueue</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2263">processAssignQueue</a>()</pre>
 </li>
 </ul>
 <a name="containsBogusAssignments-java.util.Map-java.util.List-">
@@ -3239,7 +3239,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>containsBogusAssignments</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2329">containsBogusAssignments</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/h [...]
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2327">containsBogusAssignments</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/h [...]
                                          <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;hirs)</pre>
 </li>
 </ul>
@@ -3249,7 +3249,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>processAssignmentPlans</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2342">processAssignmentPlans</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apach [...]
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2340">processAssignmentPlans</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apach [...]
                                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;retainMap,
                                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;hris,
                                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;servers)</pre>
@@ -3261,7 +3261,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>acceptPlan</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2380">acceptPlan</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hba [...]
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2378">acceptPlan</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apache/hadoop/hba [...]
                         <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/Region [...]
                  throws <a href="../../../../../../org/apache/hadoop/hbase/HBaseIOException.html" title="class in org.apache.hadoop.hbase">HBaseIOException</a></pre>
 <dl>
@@ -3276,7 +3276,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addToPendingAssignment</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2415">addToPendingAssignment</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apach [...]
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2413">addToPendingAssignment</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html?is-external=true" title="class or interface in java.util">HashMap</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>,<a href="../../../../../../org/apach [...]
                                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;pendingRegions)</pre>
 </li>
 </ul>
@@ -3286,7 +3286,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getExcludedServersForSystemTable</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2435">getExcludedServersForSystemTable</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2433">getExcludedServersForSystemTable</a>()</pre>
 <div class="block">For a given cluster with mixed versions of servers, get a list of servers with lower versions,
  where system table regions should not be assigned to. For system table, we must assign regions
  to a server with highest version. However, we can disable this exclusion using config:
@@ -3304,7 +3304,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getMaster</h4>
-<pre><a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2458">getMaster</a>()</pre>
+<pre><a href="../../../../../../org/apache/hadoop/hbase/master/MasterServices.html" title="interface in org.apache.hadoop.hbase.master">MasterServices</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2456">getMaster</a>()</pre>
 </li>
 </ul>
 <a name="getRSReports--">
@@ -3313,7 +3313,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRSReports</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;byte[]&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;byte[]&gt;&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop [...]
 <div class="block">Returns a snapshot of rsReports</div>
 </li>
 </ul>
@@ -3323,7 +3323,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getRegionStatesCount</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionStatesCount.html" title="class in org.apache.hadoop.hbase.client">RegionStatesCount</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2477">getRegionStatesCount</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionStatesCount.html" title="class in org.apache.hadoop.hbase.client">RegionStatesCount</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.html#line.2475">getRegionStatesCount</a>(<a href="../../../../../../org/apache/hadoop/hbase/TableName.html" title="class in org.apache.hadoop.hbase">TableName</a>&nbsp;tableName)</pre>
 <div class="block">Provide regions state count for given table. e.g howmany regions of give table are
  opened/closed/rit etc</div>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
index 02b3580d184..87cb1d65b14 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static final class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.691">RegionStates.RegionFailedOpen</a>
+<pre>public static final class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.686">RegionStates.RegionFailedOpen</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 </li>
 </ul>
@@ -229,7 +229,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionNode</h4>
-<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.692">regionNode</a></pre>
+<pre>private final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.687">regionNode</a></pre>
 </li>
 </ul>
 <a name="exception">
@@ -238,7 +238,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>exception</h4>
-<pre>private volatile&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.694">exception</a></pre>
+<pre>private volatile&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.689">exception</a></pre>
 </li>
 </ul>
 <a name="retries">
@@ -247,7 +247,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>retries</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.695">retries</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicInteger.html?is-external=true" title="class or interface in java.util.concurrent.atomic">AtomicInteger</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.690">retries</a></pre>
 </li>
 </ul>
 </li>
@@ -264,7 +264,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.697">RegionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.692">RegionFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
 </li>
@@ -281,7 +281,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionStateNode</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.701">getRegionStateNode</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.696">getRegionStateNode</a>()</pre>
 </li>
 </ul>
 <a name="getRegionInfo--">
@@ -290,7 +290,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionInfo</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.705">getRegionInfo</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.700">getRegionInfo</a>()</pre>
 </li>
 </ul>
 <a name="incrementAndGetRetries--">
@@ -299,7 +299,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>incrementAndGetRetries</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.709">incrementAndGetRetries</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.704">incrementAndGetRetries</a>()</pre>
 </li>
 </ul>
 <a name="getRetries--">
@@ -308,7 +308,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRetries</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.713">getRetries</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.708">getRetries</a>()</pre>
 </li>
 </ul>
 <a name="setException-java.lang.Exception-">
@@ -317,7 +317,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setException</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.717">setException</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;exception)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.712">setException</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;exception)</pre>
 </li>
 </ul>
 <a name="getException--">
@@ -326,7 +326,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getException</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.721">getException</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html#line.716">getException</a>()</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
index 87492a973e1..9cf477cd7cb 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/RegionStates.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10,"i38":10,"i39":10,"i40":10,"i41":10,"i42":10,"i43":10,"i44":10,"i45":10,"i46":10,"i47":10,"i48":10,"i49":10,"i50":10,"i51":10,"i52":10,"i53":10," [...]
+var methods = {"i0":10,"i1":10,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":10,"i8":10,"i9":10,"i10":10,"i11":10,"i12":10,"i13":10,"i14":10,"i15":10,"i16":10,"i17":10,"i18":10,"i19":10,"i20":10,"i21":10,"i22":10,"i23":10,"i24":10,"i25":10,"i26":10,"i27":10,"i28":10,"i29":10,"i30":10,"i31":10,"i32":10,"i33":10,"i34":10,"i35":10,"i36":10,"i37":10,"i38":10,"i39":10,"i40":10,"i41":10,"i42":10,"i43":10,"i44":10,"i45":10,"i46":10,"i47":10,"i48":10,"i49":10,"i50":10,"i51":10,"i52":10,"i53":10," [...]
 var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -503,26 +503,22 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeFromFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">removeFromFailedOpen</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
 </tr>
 <tr id="i57" class="rowColor">
-<td class="colFirst"><code>void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeFromOfflineRegions-org.apache.hadoop.hbase.client.RegionInfo-">removeFromOfflineRegions</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</code>&nbsp;</td>
-</tr>
-<tr id="i58" class="altColor">
 <td class="colFirst"><code><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeRegionFromServer-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">removeRegionFromServer</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                       <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</code>&nbsp;</td>
 </tr>
-<tr id="i59" class="rowColor">
+<tr id="i58" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#removeServer-org.apache.hadoop.hbase.ServerName-">removeServer</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</code>
 <div class="block">Called by SCP at end of successful processing.</div>
 </td>
 </tr>
-<tr id="i60" class="altColor">
+<tr id="i59" class="rowColor">
 <td class="colFirst"><code>private void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#setServerState-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.master.assignment.ServerState-">setServerState</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
               <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerState.html" title="enum in org.apache.hadoop.hbase.master.assignment">ServerState</a>&nbsp;state)</code>&nbsp;</td>
 </tr>
-<tr id="i61" class="rowColor">
+<tr id="i60" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#updateRegionState-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.master.RegionState.State-">updateRegionState</a></span>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo,
                  <a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master">RegionState.State</a>&nbsp;state)</code>&nbsp;</td>
@@ -1201,22 +1197,13 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.678">addToOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
-<a name="removeFromOfflineRegions-org.apache.hadoop.hbase.client.RegionInfo-">
-<!--   -->
-</a>
-<ul class="blockList">
-<li class="blockList">
-<h4>removeFromOfflineRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.684">removeFromOfflineRegions</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
-</li>
-</ul>
 <a name="addToFailedOpen-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>addToFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.726">addToFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignme [...]
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.721">addToFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignme [...]
 </li>
 </ul>
 <a name="getFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1225,7 +1212,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getFailedOpen</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.731">getFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;r [...]
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.RegionFailedOpen.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStates.RegionFailedOpen</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.726">getFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;r [...]
 </li>
 </ul>
 <a name="removeFromFailedOpen-org.apache.hadoop.hbase.client.RegionInfo-">
@@ -1234,7 +1221,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeFromFailedOpen</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.735">removeFromFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.730">removeFromFailedOpen</a>(<a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 </li>
 </ul>
 <a name="getRegionFailedOpen--">
@@ -1243,7 +1230,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionFailedOpen</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.739">getRegionFailedOpen</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/RegionState.html" title="class in org.apache.hadoop.hbase.master">RegionState</a>&gt;&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.734">getRegionFailedOpen</a>()</pre>
 </li>
 </ul>
 <a name="getOrCreateServer-org.apache.hadoop.hbase.ServerName-">
@@ -1252,7 +1239,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOrCreateServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.758">getOrCreateServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.753">getOrCreateServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Be judicious calling this method. Do it on server register ONLY otherwise you could mess up
  online server accounting. TOOD: Review usage and convert to <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStates.html#getServerNode-org.apache.hadoop.hbase.ServerName-"><code>getServerNode(ServerName)</code></a>
  where we can.</div>
@@ -1264,7 +1251,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeServer</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.765">removeServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.760">removeServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Called by SCP at end of successful processing.</div>
 </li>
 </ul>
@@ -1274,7 +1261,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getServerNode</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.770">getServerNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.765">getServerNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Returns Pertinent ServerStateNode or NULL if none found (Do not make modifications).</div>
 </li>
 </ul>
@@ -1284,7 +1271,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAverageLoad</h4>
-<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.774">getAverageLoad</a>()</pre>
+<pre>public&nbsp;double&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.769">getAverageLoad</a>()</pre>
 </li>
 </ul>
 <a name="addRegionToServer-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">
@@ -1293,7 +1280,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addRegionToServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.784">addRegionToServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nb [...]
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.779">addRegionToServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nb [...]
 </li>
 </ul>
 <a name="removeRegionFromServer-org.apache.hadoop.hbase.ServerName-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">
@@ -1302,7 +1289,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegionFromServer</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.790">removeRegionFromServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/ServerStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">ServerStateNode</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.785">removeRegionFromServer</a>(<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                               <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionStateNode.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionStateNode</a>&nbsp;regionNode)</pre>
 </li>
 </ul>
@@ -1312,7 +1299,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>regionNamesToString</h4>
-<pre>public static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.800">regionNamesToString</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;byte[]&gt;&nbsp;regions)</pre>
+<pre>public static&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/RegionStates.html#line.795">regionNamesToString</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;byte[]&gt;&nbsp;regions)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
index bb4896ebb38..36178655028 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
@@ -221,8 +221,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.GeneratorType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">StochasticLoadBalancer.GeneratorType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.Type.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalanceAction.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.GeneratorType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">StochasticLoadBalancer.GeneratorType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalancerClusterState.LocalityType</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
index 36246a47666..4a2b3a3c9f8 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
@@ -322,12 +322,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">ServerManager.ServerLiveState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MetricsMasterSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MetricsMasterSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MetricsMasterSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MetricsMasterSourceFactoryImpl.FactoryStorage</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
index 9cec29c18c9..16bc8b974c9 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
@@ -226,10 +226,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/ServerProcedureInterface.ServerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">ServerProcedureInterface.ServerOperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">TableProcedureInterface.TableOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/PeerProcedureInterface.PeerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">PeerProcedureInterface.PeerOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/ServerProcedureInterface.ServerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">ServerProcedureInterface.ServerOperationType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
index 78f0d3112d7..60250741d97 100644
--- a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
@@ -127,8 +127,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/TaskMonitor.TaskFilter.TaskType.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">TaskMonitor.TaskFilter.TaskType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/package-tree.html b/devapidocs/org/apache/hadoop/hbase/package-tree.html
index 43946e7d258..94fbd0dd1dd 100644
--- a/devapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -483,22 +483,22 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.ZNodeOpType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaRegionLocationCache.ZNodeOpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClientMetaTableAccessor.QueryType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterMetrics.Option</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CatalogReplicaMode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CatalogReplicaMode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeepDeletedCells.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeepDeletedCells</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ServerTask.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ServerTask.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClientMetaTableAccessor.QueryType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.ZNodeOpType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaRegionLocationCache.ZNodeOpType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index 40b029aaf7b..75d33843d09 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -218,10 +218,10 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockedResourceType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockedResourceType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
index 6fa69883261..b5ac65765ef 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/store/wal/package-tree.html
@@ -133,8 +133,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/ProcedureStoreTracker.DeleteState.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">ProcedureStoreTracker.DeleteState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.PushType.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">WALProcedureStore.PushType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.store.wal.<a href="../../../../../../../org/apache/hadoop/hbase/procedure2/store/wal/ProcedureStoreTracker.DeleteState.html" title="enum in org.apache.hadoop.hbase.procedure2.store.wal"><span class="typeNameLink">ProcedureStoreTracker.DeleteState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
index 4f59e3f59f4..b5670ddad02 100644
--- a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
@@ -240,12 +240,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/OperationQuota.OperationType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">OperationQuota.OperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/OperationQuota.OperationType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">OperationQuota.OperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 61046e5d0e1..b8a0af7c17c 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -748,21 +748,21 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/Region.Operation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">Region.Operation</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ReadPointCalculationLock.LockType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ReadPointCalculationLock.LockType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/SplitLogWorker.TaskExecutor.Status.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">SplitLogWorker.TaskExecutor.Status</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ReadPointCalculationLock.LockType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ReadPointCalculationLock.LockType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/Region.Operation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">Region.Operation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
index 02fabfc1f7f..cc3425651de 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
@@ -253,10 +253,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/WALActionsListener.RollRequestReason.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">WALActionsListener.RollRequestReason</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/WALEventTrackerListener.WalState.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">WALEventTrackerListener.WalState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/WALActionsListener.RollRequestReason.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">WALActionsListener.RollRequestReason</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
index f9442ed52e7..13f95f813bf 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
@@ -173,8 +173,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/ReplicationPeer.PeerState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">ReplicationPeer.PeerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/SyncReplicationState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">SyncReplicationState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/ReplicationPeer.PeerState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">ReplicationPeer.PeerState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
index 4b3c6f73344..e30a63f0725 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
@@ -217,9 +217,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/WALEntryStream.HasNext.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">WALEntryStream.HasNext</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/MetricsReplicationSourceFactoryImpl.SourceHolder.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">MetricsReplicationSourceFactoryImpl.SourceHolder</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
index 74209ee8370..522beb71feb 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
@@ -162,12 +162,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Scope.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Scope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Scope.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Scope</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
index 70afe1515d0..f82a56468bd 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
@@ -196,8 +196,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/AuthMethod.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">AuthMethod</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
index e36d11617c2..be1df7e35a6 100644
--- a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
@@ -211,9 +211,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ImplType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ImplType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html b/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
index d11adda7d5a..6566d6c7162 100644
--- a/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
@@ -97,9 +97,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.ReadType.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.ReadType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.Operation.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.Operation</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.RpcSystem.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.RpcSystem</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.ReadType.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.ReadType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
index 4b6430deb60..20d51014a74 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
@@ -536,15 +536,15 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HbckErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HbckErrorReporter.ERROR_CODE</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.PureJavaComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.PureJavaComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLockWithObjectPool.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLockWithObjectPool.ReferenceType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HbckErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HbckErrorReporter.ERROR_CODE</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/wal/package-tree.html
index 6f8f0ff1fc4..0a3cb275390 100644
--- a/devapidocs/org/apache/hadoop/hbase/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/wal/package-tree.html
@@ -197,9 +197,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/WALFactory.Providers.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">WALFactory.Providers</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/WALTailingReader.State.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">WALTailingReader.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/RegionGroupingProvider.Strategies.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">RegionGroupingProvider.Strategies</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/WALFactory.Providers.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">WALFactory.Providers</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
index ea172726b4e..09f2091a100 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.DeadServerMetricRegionChore.html
@@ -1102,1412 +1102,1410 @@
 <span class="sourceLineNo">1094</span>    regionStateStore.deleteRegions(regions);<a name="line.1094"></a>
 <span class="sourceLineNo">1095</span>    for (int i = 0; i &lt; regions.size(); ++i) {<a name="line.1095"></a>
 <span class="sourceLineNo">1096</span>      final RegionInfo regionInfo = regions.get(i);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // we expect the region to be offline<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      regionStates.removeFromOfflineRegions(regionInfo);<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      regionStates.deleteRegion(regionInfo);<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    }<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
+<span class="sourceLineNo">1097</span>      regionStates.deleteRegion(regionInfo);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span>    }<a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>  }<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span><a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>  // ============================================================================================<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>  // RS Region Transition Report helpers<a name="line.1102"></a>
 <span class="sourceLineNo">1103</span>  // ============================================================================================<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>  // RS Region Transition Report helpers<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  // ============================================================================================<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      switch (transition.getTransitionCode()) {<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>        case OPENED:<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        case FAILED_OPEN:<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        case CLOSED:<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>          long procId =<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>          break;<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>        case READY_TO_SPLIT:<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>        case SPLIT:<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>        case SPLIT_REVERTED:<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>            splitB);<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>          break;<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>        case READY_TO_MERGE:<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>        case MERGED:<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>        case MERGE_REVERTED:<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>            mergeB);<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>          break;<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      }<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span>    }<a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>  }<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span><a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    // lock protection to wait for meta online...<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    serverNode.readLock().lock();<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span>    try {<a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1158"></a>
-<span class="sourceLineNo">1159</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>        try {<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>        } catch (PleaseHoldException e) {<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>          LOG.trace("Failed transition ", e);<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>          throw e;<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>          // if the master says that one of the region transitions failed.<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span>          LOG.warn("Failed transition", e);<a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>        }<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      } else {<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          serverName);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span>        builder.setErrorMessage("You are dead");<a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      }<a name="line.1176"></a>
-<span class="sourceLineNo">1177</span>    } finally {<a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      serverNode.readLock().unlock();<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>    }<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span><a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>    return builder.build();<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>  }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>    checkMetaLoaded(regionInfo);<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>    if (regionNode == null) {<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>      throw new UnexpectedStateException(String.format(<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>        regionInfo, state));<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>    }<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span>      regionNode, state);<a name="line.1196"></a>
-<span class="sourceLineNo">1197</span><a name="line.1197"></a>
-<span class="sourceLineNo">1198</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    regionNode.lock();<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>    try {<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>        // to CLOSED<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span>        if (<a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        ) {<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span>        } else {<a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>            regionNode, state);<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>        }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span>      }<a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>    } finally {<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>      regionNode.unlock();<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>    }<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>  }<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span><a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    ServerName serverName = serverNode.getServerName();<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    if (proc == null) {<a name="line.1228"></a>
-<span class="sourceLineNo">1229</span>      return false;<a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    }<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      serverName, state, seqId, procId);<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>    return true;<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>  }<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span><a name="line.1235"></a>
-<span class="sourceLineNo">1236</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    checkMetaLoaded(parent);<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span><a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      throw new UnexpectedStateException(<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>    }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>    // sanity check on the request<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>    }<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span><a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span>      throw new DoNotRetryIOException(<a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span><a name="line.1257"></a>
-<span class="sourceLineNo">1258</span>    // Submit the Split procedure<a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>    if (LOG.isDebugEnabled()) {<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>        + Bytes.toStringBinary(splitKey));<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>    }<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    // ignore it in that case.<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>    // initialization and report failure with WARN level logging.<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    } else {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>        + " because parent is unknown or not open");<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      return;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span>    }<a name="line.1279"></a>
-<span class="sourceLineNo">1280</span><a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span>      throw new UnsupportedOperationException(<a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>    }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span>  }<a name="line.1287"></a>
-<span class="sourceLineNo">1288</span><a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>    checkMetaLoaded(merged);<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span><a name="line.1292"></a>
-<span class="sourceLineNo">1293</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>      throw new UnexpectedStateException(<a name="line.1294"></a>
-<span class="sourceLineNo">1295</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    }<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1299"></a>
-<span class="sourceLineNo">1300</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>      throw new DoNotRetryIOException(<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>    }<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span><a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>    // Submit the Merge procedure<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>    if (LOG.isDebugEnabled()) {<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>    }<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span><a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span>      throw new UnsupportedOperationException(<a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>          merged, hriA, hriB));<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>    }<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>  }<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
+<span class="sourceLineNo">1104</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1106"></a>
+<span class="sourceLineNo">1107</span>      switch (transition.getTransitionCode()) {<a name="line.1107"></a>
+<span class="sourceLineNo">1108</span>        case OPENED:<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span>        case FAILED_OPEN:<a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>        case CLOSED:<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>          long procId =<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span>          break;<a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>        case READY_TO_SPLIT:<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>        case SPLIT:<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>        case SPLIT_REVERTED:<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>            splitB);<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>          break;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>        case READY_TO_MERGE:<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>        case MERGED:<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>        case MERGE_REVERTED:<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>            mergeB);<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>          break;<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>      }<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>    }<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>  }<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span><a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    // lock protection to wait for meta online...<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    serverNode.readLock().lock();<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>    try {<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1158"></a>
+<span class="sourceLineNo">1159</span>        try {<a name="line.1159"></a>
+<span class="sourceLineNo">1160</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span>        } catch (PleaseHoldException e) {<a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>          LOG.trace("Failed transition ", e);<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>          throw e;<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>          // if the master says that one of the region transitions failed.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>          LOG.warn("Failed transition", e);<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>        }<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>      } else {<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>          serverName);<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>        builder.setErrorMessage("You are dead");<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      }<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>    } finally {<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>      serverNode.readLock().unlock();<a name="line.1176"></a>
+<span class="sourceLineNo">1177</span>    }<a name="line.1177"></a>
+<span class="sourceLineNo">1178</span><a name="line.1178"></a>
+<span class="sourceLineNo">1179</span>    return builder.build();<a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>  }<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span><a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>    checkMetaLoaded(regionInfo);<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    if (regionNode == null) {<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span>      throw new UnexpectedStateException(String.format(<a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>        regionInfo, state));<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>    }<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>      regionNode, state);<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span><a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    regionNode.lock();<a name="line.1197"></a>
+<span class="sourceLineNo">1198</span>    try {<a name="line.1198"></a>
+<span class="sourceLineNo">1199</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>        // to CLOSED<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>        if (<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        ) {<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span>        } else {<a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>            regionNode, state);<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>        }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span>      }<a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>    } finally {<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>      regionNode.unlock();<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>    }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span>  }<a name="line.1220"></a>
+<span class="sourceLineNo">1221</span><a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>    ServerName serverName = serverNode.getServerName();<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    if (proc == null) {<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>      return false;<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    }<a name="line.1228"></a>
+<span class="sourceLineNo">1229</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1229"></a>
+<span class="sourceLineNo">1230</span>      serverName, state, seqId, procId);<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span>    return true;<a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>  }<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span><a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>    checkMetaLoaded(parent);<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span><a name="line.1237"></a>
+<span class="sourceLineNo">1238</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>      throw new UnexpectedStateException(<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>    }<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span><a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>    // sanity check on the request<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>    }<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span><a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>      throw new DoNotRetryIOException(<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>    }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span><a name="line.1255"></a>
+<span class="sourceLineNo">1256</span>    // Submit the Split procedure<a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    if (LOG.isDebugEnabled()) {<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span>        + Bytes.toStringBinary(splitKey));<a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>    }<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>    // ignore it in that case.<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    // initialization and report failure with WARN level logging.<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>    } else {<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span>        + " because parent is unknown or not open");<a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>      return;<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    }<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span><a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span>      throw new UnsupportedOperationException(<a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>    }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span>  }<a name="line.1285"></a>
+<span class="sourceLineNo">1286</span><a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span>    checkMetaLoaded(merged);<a name="line.1289"></a>
+<span class="sourceLineNo">1290</span><a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>      throw new UnexpectedStateException(<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1294"></a>
+<span class="sourceLineNo">1295</span>    }<a name="line.1295"></a>
+<span class="sourceLineNo">1296</span><a name="line.1296"></a>
+<span class="sourceLineNo">1297</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>      throw new DoNotRetryIOException(<a name="line.1299"></a>
+<span class="sourceLineNo">1300</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1300"></a>
+<span class="sourceLineNo">1301</span>    }<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    // Submit the Merge procedure<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>    if (LOG.isDebugEnabled()) {<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>    }<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span><a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      throw new UnsupportedOperationException(<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>          merged, hriA, hriB));<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span>  }<a name="line.1315"></a>
+<span class="sourceLineNo">1316</span><a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>  // ============================================================================================<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>  // RS Status update (report online regions) helpers<a name="line.1318"></a>
 <span class="sourceLineNo">1319</span>  // ============================================================================================<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>  // RS Status update (report online regions) helpers<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>  // ============================================================================================<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span>  /**<a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span>   * actually there is no problem.<a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>   * &lt;p/&gt;<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>   */<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span>    if (!isRunning()) {<a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      return;<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>    }<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>    if (LOG.isTraceEnabled()) {<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span>        regionNames.size(), isMetaLoaded(),<a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>    }<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span><a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    synchronized (serverNode) {<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>        return;<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      }<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>    }<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span><a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>    // Track the regionserver reported online regions in memory.<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>    synchronized (rsReports) {<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      rsReports.put(serverName, regionNames);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>    }<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span><a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    if (regionNames.isEmpty()) {<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span>      // nothing to do if we don't have regions<a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>      return;<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>    }<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    if (!isMetaLoaded()) {<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span>      // we are still on startup, skip checking<a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>      return;<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>    }<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>  }<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span><a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>  /**<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1370"></a>
-<span class="sourceLineNo">1371</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1371"></a>
-<span class="sourceLineNo">1372</span>   * accounting.<a name="line.1372"></a>
-<span class="sourceLineNo">1373</span>   */<a name="line.1373"></a>
-<span class="sourceLineNo">1374</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span>    try {<a name="line.1375"></a>
-<span class="sourceLineNo">1376</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1376"></a>
-<span class="sourceLineNo">1377</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1377"></a>
-<span class="sourceLineNo">1378</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span>    } catch (Exception e) {<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span>    }<a name="line.1381"></a>
-<span class="sourceLineNo">1382</span>  }<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span><a name="line.1383"></a>
-<span class="sourceLineNo">1384</span>  /**<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1385"></a>
-<span class="sourceLineNo">1386</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1386"></a>
-<span class="sourceLineNo">1387</span>   */<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1388"></a>
-<span class="sourceLineNo">1389</span>    ServerName serverName = serverNode.getServerName();<a name="line.1389"></a>
-<span class="sourceLineNo">1390</span>    for (byte[] regionName : regionNames) {<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span>      if (!isRunning()) {<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span>        return;<a name="line.1392"></a>
-<span class="sourceLineNo">1393</span>      }<a name="line.1393"></a>
-<span class="sourceLineNo">1394</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1394"></a>
-<span class="sourceLineNo">1395</span>      if (regionNode == null) {<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1396"></a>
-<span class="sourceLineNo">1397</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1397"></a>
-<span class="sourceLineNo">1398</span>          serverName);<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span>        continue;<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span>      }<a name="line.1401"></a>
-<span class="sourceLineNo">1402</span>      final long lag = 1000;<a name="line.1402"></a>
-<span class="sourceLineNo">1403</span>      regionNode.lock();<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span>      try {<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1406"></a>
-<span class="sourceLineNo">1407</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1407"></a>
-<span class="sourceLineNo">1408</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1408"></a>
-<span class="sourceLineNo">1409</span>          // is some elapsed time so less false alarms.<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1410"></a>
-<span class="sourceLineNo">1411</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1413"></a>
-<span class="sourceLineNo">1414</span>          }<a name="line.1414"></a>
-<span class="sourceLineNo">1415</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1415"></a>
-<span class="sourceLineNo">1416</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1416"></a>
-<span class="sourceLineNo">1417</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1417"></a>
-<span class="sourceLineNo">1418</span>          // elapsed time so less false alarms.<a name="line.1418"></a>
-<span class="sourceLineNo">1419</span>          if (diff &gt; lag) {<a name="line.1419"></a>
-<span class="sourceLineNo">1420</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1420"></a>
-<span class="sourceLineNo">1421</span>              serverName, regionNode, diff);<a name="line.1421"></a>
-<span class="sourceLineNo">1422</span>          }<a name="line.1422"></a>
-<span class="sourceLineNo">1423</span>        }<a name="line.1423"></a>
-<span class="sourceLineNo">1424</span>      } finally {<a name="line.1424"></a>
-<span class="sourceLineNo">1425</span>        regionNode.unlock();<a name="line.1425"></a>
-<span class="sourceLineNo">1426</span>      }<a name="line.1426"></a>
-<span class="sourceLineNo">1427</span>    }<a name="line.1427"></a>
-<span class="sourceLineNo">1428</span>  }<a name="line.1428"></a>
-<span class="sourceLineNo">1429</span><a name="line.1429"></a>
+<span class="sourceLineNo">1320</span>  /**<a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>   * actually there is no problem.<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>   * &lt;p/&gt;<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>   */<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>    if (!isRunning()) {<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      return;<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>    }<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>    if (LOG.isTraceEnabled()) {<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>        regionNames.size(), isMetaLoaded(),<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>    }<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span><a name="line.1339"></a>
+<span class="sourceLineNo">1340</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>    synchronized (serverNode) {<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>        return;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>      }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span>    }<a name="line.1346"></a>
+<span class="sourceLineNo">1347</span><a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    // Track the regionserver reported online regions in memory.<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>    synchronized (rsReports) {<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      rsReports.put(serverName, regionNames);<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>    }<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span><a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>    if (regionNames.isEmpty()) {<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      // nothing to do if we don't have regions<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1355"></a>
+<span class="sourceLineNo">1356</span>      return;<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span>    }<a name="line.1357"></a>
+<span class="sourceLineNo">1358</span>    if (!isMetaLoaded()) {<a name="line.1358"></a>
+<span class="sourceLineNo">1359</span>      // we are still on startup, skip checking<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span>      return;<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span>    }<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1363"></a>
+<span class="sourceLineNo">1364</span>  }<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span><a name="line.1365"></a>
+<span class="sourceLineNo">1366</span>  /**<a name="line.1366"></a>
+<span class="sourceLineNo">1367</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1367"></a>
+<span class="sourceLineNo">1368</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1369"></a>
+<span class="sourceLineNo">1370</span>   * accounting.<a name="line.1370"></a>
+<span class="sourceLineNo">1371</span>   */<a name="line.1371"></a>
+<span class="sourceLineNo">1372</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1372"></a>
+<span class="sourceLineNo">1373</span>    try {<a name="line.1373"></a>
+<span class="sourceLineNo">1374</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1374"></a>
+<span class="sourceLineNo">1375</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1375"></a>
+<span class="sourceLineNo">1376</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1376"></a>
+<span class="sourceLineNo">1377</span>    } catch (Exception e) {<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1378"></a>
+<span class="sourceLineNo">1379</span>    }<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span>  }<a name="line.1380"></a>
+<span class="sourceLineNo">1381</span><a name="line.1381"></a>
+<span class="sourceLineNo">1382</span>  /**<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1384"></a>
+<span class="sourceLineNo">1385</span>   */<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span>    ServerName serverName = serverNode.getServerName();<a name="line.1387"></a>
+<span class="sourceLineNo">1388</span>    for (byte[] regionName : regionNames) {<a name="line.1388"></a>
+<span class="sourceLineNo">1389</span>      if (!isRunning()) {<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span>        return;<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span>      }<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span>      if (regionNode == null) {<a name="line.1393"></a>
+<span class="sourceLineNo">1394</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1394"></a>
+<span class="sourceLineNo">1395</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1395"></a>
+<span class="sourceLineNo">1396</span>          serverName);<a name="line.1396"></a>
+<span class="sourceLineNo">1397</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span>        continue;<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span>      }<a name="line.1399"></a>
+<span class="sourceLineNo">1400</span>      final long lag = 1000;<a name="line.1400"></a>
+<span class="sourceLineNo">1401</span>      regionNode.lock();<a name="line.1401"></a>
+<span class="sourceLineNo">1402</span>      try {<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1405"></a>
+<span class="sourceLineNo">1406</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1406"></a>
+<span class="sourceLineNo">1407</span>          // is some elapsed time so less false alarms.<a name="line.1407"></a>
+<span class="sourceLineNo">1408</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1409"></a>
+<span class="sourceLineNo">1410</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>          }<a name="line.1412"></a>
+<span class="sourceLineNo">1413</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1413"></a>
+<span class="sourceLineNo">1414</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1414"></a>
+<span class="sourceLineNo">1415</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1415"></a>
+<span class="sourceLineNo">1416</span>          // elapsed time so less false alarms.<a name="line.1416"></a>
+<span class="sourceLineNo">1417</span>          if (diff &gt; lag) {<a name="line.1417"></a>
+<span class="sourceLineNo">1418</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1418"></a>
+<span class="sourceLineNo">1419</span>              serverName, regionNode, diff);<a name="line.1419"></a>
+<span class="sourceLineNo">1420</span>          }<a name="line.1420"></a>
+<span class="sourceLineNo">1421</span>        }<a name="line.1421"></a>
+<span class="sourceLineNo">1422</span>      } finally {<a name="line.1422"></a>
+<span class="sourceLineNo">1423</span>        regionNode.unlock();<a name="line.1423"></a>
+<span class="sourceLineNo">1424</span>      }<a name="line.1424"></a>
+<span class="sourceLineNo">1425</span>    }<a name="line.1425"></a>
+<span class="sourceLineNo">1426</span>  }<a name="line.1426"></a>
+<span class="sourceLineNo">1427</span><a name="line.1427"></a>
+<span class="sourceLineNo">1428</span>  // ============================================================================================<a name="line.1428"></a>
+<span class="sourceLineNo">1429</span>  // RIT chore<a name="line.1429"></a>
 <span class="sourceLineNo">1430</span>  // ============================================================================================<a name="line.1430"></a>
-<span class="sourceLineNo">1431</span>  // RIT chore<a name="line.1431"></a>
-<span class="sourceLineNo">1432</span>  // ============================================================================================<a name="line.1432"></a>
-<span class="sourceLineNo">1433</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1433"></a>
-<span class="sourceLineNo">1434</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1434"></a>
-<span class="sourceLineNo">1435</span>      super(timeoutMsec);<a name="line.1435"></a>
-<span class="sourceLineNo">1436</span>    }<a name="line.1436"></a>
-<span class="sourceLineNo">1437</span><a name="line.1437"></a>
-<span class="sourceLineNo">1438</span>    @Override<a name="line.1438"></a>
-<span class="sourceLineNo">1439</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1439"></a>
-<span class="sourceLineNo">1440</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1440"></a>
-<span class="sourceLineNo">1441</span><a name="line.1441"></a>
-<span class="sourceLineNo">1442</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1442"></a>
-<span class="sourceLineNo">1443</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1443"></a>
-<span class="sourceLineNo">1444</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1444"></a>
-<span class="sourceLineNo">1445</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1445"></a>
-<span class="sourceLineNo">1446</span>        }<a name="line.1446"></a>
-<span class="sourceLineNo">1447</span>      }<a name="line.1447"></a>
-<span class="sourceLineNo">1448</span><a name="line.1448"></a>
-<span class="sourceLineNo">1449</span>      // update metrics<a name="line.1449"></a>
-<span class="sourceLineNo">1450</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1450"></a>
-<span class="sourceLineNo">1451</span>    }<a name="line.1451"></a>
-<span class="sourceLineNo">1452</span>  }<a name="line.1452"></a>
-<span class="sourceLineNo">1453</span><a name="line.1453"></a>
-<span class="sourceLineNo">1454</span>  private static class DeadServerMetricRegionChore<a name="line.1454"></a>
-<span class="sourceLineNo">1455</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1455"></a>
-<span class="sourceLineNo">1456</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1456"></a>
-<span class="sourceLineNo">1457</span>      super(timeoutMsec);<a name="line.1457"></a>
-<span class="sourceLineNo">1458</span>    }<a name="line.1458"></a>
-<span class="sourceLineNo">1459</span><a name="line.1459"></a>
-<span class="sourceLineNo">1460</span>    @Override<a name="line.1460"></a>
-<span class="sourceLineNo">1461</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1461"></a>
-<span class="sourceLineNo">1462</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1462"></a>
-<span class="sourceLineNo">1463</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1463"></a>
-<span class="sourceLineNo">1464</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1464"></a>
-<span class="sourceLineNo">1465</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1465"></a>
-<span class="sourceLineNo">1466</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1466"></a>
-<span class="sourceLineNo">1467</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1467"></a>
-<span class="sourceLineNo">1468</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1468"></a>
-<span class="sourceLineNo">1469</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1469"></a>
-<span class="sourceLineNo">1470</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1470"></a>
-<span class="sourceLineNo">1471</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1471"></a>
-<span class="sourceLineNo">1472</span>        if (rsn.getState() != State.OPEN) {<a name="line.1472"></a>
-<span class="sourceLineNo">1473</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1473"></a>
-<span class="sourceLineNo">1474</span>        }<a name="line.1474"></a>
-<span class="sourceLineNo">1475</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1475"></a>
-<span class="sourceLineNo">1476</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1476"></a>
-<span class="sourceLineNo">1477</span>        State state = rsn.getState();<a name="line.1477"></a>
-<span class="sourceLineNo">1478</span>        if (state != State.OPEN) {<a name="line.1478"></a>
-<span class="sourceLineNo">1479</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1479"></a>
-<span class="sourceLineNo">1480</span>        }<a name="line.1480"></a>
-<span class="sourceLineNo">1481</span>        if (sn == null) {<a name="line.1481"></a>
-<span class="sourceLineNo">1482</span>          ++unknownRegions; // Opened on null?<a name="line.1482"></a>
-<span class="sourceLineNo">1483</span>          continue;<a name="line.1483"></a>
-<span class="sourceLineNo">1484</span>        }<a name="line.1484"></a>
-<span class="sourceLineNo">1485</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1485"></a>
-<span class="sourceLineNo">1486</span>          continue;<a name="line.1486"></a>
-<span class="sourceLineNo">1487</span>        }<a name="line.1487"></a>
-<span class="sourceLineNo">1488</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1488"></a>
-<span class="sourceLineNo">1489</span>        switch (sls) {<a name="line.1489"></a>
-<span class="sourceLineNo">1490</span>          case LIVE:<a name="line.1490"></a>
-<span class="sourceLineNo">1491</span>            recentlyLiveServers.add(sn);<a name="line.1491"></a>
-<span class="sourceLineNo">1492</span>            break;<a name="line.1492"></a>
-<span class="sourceLineNo">1493</span>          case DEAD:<a name="line.1493"></a>
-<span class="sourceLineNo">1494</span>            ++deadRegions;<a name="line.1494"></a>
-<span class="sourceLineNo">1495</span>            break;<a name="line.1495"></a>
-<span class="sourceLineNo">1496</span>          case UNKNOWN:<a name="line.1496"></a>
-<span class="sourceLineNo">1497</span>            ++unknownRegions;<a name="line.1497"></a>
-<span class="sourceLineNo">1498</span>            break;<a name="line.1498"></a>
-<span class="sourceLineNo">1499</span>          default:<a name="line.1499"></a>
-<span class="sourceLineNo">1500</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1500"></a>
-<span class="sourceLineNo">1501</span>        }<a name="line.1501"></a>
-<span class="sourceLineNo">1502</span>      }<a name="line.1502"></a>
-<span class="sourceLineNo">1503</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1503"></a>
-<span class="sourceLineNo">1504</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1504"></a>
-<span class="sourceLineNo">1505</span>          deadRegions, unknownRegions);<a name="line.1505"></a>
-<span class="sourceLineNo">1506</span>      }<a name="line.1506"></a>
-<span class="sourceLineNo">1507</span><a name="line.1507"></a>
-<span class="sourceLineNo">1508</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1508"></a>
-<span class="sourceLineNo">1509</span>    }<a name="line.1509"></a>
-<span class="sourceLineNo">1510</span>  }<a name="line.1510"></a>
-<span class="sourceLineNo">1511</span><a name="line.1511"></a>
-<span class="sourceLineNo">1512</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1512"></a>
-<span class="sourceLineNo">1513</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1513"></a>
-<span class="sourceLineNo">1514</span>    rit.update(this);<a name="line.1514"></a>
-<span class="sourceLineNo">1515</span>    return rit;<a name="line.1515"></a>
-<span class="sourceLineNo">1516</span>  }<a name="line.1516"></a>
-<span class="sourceLineNo">1517</span><a name="line.1517"></a>
-<span class="sourceLineNo">1518</span>  public static class RegionInTransitionStat {<a name="line.1518"></a>
-<span class="sourceLineNo">1519</span>    private final int ritThreshold;<a name="line.1519"></a>
-<span class="sourceLineNo">1520</span><a name="line.1520"></a>
-<span class="sourceLineNo">1521</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1521"></a>
-<span class="sourceLineNo">1522</span>    private long statTimestamp;<a name="line.1522"></a>
-<span class="sourceLineNo">1523</span>    private long oldestRITTime = 0;<a name="line.1523"></a>
-<span class="sourceLineNo">1524</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1524"></a>
-<span class="sourceLineNo">1525</span>    private int totalRITs = 0;<a name="line.1525"></a>
-<span class="sourceLineNo">1526</span><a name="line.1526"></a>
-<span class="sourceLineNo">1527</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1527"></a>
-<span class="sourceLineNo">1528</span>      this.ritThreshold =<a name="line.1528"></a>
-<span class="sourceLineNo">1529</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1529"></a>
-<span class="sourceLineNo">1530</span>    }<a name="line.1530"></a>
-<span class="sourceLineNo">1531</span><a name="line.1531"></a>
-<span class="sourceLineNo">1532</span>    public int getRITThreshold() {<a name="line.1532"></a>
-<span class="sourceLineNo">1533</span>      return ritThreshold;<a name="line.1533"></a>
-<span class="sourceLineNo">1534</span>    }<a name="line.1534"></a>
-<span class="sourceLineNo">1535</span><a name="line.1535"></a>
-<span class="sourceLineNo">1536</span>    public long getTimestamp() {<a name="line.1536"></a>
-<span class="sourceLineNo">1537</span>      return statTimestamp;<a name="line.1537"></a>
-<span class="sourceLineNo">1538</span>    }<a name="line.1538"></a>
-<span class="sourceLineNo">1539</span><a name="line.1539"></a>
-<span class="sourceLineNo">1540</span>    public int getTotalRITs() {<a name="line.1540"></a>
-<span class="sourceLineNo">1541</span>      return totalRITs;<a name="line.1541"></a>
-<span class="sourceLineNo">1542</span>    }<a name="line.1542"></a>
-<span class="sourceLineNo">1543</span><a name="line.1543"></a>
-<span class="sourceLineNo">1544</span>    public long getOldestRITTime() {<a name="line.1544"></a>
-<span class="sourceLineNo">1545</span>      return oldestRITTime;<a name="line.1545"></a>
-<span class="sourceLineNo">1546</span>    }<a name="line.1546"></a>
-<span class="sourceLineNo">1547</span><a name="line.1547"></a>
-<span class="sourceLineNo">1548</span>    public int getTotalRITsOverThreshold() {<a name="line.1548"></a>
-<span class="sourceLineNo">1549</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1549"></a>
-<span class="sourceLineNo">1550</span>      return m != null ? m.size() : 0;<a name="line.1550"></a>
-<span class="sourceLineNo">1551</span>    }<a name="line.1551"></a>
-<span class="sourceLineNo">1552</span><a name="line.1552"></a>
-<span class="sourceLineNo">1553</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1553"></a>
-<span class="sourceLineNo">1554</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1554"></a>
-<span class="sourceLineNo">1555</span>    }<a name="line.1555"></a>
-<span class="sourceLineNo">1556</span><a name="line.1556"></a>
-<span class="sourceLineNo">1557</span>    public boolean hasRegionsOverThreshold() {<a name="line.1557"></a>
-<span class="sourceLineNo">1558</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1558"></a>
-<span class="sourceLineNo">1559</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1559"></a>
-<span class="sourceLineNo">1560</span>    }<a name="line.1560"></a>
-<span class="sourceLineNo">1561</span><a name="line.1561"></a>
-<span class="sourceLineNo">1562</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1562"></a>
-<span class="sourceLineNo">1563</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1563"></a>
-<span class="sourceLineNo">1564</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1564"></a>
-<span class="sourceLineNo">1565</span>    }<a name="line.1565"></a>
-<span class="sourceLineNo">1566</span><a name="line.1566"></a>
-<span class="sourceLineNo">1567</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1567"></a>
-<span class="sourceLineNo">1568</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1568"></a>
-<span class="sourceLineNo">1569</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1569"></a>
-<span class="sourceLineNo">1570</span>    }<a name="line.1570"></a>
-<span class="sourceLineNo">1571</span><a name="line.1571"></a>
-<span class="sourceLineNo">1572</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1572"></a>
-<span class="sourceLineNo">1573</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>      if (m == null) {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>        return false;<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>      }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1577"></a>
-<span class="sourceLineNo">1578</span>      if (state == null) {<a name="line.1578"></a>
-<span class="sourceLineNo">1579</span>        return false;<a name="line.1579"></a>
-<span class="sourceLineNo">1580</span>      }<a name="line.1580"></a>
-<span class="sourceLineNo">1581</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1581"></a>
-<span class="sourceLineNo">1582</span>    }<a name="line.1582"></a>
-<span class="sourceLineNo">1583</span><a name="line.1583"></a>
-<span class="sourceLineNo">1584</span>    protected void update(final AssignmentManager am) {<a name="line.1584"></a>
-<span class="sourceLineNo">1585</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1585"></a>
-<span class="sourceLineNo">1586</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1586"></a>
-<span class="sourceLineNo">1587</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1587"></a>
-<span class="sourceLineNo">1588</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1588"></a>
-<span class="sourceLineNo">1589</span><a name="line.1589"></a>
-<span class="sourceLineNo">1590</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1590"></a>
-<span class="sourceLineNo">1591</span>        LOG.debug("RITs over threshold: {}",<a name="line.1591"></a>
-<span class="sourceLineNo">1592</span>          ritsOverThreshold.entrySet().stream()<a name="line.1592"></a>
-<span class="sourceLineNo">1593</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1593"></a>
-<span class="sourceLineNo">1594</span>            .collect(Collectors.joining("\n")));<a name="line.1594"></a>
-<span class="sourceLineNo">1595</span>      }<a name="line.1595"></a>
-<span class="sourceLineNo">1596</span>    }<a name="line.1596"></a>
-<span class="sourceLineNo">1597</span><a name="line.1597"></a>
-<span class="sourceLineNo">1598</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1598"></a>
-<span class="sourceLineNo">1599</span>      for (RegionState state : regions) {<a name="line.1599"></a>
-<span class="sourceLineNo">1600</span>        totalRITs++;<a name="line.1600"></a>
-<span class="sourceLineNo">1601</span>        final long ritStartedMs = state.getStamp();<a name="line.1601"></a>
-<span class="sourceLineNo">1602</span>        if (ritStartedMs == 0) {<a name="line.1602"></a>
-<span class="sourceLineNo">1603</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1603"></a>
-<span class="sourceLineNo">1604</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1604"></a>
-<span class="sourceLineNo">1605</span>          continue;<a name="line.1605"></a>
-<span class="sourceLineNo">1606</span>        }<a name="line.1606"></a>
-<span class="sourceLineNo">1607</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1607"></a>
-<span class="sourceLineNo">1608</span>        if (ritTime &gt; ritThreshold) {<a name="line.1608"></a>
-<span class="sourceLineNo">1609</span>          if (ritsOverThreshold == null) {<a name="line.1609"></a>
-<span class="sourceLineNo">1610</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1610"></a>
-<span class="sourceLineNo">1611</span>          }<a name="line.1611"></a>
-<span class="sourceLineNo">1612</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1612"></a>
-<span class="sourceLineNo">1613</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1613"></a>
-<span class="sourceLineNo">1614</span>        }<a name="line.1614"></a>
-<span class="sourceLineNo">1615</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1615"></a>
-<span class="sourceLineNo">1616</span>          oldestRITTime = ritTime;<a name="line.1616"></a>
-<span class="sourceLineNo">1617</span>        }<a name="line.1617"></a>
-<span class="sourceLineNo">1618</span>      }<a name="line.1618"></a>
-<span class="sourceLineNo">1619</span>    }<a name="line.1619"></a>
-<span class="sourceLineNo">1620</span>  }<a name="line.1620"></a>
-<span class="sourceLineNo">1621</span><a name="line.1621"></a>
-<span class="sourceLineNo">1622</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1622"></a>
-<span class="sourceLineNo">1623</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1623"></a>
-<span class="sourceLineNo">1624</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1624"></a>
-<span class="sourceLineNo">1625</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1625"></a>
-<span class="sourceLineNo">1626</span>  }<a name="line.1626"></a>
-<span class="sourceLineNo">1627</span><a name="line.1627"></a>
-<span class="sourceLineNo">1628</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1628"></a>
-<span class="sourceLineNo">1629</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1629"></a>
-<span class="sourceLineNo">1630</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1630"></a>
-<span class="sourceLineNo">1631</span>  }<a name="line.1631"></a>
-<span class="sourceLineNo">1632</span><a name="line.1632"></a>
-<span class="sourceLineNo">1633</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1633"></a>
-<span class="sourceLineNo">1634</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1634"></a>
-<span class="sourceLineNo">1635</span>    // if (regionNode.isStuck()) {<a name="line.1635"></a>
-<span class="sourceLineNo">1636</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1636"></a>
-<span class="sourceLineNo">1637</span>  }<a name="line.1637"></a>
-<span class="sourceLineNo">1638</span><a name="line.1638"></a>
+<span class="sourceLineNo">1431</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1431"></a>
+<span class="sourceLineNo">1432</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1432"></a>
+<span class="sourceLineNo">1433</span>      super(timeoutMsec);<a name="line.1433"></a>
+<span class="sourceLineNo">1434</span>    }<a name="line.1434"></a>
+<span class="sourceLineNo">1435</span><a name="line.1435"></a>
+<span class="sourceLineNo">1436</span>    @Override<a name="line.1436"></a>
+<span class="sourceLineNo">1437</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1437"></a>
+<span class="sourceLineNo">1438</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1438"></a>
+<span class="sourceLineNo">1439</span><a name="line.1439"></a>
+<span class="sourceLineNo">1440</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1440"></a>
+<span class="sourceLineNo">1441</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1441"></a>
+<span class="sourceLineNo">1442</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1442"></a>
+<span class="sourceLineNo">1443</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1443"></a>
+<span class="sourceLineNo">1444</span>        }<a name="line.1444"></a>
+<span class="sourceLineNo">1445</span>      }<a name="line.1445"></a>
+<span class="sourceLineNo">1446</span><a name="line.1446"></a>
+<span class="sourceLineNo">1447</span>      // update metrics<a name="line.1447"></a>
+<span class="sourceLineNo">1448</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1448"></a>
+<span class="sourceLineNo">1449</span>    }<a name="line.1449"></a>
+<span class="sourceLineNo">1450</span>  }<a name="line.1450"></a>
+<span class="sourceLineNo">1451</span><a name="line.1451"></a>
+<span class="sourceLineNo">1452</span>  private static class DeadServerMetricRegionChore<a name="line.1452"></a>
+<span class="sourceLineNo">1453</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1453"></a>
+<span class="sourceLineNo">1454</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1454"></a>
+<span class="sourceLineNo">1455</span>      super(timeoutMsec);<a name="line.1455"></a>
+<span class="sourceLineNo">1456</span>    }<a name="line.1456"></a>
+<span class="sourceLineNo">1457</span><a name="line.1457"></a>
+<span class="sourceLineNo">1458</span>    @Override<a name="line.1458"></a>
+<span class="sourceLineNo">1459</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1459"></a>
+<span class="sourceLineNo">1460</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1460"></a>
+<span class="sourceLineNo">1461</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1461"></a>
+<span class="sourceLineNo">1462</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1462"></a>
+<span class="sourceLineNo">1463</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1463"></a>
+<span class="sourceLineNo">1464</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1464"></a>
+<span class="sourceLineNo">1465</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1465"></a>
+<span class="sourceLineNo">1466</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1466"></a>
+<span class="sourceLineNo">1467</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1467"></a>
+<span class="sourceLineNo">1468</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1468"></a>
+<span class="sourceLineNo">1469</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1469"></a>
+<span class="sourceLineNo">1470</span>        if (rsn.getState() != State.OPEN) {<a name="line.1470"></a>
+<span class="sourceLineNo">1471</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1471"></a>
+<span class="sourceLineNo">1472</span>        }<a name="line.1472"></a>
+<span class="sourceLineNo">1473</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1473"></a>
+<span class="sourceLineNo">1474</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1474"></a>
+<span class="sourceLineNo">1475</span>        State state = rsn.getState();<a name="line.1475"></a>
+<span class="sourceLineNo">1476</span>        if (state != State.OPEN) {<a name="line.1476"></a>
+<span class="sourceLineNo">1477</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1477"></a>
+<span class="sourceLineNo">1478</span>        }<a name="line.1478"></a>
+<span class="sourceLineNo">1479</span>        if (sn == null) {<a name="line.1479"></a>
+<span class="sourceLineNo">1480</span>          ++unknownRegions; // Opened on null?<a name="line.1480"></a>
+<span class="sourceLineNo">1481</span>          continue;<a name="line.1481"></a>
+<span class="sourceLineNo">1482</span>        }<a name="line.1482"></a>
+<span class="sourceLineNo">1483</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1483"></a>
+<span class="sourceLineNo">1484</span>          continue;<a name="line.1484"></a>
+<span class="sourceLineNo">1485</span>        }<a name="line.1485"></a>
+<span class="sourceLineNo">1486</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1486"></a>
+<span class="sourceLineNo">1487</span>        switch (sls) {<a name="line.1487"></a>
+<span class="sourceLineNo">1488</span>          case LIVE:<a name="line.1488"></a>
+<span class="sourceLineNo">1489</span>            recentlyLiveServers.add(sn);<a name="line.1489"></a>
+<span class="sourceLineNo">1490</span>            break;<a name="line.1490"></a>
+<span class="sourceLineNo">1491</span>          case DEAD:<a name="line.1491"></a>
+<span class="sourceLineNo">1492</span>            ++deadRegions;<a name="line.1492"></a>
+<span class="sourceLineNo">1493</span>            break;<a name="line.1493"></a>
+<span class="sourceLineNo">1494</span>          case UNKNOWN:<a name="line.1494"></a>
+<span class="sourceLineNo">1495</span>            ++unknownRegions;<a name="line.1495"></a>
+<span class="sourceLineNo">1496</span>            break;<a name="line.1496"></a>
+<span class="sourceLineNo">1497</span>          default:<a name="line.1497"></a>
+<span class="sourceLineNo">1498</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1498"></a>
+<span class="sourceLineNo">1499</span>        }<a name="line.1499"></a>
+<span class="sourceLineNo">1500</span>      }<a name="line.1500"></a>
+<span class="sourceLineNo">1501</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1501"></a>
+<span class="sourceLineNo">1502</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1502"></a>
+<span class="sourceLineNo">1503</span>          deadRegions, unknownRegions);<a name="line.1503"></a>
+<span class="sourceLineNo">1504</span>      }<a name="line.1504"></a>
+<span class="sourceLineNo">1505</span><a name="line.1505"></a>
+<span class="sourceLineNo">1506</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1506"></a>
+<span class="sourceLineNo">1507</span>    }<a name="line.1507"></a>
+<span class="sourceLineNo">1508</span>  }<a name="line.1508"></a>
+<span class="sourceLineNo">1509</span><a name="line.1509"></a>
+<span class="sourceLineNo">1510</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1510"></a>
+<span class="sourceLineNo">1511</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1511"></a>
+<span class="sourceLineNo">1512</span>    rit.update(this);<a name="line.1512"></a>
+<span class="sourceLineNo">1513</span>    return rit;<a name="line.1513"></a>
+<span class="sourceLineNo">1514</span>  }<a name="line.1514"></a>
+<span class="sourceLineNo">1515</span><a name="line.1515"></a>
+<span class="sourceLineNo">1516</span>  public static class RegionInTransitionStat {<a name="line.1516"></a>
+<span class="sourceLineNo">1517</span>    private final int ritThreshold;<a name="line.1517"></a>
+<span class="sourceLineNo">1518</span><a name="line.1518"></a>
+<span class="sourceLineNo">1519</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1519"></a>
+<span class="sourceLineNo">1520</span>    private long statTimestamp;<a name="line.1520"></a>
+<span class="sourceLineNo">1521</span>    private long oldestRITTime = 0;<a name="line.1521"></a>
+<span class="sourceLineNo">1522</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1522"></a>
+<span class="sourceLineNo">1523</span>    private int totalRITs = 0;<a name="line.1523"></a>
+<span class="sourceLineNo">1524</span><a name="line.1524"></a>
+<span class="sourceLineNo">1525</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1525"></a>
+<span class="sourceLineNo">1526</span>      this.ritThreshold =<a name="line.1526"></a>
+<span class="sourceLineNo">1527</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1527"></a>
+<span class="sourceLineNo">1528</span>    }<a name="line.1528"></a>
+<span class="sourceLineNo">1529</span><a name="line.1529"></a>
+<span class="sourceLineNo">1530</span>    public int getRITThreshold() {<a name="line.1530"></a>
+<span class="sourceLineNo">1531</span>      return ritThreshold;<a name="line.1531"></a>
+<span class="sourceLineNo">1532</span>    }<a name="line.1532"></a>
+<span class="sourceLineNo">1533</span><a name="line.1533"></a>
+<span class="sourceLineNo">1534</span>    public long getTimestamp() {<a name="line.1534"></a>
+<span class="sourceLineNo">1535</span>      return statTimestamp;<a name="line.1535"></a>
+<span class="sourceLineNo">1536</span>    }<a name="line.1536"></a>
+<span class="sourceLineNo">1537</span><a name="line.1537"></a>
+<span class="sourceLineNo">1538</span>    public int getTotalRITs() {<a name="line.1538"></a>
+<span class="sourceLineNo">1539</span>      return totalRITs;<a name="line.1539"></a>
+<span class="sourceLineNo">1540</span>    }<a name="line.1540"></a>
+<span class="sourceLineNo">1541</span><a name="line.1541"></a>
+<span class="sourceLineNo">1542</span>    public long getOldestRITTime() {<a name="line.1542"></a>
+<span class="sourceLineNo">1543</span>      return oldestRITTime;<a name="line.1543"></a>
+<span class="sourceLineNo">1544</span>    }<a name="line.1544"></a>
+<span class="sourceLineNo">1545</span><a name="line.1545"></a>
+<span class="sourceLineNo">1546</span>    public int getTotalRITsOverThreshold() {<a name="line.1546"></a>
+<span class="sourceLineNo">1547</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1547"></a>
+<span class="sourceLineNo">1548</span>      return m != null ? m.size() : 0;<a name="line.1548"></a>
+<span class="sourceLineNo">1549</span>    }<a name="line.1549"></a>
+<span class="sourceLineNo">1550</span><a name="line.1550"></a>
+<span class="sourceLineNo">1551</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1551"></a>
+<span class="sourceLineNo">1552</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1552"></a>
+<span class="sourceLineNo">1553</span>    }<a name="line.1553"></a>
+<span class="sourceLineNo">1554</span><a name="line.1554"></a>
+<span class="sourceLineNo">1555</span>    public boolean hasRegionsOverThreshold() {<a name="line.1555"></a>
+<span class="sourceLineNo">1556</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1556"></a>
+<span class="sourceLineNo">1557</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1557"></a>
+<span class="sourceLineNo">1558</span>    }<a name="line.1558"></a>
+<span class="sourceLineNo">1559</span><a name="line.1559"></a>
+<span class="sourceLineNo">1560</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1560"></a>
+<span class="sourceLineNo">1561</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1561"></a>
+<span class="sourceLineNo">1562</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1562"></a>
+<span class="sourceLineNo">1563</span>    }<a name="line.1563"></a>
+<span class="sourceLineNo">1564</span><a name="line.1564"></a>
+<span class="sourceLineNo">1565</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1565"></a>
+<span class="sourceLineNo">1566</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1566"></a>
+<span class="sourceLineNo">1567</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1567"></a>
+<span class="sourceLineNo">1568</span>    }<a name="line.1568"></a>
+<span class="sourceLineNo">1569</span><a name="line.1569"></a>
+<span class="sourceLineNo">1570</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1570"></a>
+<span class="sourceLineNo">1571</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1571"></a>
+<span class="sourceLineNo">1572</span>      if (m == null) {<a name="line.1572"></a>
+<span class="sourceLineNo">1573</span>        return false;<a name="line.1573"></a>
+<span class="sourceLineNo">1574</span>      }<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>      if (state == null) {<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>        return false;<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>      }<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>    }<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span><a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>    protected void update(final AssignmentManager am) {<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span><a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span>        LOG.debug("RITs over threshold: {}",<a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>          ritsOverThreshold.entrySet().stream()<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>            .collect(Collectors.joining("\n")));<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>      }<a name="line.1593"></a>
+<span class="sourceLineNo">1594</span>    }<a name="line.1594"></a>
+<span class="sourceLineNo">1595</span><a name="line.1595"></a>
+<span class="sourceLineNo">1596</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1596"></a>
+<span class="sourceLineNo">1597</span>      for (RegionState state : regions) {<a name="line.1597"></a>
+<span class="sourceLineNo">1598</span>        totalRITs++;<a name="line.1598"></a>
+<span class="sourceLineNo">1599</span>        final long ritStartedMs = state.getStamp();<a name="line.1599"></a>
+<span class="sourceLineNo">1600</span>        if (ritStartedMs == 0) {<a name="line.1600"></a>
+<span class="sourceLineNo">1601</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1601"></a>
+<span class="sourceLineNo">1602</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1602"></a>
+<span class="sourceLineNo">1603</span>          continue;<a name="line.1603"></a>
+<span class="sourceLineNo">1604</span>        }<a name="line.1604"></a>
+<span class="sourceLineNo">1605</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1605"></a>
+<span class="sourceLineNo">1606</span>        if (ritTime &gt; ritThreshold) {<a name="line.1606"></a>
+<span class="sourceLineNo">1607</span>          if (ritsOverThreshold == null) {<a name="line.1607"></a>
+<span class="sourceLineNo">1608</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1608"></a>
+<span class="sourceLineNo">1609</span>          }<a name="line.1609"></a>
+<span class="sourceLineNo">1610</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1610"></a>
+<span class="sourceLineNo">1611</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1611"></a>
+<span class="sourceLineNo">1612</span>        }<a name="line.1612"></a>
+<span class="sourceLineNo">1613</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1613"></a>
+<span class="sourceLineNo">1614</span>          oldestRITTime = ritTime;<a name="line.1614"></a>
+<span class="sourceLineNo">1615</span>        }<a name="line.1615"></a>
+<span class="sourceLineNo">1616</span>      }<a name="line.1616"></a>
+<span class="sourceLineNo">1617</span>    }<a name="line.1617"></a>
+<span class="sourceLineNo">1618</span>  }<a name="line.1618"></a>
+<span class="sourceLineNo">1619</span><a name="line.1619"></a>
+<span class="sourceLineNo">1620</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1620"></a>
+<span class="sourceLineNo">1621</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1621"></a>
+<span class="sourceLineNo">1622</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1622"></a>
+<span class="sourceLineNo">1623</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1623"></a>
+<span class="sourceLineNo">1624</span>  }<a name="line.1624"></a>
+<span class="sourceLineNo">1625</span><a name="line.1625"></a>
+<span class="sourceLineNo">1626</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1626"></a>
+<span class="sourceLineNo">1627</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1627"></a>
+<span class="sourceLineNo">1628</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1628"></a>
+<span class="sourceLineNo">1629</span>  }<a name="line.1629"></a>
+<span class="sourceLineNo">1630</span><a name="line.1630"></a>
+<span class="sourceLineNo">1631</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1631"></a>
+<span class="sourceLineNo">1632</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1632"></a>
+<span class="sourceLineNo">1633</span>    // if (regionNode.isStuck()) {<a name="line.1633"></a>
+<span class="sourceLineNo">1634</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1634"></a>
+<span class="sourceLineNo">1635</span>  }<a name="line.1635"></a>
+<span class="sourceLineNo">1636</span><a name="line.1636"></a>
+<span class="sourceLineNo">1637</span>  // ============================================================================================<a name="line.1637"></a>
+<span class="sourceLineNo">1638</span>  // TODO: Master load/bootstrap<a name="line.1638"></a>
 <span class="sourceLineNo">1639</span>  // ============================================================================================<a name="line.1639"></a>
-<span class="sourceLineNo">1640</span>  // TODO: Master load/bootstrap<a name="line.1640"></a>
-<span class="sourceLineNo">1641</span>  // ============================================================================================<a name="line.1641"></a>
-<span class="sourceLineNo">1642</span>  public void joinCluster() throws IOException {<a name="line.1642"></a>
-<span class="sourceLineNo">1643</span>    long startTime = System.nanoTime();<a name="line.1643"></a>
-<span class="sourceLineNo">1644</span>    LOG.debug("Joining cluster...");<a name="line.1644"></a>
-<span class="sourceLineNo">1645</span><a name="line.1645"></a>
-<span class="sourceLineNo">1646</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1646"></a>
-<span class="sourceLineNo">1647</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1647"></a>
-<span class="sourceLineNo">1648</span>    // w/o meta.<a name="line.1648"></a>
-<span class="sourceLineNo">1649</span>    loadMeta();<a name="line.1649"></a>
-<span class="sourceLineNo">1650</span><a name="line.1650"></a>
-<span class="sourceLineNo">1651</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1651"></a>
-<span class="sourceLineNo">1652</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1652"></a>
-<span class="sourceLineNo">1653</span>        master.getServerManager().countOfRegionServers());<a name="line.1653"></a>
-<span class="sourceLineNo">1654</span>      Threads.sleep(250);<a name="line.1654"></a>
-<span class="sourceLineNo">1655</span>    }<a name="line.1655"></a>
-<span class="sourceLineNo">1656</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1656"></a>
-<span class="sourceLineNo">1657</span><a name="line.1657"></a>
-<span class="sourceLineNo">1658</span>    // Start the chores<a name="line.1658"></a>
-<span class="sourceLineNo">1659</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1659"></a>
-<span class="sourceLineNo">1660</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1660"></a>
-<span class="sourceLineNo">1661</span><a name="line.1661"></a>
-<span class="sourceLineNo">1662</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1662"></a>
-<span class="sourceLineNo">1663</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1663"></a>
-<span class="sourceLineNo">1664</span>  }<a name="line.1664"></a>
-<span class="sourceLineNo">1665</span><a name="line.1665"></a>
-<span class="sourceLineNo">1666</span>  /**<a name="line.1666"></a>
-<span class="sourceLineNo">1667</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1667"></a>
-<span class="sourceLineNo">1668</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1668"></a>
-<span class="sourceLineNo">1669</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1669"></a>
-<span class="sourceLineNo">1670</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1670"></a>
-<span class="sourceLineNo">1671</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1671"></a>
-<span class="sourceLineNo">1672</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1672"></a>
-<span class="sourceLineNo">1673</span>   * method any more. Need to revisit later.<a name="line.1673"></a>
-<span class="sourceLineNo">1674</span>   */<a name="line.1674"></a>
-<span class="sourceLineNo">1675</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1675"></a>
-<span class="sourceLineNo">1676</span>  // Needs to be done after the table state manager has been started.<a name="line.1676"></a>
-<span class="sourceLineNo">1677</span>  public void processOfflineRegions() {<a name="line.1677"></a>
-<span class="sourceLineNo">1678</span>    TransitRegionStateProcedure[] procs =<a name="line.1678"></a>
-<span class="sourceLineNo">1679</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1679"></a>
-<span class="sourceLineNo">1680</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1680"></a>
-<span class="sourceLineNo">1681</span>          rsn.lock();<a name="line.1681"></a>
-<span class="sourceLineNo">1682</span>          try {<a name="line.1682"></a>
-<span class="sourceLineNo">1683</span>            if (rsn.getProcedure() != null) {<a name="line.1683"></a>
-<span class="sourceLineNo">1684</span>              return null;<a name="line.1684"></a>
-<span class="sourceLineNo">1685</span>            } else {<a name="line.1685"></a>
-<span class="sourceLineNo">1686</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1686"></a>
-<span class="sourceLineNo">1687</span>                rsn.getRegionInfo(), null));<a name="line.1687"></a>
-<span class="sourceLineNo">1688</span>            }<a name="line.1688"></a>
-<span class="sourceLineNo">1689</span>          } finally {<a name="line.1689"></a>
-<span class="sourceLineNo">1690</span>            rsn.unlock();<a name="line.1690"></a>
-<span class="sourceLineNo">1691</span>          }<a name="line.1691"></a>
-<span class="sourceLineNo">1692</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1692"></a>
-<span class="sourceLineNo">1693</span>    if (procs.length &gt; 0) {<a name="line.1693"></a>
-<span class="sourceLineNo">1694</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1694"></a>
-<span class="sourceLineNo">1695</span>    }<a name="line.1695"></a>
-<span class="sourceLineNo">1696</span>  }<a name="line.1696"></a>
-<span class="sourceLineNo">1697</span><a name="line.1697"></a>
-<span class="sourceLineNo">1698</span>  /*<a name="line.1698"></a>
-<span class="sourceLineNo">1699</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1699"></a>
-<span class="sourceLineNo">1700</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1700"></a>
-<span class="sourceLineNo">1701</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1701"></a>
-<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1702"></a>
-<span class="sourceLineNo">1703</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1703"></a>
-<span class="sourceLineNo">1704</span>   * AssignmentManager.regionStates.<a name="line.1704"></a>
-<span class="sourceLineNo">1705</span>   */<a name="line.1705"></a>
-<span class="sourceLineNo">1706</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1706"></a>
-<span class="sourceLineNo">1707</span><a name="line.1707"></a>
-<span class="sourceLineNo">1708</span>    @Override<a name="line.1708"></a>
-<span class="sourceLineNo">1709</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1709"></a>
-<span class="sourceLineNo">1710</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1710"></a>
-<span class="sourceLineNo">1711</span>      if (<a name="line.1711"></a>
-<span class="sourceLineNo">1712</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1712"></a>
-<span class="sourceLineNo">1713</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1713"></a>
-<span class="sourceLineNo">1714</span>      ) {<a name="line.1714"></a>
-<span class="sourceLineNo">1715</span>        // This is a row with nothing in it.<a name="line.1715"></a>
-<span class="sourceLineNo">1716</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1716"></a>
-<span class="sourceLineNo">1717</span>        return;<a name="line.1717"></a>
-<span class="sourceLineNo">1718</span>      }<a name="line.1718"></a>
-<span class="sourceLineNo">1719</span>      State localState = state;<a name="line.1719"></a>
-<span class="sourceLineNo">1720</span>      if (localState == null) {<a name="line.1720"></a>
-<span class="sourceLineNo">1721</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1721"></a>
-<span class="sourceLineNo">1722</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1722"></a>
-<span class="sourceLineNo">1723</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1723"></a>
-<span class="sourceLineNo">1724</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1724"></a>
-<span class="sourceLineNo">1725</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1725"></a>
-<span class="sourceLineNo">1726</span>        localState = State.OFFLINE;<a name="line.1726"></a>
-<span class="sourceLineNo">1727</span>      }<a name="line.1727"></a>
-<span class="sourceLineNo">1728</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1728"></a>
-<span class="sourceLineNo">1729</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1729"></a>
-<span class="sourceLineNo">1730</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1730"></a>
-<span class="sourceLineNo">1731</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1731"></a>
-<span class="sourceLineNo">1732</span>      regionNode.setState(localState);<a name="line.1732"></a>
-<span class="sourceLineNo">1733</span>      regionNode.setLastHost(lastHost);<a name="line.1733"></a>
-<span class="sourceLineNo">1734</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1734"></a>
-<span class="sourceLineNo">1735</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1735"></a>
-<span class="sourceLineNo">1736</span><a name="line.1736"></a>
-<span class="sourceLineNo">1737</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1737"></a>
-<span class="sourceLineNo">1738</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1738"></a>
-<span class="sourceLineNo">1739</span>      if (<a name="line.1739"></a>
-<span class="sourceLineNo">1740</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1740"></a>
-<span class="sourceLineNo">1741</span>      ) {<a name="line.1741"></a>
-<span class="sourceLineNo">1742</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1742"></a>
-<span class="sourceLineNo">1743</span>        regionStates.addRegionToServer(regionNode);<a name="line.1743"></a>
-<span class="sourceLineNo">1744</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1744"></a>
-<span class="sourceLineNo">1745</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1745"></a>
-<span class="sourceLineNo">1746</span>      }<a name="line.1746"></a>
-<span class="sourceLineNo">1747</span>      if (regionNode.getProcedure() != null) {<a name="line.1747"></a>
-<span class="sourceLineNo">1748</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1748"></a>
-<span class="sourceLineNo">1749</span>      }<a name="line.1749"></a>
-<span class="sourceLineNo">1750</span>    }<a name="line.1750"></a>
-<span class="sourceLineNo">1751</span>  };<a name="line.1751"></a>
-<span class="sourceLineNo">1752</span><a name="line.1752"></a>
-<span class="sourceLineNo">1753</span>  /**<a name="line.1753"></a>
-<span class="sourceLineNo">1754</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1754"></a>
-<span class="sourceLineNo">1755</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1755"></a>
-<span class="sourceLineNo">1756</span>   * @param regionInfo the region to be loaded from META.<a name="line.1756"></a>
-<span class="sourceLineNo">1757</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1757"></a>
-<span class="sourceLineNo">1758</span>   */<a name="line.1758"></a>
-<span class="sourceLineNo">1759</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1759"></a>
-<span class="sourceLineNo">1760</span>    throws IOException {<a name="line.1760"></a>
-<span class="sourceLineNo">1761</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1761"></a>
-<span class="sourceLineNo">1762</span>      ? regionInfo.getEncodedName()<a name="line.1762"></a>
-<span class="sourceLineNo">1763</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1763"></a>
-<span class="sourceLineNo">1764</span>        .getEncodedName();<a name="line.1764"></a>
-<span class="sourceLineNo">1765</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1765"></a>
-<span class="sourceLineNo">1766</span>  }<a name="line.1766"></a>
-<span class="sourceLineNo">1767</span><a name="line.1767"></a>
-<span class="sourceLineNo">1768</span>  /**<a name="line.1768"></a>
-<span class="sourceLineNo">1769</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1769"></a>
-<span class="sourceLineNo">1770</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1770"></a>
-<span class="sourceLineNo">1771</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1771"></a>
-<span class="sourceLineNo">1772</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1772"></a>
-<span class="sourceLineNo">1773</span>   */<a name="line.1773"></a>
-<span class="sourceLineNo">1774</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1774"></a>
-<span class="sourceLineNo">1775</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1775"></a>
-<span class="sourceLineNo">1776</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1776"></a>
-<span class="sourceLineNo">1777</span>  }<a name="line.1777"></a>
-<span class="sourceLineNo">1778</span><a name="line.1778"></a>
-<span class="sourceLineNo">1779</span>  private void loadMeta() throws IOException {<a name="line.1779"></a>
-<span class="sourceLineNo">1780</span>    // TODO: use a thread pool<a name="line.1780"></a>
-<span class="sourceLineNo">1781</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1781"></a>
-<span class="sourceLineNo">1782</span>  }<a name="line.1782"></a>
-<span class="sourceLineNo">1783</span><a name="line.1783"></a>
-<span class="sourceLineNo">1784</span>  /**<a name="line.1784"></a>
-<span class="sourceLineNo">1785</span>   * Used to check if the meta loading is done.<a name="line.1785"></a>
-<span class="sourceLineNo">1786</span>   * &lt;p/&gt;<a name="line.1786"></a>
-<span class="sourceLineNo">1787</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1787"></a>
-<span class="sourceLineNo">1788</span>   * @param hri region to check if it is already rebuild<a name="line.1788"></a>
-<span class="sourceLineNo">1789</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1789"></a>
-<span class="sourceLineNo">1790</span>   */<a name="line.1790"></a>
-<span class="sourceLineNo">1791</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1791"></a>
-<span class="sourceLineNo">1792</span>    if (!isRunning()) {<a name="line.1792"></a>
-<span class="sourceLineNo">1793</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1793"></a>
-<span class="sourceLineNo">1794</span>    }<a name="line.1794"></a>
-<span class="sourceLineNo">1795</span>    boolean meta = isMetaRegion(hri);<a name="line.1795"></a>
-<span class="sourceLineNo">1796</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1796"></a>
-<span class="sourceLineNo">1797</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1797"></a>
-<span class="sourceLineNo">1798</span>      throw new PleaseHoldException(<a name="line.1798"></a>
-<span class="sourceLineNo">1799</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1799"></a>
-<span class="sourceLineNo">1800</span>    }<a name="line.1800"></a>
-<span class="sourceLineNo">1801</span>  }<a name="line.1801"></a>
-<span class="sourceLineNo">1802</span><a name="line.1802"></a>
+<span class="sourceLineNo">1640</span>  public void joinCluster() throws IOException {<a name="line.1640"></a>
+<span class="sourceLineNo">1641</span>    long startTime = System.nanoTime();<a name="line.1641"></a>
+<span class="sourceLineNo">1642</span>    LOG.debug("Joining cluster...");<a name="line.1642"></a>
+<span class="sourceLineNo">1643</span><a name="line.1643"></a>
+<span class="sourceLineNo">1644</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1644"></a>
+<span class="sourceLineNo">1645</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1645"></a>
+<span class="sourceLineNo">1646</span>    // w/o meta.<a name="line.1646"></a>
+<span class="sourceLineNo">1647</span>    loadMeta();<a name="line.1647"></a>
+<span class="sourceLineNo">1648</span><a name="line.1648"></a>
+<span class="sourceLineNo">1649</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1649"></a>
+<span class="sourceLineNo">1650</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1650"></a>
+<span class="sourceLineNo">1651</span>        master.getServerManager().countOfRegionServers());<a name="line.1651"></a>
+<span class="sourceLineNo">1652</span>      Threads.sleep(250);<a name="line.1652"></a>
+<span class="sourceLineNo">1653</span>    }<a name="line.1653"></a>
+<span class="sourceLineNo">1654</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1654"></a>
+<span class="sourceLineNo">1655</span><a name="line.1655"></a>
+<span class="sourceLineNo">1656</span>    // Start the chores<a name="line.1656"></a>
+<span class="sourceLineNo">1657</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1657"></a>
+<span class="sourceLineNo">1658</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1658"></a>
+<span class="sourceLineNo">1659</span><a name="line.1659"></a>
+<span class="sourceLineNo">1660</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1660"></a>
+<span class="sourceLineNo">1661</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1661"></a>
+<span class="sourceLineNo">1662</span>  }<a name="line.1662"></a>
+<span class="sourceLineNo">1663</span><a name="line.1663"></a>
+<span class="sourceLineNo">1664</span>  /**<a name="line.1664"></a>
+<span class="sourceLineNo">1665</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1665"></a>
+<span class="sourceLineNo">1666</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1666"></a>
+<span class="sourceLineNo">1667</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1667"></a>
+<span class="sourceLineNo">1668</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1668"></a>
+<span class="sourceLineNo">1669</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1669"></a>
+<span class="sourceLineNo">1670</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1670"></a>
+<span class="sourceLineNo">1671</span>   * method any more. Need to revisit later.<a name="line.1671"></a>
+<span class="sourceLineNo">1672</span>   */<a name="line.1672"></a>
+<span class="sourceLineNo">1673</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1673"></a>
+<span class="sourceLineNo">1674</span>  // Needs to be done after the table state manager has been started.<a name="line.1674"></a>
+<span class="sourceLineNo">1675</span>  public void processOfflineRegions() {<a name="line.1675"></a>
+<span class="sourceLineNo">1676</span>    TransitRegionStateProcedure[] procs =<a name="line.1676"></a>
+<span class="sourceLineNo">1677</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1677"></a>
+<span class="sourceLineNo">1678</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1678"></a>
+<span class="sourceLineNo">1679</span>          rsn.lock();<a name="line.1679"></a>
+<span class="sourceLineNo">1680</span>          try {<a name="line.1680"></a>
+<span class="sourceLineNo">1681</span>            if (rsn.getProcedure() != null) {<a name="line.1681"></a>
+<span class="sourceLineNo">1682</span>              return null;<a name="line.1682"></a>
+<span class="sourceLineNo">1683</span>            } else {<a name="line.1683"></a>
+<span class="sourceLineNo">1684</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1684"></a>
+<span class="sourceLineNo">1685</span>                rsn.getRegionInfo(), null));<a name="line.1685"></a>
+<span class="sourceLineNo">1686</span>            }<a name="line.1686"></a>
+<span class="sourceLineNo">1687</span>          } finally {<a name="line.1687"></a>
+<span class="sourceLineNo">1688</span>            rsn.unlock();<a name="line.1688"></a>
+<span class="sourceLineNo">1689</span>          }<a name="line.1689"></a>
+<span class="sourceLineNo">1690</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1690"></a>
+<span class="sourceLineNo">1691</span>    if (procs.length &gt; 0) {<a name="line.1691"></a>
+<span class="sourceLineNo">1692</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1692"></a>
+<span class="sourceLineNo">1693</span>    }<a name="line.1693"></a>
+<span class="sourceLineNo">1694</span>  }<a name="line.1694"></a>
+<span class="sourceLineNo">1695</span><a name="line.1695"></a>
+<span class="sourceLineNo">1696</span>  /*<a name="line.1696"></a>
+<span class="sourceLineNo">1697</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1697"></a>
+<span class="sourceLineNo">1698</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1698"></a>
+<span class="sourceLineNo">1699</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1699"></a>
+<span class="sourceLineNo">1700</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1700"></a>
+<span class="sourceLineNo">1701</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1701"></a>
+<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates.<a name="line.1702"></a>
+<span class="sourceLineNo">1703</span>   */<a name="line.1703"></a>
+<span class="sourceLineNo">1704</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1704"></a>
+<span class="sourceLineNo">1705</span><a name="line.1705"></a>
+<span class="sourceLineNo">1706</span>    @Override<a name="line.1706"></a>
+<span class="sourceLineNo">1707</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1707"></a>
+<span class="sourceLineNo">1708</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1708"></a>
+<span class="sourceLineNo">1709</span>      if (<a name="line.1709"></a>
+<span class="sourceLineNo">1710</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1710"></a>
+<span class="sourceLineNo">1711</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1711"></a>
+<span class="sourceLineNo">1712</span>      ) {<a name="line.1712"></a>
+<span class="sourceLineNo">1713</span>        // This is a row with nothing in it.<a name="line.1713"></a>
+<span class="sourceLineNo">1714</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1714"></a>
+<span class="sourceLineNo">1715</span>        return;<a name="line.1715"></a>
+<span class="sourceLineNo">1716</span>      }<a name="line.1716"></a>
+<span class="sourceLineNo">1717</span>      State localState = state;<a name="line.1717"></a>
+<span class="sourceLineNo">1718</span>      if (localState == null) {<a name="line.1718"></a>
+<span class="sourceLineNo">1719</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1719"></a>
+<span class="sourceLineNo">1720</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1720"></a>
+<span class="sourceLineNo">1721</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1721"></a>
+<span class="sourceLineNo">1722</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1722"></a>
+<span class="sourceLineNo">1723</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1723"></a>
+<span class="sourceLineNo">1724</span>        localState = State.OFFLINE;<a name="line.1724"></a>
+<span class="sourceLineNo">1725</span>      }<a name="line.1725"></a>
+<span class="sourceLineNo">1726</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1726"></a>
+<span class="sourceLineNo">1727</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1727"></a>
+<span class="sourceLineNo">1728</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1728"></a>
+<span class="sourceLineNo">1729</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1729"></a>
+<span class="sourceLineNo">1730</span>      regionNode.setState(localState);<a name="line.1730"></a>
+<span class="sourceLineNo">1731</span>      regionNode.setLastHost(lastHost);<a name="line.1731"></a>
+<span class="sourceLineNo">1732</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1732"></a>
+<span class="sourceLineNo">1733</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1733"></a>
+<span class="sourceLineNo">1734</span><a name="line.1734"></a>
+<span class="sourceLineNo">1735</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1735"></a>
+<span class="sourceLineNo">1736</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1736"></a>
+<span class="sourceLineNo">1737</span>      if (<a name="line.1737"></a>
+<span class="sourceLineNo">1738</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1738"></a>
+<span class="sourceLineNo">1739</span>      ) {<a name="line.1739"></a>
+<span class="sourceLineNo">1740</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1740"></a>
+<span class="sourceLineNo">1741</span>        regionStates.addRegionToServer(regionNode);<a name="line.1741"></a>
+<span class="sourceLineNo">1742</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1742"></a>
+<span class="sourceLineNo">1743</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1743"></a>
+<span class="sourceLineNo">1744</span>      }<a name="line.1744"></a>
+<span class="sourceLineNo">1745</span>      if (regionNode.getProcedure() != null) {<a name="line.1745"></a>
+<span class="sourceLineNo">1746</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1746"></a>
+<span class="sourceLineNo">1747</span>      }<a name="line.1747"></a>
+<span class="sourceLineNo">1748</span>    }<a name="line.1748"></a>
+<span class="sourceLineNo">1749</span>  };<a name="line.1749"></a>
+<span class="sourceLineNo">1750</span><a name="line.1750"></a>
+<span class="sourceLineNo">1751</span>  /**<a name="line.1751"></a>
+<span class="sourceLineNo">1752</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1752"></a>
+<span class="sourceLineNo">1753</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1753"></a>
+<span class="sourceLineNo">1754</span>   * @param regionInfo the region to be loaded from META.<a name="line.1754"></a>
+<span class="sourceLineNo">1755</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1755"></a>
+<span class="sourceLineNo">1756</span>   */<a name="line.1756"></a>
+<span class="sourceLineNo">1757</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1757"></a>
+<span class="sourceLineNo">1758</span>    throws IOException {<a name="line.1758"></a>
+<span class="sourceLineNo">1759</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1759"></a>
+<span class="sourceLineNo">1760</span>      ? regionInfo.getEncodedName()<a name="line.1760"></a>
+<span class="sourceLineNo">1761</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1761"></a>
+<span class="sourceLineNo">1762</span>        .getEncodedName();<a name="line.1762"></a>
+<span class="sourceLineNo">1763</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1763"></a>
+<span class="sourceLineNo">1764</span>  }<a name="line.1764"></a>
+<span class="sourceLineNo">1765</span><a name="line.1765"></a>
+<span class="sourceLineNo">1766</span>  /**<a name="line.1766"></a>
+<span class="sourceLineNo">1767</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1767"></a>
+<span class="sourceLineNo">1768</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1768"></a>
+<span class="sourceLineNo">1769</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1769"></a>
+<span class="sourceLineNo">1770</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1770"></a>
+<span class="sourceLineNo">1771</span>   */<a name="line.1771"></a>
+<span class="sourceLineNo">1772</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1772"></a>
+<span class="sourceLineNo">1773</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1773"></a>
+<span class="sourceLineNo">1774</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1774"></a>
+<span class="sourceLineNo">1775</span>  }<a name="line.1775"></a>
+<span class="sourceLineNo">1776</span><a name="line.1776"></a>
+<span class="sourceLineNo">1777</span>  private void loadMeta() throws IOException {<a name="line.1777"></a>
+<span class="sourceLineNo">1778</span>    // TODO: use a thread pool<a name="line.1778"></a>
+<span class="sourceLineNo">1779</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1779"></a>
+<span class="sourceLineNo">1780</span>  }<a name="line.1780"></a>
+<span class="sourceLineNo">1781</span><a name="line.1781"></a>
+<span class="sourceLineNo">1782</span>  /**<a name="line.1782"></a>
+<span class="sourceLineNo">1783</span>   * Used to check if the meta loading is done.<a name="line.1783"></a>
+<span class="sourceLineNo">1784</span>   * &lt;p/&gt;<a name="line.1784"></a>
+<span class="sourceLineNo">1785</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1785"></a>
+<span class="sourceLineNo">1786</span>   * @param hri region to check if it is already rebuild<a name="line.1786"></a>
+<span class="sourceLineNo">1787</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1787"></a>
+<span class="sourceLineNo">1788</span>   */<a name="line.1788"></a>
+<span class="sourceLineNo">1789</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1789"></a>
+<span class="sourceLineNo">1790</span>    if (!isRunning()) {<a name="line.1790"></a>
+<span class="sourceLineNo">1791</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1791"></a>
+<span class="sourceLineNo">1792</span>    }<a name="line.1792"></a>
+<span class="sourceLineNo">1793</span>    boolean meta = isMetaRegion(hri);<a name="line.1793"></a>
+<span class="sourceLineNo">1794</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1794"></a>
+<span class="sourceLineNo">1795</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1795"></a>
+<span class="sourceLineNo">1796</span>      throw new PleaseHoldException(<a name="line.1796"></a>
+<span class="sourceLineNo">1797</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1797"></a>
+<span class="sourceLineNo">1798</span>    }<a name="line.1798"></a>
+<span class="sourceLineNo">1799</span>  }<a name="line.1799"></a>
+<span class="sourceLineNo">1800</span><a name="line.1800"></a>
+<span class="sourceLineNo">1801</span>  // ============================================================================================<a name="line.1801"></a>
+<span class="sourceLineNo">1802</span>  // TODO: Metrics<a name="line.1802"></a>
 <span class="sourceLineNo">1803</span>  // ============================================================================================<a name="line.1803"></a>
-<span class="sourceLineNo">1804</span>  // TODO: Metrics<a name="line.1804"></a>
-<span class="sourceLineNo">1805</span>  // ============================================================================================<a name="line.1805"></a>
-<span class="sourceLineNo">1806</span>  public int getNumRegionsOpened() {<a name="line.1806"></a>
-<span class="sourceLineNo">1807</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1807"></a>
-<span class="sourceLineNo">1808</span>    return 0;<a name="line.1808"></a>
-<span class="sourceLineNo">1809</span>  }<a name="line.1809"></a>
-<span class="sourceLineNo">1810</span><a name="line.1810"></a>
-<span class="sourceLineNo">1811</span>  /**<a name="line.1811"></a>
-<span class="sourceLineNo">1812</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1812"></a>
-<span class="sourceLineNo">1813</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1813"></a>
-<span class="sourceLineNo">1814</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1814"></a>
-<span class="sourceLineNo">1815</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1815"></a>
-<span class="sourceLineNo">1816</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1816"></a>
-<span class="sourceLineNo">1817</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1817"></a>
-<span class="sourceLineNo">1818</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1818"></a>
-<span class="sourceLineNo">1819</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1819"></a>
-<span class="sourceLineNo">1820</span>   */<a name="line.1820"></a>
-<span class="sourceLineNo">1821</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1821"></a>
-<span class="sourceLineNo">1822</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1822"></a>
-<span class="sourceLineNo">1823</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1823"></a>
-<span class="sourceLineNo">1824</span>    // Remove the in-memory rsReports result<a name="line.1824"></a>
-<span class="sourceLineNo">1825</span>    synchronized (rsReports) {<a name="line.1825"></a>
-<span class="sourceLineNo">1826</span>      rsReports.remove(serverName);<a name="line.1826"></a>
-<span class="sourceLineNo">1827</span>    }<a name="line.1827"></a>
-<span class="sourceLineNo">1828</span><a name="line.1828"></a>
-<span class="sourceLineNo">1829</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1829"></a>
-<span class="sourceLineNo">1830</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1830"></a>
-<span class="sourceLineNo">1831</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1831"></a>
-<span class="sourceLineNo">1832</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1832"></a>
-<span class="sourceLineNo">1833</span>    if (serverNode != null) {<a name="line.1833"></a>
-<span class="sourceLineNo">1834</span>      serverNode.writeLock().lock();<a name="line.1834"></a>
-<span class="sourceLineNo">1835</span>    }<a name="line.1835"></a>
-<span class="sourceLineNo">1836</span>    boolean carryingMeta;<a name="line.1836"></a>
-<span class="sourceLineNo">1837</span>    long pid;<a name="line.1837"></a>
-<span class="sourceLineNo">1838</span>    try {<a name="line.1838"></a>
-<span class="sourceLineNo">1839</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1839"></a>
-<span class="sourceLineNo">1840</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1840"></a>
-<span class="sourceLineNo">1841</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1841"></a>
-<span class="sourceLineNo">1842</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1842"></a>
-<span class="sourceLineNo">1843</span>          carryingMeta);<a name="line.1843"></a>
-<span class="sourceLineNo">1844</span>        return Procedure.NO_PROC_ID;<a name="line.1844"></a>
-<span class="sourceLineNo">1845</span>      } else {<a name="line.1845"></a>
-<span class="sourceLineNo">1846</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1846"></a>
-<span class="sourceLineNo">1847</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1847"></a>
-<span class="sourceLineNo">1848</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1848"></a>
-<span class="sourceLineNo">1849</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1849"></a>
-<span class="sourceLineNo">1850</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1850"></a>
-<span class="sourceLineNo">1851</span>        ServerState oldState = null;<a name="line.1851"></a>
-<span class="sourceLineNo">1852</span>        if (serverNode != null) {<a name="line.1852"></a>
-<span class="sourceLineNo">1853</span>          oldState = serverNode.getState();<a name="line.1853"></a>
-<span class="sourceLineNo">1854</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1854"></a>
-<span class="sourceLineNo">1855</span>        }<a name="line.1855"></a>
-<span class="sourceLineNo">1856</span><a name="line.1856"></a>
-<span class="sourceLineNo">1857</span>        if (force) {<a name="line.1857"></a>
-<span class="sourceLineNo">1858</span>          pid = procExec.submitProcedure(<a name="line.1858"></a>
-<span class="sourceLineNo">1859</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1859"></a>
-<span class="sourceLineNo">1860</span>        } else {<a name="line.1860"></a>
-<span class="sourceLineNo">1861</span>          pid = procExec.submitProcedure(<a name="line.1861"></a>
-<span class="sourceLineNo">1862</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1862"></a>
-<span class="sourceLineNo">1863</span>        }<a name="line.1863"></a>
-<span class="sourceLineNo">1864</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1864"></a>
-<span class="sourceLineNo">1865</span>          serverName, carryingMeta,<a name="line.1865"></a>
-<span class="sourceLineNo">1866</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1866"></a>
-<span class="sourceLineNo">1867</span>      }<a name="line.1867"></a>
-<span class="sourceLineNo">1868</span>    } finally {<a name="line.1868"></a>
-<span class="sourceLineNo">1869</span>      if (serverNode != null) {<a name="line.1869"></a>
-<span class="sourceLineNo">1870</span>        serverNode.writeLock().unlock();<a name="line.1870"></a>
-<span class="sourceLineNo">1871</span>      }<a name="line.1871"></a>
-<span class="sourceLineNo">1872</span>    }<a name="line.1872"></a>
-<span class="sourceLineNo">1873</span>    return pid;<a name="line.1873"></a>
-<span class="sourceLineNo">1874</span>  }<a name="line.1874"></a>
-<span class="sourceLineNo">1875</span><a name="line.1875"></a>
-<span class="sourceLineNo">1876</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1876"></a>
-<span class="sourceLineNo">1877</span>    // TODO used by MasterRpcServices<a name="line.1877"></a>
-<span class="sourceLineNo">1878</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1878"></a>
-<span class="sourceLineNo">1879</span>    if (node != null) {<a name="line.1879"></a>
-<span class="sourceLineNo">1880</span>      node.offline();<a name="line.1880"></a>
-<span class="sourceLineNo">1881</span>    }<a name="line.1881"></a>
-<span class="sourceLineNo">1882</span>  }<a name="line.1882"></a>
-<span class="sourceLineNo">1883</span><a name="line.1883"></a>
-<span class="sourceLineNo">1884</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1884"></a>
-<span class="sourceLineNo">1885</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1885"></a>
-<span class="sourceLineNo">1886</span>  }<a name="line.1886"></a>
-<span class="sourceLineNo">1887</span><a name="line.1887"></a>
-<span class="sourceLineNo">1888</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1888"></a>
-<span class="sourceLineNo">1889</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1889"></a>
-<span class="sourceLineNo">1890</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1890"></a>
-<span class="sourceLineNo">1891</span>  }<a name="line.1891"></a>
-<span class="sourceLineNo">1892</span><a name="line.1892"></a>
+<span class="sourceLineNo">1804</span>  public int getNumRegionsOpened() {<a name="line.1804"></a>
+<span class="sourceLineNo">1805</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1805"></a>
+<span class="sourceLineNo">1806</span>    return 0;<a name="line.1806"></a>
+<span class="sourceLineNo">1807</span>  }<a name="line.1807"></a>
+<span class="sourceLineNo">1808</span><a name="line.1808"></a>
+<span class="sourceLineNo">1809</span>  /**<a name="line.1809"></a>
+<span class="sourceLineNo">1810</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1810"></a>
+<span class="sourceLineNo">1811</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1811"></a>
+<span class="sourceLineNo">1812</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1812"></a>
+<span class="sourceLineNo">1813</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1813"></a>
+<span class="sourceLineNo">1814</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1814"></a>
+<span class="sourceLineNo">1815</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1815"></a>
+<span class="sourceLineNo">1816</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1816"></a>
+<span class="sourceLineNo">1817</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1817"></a>
+<span class="sourceLineNo">1818</span>   */<a name="line.1818"></a>
+<span class="sourceLineNo">1819</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1819"></a>
+<span class="sourceLineNo">1820</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1820"></a>
+<span class="sourceLineNo">1821</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1821"></a>
+<span class="sourceLineNo">1822</span>    // Remove the in-memory rsReports result<a name="line.1822"></a>
+<span class="sourceLineNo">1823</span>    synchronized (rsReports) {<a name="line.1823"></a>
+<span class="sourceLineNo">1824</span>      rsReports.remove(serverName);<a name="line.1824"></a>
+<span class="sourceLineNo">1825</span>    }<a name="line.1825"></a>
+<span class="sourceLineNo">1826</span><a name="line.1826"></a>
+<span class="sourceLineNo">1827</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1827"></a>
+<span class="sourceLineNo">1828</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1828"></a>
+<span class="sourceLineNo">1829</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1829"></a>
+<span class="sourceLineNo">1830</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1830"></a>
+<span class="sourceLineNo">1831</span>    if (serverNode != null) {<a name="line.1831"></a>
+<span class="sourceLineNo">1832</span>      serverNode.writeLock().lock();<a name="line.1832"></a>
+<span class="sourceLineNo">1833</span>    }<a name="line.1833"></a>
+<span class="sourceLineNo">1834</span>    boolean carryingMeta;<a name="line.1834"></a>
+<span class="sourceLineNo">1835</span>    long pid;<a name="line.1835"></a>
+<span class="sourceLineNo">1836</span>    try {<a name="line.1836"></a>
+<span class="sourceLineNo">1837</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1837"></a>
+<span class="sourceLineNo">1838</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1838"></a>
+<span class="sourceLineNo">1839</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1839"></a>
+<span class="sourceLineNo">1840</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1840"></a>
+<span class="sourceLineNo">1841</span>          carryingMeta);<a name="line.1841"></a>
+<span class="sourceLineNo">1842</span>        return Procedure.NO_PROC_ID;<a name="line.1842"></a>
+<span class="sourceLineNo">1843</span>      } else {<a name="line.1843"></a>
+<span class="sourceLineNo">1844</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1844"></a>
+<span class="sourceLineNo">1845</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1845"></a>
+<span class="sourceLineNo">1846</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1846"></a>
+<span class="sourceLineNo">1847</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1847"></a>
+<span class="sourceLineNo">1848</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1848"></a>
+<span class="sourceLineNo">1849</span>        ServerState oldState = null;<a name="line.1849"></a>
+<span class="sourceLineNo">1850</span>        if (serverNode != null) {<a name="line.1850"></a>
+<span class="sourceLineNo">1851</span>          oldState = serverNode.getState();<a name="line.1851"></a>
+<span class="sourceLineNo">1852</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1852"></a>
+<span class="sourceLineNo">1853</span>        }<a name="line.1853"></a>
+<span class="sourceLineNo">1854</span><a name="line.1854"></a>
+<span class="sourceLineNo">1855</span>        if (force) {<a name="line.1855"></a>
+<span class="sourceLineNo">1856</span>          pid = procExec.submitProcedure(<a name="line.1856"></a>
+<span class="sourceLineNo">1857</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1857"></a>
+<span class="sourceLineNo">1858</span>        } else {<a name="line.1858"></a>
+<span class="sourceLineNo">1859</span>          pid = procExec.submitProcedure(<a name="line.1859"></a>
+<span class="sourceLineNo">1860</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1860"></a>
+<span class="sourceLineNo">1861</span>        }<a name="line.1861"></a>
+<span class="sourceLineNo">1862</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1862"></a>
+<span class="sourceLineNo">1863</span>          serverName, carryingMeta,<a name="line.1863"></a>
+<span class="sourceLineNo">1864</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1864"></a>
+<span class="sourceLineNo">1865</span>      }<a name="line.1865"></a>
+<span class="sourceLineNo">1866</span>    } finally {<a name="line.1866"></a>
+<span class="sourceLineNo">1867</span>      if (serverNode != null) {<a name="line.1867"></a>
+<span class="sourceLineNo">1868</span>        serverNode.writeLock().unlock();<a name="line.1868"></a>
+<span class="sourceLineNo">1869</span>      }<a name="line.1869"></a>
+<span class="sourceLineNo">1870</span>    }<a name="line.1870"></a>
+<span class="sourceLineNo">1871</span>    return pid;<a name="line.1871"></a>
+<span class="sourceLineNo">1872</span>  }<a name="line.1872"></a>
+<span class="sourceLineNo">1873</span><a name="line.1873"></a>
+<span class="sourceLineNo">1874</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1874"></a>
+<span class="sourceLineNo">1875</span>    // TODO used by MasterRpcServices<a name="line.1875"></a>
+<span class="sourceLineNo">1876</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1876"></a>
+<span class="sourceLineNo">1877</span>    if (node != null) {<a name="line.1877"></a>
+<span class="sourceLineNo">1878</span>      node.offline();<a name="line.1878"></a>
+<span class="sourceLineNo">1879</span>    }<a name="line.1879"></a>
+<span class="sourceLineNo">1880</span>  }<a name="line.1880"></a>
+<span class="sourceLineNo">1881</span><a name="line.1881"></a>
+<span class="sourceLineNo">1882</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1882"></a>
+<span class="sourceLineNo">1883</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1883"></a>
+<span class="sourceLineNo">1884</span>  }<a name="line.1884"></a>
+<span class="sourceLineNo">1885</span><a name="line.1885"></a>
+<span class="sourceLineNo">1886</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1886"></a>
+<span class="sourceLineNo">1887</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1887"></a>
+<span class="sourceLineNo">1888</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1888"></a>
+<span class="sourceLineNo">1889</span>  }<a name="line.1889"></a>
+<span class="sourceLineNo">1890</span><a name="line.1890"></a>
+<span class="sourceLineNo">1891</span>  // ============================================================================================<a name="line.1891"></a>
+<span class="sourceLineNo">1892</span>  // TODO: UTILS/HELPERS?<a name="line.1892"></a>
 <span class="sourceLineNo">1893</span>  // ============================================================================================<a name="line.1893"></a>
-<span class="sourceLineNo">1894</span>  // TODO: UTILS/HELPERS?<a name="line.1894"></a>
-<span class="sourceLineNo">1895</span>  // ============================================================================================<a name="line.1895"></a>
-<span class="sourceLineNo">1896</span>  /**<a name="line.1896"></a>
-<span class="sourceLineNo">1897</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1897"></a>
-<span class="sourceLineNo">1898</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1898"></a>
-<span class="sourceLineNo">1899</span>   */<a name="line.1899"></a>
-<span class="sourceLineNo">1900</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1900"></a>
-<span class="sourceLineNo">1901</span>    if (isTableDisabled(tableName)) {<a name="line.1901"></a>
-<span class="sourceLineNo">1902</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1902"></a>
-<span class="sourceLineNo">1903</span>    }<a name="line.1903"></a>
-<span class="sourceLineNo">1904</span><a name="line.1904"></a>
-<span class="sourceLineNo">1905</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1905"></a>
-<span class="sourceLineNo">1906</span>    int ritCount = 0;<a name="line.1906"></a>
-<span class="sourceLineNo">1907</span>    for (RegionState regionState : states) {<a name="line.1907"></a>
-<span class="sourceLineNo">1908</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1908"></a>
-<span class="sourceLineNo">1909</span>        ritCount++;<a name="line.1909"></a>
-<span class="sourceLineNo">1910</span>      }<a name="line.1910"></a>
-<span class="sourceLineNo">1911</span>    }<a name="line.1911"></a>
-<span class="sourceLineNo">1912</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1912"></a>
-<span class="sourceLineNo">1913</span>  }<a name="line.1913"></a>
-<span class="sourceLineNo">1914</span><a name="line.1914"></a>
+<span class="sourceLineNo">1894</span>  /**<a name="line.1894"></a>
+<span class="sourceLineNo">1895</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1895"></a>
+<span class="sourceLineNo">1896</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1896"></a>
+<span class="sourceLineNo">1897</span>   */<a name="line.1897"></a>
+<span class="sourceLineNo">1898</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1898"></a>
+<span class="sourceLineNo">1899</span>    if (isTableDisabled(tableName)) {<a name="line.1899"></a>
+<span class="sourceLineNo">1900</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1900"></a>
+<span class="sourceLineNo">1901</span>    }<a name="line.1901"></a>
+<span class="sourceLineNo">1902</span><a name="line.1902"></a>
+<span class="sourceLineNo">1903</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1903"></a>
+<span class="sourceLineNo">1904</span>    int ritCount = 0;<a name="line.1904"></a>
+<span class="sourceLineNo">1905</span>    for (RegionState regionState : states) {<a name="line.1905"></a>
+<span class="sourceLineNo">1906</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1906"></a>
+<span class="sourceLineNo">1907</span>        ritCount++;<a name="line.1907"></a>
+<span class="sourceLineNo">1908</span>      }<a name="line.1908"></a>
+<span class="sourceLineNo">1909</span>    }<a name="line.1909"></a>
+<span class="sourceLineNo">1910</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1910"></a>
+<span class="sourceLineNo">1911</span>  }<a name="line.1911"></a>
+<span class="sourceLineNo">1912</span><a name="line.1912"></a>
+<span class="sourceLineNo">1913</span>  // ============================================================================================<a name="line.1913"></a>
+<span class="sourceLineNo">1914</span>  // TODO: Region State In Transition<a name="line.1914"></a>
 <span class="sourceLineNo">1915</span>  // ============================================================================================<a name="line.1915"></a>
-<span class="sourceLineNo">1916</span>  // TODO: Region State In Transition<a name="line.1916"></a>
-<span class="sourceLineNo">1917</span>  // ============================================================================================<a name="line.1917"></a>
-<span class="sourceLineNo">1918</span>  public boolean hasRegionsInTransition() {<a name="line.1918"></a>
-<span class="sourceLineNo">1919</span>    return regionStates.hasRegionsInTransition();<a name="line.1919"></a>
-<span class="sourceLineNo">1920</span>  }<a name="line.1920"></a>
-<span class="sourceLineNo">1921</span><a name="line.1921"></a>
-<span class="sourceLineNo">1922</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1922"></a>
-<span class="sourceLineNo">1923</span>    return regionStates.getRegionsInTransition();<a name="line.1923"></a>
-<span class="sourceLineNo">1924</span>  }<a name="line.1924"></a>
-<span class="sourceLineNo">1925</span><a name="line.1925"></a>
-<span class="sourceLineNo">1926</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1926"></a>
-<span class="sourceLineNo">1927</span>    return regionStates.getAssignedRegions();<a name="line.1927"></a>
-<span class="sourceLineNo">1928</span>  }<a name="line.1928"></a>
-<span class="sourceLineNo">1929</span><a name="line.1929"></a>
-<span class="sourceLineNo">1930</span>  /**<a name="line.1930"></a>
-<span class="sourceLineNo">1931</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1931"></a>
-<span class="sourceLineNo">1932</span>   */<a name="line.1932"></a>
-<span class="sourceLineNo">1933</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1933"></a>
-<span class="sourceLineNo">1934</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1934"></a>
-<span class="sourceLineNo">1935</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1935"></a>
-<span class="sourceLineNo">1936</span>  }<a name="line.1936"></a>
-<span class="sourceLineNo">1937</span><a name="line.1937"></a>
-<span class="sourceLineNo">1938</span>  /**<a name="line.1938"></a>
-<span class="sourceLineNo">1939</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1939"></a>
-<span class="sourceLineNo">1940</span>   */<a name="line.1940"></a>
-<span class="sourceLineNo">1941</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1941"></a>
-<span class="sourceLineNo">1942</span>    final RegionStateNode regionState =<a name="line.1942"></a>
-<span class="sourceLineNo">1943</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1943"></a>
-<span class="sourceLineNo">1944</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1944"></a>
-<span class="sourceLineNo">1945</span>  }<a name="line.1945"></a>
-<span class="sourceLineNo">1946</span><a name="line.1946"></a>
-<span class="sourceLineNo">1947</span>  // ============================================================================================<a name="line.1947"></a>
-<span class="sourceLineNo">1948</span>  // Expected states on region state transition.<a name="line.1948"></a>
-<span class="sourceLineNo">1949</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1949"></a>
-<span class="sourceLineNo">1950</span>  // See the comments in regionOpening method for more details.<a name="line.1950"></a>
-<span class="sourceLineNo">1951</span>  // ============================================================================================<a name="line.1951"></a>
-<span class="sourceLineNo">1952</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1952"></a>
-<span class="sourceLineNo">1953</span>    State.OPEN // Retrying<a name="line.1953"></a>
-<span class="sourceLineNo">1954</span>  };<a name="line.1954"></a>
-<span class="sourceLineNo">1955</span><a name="line.1955"></a>
-<span class="sourceLineNo">1956</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1956"></a>
-<span class="sourceLineNo">1957</span>    State.CLOSING, // Retrying<a name="line.1957"></a>
-<span class="sourceLineNo">1958</span>    State.SPLITTING, // Offline the split parent<a name="line.1958"></a>
-<span class="sourceLineNo">1959</span>    State.MERGING // Offline the merge parents<a name="line.1959"></a>
-<span class="sourceLineNo">1960</span>  };<a name="line.1960"></a>
-<span class="sourceLineNo">1961</span><a name="line.1961"></a>
-<span class="sourceLineNo">1962</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1962"></a>
-<span class="sourceLineNo">1963</span>    State.CLOSED // Retrying<a name="line.1963"></a>
-<span class="sourceLineNo">1964</span>  };<a name="line.1964"></a>
-<span class="sourceLineNo">1965</span><a name="line.1965"></a>
-<span class="sourceLineNo">1966</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1966"></a>
-<span class="sourceLineNo">1967</span>  // usages<a name="line.1967"></a>
-<span class="sourceLineNo">1968</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1968"></a>
-<span class="sourceLineNo">1969</span><a name="line.1969"></a>
-<span class="sourceLineNo">1970</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1970"></a>
-<span class="sourceLineNo">1971</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1971"></a>
-<span class="sourceLineNo">1972</span><a name="line.1972"></a>
-<span class="sourceLineNo">1973</span>  // ============================================================================================<a name="line.1973"></a>
-<span class="sourceLineNo">1974</span>  // Region Status update<a name="line.1974"></a>
-<span class="sourceLineNo">1975</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1975"></a>
-<span class="sourceLineNo">1976</span>  // and pre-assumptions are very tricky.<a name="line.1976"></a>
-<span class="sourceLineNo">1977</span>  // ============================================================================================<a name="line.1977"></a>
-<span class="sourceLineNo">1978</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1978"></a>
-<span class="sourceLineNo">1979</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1979"></a>
-<span class="sourceLineNo">1980</span>    RegionState.State state = regionNode.getState();<a name="line.1980"></a>
-<span class="sourceLineNo">1981</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1981"></a>
-<span class="sourceLineNo">1982</span>    boolean succ = false;<a name="line.1982"></a>
-<span class="sourceLineNo">1983</span>    try {<a name="line.1983"></a>
-<span class="sourceLineNo">1984</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1984"></a>
-<span class="sourceLineNo">1985</span>      succ = true;<a name="line.1985"></a>
-<span class="sourceLineNo">1986</span>    } finally {<a name="line.1986"></a>
-<span class="sourceLineNo">1987</span>      if (!succ) {<a name="line.1987"></a>
-<span class="sourceLineNo">1988</span>        // revert<a name="line.1988"></a>
-<span class="sourceLineNo">1989</span>        regionNode.setState(state);<a name="line.1989"></a>
-<span class="sourceLineNo">1990</span>      }<a name="line.1990"></a>
-<span class="sourceLineNo">1991</span>    }<a name="line.1991"></a>
-<span class="sourceLineNo">1992</span>  }<a name="line.1992"></a>
-<span class="sourceLineNo">1993</span><a name="line.1993"></a>
-<span class="sourceLineNo">1994</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1994"></a>
-<span class="sourceLineNo">1995</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1995"></a>
-<span class="sourceLineNo">1996</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1996"></a>
-<span class="sourceLineNo">1997</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1997"></a>
-<span class="sourceLineNo">1998</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1998"></a>
-<span class="sourceLineNo">1999</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1999"></a>
-<span class="sourceLineNo">2000</span>    regionStates.addRegionToServer(regionNode);<a name="line.2000"></a>
-<span class="sourceLineNo">2001</span>    // update the operation count metrics<a name="line.2001"></a>
-<span class="sourceLineNo">2002</span>    metrics.incrementOperationCounter();<a name="line.2002"></a>
-<span class="sourceLineNo">2003</span>  }<a name="line.2003"></a>
-<span class="sourceLineNo">2004</span><a name="line.2004"></a>
-<span class="sourceLineNo">2005</span>  // should be called under the RegionStateNode lock<a name="line.2005"></a>
-<span class="sourceLineNo">2006</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2006"></a>
-<span class="sourceLineNo">2007</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2007"></a>
-<span class="sourceLineNo">2008</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2008"></a>
-<span class="sourceLineNo">2009</span>    RegionState.State state = regionNode.getState();<a name="line.2009"></a>
-<span class="sourceLineNo">2010</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2010"></a>
-<span class="sourceLineNo">2011</span>    if (giveUp) {<a name="line.2011"></a>
-<span class="sourceLineNo">2012</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2012"></a>
-<span class="sourceLineNo">2013</span>      regionNode.setRegionLocation(null);<a name="line.2013"></a>
-<span class="sourceLineNo">2014</span>      boolean succ = false;<a name="line.2014"></a>
-<span class="sourceLineNo">2015</span>      try {<a name="line.2015"></a>
-<span class="sourceLineNo">2016</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2016"></a>
-<span class="sourceLineNo">2017</span>        succ = true;<a name="line.2017"></a>
-<span class="sourceLineNo">2018</span>      } finally {<a name="line.2018"></a>
-<span class="sourceLineNo">2019</span>        if (!succ) {<a name="line.2019"></a>
-<span class="sourceLineNo">2020</span>          // revert<a name="line.2020"></a>
-<span class="sourceLineNo">2021</span>          regionNode.setState(state);<a name="line.2021"></a>
-<span class="sourceLineNo">2022</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2022"></a>
-<span class="sourceLineNo">2023</span>        }<a name="line.2023"></a>
-<span class="sourceLineNo">2024</span>      }<a name="line.2024"></a>
-<span class="sourceLineNo">2025</span>    }<a name="line.2025"></a>
-<span class="sourceLineNo">2026</span>    if (regionLocation != null) {<a name="line.2026"></a>
-<span class="sourceLineNo">2027</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2027"></a>
-<span class="sourceLineNo">2028</span>    }<a name="line.2028"></a>
-<span class="sourceLineNo">2029</span>  }<a name="line.2029"></a>
-<span class="sourceLineNo">2030</span><a name="line.2030"></a>
-<span class="sourceLineNo">2031</span>  // should be called under the RegionStateNode lock<a name="line.2031"></a>
-<span class="sourceLineNo">2032</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2032"></a>
-<span class="sourceLineNo">2033</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2033"></a>
-<span class="sourceLineNo">2034</span><a name="line.2034"></a>
-<span class="sourceLineNo">2035</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2035"></a>
-<span class="sourceLineNo">2036</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2036"></a>
-<span class="sourceLineNo">2037</span>    if (isMetaRegion(hri)) {<a name="line.2037"></a>
-<span class="sourceLineNo">2038</span>      setMetaAssigned(hri, false);<a name="line.2038"></a>
-<span class="sourceLineNo">2039</span>    }<a name="line.2039"></a>
-<span class="sourceLineNo">2040</span>    regionStates.addRegionToServer(regionNode);<a name="line.2040"></a>
-<span class="sourceLineNo">2041</span>    // update the operation count metrics<a name="line.2041"></a>
-<span class="sourceLineNo">2042</span>    metrics.incrementOperationCounter();<a name="line.2042"></a>
-<span class="sourceLineNo">2043</span>  }<a name="line.2043"></a>
-<span class="sourceLineNo">2044</span><a name="line.2044"></a>
-<span class="sourceLineNo">2045</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2045"></a>
-<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2046"></a>
-<span class="sourceLineNo">2047</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2047"></a>
-<span class="sourceLineNo">2048</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2048"></a>
-<span class="sourceLineNo">2049</span><a name="line.2049"></a>
-<span class="sourceLineNo">2050</span>  // should be called under the RegionStateNode lock<a name="line.2050"></a>
-<span class="sourceLineNo">2051</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2051"></a>
-<span class="sourceLineNo">2052</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2052"></a>
-<span class="sourceLineNo">2053</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2053"></a>
-<span class="sourceLineNo">2054</span>    regionStates.addRegionToServer(regionNode);<a name="line.2054"></a>
-<span class="sourceLineNo">2055</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2055"></a>
-<span class="sourceLineNo">2056</span>  }<a name="line.2056"></a>
-<span class="sourceLineNo">2057</span><a name="line.2057"></a>
-<span class="sourceLineNo">2058</span>  // should be called under the RegionStateNode lock<a name="line.2058"></a>
-<span class="sourceLineNo">2059</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2059"></a>
-<span class="sourceLineNo">2060</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2060"></a>
-<span class="sourceLineNo">2061</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2061"></a>
-<span class="sourceLineNo">2062</span>    regionNode.setRegionLocation(null);<a name="line.2062"></a>
-<span class="sourceLineNo">2063</span>    if (regionLocation != null) {<a name="line.2063"></a>
-<span class="sourceLineNo">2064</span>      regionNode.setLastHost(regionLocation);<a name="line.2064"></a>
-<span class="sourceLineNo">2065</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2065"></a>
-<span class="sourceLineNo">2066</span>    }<a name="line.2066"></a>
-<span class="sourceLineNo">2067</span>  }<a name="line.2067"></a>
-<span class="sourceLineNo">2068</span><a name="line.2068"></a>
-<span class="sourceLineNo">2069</span>  // should be called under the RegionStateNode lock<a name="line.2069"></a>
-<span class="sourceLineNo">2070</span>  // for SCP<a name="line.2070"></a>
-<span class="sourceLineNo">2071</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2071"></a>
-<span class="sourceLineNo">2072</span>    RegionState.State state = regionNode.getState();<a name="line.2072"></a>
-<span class="sourceLineNo">2073</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2073"></a>
-<span class="sourceLineNo">2074</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2074"></a>
-<span class="sourceLineNo">2075</span>    regionNode.setRegionLocation(null);<a name="line.2075"></a>
-<span class="sourceLineNo">2076</span>    boolean succ = false;<a name="line.2076"></a>
-<span class="sourceLineNo">2077</span>    try {<a name="line.2077"></a>
-<span class="sourceLineNo">2078</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2078"></a>
-<span class="sourceLineNo">2079</span>      succ = true;<a name="line.2079"></a>
-<span class="sourceLineNo">2080</span>    } finally {<a name="line.2080"></a>
-<span class="sourceLineNo">2081</span>      if (!succ) {<a name="line.2081"></a>
-<span class="sourceLineNo">2082</span>        // revert<a name="line.2082"></a>
-<span class="sourceLineNo">2083</span>        regionNode.setState(state);<a name="line.2083"></a>
-<span class="sourceLineNo">2084</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2084"></a>
-<span class="sourceLineNo">2085</span>      }<a name="line.2085"></a>
-<span class="sourceLineNo">2086</span>    }<a name="line.2086"></a>
-<span class="sourceLineNo">2087</span>    if (regionLocation != null) {<a name="line.2087"></a>
-<span class="sourceLineNo">2088</span>      regionNode.setLastHost(regionLocation);<a name="line.2088"></a>
-<span class="sourceLineNo">2089</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2089"></a>
-<span class="sourceLineNo">2090</span>    }<a name="line.2090"></a>
-<span class="sourceLineNo">2091</span>  }<a name="line.2091"></a>
-<span class="sourceLineNo">2092</span><a name="line.2092"></a>
-<span class="sourceLineNo">2093</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2093"></a>
-<span class="sourceLineNo">2094</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2094"></a>
-<span class="sourceLineNo">2095</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2095"></a>
-<span class="sourceLineNo">2096</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2096"></a>
-<span class="sourceLineNo">2097</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2097"></a>
-<span class="sourceLineNo">2098</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2098"></a>
-<span class="sourceLineNo">2099</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2099"></a>
-<span class="sourceLineNo">2100</span>      // on table that contains state.<a name="line.2100"></a>
-<span class="sourceLineNo">2101</span>      setMetaAssigned(regionInfo, true);<a name="line.2101"></a>
-<span class="sourceLineNo">2102</span>    }<a name="line.2102"></a>
-<span class="sourceLineNo">2103</span>  }<a name="line.2103"></a>
-<span class="sourceLineNo">2104</span><a name="line.2104"></a>
+<span class="sourceLineNo">1916</span>  public boolean hasRegionsInTransition() {<a name="line.1916"></a>
+<span class="sourceLineNo">1917</span>    return regionStates.hasRegionsInTransition();<a name="line.1917"></a>
+<span class="sourceLineNo">1918</span>  }<a name="line.1918"></a>
+<span class="sourceLineNo">1919</span><a name="line.1919"></a>
+<span class="sourceLineNo">1920</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1920"></a>
+<span class="sourceLineNo">1921</span>    return regionStates.getRegionsInTransition();<a name="line.1921"></a>
+<span class="sourceLineNo">1922</span>  }<a name="line.1922"></a>
+<span class="sourceLineNo">1923</span><a name="line.1923"></a>
+<span class="sourceLineNo">1924</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1924"></a>
+<span class="sourceLineNo">1925</span>    return regionStates.getAssignedRegions();<a name="line.1925"></a>
+<span class="sourceLineNo">1926</span>  }<a name="line.1926"></a>
+<span class="sourceLineNo">1927</span><a name="line.1927"></a>
+<span class="sourceLineNo">1928</span>  /**<a name="line.1928"></a>
+<span class="sourceLineNo">1929</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1929"></a>
+<span class="sourceLineNo">1930</span>   */<a name="line.1930"></a>
+<span class="sourceLineNo">1931</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1931"></a>
+<span class="sourceLineNo">1932</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1932"></a>
+<span class="sourceLineNo">1933</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1933"></a>
+<span class="sourceLineNo">1934</span>  }<a name="line.1934"></a>
+<span class="sourceLineNo">1935</span><a name="line.1935"></a>
+<span class="sourceLineNo">1936</span>  /**<a name="line.1936"></a>
+<span class="sourceLineNo">1937</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1937"></a>
+<span class="sourceLineNo">1938</span>   */<a name="line.1938"></a>
+<span class="sourceLineNo">1939</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1939"></a>
+<span class="sourceLineNo">1940</span>    final RegionStateNode regionState =<a name="line.1940"></a>
+<span class="sourceLineNo">1941</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1941"></a>
+<span class="sourceLineNo">1942</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1942"></a>
+<span class="sourceLineNo">1943</span>  }<a name="line.1943"></a>
+<span class="sourceLineNo">1944</span><a name="line.1944"></a>
+<span class="sourceLineNo">1945</span>  // ============================================================================================<a name="line.1945"></a>
+<span class="sourceLineNo">1946</span>  // Expected states on region state transition.<a name="line.1946"></a>
+<span class="sourceLineNo">1947</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1947"></a>
+<span class="sourceLineNo">1948</span>  // See the comments in regionOpening method for more details.<a name="line.1948"></a>
+<span class="sourceLineNo">1949</span>  // ============================================================================================<a name="line.1949"></a>
+<span class="sourceLineNo">1950</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1950"></a>
+<span class="sourceLineNo">1951</span>    State.OPEN // Retrying<a name="line.1951"></a>
+<span class="sourceLineNo">1952</span>  };<a name="line.1952"></a>
+<span class="sourceLineNo">1953</span><a name="line.1953"></a>
+<span class="sourceLineNo">1954</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1954"></a>
+<span class="sourceLineNo">1955</span>    State.CLOSING, // Retrying<a name="line.1955"></a>
+<span class="sourceLineNo">1956</span>    State.SPLITTING, // Offline the split parent<a name="line.1956"></a>
+<span class="sourceLineNo">1957</span>    State.MERGING // Offline the merge parents<a name="line.1957"></a>
+<span class="sourceLineNo">1958</span>  };<a name="line.1958"></a>
+<span class="sourceLineNo">1959</span><a name="line.1959"></a>
+<span class="sourceLineNo">1960</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1960"></a>
+<span class="sourceLineNo">1961</span>    State.CLOSED // Retrying<a name="line.1961"></a>
+<span class="sourceLineNo">1962</span>  };<a name="line.1962"></a>
+<span class="sourceLineNo">1963</span><a name="line.1963"></a>
+<span class="sourceLineNo">1964</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1964"></a>
+<span class="sourceLineNo">1965</span>  // usages<a name="line.1965"></a>
+<span class="sourceLineNo">1966</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1966"></a>
+<span class="sourceLineNo">1967</span><a name="line.1967"></a>
+<span class="sourceLineNo">1968</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1968"></a>
+<span class="sourceLineNo">1969</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1969"></a>
+<span class="sourceLineNo">1970</span><a name="line.1970"></a>
+<span class="sourceLineNo">1971</span>  // ============================================================================================<a name="line.1971"></a>
+<span class="sourceLineNo">1972</span>  // Region Status update<a name="line.1972"></a>
+<span class="sourceLineNo">1973</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1973"></a>
+<span class="sourceLineNo">1974</span>  // and pre-assumptions are very tricky.<a name="line.1974"></a>
+<span class="sourceLineNo">1975</span>  // ============================================================================================<a name="line.1975"></a>
+<span class="sourceLineNo">1976</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1976"></a>
+<span class="sourceLineNo">1977</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1977"></a>
+<span class="sourceLineNo">1978</span>    RegionState.State state = regionNode.getState();<a name="line.1978"></a>
+<span class="sourceLineNo">1979</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1979"></a>
+<span class="sourceLineNo">1980</span>    boolean succ = false;<a name="line.1980"></a>
+<span class="sourceLineNo">1981</span>    try {<a name="line.1981"></a>
+<span class="sourceLineNo">1982</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1982"></a>
+<span class="sourceLineNo">1983</span>      succ = true;<a name="line.1983"></a>
+<span class="sourceLineNo">1984</span>    } finally {<a name="line.1984"></a>
+<span class="sourceLineNo">1985</span>      if (!succ) {<a name="line.1985"></a>
+<span class="sourceLineNo">1986</span>        // revert<a name="line.1986"></a>
+<span class="sourceLineNo">1987</span>        regionNode.setState(state);<a name="line.1987"></a>
+<span class="sourceLineNo">1988</span>      }<a name="line.1988"></a>
+<span class="sourceLineNo">1989</span>    }<a name="line.1989"></a>
+<span class="sourceLineNo">1990</span>  }<a name="line.1990"></a>
+<span class="sourceLineNo">1991</span><a name="line.1991"></a>
+<span class="sourceLineNo">1992</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1992"></a>
+<span class="sourceLineNo">1993</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1993"></a>
+<span class="sourceLineNo">1994</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1994"></a>
+<span class="sourceLineNo">1995</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1995"></a>
+<span class="sourceLineNo">1996</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1996"></a>
+<span class="sourceLineNo">1997</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1997"></a>
+<span class="sourceLineNo">1998</span>    regionStates.addRegionToServer(regionNode);<a name="line.1998"></a>
+<span class="sourceLineNo">1999</span>    // update the operation count metrics<a name="line.1999"></a>
+<span class="sourceLineNo">2000</span>    metrics.incrementOperationCounter();<a name="line.2000"></a>
+<span class="sourceLineNo">2001</span>  }<a name="line.2001"></a>
+<span class="sourceLineNo">2002</span><a name="line.2002"></a>
+<span class="sourceLineNo">2003</span>  // should be called under the RegionStateNode lock<a name="line.2003"></a>
+<span class="sourceLineNo">2004</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2004"></a>
+<span class="sourceLineNo">2005</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2005"></a>
+<span class="sourceLineNo">2006</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2006"></a>
+<span class="sourceLineNo">2007</span>    RegionState.State state = regionNode.getState();<a name="line.2007"></a>
+<span class="sourceLineNo">2008</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2008"></a>
+<span class="sourceLineNo">2009</span>    if (giveUp) {<a name="line.2009"></a>
+<span class="sourceLineNo">2010</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2010"></a>
+<span class="sourceLineNo">2011</span>      regionNode.setRegionLocation(null);<a name="line.2011"></a>
+<span class="sourceLineNo">2012</span>      boolean succ = false;<a name="line.2012"></a>
+<span class="sourceLineNo">2013</span>      try {<a name="line.2013"></a>
+<span class="sourceLineNo">2014</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2014"></a>
+<span class="sourceLineNo">2015</span>        succ = true;<a name="line.2015"></a>
+<span class="sourceLineNo">2016</span>      } finally {<a name="line.2016"></a>
+<span class="sourceLineNo">2017</span>        if (!succ) {<a name="line.2017"></a>
+<span class="sourceLineNo">2018</span>          // revert<a name="line.2018"></a>
+<span class="sourceLineNo">2019</span>          regionNode.setState(state);<a name="line.2019"></a>
+<span class="sourceLineNo">2020</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2020"></a>
+<span class="sourceLineNo">2021</span>        }<a name="line.2021"></a>
+<span class="sourceLineNo">2022</span>      }<a name="line.2022"></a>
+<span class="sourceLineNo">2023</span>    }<a name="line.2023"></a>
+<span class="sourceLineNo">2024</span>    if (regionLocation != null) {<a name="line.2024"></a>
+<span class="sourceLineNo">2025</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2025"></a>
+<span class="sourceLineNo">2026</span>    }<a name="line.2026"></a>
+<span class="sourceLineNo">2027</span>  }<a name="line.2027"></a>
+<span class="sourceLineNo">2028</span><a name="line.2028"></a>
+<span class="sourceLineNo">2029</span>  // should be called under the RegionStateNode lock<a name="line.2029"></a>
+<span class="sourceLineNo">2030</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2030"></a>
+<span class="sourceLineNo">2031</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2031"></a>
+<span class="sourceLineNo">2032</span><a name="line.2032"></a>
+<span class="sourceLineNo">2033</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2033"></a>
+<span class="sourceLineNo">2034</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2034"></a>
+<span class="sourceLineNo">2035</span>    if (isMetaRegion(hri)) {<a name="line.2035"></a>
+<span class="sourceLineNo">2036</span>      setMetaAssigned(hri, false);<a name="line.2036"></a>
+<span class="sourceLineNo">2037</span>    }<a name="line.2037"></a>
+<span class="sourceLineNo">2038</span>    regionStates.addRegionToServer(regionNode);<a name="line.2038"></a>
+<span class="sourceLineNo">2039</span>    // update the operation count metrics<a name="line.2039"></a>
+<span class="sourceLineNo">2040</span>    metrics.incrementOperationCounter();<a name="line.2040"></a>
+<span class="sourceLineNo">2041</span>  }<a name="line.2041"></a>
+<span class="sourceLineNo">2042</span><a name="line.2042"></a>
+<span class="sourceLineNo">2043</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2043"></a>
+<span class="sourceLineNo">2044</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2044"></a>
+<span class="sourceLineNo">2045</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2045"></a>
+<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2046"></a>
+<span class="sourceLineNo">2047</span><a name="line.2047"></a>
+<span class="sourceLineNo">2048</span>  // should be called under the RegionStateNode lock<a name="line.2048"></a>
+<span class="sourceLineNo">2049</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2049"></a>
+<span class="sourceLineNo">2050</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2050"></a>
+<span class="sourceLineNo">2051</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2051"></a>
+<span class="sourceLineNo">2052</span>    regionStates.addRegionToServer(regionNode);<a name="line.2052"></a>
+<span class="sourceLineNo">2053</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2053"></a>
+<span class="sourceLineNo">2054</span>  }<a name="line.2054"></a>
+<span class="sourceLineNo">2055</span><a name="line.2055"></a>
+<span class="sourceLineNo">2056</span>  // should be called under the RegionStateNode lock<a name="line.2056"></a>
+<span class="sourceLineNo">2057</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2057"></a>
+<span class="sourceLineNo">2058</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2058"></a>
+<span class="sourceLineNo">2059</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2059"></a>
+<span class="sourceLineNo">2060</span>    regionNode.setRegionLocation(null);<a name="line.2060"></a>
+<span class="sourceLineNo">2061</span>    if (regionLocation != null) {<a name="line.2061"></a>
+<span class="sourceLineNo">2062</span>      regionNode.setLastHost(regionLocation);<a name="line.2062"></a>
+<span class="sourceLineNo">2063</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2063"></a>
+<span class="sourceLineNo">2064</span>    }<a name="line.2064"></a>
+<span class="sourceLineNo">2065</span>  }<a name="line.2065"></a>
+<span class="sourceLineNo">2066</span><a name="line.2066"></a>
+<span class="sourceLineNo">2067</span>  // should be called under the RegionStateNode lock<a name="line.2067"></a>
+<span class="sourceLineNo">2068</span>  // for SCP<a name="line.2068"></a>
+<span class="sourceLineNo">2069</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2069"></a>
+<span class="sourceLineNo">2070</span>    RegionState.State state = regionNode.getState();<a name="line.2070"></a>
+<span class="sourceLineNo">2071</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2071"></a>
+<span class="sourceLineNo">2072</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2072"></a>
+<span class="sourceLineNo">2073</span>    regionNode.setRegionLocation(null);<a name="line.2073"></a>
+<span class="sourceLineNo">2074</span>    boolean succ = false;<a name="line.2074"></a>
+<span class="sourceLineNo">2075</span>    try {<a name="line.2075"></a>
+<span class="sourceLineNo">2076</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2076"></a>
+<span class="sourceLineNo">2077</span>      succ = true;<a name="line.2077"></a>
+<span class="sourceLineNo">2078</span>    } finally {<a name="line.2078"></a>
+<span class="sourceLineNo">2079</span>      if (!succ) {<a name="line.2079"></a>
+<span class="sourceLineNo">2080</span>        // revert<a name="line.2080"></a>
+<span class="sourceLineNo">2081</span>        regionNode.setState(state);<a name="line.2081"></a>
+<span class="sourceLineNo">2082</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2082"></a>
+<span class="sourceLineNo">2083</span>      }<a name="line.2083"></a>
+<span class="sourceLineNo">2084</span>    }<a name="line.2084"></a>
+<span class="sourceLineNo">2085</span>    if (regionLocation != null) {<a name="line.2085"></a>
+<span class="sourceLineNo">2086</span>      regionNode.setLastHost(regionLocation);<a name="line.2086"></a>
+<span class="sourceLineNo">2087</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2087"></a>
+<span class="sourceLineNo">2088</span>    }<a name="line.2088"></a>
+<span class="sourceLineNo">2089</span>  }<a name="line.2089"></a>
+<span class="sourceLineNo">2090</span><a name="line.2090"></a>
+<span class="sourceLineNo">2091</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2091"></a>
+<span class="sourceLineNo">2092</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2092"></a>
+<span class="sourceLineNo">2093</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2093"></a>
+<span class="sourceLineNo">2094</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2094"></a>
+<span class="sourceLineNo">2095</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2095"></a>
+<span class="sourceLineNo">2096</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2096"></a>
+<span class="sourceLineNo">2097</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2097"></a>
+<span class="sourceLineNo">2098</span>      // on table that contains state.<a name="line.2098"></a>
+<span class="sourceLineNo">2099</span>      setMetaAssigned(regionInfo, true);<a name="line.2099"></a>
+<span class="sourceLineNo">2100</span>    }<a name="line.2100"></a>
+<span class="sourceLineNo">2101</span>  }<a name="line.2101"></a>
+<span class="sourceLineNo">2102</span><a name="line.2102"></a>
+<span class="sourceLineNo">2103</span>  // ============================================================================================<a name="line.2103"></a>
+<span class="sourceLineNo">2104</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2104"></a>
 <span class="sourceLineNo">2105</span>  // ============================================================================================<a name="line.2105"></a>
-<span class="sourceLineNo">2106</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2106"></a>
-<span class="sourceLineNo">2107</span>  // ============================================================================================<a name="line.2107"></a>
-<span class="sourceLineNo">2108</span><a name="line.2108"></a>
-<span class="sourceLineNo">2109</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2109"></a>
-<span class="sourceLineNo">2110</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2110"></a>
-<span class="sourceLineNo">2111</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2111"></a>
-<span class="sourceLineNo">2112</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2112"></a>
-<span class="sourceLineNo">2113</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2113"></a>
-<span class="sourceLineNo">2114</span>    // later figuring what regions are in a table and what are not: see<a name="line.2114"></a>
-<span class="sourceLineNo">2115</span>    // regionStates#getRegionsOfTable<a name="line.2115"></a>
-<span class="sourceLineNo">2116</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2116"></a>
-<span class="sourceLineNo">2117</span>    node.setState(State.SPLIT);<a name="line.2117"></a>
-<span class="sourceLineNo">2118</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2118"></a>
-<span class="sourceLineNo">2119</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
-<span class="sourceLineNo">2120</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2120"></a>
-<span class="sourceLineNo">2121</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2121"></a>
-<span class="sourceLineNo">2122</span><a name="line.2122"></a>
-<span class="sourceLineNo">2123</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2123"></a>
-<span class="sourceLineNo">2124</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2124"></a>
-<span class="sourceLineNo">2125</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2125"></a>
-<span class="sourceLineNo">2126</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2126"></a>
-<span class="sourceLineNo">2127</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2127"></a>
-<span class="sourceLineNo">2128</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2128"></a>
-<span class="sourceLineNo">2129</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2129"></a>
-<span class="sourceLineNo">2130</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2130"></a>
-<span class="sourceLineNo">2131</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2131"></a>
-<span class="sourceLineNo">2132</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2132"></a>
-<span class="sourceLineNo">2133</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2133"></a>
-<span class="sourceLineNo">2134</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2134"></a>
-<span class="sourceLineNo">2135</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2135"></a>
-<span class="sourceLineNo">2136</span>        daughterB);<a name="line.2136"></a>
-<span class="sourceLineNo">2137</span>    }<a name="line.2137"></a>
-<span class="sourceLineNo">2138</span>  }<a name="line.2138"></a>
-<span class="sourceLineNo">2139</span><a name="line.2139"></a>
-<span class="sourceLineNo">2140</span>  /**<a name="line.2140"></a>
-<span class="sourceLineNo">2141</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2141"></a>
-<span class="sourceLineNo">2142</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2142"></a>
-<span class="sourceLineNo">2143</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2143"></a>
-<span class="sourceLineNo">2144</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2144"></a>
-<span class="sourceLineNo">2145</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2145"></a>
-<span class="sourceLineNo">2146</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2146"></a>
-<span class="sourceLineNo">2147</span>   * the archiver chore runs, are the References removed).<a name="line.2147"></a>
-<span class="sourceLineNo">2148</span>   */<a name="line.2148"></a>
-<span class="sourceLineNo">2149</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2149"></a>
-<span class="sourceLineNo">2150</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2150"></a>
-<span class="sourceLineNo">2151</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2151"></a>
-<span class="sourceLineNo">2152</span>    node.setState(State.MERGED);<a name="line.2152"></a>
-<span class="sourceLineNo">2153</span>    for (RegionInfo ri : mergeParents) {<a name="line.2153"></a>
-<span class="sourceLineNo">2154</span>      regionStates.deleteRegion(ri);<a name="line.2154"></a>
-<span class="sourceLineNo">2155</span>    }<a name="line.2155"></a>
-<span class="sourceLineNo">2156</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2156"></a>
-<span class="sourceLineNo">2157</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2157"></a>
-<span class="sourceLineNo">2158</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2158"></a>
-<span class="sourceLineNo">2159</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2159"></a>
-<span class="sourceLineNo">2160</span>    }<a name="line.2160"></a>
-<span class="sourceLineNo">2161</span>  }<a name="line.2161"></a>
-<span class="sourceLineNo">2162</span><a name="line.2162"></a>
-<span class="sourceLineNo">2163</span>  /*<a name="line.2163"></a>
-<span class="sourceLineNo">2164</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2164"></a>
-<span class="sourceLineNo">2165</span>   * belongs to a non-system table.<a name="line.2165"></a>
-<span class="sourceLineNo">2166</span>   */<a name="line.2166"></a>
-<span class="sourceLineNo">2167</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2167"></a>
-<span class="sourceLineNo">2168</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2168"></a>
-<span class="sourceLineNo">2169</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2169"></a>
-<span class="sourceLineNo">2170</span>  }<a name="line.2170"></a>
-<span class="sourceLineNo">2171</span><a name="line.2171"></a>
+<span class="sourceLineNo">2106</span><a name="line.2106"></a>
+<span class="sourceLineNo">2107</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2107"></a>
+<span class="sourceLineNo">2108</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2108"></a>
+<span class="sourceLineNo">2109</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2109"></a>
+<span class="sourceLineNo">2110</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2110"></a>
+<span class="sourceLineNo">2111</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2111"></a>
+<span class="sourceLineNo">2112</span>    // later figuring what regions are in a table and what are not: see<a name="line.2112"></a>
+<span class="sourceLineNo">2113</span>    // regionStates#getRegionsOfTable<a name="line.2113"></a>
+<span class="sourceLineNo">2114</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2114"></a>
+<span class="sourceLineNo">2115</span>    node.setState(State.SPLIT);<a name="line.2115"></a>
+<span class="sourceLineNo">2116</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2116"></a>
+<span class="sourceLineNo">2117</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2117"></a>
+<span class="sourceLineNo">2118</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2118"></a>
+<span class="sourceLineNo">2119</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
+<span class="sourceLineNo">2120</span><a name="line.2120"></a>
+<span class="sourceLineNo">2121</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2121"></a>
+<span class="sourceLineNo">2122</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2122"></a>
+<span class="sourceLineNo">2123</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2123"></a>
+<span class="sourceLineNo">2124</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2124"></a>
+<span class="sourceLineNo">2125</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2125"></a>
+<span class="sourceLineNo">2126</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2126"></a>
+<span class="sourceLineNo">2127</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2127"></a>
+<span class="sourceLineNo">2128</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2128"></a>
+<span class="sourceLineNo">2129</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2129"></a>
+<span class="sourceLineNo">2130</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2130"></a>
+<span class="sourceLineNo">2131</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2131"></a>
+<span class="sourceLineNo">2132</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2132"></a>
+<span class="sourceLineNo">2133</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2133"></a>
+<span class="sourceLineNo">2134</span>        daughterB);<a name="line.2134"></a>
+<span class="sourceLineNo">2135</span>    }<a name="line.2135"></a>
+<span class="sourceLineNo">2136</span>  }<a name="line.2136"></a>
+<span class="sourceLineNo">2137</span><a name="line.2137"></a>
+<span class="sourceLineNo">2138</span>  /**<a name="line.2138"></a>
+<span class="sourceLineNo">2139</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2139"></a>
+<span class="sourceLineNo">2140</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2140"></a>
+<span class="sourceLineNo">2141</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2141"></a>
+<span class="sourceLineNo">2142</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2142"></a>
+<span class="sourceLineNo">2143</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2143"></a>
+<span class="sourceLineNo">2144</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2144"></a>
+<span class="sourceLineNo">2145</span>   * the archiver chore runs, are the References removed).<a name="line.2145"></a>
+<span class="sourceLineNo">2146</span>   */<a name="line.2146"></a>
+<span class="sourceLineNo">2147</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2147"></a>
+<span class="sourceLineNo">2148</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2148"></a>
+<span class="sourceLineNo">2149</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2149"></a>
+<span class="sourceLineNo">2150</span>    node.setState(State.MERGED);<a name="line.2150"></a>
+<span class="sourceLineNo">2151</span>    for (RegionInfo ri : mergeParents) {<a name="line.2151"></a>
+<span class="sourceLineNo">2152</span>      regionStates.deleteRegion(ri);<a name="line.2152"></a>
+<span class="sourceLineNo">2153</span>    }<a name="line.2153"></a>
+<span class="sourceLineNo">2154</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2154"></a>
+<span class="sourceLineNo">2155</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2155"></a>
+<span class="sourceLineNo">2156</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2156"></a>
+<span class="sourceLineNo">2157</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2157"></a>
+<span class="sourceLineNo">2158</span>    }<a name="line.2158"></a>
+<span class="sourceLineNo">2159</span>  }<a name="line.2159"></a>
+<span class="sourceLineNo">2160</span><a name="line.2160"></a>
+<span class="sourceLineNo">2161</span>  /*<a name="line.2161"></a>
+<span class="sourceLineNo">2162</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2162"></a>
+<span class="sourceLineNo">2163</span>   * belongs to a non-system table.<a name="line.2163"></a>
+<span class="sourceLineNo">2164</span>   */<a name="line.2164"></a>
+<span class="sourceLineNo">2165</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2165"></a>
+<span class="sourceLineNo">2166</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2166"></a>
+<span class="sourceLineNo">2167</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2167"></a>
+<span class="sourceLineNo">2168</span>  }<a name="line.2168"></a>
+<span class="sourceLineNo">2169</span><a name="line.2169"></a>
+<span class="sourceLineNo">2170</span>  // ============================================================================================<a name="line.2170"></a>
+<span class="sourceLineNo">2171</span>  // Assign Queue (Assign/Balance)<a name="line.2171"></a>
 <span class="sourceLineNo">2172</span>  // ============================================================================================<a name="line.2172"></a>
-<span class="sourceLineNo">2173</span>  // Assign Queue (Assign/Balance)<a name="line.2173"></a>
-<span class="sourceLineNo">2174</span>  // ============================================================================================<a name="line.2174"></a>
-<span class="sourceLineNo">2175</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2175"></a>
-<span class="sourceLineNo">2176</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2176"></a>
-<span class="sourceLineNo">2177</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2177"></a>
-<span class="sourceLineNo">2178</span><a name="line.2178"></a>
-<span class="sourceLineNo">2179</span>  /**<a name="line.2179"></a>
-<span class="sourceLineNo">2180</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2180"></a>
-<span class="sourceLineNo">2181</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2181"></a>
-<span class="sourceLineNo">2182</span>   */<a name="line.2182"></a>
-<span class="sourceLineNo">2183</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2183"></a>
-<span class="sourceLineNo">2184</span>    regionNode.getProcedureEvent().suspend();<a name="line.2184"></a>
-<span class="sourceLineNo">2185</span><a name="line.2185"></a>
-<span class="sourceLineNo">2186</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2186"></a>
-<span class="sourceLineNo">2187</span>    assignQueueLock.lock();<a name="line.2187"></a>
-<span class="sourceLineNo">2188</span>    try {<a name="line.2188"></a>
-<span class="sourceLineNo">2189</span>      pendingAssignQueue.add(regionNode);<a name="line.2189"></a>
-<span class="sourceLineNo">2190</span>      if (<a name="line.2190"></a>
-<span class="sourceLineNo">2191</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2191"></a>
-<span class="sourceLineNo">2192</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2192"></a>
-<span class="sourceLineNo">2193</span>      ) {<a name="line.2193"></a>
-<span class="sourceLineNo">2194</span>        assignQueueFullCond.signal();<a name="line.2194"></a>
-<span class="sourceLineNo">2195</span>      }<a name="line.2195"></a>
-<span class="sourceLineNo">2196</span>    } finally {<a name="line.2196"></a>
-<span class="sourceLineNo">2197</span>      assignQueueLock.unlock();<a name="line.2197"></a>
-<span class="sourceLineNo">2198</span>    }<a name="line.2198"></a>
-<span class="sourceLineNo">2199</span>  }<a name="line.2199"></a>
-<span class="sourceLineNo">2200</span><a name="line.2200"></a>
-<span class="sourceLineNo">2201</span>  private void startAssignmentThread() {<a name="line.2201"></a>
-<span class="sourceLineNo">2202</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2202"></a>
-<span class="sourceLineNo">2203</span>      @Override<a name="line.2203"></a>
-<span class="sourceLineNo">2204</span>      public void run() {<a name="line.2204"></a>
-<span class="sourceLineNo">2205</span>        while (isRunning()) {<a name="line.2205"></a>
-<span class="sourceLineNo">2206</span>          processAssignQueue();<a name="line.2206"></a>
-<span class="sourceLineNo">2207</span>        }<a name="line.2207"></a>
-<span class="sourceLineNo">2208</span>        pendingAssignQueue.clear();<a name="line.2208"></a>
-<span class="sourceLineNo">2209</span>      }<a name="line.2209"></a>
-<span class="sourceLineNo">2210</span>    };<a name="line.2210"></a>
-<span class="sourceLineNo">2211</span>    assignThread.setDaemon(true);<a name="line.2211"></a>
-<span class="sourceLineNo">2212</span>    assignThread.start();<a name="line.2212"></a>
-<span class="sourceLineNo">2213</span>  }<a name="line.2213"></a>
-<span class="sourceLineNo">2214</span><a name="line.2214"></a>
-<span class="sourceLineNo">2215</span>  private void stopAssignmentThread() {<a name="line.2215"></a>
-<span class="sourceLineNo">2216</span>    assignQueueSignal();<a name="line.2216"></a>
-<span class="sourceLineNo">2217</span>    try {<a name="line.2217"></a>
-<span class="sourceLineNo">2218</span>      while (assignThread.isAlive()) {<a name="line.2218"></a>
-<span class="sourceLineNo">2219</span>        assignQueueSignal();<a name="line.2219"></a>
-<span class="sourceLineNo">2220</span>        assignThread.join(250);<a name="line.2220"></a>
-<span class="sourceLineNo">2221</span>      }<a name="line.2221"></a>
-<span class="sourceLineNo">2222</span>    } catch (InterruptedException e) {<a name="line.2222"></a>
-<span class="sourceLineNo">2223</span>      LOG.warn("join interrupted", e);<a name="line.2223"></a>
-<span class="sourceLineNo">2224</span>      Thread.currentThread().interrupt();<a name="line.2224"></a>
-<span class="sourceLineNo">2225</span>    }<a name="line.2225"></a>
-<span class="sourceLineNo">2226</span>  }<a name="line.2226"></a>
-<span class="sourceLineNo">2227</span><a name="line.2227"></a>
-<span class="sourceLineNo">2228</span>  private void assignQueueSignal() {<a name="line.2228"></a>
-<span class="sourceLineNo">2229</span>    assignQueueLock.lock();<a name="line.2229"></a>
-<span class="sourceLineNo">2230</span>    try {<a name="line.2230"></a>
-<span class="sourceLineNo">2231</span>      assignQueueFullCond.signal();<a name="line.2231"></a>
-<span class="sourceLineNo">2232</span>    } finally {<a name="line.2232"></a>
-<span class="sourceLineNo">2233</span>      assignQueueLock.unlock();<a name="line.2233"></a>
-<span class="sourceLineNo">2234</span>    }<a name="line.2234"></a>
-<span class="sourceLineNo">2235</span>  }<a name="line.2235"></a>
-<span class="sourceLineNo">2236</span><a name="line.2236"></a>
-<span class="sourceLineNo">2237</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2237"></a>
-<span class="sourceLineNo">2238</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2238"></a>
-<span class="sourceLineNo">2239</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2239"></a>
-<span class="sourceLineNo">2240</span><a name="line.2240"></a>
-<span class="sourceLineNo">2241</span>    assignQueueLock.lock();<a name="line.2241"></a>
-<span class="sourceLineNo">2242</span>    try {<a name="line.2242"></a>
-<span class="sourceLineNo">2243</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2243"></a>
-<span class="sourceLineNo">2244</span>        assignQueueFullCond.await();<a name="line.2244"></a>
-<span class="sourceLineNo">2245</span>      }<a name="line.2245"></a>
-<span class="sourceLineNo">2246</span><a name="line.2246"></a>
-<span class="sourceLineNo">2247</span>      if (!isRunning()) {<a name="line.2247"></a>
-<span class="sourceLineNo">2248</span>        return null;<a name="line.2248"></a>
-<span class="sourceLineNo">2249</span>      }<a name="line.2249"></a>
-<span class="sourceLineNo">2250</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2250"></a>
-<span class="sourceLineNo">2251</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2251"></a>
-<span class="sourceLineNo">2252</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2252"></a>
-<span class="sourceLineNo">2253</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2253"></a>
-<span class="sourceLineNo">2254</span>      }<a name="line.2254"></a>
-<span class="sourceLineNo">2255</span>      pendingAssignQueue.clear();<a name="line.2255"></a>
-<span class="sourceLineNo">2256</span>    } catch (InterruptedException e) {<a name="line.2256"></a>
-<span class="sourceLineNo">2257</span>      LOG.warn("got interrupted ", e);<a name="line.2257"></a>
-<span class="sourceLineNo">2258</span>      Thread.currentThread().interrupt();<a name="line.2258"></a>
-<span class="sourceLineNo">2259</span>    } finally {<a name="line.2259"></a>
-<span class="sourceLineNo">2260</span>      assignQueueLock.unlock();<a name="line.2260"></a>
-<span class="sourceLineNo">2261</span>    }<a name="line.2261"></a>
-<span class="sourceLineNo">2262</span>    return regions;<a name="line.2262"></a>
-<span class="sourceLineNo">2263</span>  }<a name="line.2263"></a>
-<span class="sourceLineNo">2264</span><a name="line.2264"></a>
-<span class="sourceLineNo">2265</span>  private void processAssignQueue() {<a name="line.2265"></a>
-<span class="sourceLineNo">2266</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2266"></a>
-<span class="sourceLineNo">2267</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2267"></a>
-<span class="sourceLineNo">2268</span>      return;<a name="line.2268"></a>
-<span class="sourceLineNo">2269</span>    }<a name="line.2269"></a>
-<span class="sourceLineNo">2270</span><a name="line.2270"></a>
-<span class="sourceLineNo">2271</span>    if (LOG.isTraceEnabled()) {<a name="line.2271"></a>
-<span class="sourceLineNo">2272</span>      LOG.trace("PROCESS ASSIGN QUEUE regionCount=" + regions.size());<a name="line.2272"></a>
-<span class="sourceLineNo">2273</span>    }<a name="line.2273"></a>
-<span class="sourceLineNo">2274</span><a name="line.2274"></a>
-<span class="sourceLineNo">2275</span>    // TODO: Optimize balancer. pass a RegionPlan?<a name="line.2275"></a>
-<span class="sourceLineNo">2276</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap = new HashMap&lt;&gt;();<a name="line.2276"></a>
-<span class="sourceLineNo">2277</span>    final List&lt;RegionInfo&gt; userHRIs = new ArrayList&lt;&gt;(regions.size());<a name="line.2277"></a>
-<span class="sourceLineNo">2278</span>    // Regions for system tables requiring reassignment<a name="line.2278"></a>
-<span class="sourceLineNo">2279</span>    final List&lt;RegionInfo&gt; systemHRIs = new ArrayList&lt;&gt;();<a name="line.2279"></a>
-<span class="sourceLineNo">2280</span>    for (RegionStateNode regionStateNode : regions.values()) {<a name="line.2280"></a>
-<span class="sourceLineNo">2281</span>      boolean sysTable = regionStateNode.isSystemTable();<a name="line.2281"></a>
-<span class="sourceLineNo">2282</span>      final List&lt;RegionInfo&gt; hris = sysTable ? systemHRIs : userHRIs;<a name="line.2282"></a>
-<span class="sourceLineNo">2283</span>      if (regionStateNode.getRegionLocation() != null) {<a name="line.2283"></a>
-<span class="sourceLineNo">2284</span>        retainMap.put(regionStateNode.getRegionInfo(), regionStateNode.getRegionLocation());<a name="line.2284"></a>
-<span class="sourceLineNo">2285</span>      } else {<a name="line.2285"></a>
-<span class="sourceLineNo">2286</span>        hris.add(regionStateNode.getRegionInfo());<a name="line.2286"></a>
-<span class="sourceLineNo">2287</span>      }<a name="line.2287"></a>
-<span class="sourceLineNo">2288</span>    }<a name="line.2288"></a>
+<span class="sourceLineNo">2173</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2173"></a>
+<span class="sourceLineNo">2174</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2174"></a>
+<span class="sourceLineNo">2175</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2175"></a>
+<span class="sourceLineNo">2176</span><a name="line.2176"></a>
+<span class="sourceLineNo">2177</span>  /**<a name="line.2177"></a>
+<span class="sourceLineNo">2178</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2178"></a>
+<span class="sourceLineNo">2179</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2179"></a>
+<span class="sourceLineNo">2180</span>   */<a name="line.2180"></a>
+<span class="sourceLineNo">2181</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2181"></a>
+<span class="sourceLineNo">2182</span>    regionNode.getProcedureEvent().suspend();<a name="line.2182"></a>
+<span class="sourceLineNo">2183</span><a name="line.2183"></a>
+<span class="sourceLineNo">2184</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2184"></a>
+<span class="sourceLineNo">2185</span>    assignQueueLock.lock();<a name="line.2185"></a>
+<span class="sourceLineNo">2186</span>    try {<a name="line.2186"></a>
+<span class="sourceLineNo">2187</span>      pendingAssignQueue.add(regionNode);<a name="line.2187"></a>
+<span class="sourceLineNo">2188</span>      if (<a name="line.2188"></a>
+<span class="sourceLineNo">2189</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2189"></a>
+<span class="sourceLineNo">2190</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2190"></a>
+<span class="sourceLineNo">2191</span>      ) {<a name="line.2191"></a>
+<span class="sourceLineNo">2192</span>        assignQueueFullCond.signal();<a name="line.2192"></a>
+<span class="sourceLineNo">2193</span>      }<a name="line.2193"></a>
+<span class="sourceLineNo">2194</span>    } finally {<a name="line.2194"></a>
+<span class="sourceLineNo">2195</span>      assignQueueLock.unlock();<a name="line.2195"></a>
+<span class="sourceLineNo">2196</span>    }<a name="line.2196"></a>
+<span class="sourceLineNo">2197</span>  }<a name="line.2197"></a>
+<span class="sourceLineNo">2198</span><a name="line.2198"></a>
+<span class="sourceLineNo">2199</span>  private void startAssignmentThread() {<a name="line.2199"></a>
+<span class="sourceLineNo">2200</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2200"></a>
+<span class="sourceLineNo">2201</span>      @Override<a name="line.2201"></a>
+<span class="sourceLineNo">2202</span>      public void run() {<a name="line.2202"></a>
+<span class="sourceLineNo">2203</span>        while (isRunning()) {<a name="line.2203"></a>
+<span class="sourceLineNo">2204</span>          processAssignQueue();<a name="line.2204"></a>
+<span class="sourceLineNo">2205</span>        }<a name="line.2205"></a>
+<span class="sourceLineNo">2206</span>        pendingAssignQueue.clear();<a name="line.2206"></a>
+<span class="sourceLineNo">2207</span>      }<a name="line.2207"></a>
+<span class="sourceLineNo">2208</span>    };<a name="line.2208"></a>
+<span class="sourceLineNo">2209</span>    assignThread.setDaemon(true);<a name="line.2209"></a>
+<span class="sourceLineNo">2210</span>    assignThread.start();<a name="line.2210"></a>
+<span class="sourceLineNo">2211</span>  }<a name="line.2211"></a>
+<span class="sourceLineNo">2212</span><a name="line.2212"></a>
+<span class="sourceLineNo">2213</span>  private void stopAssignmentThread() {<a name="line.2213"></a>
+<span class="sourceLineNo">2214</span>    assignQueueSignal();<a name="line.2214"></a>
+<span class="sourceLineNo">2215</span>    try {<a name="line.2215"></a>
+<span class="sourceLineNo">2216</span>      while (assignThread.isAlive()) {<a name="line.2216"></a>
+<span class="sourceLineNo">2217</span>        assignQueueSignal();<a name="line.2217"></a>
+<span class="sourceLineNo">2218</span>        assignThread.join(250);<a name="line.2218"></a>
+<span class="sourceLineNo">2219</span>      }<a name="line.2219"></a>
+<span class="sourceLineNo">2220</span>    } catch (InterruptedException e) {<a name="line.2220"></a>
+<span class="sourceLineNo">2221</span>      LOG.warn("join interrupted", e);<a name="line.2221"></a>
+<span class="sourceLineNo">2222</span>      Thread.currentThread().interrupt();<a name="line.2222"></a>
+<span class="sourceLineNo">2223</span>    }<a name="line.2223"></a>
+<span class="sourceLineNo">2224</span>  }<a name="line.2224"></a>
+<span class="sourceLineNo">2225</span><a name="line.2225"></a>
+<span class="sourceLineNo">2226</span>  private void assignQueueSignal() {<a name="line.2226"></a>
+<span class="sourceLineNo">2227</span>    assignQueueLock.lock();<a name="line.2227"></a>
+<span class="sourceLineNo">2228</span>    try {<a name="line.2228"></a>
+<span class="sourceLineNo">2229</span>      assignQueueFullCond.signal();<a name="line.2229"></a>
+<span class="sourceLineNo">2230</span>    } finally {<a name="line.2230"></a>
+<span class="sourceLineNo">2231</span>      assignQueueLock.unlock();<a name="line.2231"></a>
+<span class="sourceLineNo">2232</span>    }<a name="line.2232"></a>
+<span class="sourceLineNo">2233</span>  }<a name="line.2233"></a>
+<span class="sourceLineNo">2234</span><a name="line.2234"></a>
+<span class="sourceLineNo">2235</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2235"></a>
+<span class="sourceLineNo">2236</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2236"></a>
+<span class="sourceLineNo">2237</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2237"></a>
+<span class="sourceLineNo">2238</span><a name="line.2238"></a>
+<span class="sourceLineNo">2239</span>    assignQueueLock.lock();<a name="line.2239"></a>
+<span class="sourceLineNo">2240</span>    try {<a name="line.2240"></a>
+<span class="sourceLineNo">2241</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2241"></a>
+<span class="sourceLineNo">2242</span>        assignQueueFullCond.await();<a name="line.2242"></a>
+<span class="sourceLineNo">2243</span>      }<a name="line.2243"></a>
+<span class="sourceLineNo">2244</span><a name="line.2244"></a>
+<span class="sourceLineNo">2245</span>      if (!isRunning()) {<a name="line.2245"></a>
+<span class="sourceLineNo">2246</span>        return null;<a name="line.2246"></a>
+<span class="sourceLineNo">2247</span>      }<a name="line.2247"></a>
+<span class="sourceLineNo">2248</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2248"></a>
+<span class="sourceLineNo">2249</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2249"></a>
+<span class="sourceLineNo">2250</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2250"></a>
+<span class="sourceLineNo">2251</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2251"></a>
+<span class="sourceLineNo">2252</span>      }<a name="line.2252"></a>
+<span class="sourceLineNo">2253</span>      pendingAssignQueue.clear();<a name="line.2253"></a>
+<span class="sourceLineNo">2254</span>    } catch (InterruptedException e) {<a name="line.2254"></a>
+<span class="sourceLineNo">2255</span>      LOG.warn("got interrupted ", e);<a name="line.2255"></a>
+<span class="sourceLineNo">2256</span>      Thread.currentThread().interrupt();<a name="line.2256"></a>
+<span class="sourceLineNo">2257</span>    } finally {<a name="line.2257"></a>
+<span class="sourceLineNo">2258</span>      assignQueueLock.unlock();<a name="line.2258"></a>
+<span class="sourceLineNo">2259</span>    }<a name="line.2259"></a>
+<span class="sourceLineNo">2260</span>    return regions;<a name="line.2260"></a>
+<span class="sourceLineNo">2261</span>  }<a name="line.2261"></a>
+<span class="sourceLineNo">2262</span><a name="line.2262"></a>
+<span class="sourceLineNo">2263</span>  private void processAssignQueue() {<a name="line.2263"></a>
+<span class="sourceLineNo">2264</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2264"></a>
+<span class="sourceLineNo">2265</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2265"></a>
+<span class="sourceLineNo">2266</span>      return;<a name="line.2266"></a>
+<span class="sourceLineNo">2267</span>    }<a name="line.2267"></a>
+<span class="sourceLineNo">2268</span><a name="line.2268"></a>
+<span class="sourceLineNo">2269</span>    if (LOG.isTraceEnabled()) {<a name="line.2269"></a>
+<span class="sourceLineNo">2270</span>      LOG.trace("PROCESS ASSIGN QUEUE regionCount=" + regions.size());<a name="line.2270"></a>
+<span class="sourceLineNo">2271</span>    }<a name="line.2271"></a>
+<span class="sourceLineNo">2272</span><a name="line.2272"></a>
+<span class="sourceLineNo">2273</span>    // TODO: Optimize balancer. pass a RegionPlan?<a name="line.2273"></a>
+<span class="sourceLineNo">2274</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap = new HashMap&lt;&gt;();<a name="line.2274"></a>
+<span class="sourceLineNo">2275</span>    final List&lt;RegionInfo&gt; userHRIs = new ArrayList&lt;&gt;(regions.size());<a name="line.2275"></a>
+<span class="sourceLineNo">2276</span>    // Regions for system tables requiring reassignment<a name="line.2276"></a>
+<span class="sourceLineNo">2277</span>    final List&lt;RegionInfo&gt; systemHRIs = new ArrayList&lt;&gt;();<a name="line.2277"></a>
+<span class="sourceLineNo">2278</span>    for (RegionStateNode regionStateNode : regions.values()) {<a name="line.2278"></a>
+<span class="sourceLineNo">2279</span>      boolean sysTable = regionStateNode.isSystemTable();<a name="line.2279"></a>
+<span class="sourceLineNo">2280</span>      final List&lt;RegionInfo&gt; hris = sysTable ? systemHRIs : userHRIs;<a name="line.2280"></a>
+<span class="sourceLineNo">2281</span>      if (regionStateNode.getRegionLocation() != null) {<a name="line.2281"></a>
+<span class="sourceLineNo">2282</span>        retainMap.put(regionStateNode.getRegionInfo(), regionStateNode.getRegionLocation());<a name="line.2282"></a>
+<span class="sourceLineNo">2283</span>      } else {<a name="line.2283"></a>
+<span class="sourceLineNo">2284</span>        hris.add(regionStateNode.getRegionInfo());<a name="line.2284"></a>
+<span class="sourceLineNo">2285</span>      }<a name="line.2285"></a>
+<span class="sourceLineNo">2286</span>    }<a name="line.2286"></a>
+<span class="sourceLineNo">2287</span><a name="line.2287"></a>
+<span class="sourceLineNo">2288</span>    // TODO: connect with the listener to invalidate the cache<a name="line.2288"></a>
 <span class="sourceLineNo">2289</span><a name="line.2289"></a>
-<span class="sourceLineNo">2290</span>    // TODO: connect with the listener to invalidate the cache<a name="line.2290"></a>
-<span class="sourceLineNo">2291</span><a name="line.2291"></a>
-<span class="sourceLineNo">2292</span>    // TODO use events<a name="line.2292"></a>
-<span class="sourceLineNo">2293</span>    List&lt;ServerName&gt; servers = master.getServerManager().createDestinationServersList();<a name="line.2293"></a>
-<span class="sourceLineNo">2294</span>    for (int i = 0; servers.size() &lt; 1; ++i) {<a name="line.2294"></a>
-<span class="sourceLineNo">2295</span>      // Report every fourth time around this loop; try not to flood log.<a name="line.2295"></a>
-<span class="sourceLineNo">2296</span>      if (i % 4 == 0) {<a name="line.2296"></a>
-<span class="sourceLineNo">2297</span>        LOG.warn("No servers available; cannot place " + regions.size() + " unassigned regions.");<a name="line.2297"></a>
-<span class="sourceLineNo">2298</span>      }<a name="line.2298"></a>
-<span class="sourceLineNo">2299</span><a name="line.2299"></a>
-<span class="sourceLineNo">2300</span>      if (!isRunning()) {<a name="line.2300"></a>
-<span class="sourceLineNo">2301</span>        LOG.debug("Stopped! Dropping assign of " + regions.size() + " queued regions.");<a name="line.2301"></a>
-<span class="sourceLineNo">2302</span>        return;<a name="line.2302"></a>
-<span class="sourceLineNo">2303</span>      }<a name="line.2303"></a>
-<span class="sourceLineNo">2304</span>      Threads.sleep(250);<a name="line.2304"></a>
-<span class="sourceLineNo">2305</span>      servers = master.getServerManager().createDestinationServersList();<a name="line.2305"></a>
-<span class="sourceLineNo">2306</span>    }<a name="line.2306"></a>
-<span class="sourceLineNo">2307</span><a name="line.2307"></a>
-<span class="sourceLineNo">2308</span>    if (!systemHRIs.isEmpty()) {<a name="line.2308"></a>
-<span class="sourceLineNo">2309</span>      // System table regions requiring reassignment are present, get region servers<a name="line.2309"></a>
-<span class="sourceLineNo">2310</span>      // not available for system table regions<a name="line.2310"></a>
-<span class="sourceLineNo">2311</span>      final List&lt;ServerName&gt; excludeServers = getExcludedServersForSystemTable();<a name="line.2311"></a>
-<span class="sourceLineNo">2312</span>      List&lt;ServerName&gt; serversForSysTables =<a name="line.2312"></a>
-<span class="sourceLineNo">2313</span>        servers.stream().filter(s -&gt; !excludeServers.contains(s)).collect(Collectors.toList());<a name="line.2313"></a>
-<span class="sourceLineNo">2314</span>      if (serversForSysTables.isEmpty()) {<a name="line.2314"></a>
-<span class="sourceLineNo">2315</span>        LOG.warn("Filtering old server versions and the excluded produced an empty set; "<a name="line.2315"></a>
-<span class="sourceLineNo">2316</span>          + "instead considering all candidate servers!");<a name="line.2316"></a>
-<span class="sourceLineNo">2317</span>      }<a name="line.2317"></a>
-<span class="sourceLineNo">2318</span>      LOG.debug("Processing assignQueue; systemServersCount=" + serversForSysTables.size()<a name="line.2318"></a>
-<span class="sourceLineNo">2319</span>        + ", allServersCount=" + servers.size());<a name="line.2319"></a>
-<span class="sourceLineNo">2320</span>      processAssignmentPlans(regions, null, systemHRIs,<a name="line.2320"></a>
-<span class="sourceLineNo">2321</span>        serversForSysTables.isEmpty() &amp;&amp; !containsBogusAssignments(regions, systemHRIs)<a name="line.2321"></a>
-<span class="sourceLineNo">2322</span>          ? servers<a name="line.2322"></a>
-<span class="sourceLineNo">2323</span>          : serversForSysTables);<a name="line.2323"></a>
-<span class="sourceLineNo">2324</span>    }<a name="line.2324"></a>
-<span class="sourceLineNo">2325</span><a name="line.2325"></a>
-<span class="sourceLineNo">2326</span>    processAssignmentPlans(regions, retainMap, userHRIs, servers);<a name="line.2326"></a>
-<span class="sourceLineNo">2327</span>  }<a name="line.2327"></a>
-<span class="sourceLineNo">2328</span><a name="line.2328"></a>
-<span class="sourceLineNo">2329</span>  private boolean containsBogusAssignments(Map&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2329"></a>
-<span class="sourceLineNo">2330</span>    List&lt;RegionInfo&gt; hirs) {<a name="line.2330"></a>
-<span class="sourceLineNo">2331</span>    for (RegionInfo ri : hirs) {<a name="line.2331"></a>
-<span class="sourceLineNo">2332</span>      if (<a name="line.2332"></a>
-<span class="sourceLineNo">2333</span>        regions.get(ri).getRegionLocation() != null<a name="line.2333"></a>
-<span class="sourceLineNo">2334</span>          &amp;&amp; regions.get(ri).getRegionLocation().equals(LoadBalancer.BOGUS_SERVER_NAME)<a name="line.2334"></a>
-<span class="sourceLineNo">2335</span>      ) {<a name="line.2335"></a>
-<span class="sourceLineNo">2336</span>        return true;<a name="line.2336"></a>
-<span class="sourceLineNo">2337</span>      }<a name="line.2337"></a>
-<span class="sourceLineNo">2338</span>    }<a name="line.2338"></a>
-<span class="sourceLineNo">2339</span>    return false;<a name="line.2339"></a>
-<span class="sourceLineNo">2340</span>  }<a name="line.2340"></a>
-<span class="sourceLineNo">2341</span><a name="line.2341"></a>
-<span class="sourceLineNo">2342</span>  private void processAssignmentPlans(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2342"></a>
-<span class="sourceLineNo">2343</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap, final List&lt;RegionInfo&gt; hris,<a name="line.2343"></a>
-<span class="sourceLineNo">2344</span>    final List&lt;ServerName&gt; servers) {<a name="line.2344"></a>
-<span class="sourceLineNo">2345</span>    boolean isTraceEnabled = LOG.isTraceEnabled();<a name="line.2345"></a>
-<span class="sourceLineNo">2346</span>    if (isTraceEnabled) {<a name="line.2346"></a>
-<span class="sourceLineNo">2347</span>      LOG.trace("Available servers count=" + servers.size() + ": " + servers);<a name="line.2347"></a>
-<span class="sourceLineNo">2348</span>    }<a name="line.2348"></a>
-<span class="sourceLineNo">2349</span><a name="line.2349"></a>
-<span class="sourceLineNo">2350</span>    final LoadBalancer balancer = getBalancer();<a name="line.2350"></a>
-<span class="sourceLineNo">2351</span>    // ask the balancer where to place regions<a name="line.2351"></a>
-<span class="sourceLineNo">2352</span>    if (retainMap != null &amp;&amp; !retainMap.isEmpty()) {<a name="line.2352"></a>
-<span class="sourceLineNo">2353</span>      if (isTraceEnabled) {<a name="line.2353"></a>
-<span class="sourceLineNo">2354</span>        LOG.trace("retain assign regions=" + retainMap);<a name="line.2354"></a>
-<span class="sourceLineNo">2355</span>      }<a name="line.2355"></a>
-<span class="sourceLineNo">2356</span>      try {<a name="line.2356"></a>
-<span class="sourceLineNo">2357</span>        acceptPlan(regions, balancer.retainAssignment(retainMap, servers));<a name="line.2357"></a>
-<span class="sourceLineNo">2358</span>      } catch (IOException e) {<a name="line.2358"></a>
-<span class="sourceLineNo">2359</span>        LOG.warn("unable to retain assignment", e);<a name="line.2359"></a>
-<span class="sourceLineNo">2360</span>        addToPendingAssignment(regions, retainMap.keySet());<a name="line.2360"></a>
-<span class="sourceLineNo">2361</span>      }<a name="line.2361"></a>
-<span class="sourceLineNo">2362</span>    }<a name="line.2362"></a>
-<span class="sourceLineNo">2363</span><a name="line.2363"></a>
-<span class="sourceLineNo">2364</span>    // TODO: Do we need to split retain and round-robin?<a name="line.2364"></a>
-<span class="sourceLineNo">2365</span>    // the retain seems to fallback to round-robin/random if the region is not in the map.<a name="line.2365"></a>
-<span class="sourceLineNo">2366</span>    if (!hris.isEmpty()) {<a name="line.2366"></a>
-<span class="sourceLineNo">2367</span>      Collections.sort(hris, RegionInfo.COMPARATOR);<a name="line.2367"></a>
-<span class="sourceLineNo">2368</span>      if (isTraceEnabled) {<a name="line.2368"></a>
-<span class="sourceLineNo">2369</span>        LOG.trace("round robin regions=" + hris);<a name="line.2369"></a>
-<span class="sourceLineNo">2370</span>      }<a name="line.2370"></a>
-<span class="sourceLineNo">2371</span>      try {<a name="line.2371"></a>
-<span class="sourceLineNo">2372</span>        acceptPlan(regions, balancer.roundRobinAssignment(hris, servers));<a name="line.2372"></a>
-<span class="sourceLineNo">2373</span>      } catch (IOException e) {<a name="line.2373"></a>
-<span class="sourceLineNo">2374</span>        LOG.warn("unable to round-robin assignment", e);<a name="line.2374"></a>
-<span class="sourceLineNo">2375</span>        addToPendingAssignment(regions, hris);<a name="line.2375"></a>
-<span class="sourceLineNo">2376</span>      }<a name="line.2376"></a>
-<span class="sourceLineNo">2377</span>    }<a name="line.2377"></a>
-<span class="sourceLineNo">2378</span>  }<a name="line.2378"></a>
-<span class="sourceLineNo">2379</span><a name="line.2379"></a>
-<span class="sourceLineNo">2380</span>  private void acceptPlan(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2380"></a>
-<span class="sourceLineNo">2381</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; plan) throws HBaseIOException {<a name="line.2381"></a>
-<span class="sourceLineNo">2382</span>    final ProcedureEvent&lt;?&gt;[] events = new ProcedureEvent[regions.size()];<a name="line.2382"></a>
-<span class="sourceLineNo">2383</span>    final long st = EnvironmentEdgeManager.currentTime();<a name="line.2383"></a>
-<span class="sourceLineNo">2384</span><a name="line.2384"></a>
-<span class="sourceLineNo">2385</span>    if (plan.isEmpty()) {<a name="line.2385"></a>
-<span class="sourceLineNo">2386</span>      throw new HBaseIOException("unable to compute plans for regions=" + regions.size());<a name="line.2386"></a>
-<span class="sourceLineNo">2387</span>    }<a name="line.2387"></a>
-<span class="sourceLineNo">2388</span><a name="line.2388"></a>
-<span class="sourceLineNo">2389</span>    int evcount = 0;<a name="line.2389"></a>
-<span class="sourceLineNo">2390</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : plan.entrySet()) {<a name="line.2390"></a>
-<span class="sourceLineNo">2391</span>      final ServerName server = entry.getKey();<a name="line.2391"></a>
-<span class="sourceLineNo">2392</span>      for (RegionInfo hri : entry.getValue()) {<a name="line.2392"></a>
-<span class="sourceLineNo">2393</span>        final RegionStateNode regionNode = regions.get(hri);<a name="line.2393"></a>
-<span class="sourceLineNo">2394</span>        regionNode.setRegionLocation(server);<a name="line.2394"></a>
-<span class="sourceLineNo">2395</span>        if (server.equals(LoadBalancer.BOGUS_SERVER_NAME) &amp;&amp; regionNode.isSystemTable()) {<a name="line.2395"></a>
-<span class="sourceLineNo">2396</span>          assignQueueLock.lock();<a name="line.2396"></a>
-<span class="sourceLineNo">2397</span>          try {<a name="line.2397"></a>
-<span class="sourceLineNo">2398</span>            pendingAssignQueue.add(regionNode);<a name="line.2398"></a>
-<span class="sourceLineNo">2399</span>          } finally {<a name="line.2399"></a>
-<span class="sourceLineNo">2400</span>            assignQueueLock.unlock();<a name="line.2400"></a>
-<span class="sourceLineNo">2401</span>          }<a name="line.2401"></a>
-<span class="sourceLineNo">2402</span>        } else {<a name="line.2402"></a>
-<span class="sourceLineNo">2403</span>          events[evcount++] = regionNode.getProcedureEvent();<a name="line.2403"></a>
-<span class="sourceLineNo">2404</span>        }<a name="line.2404"></a>
-<span class="sourceLineNo">2405</span>      }<a name="line.2405"></a>
-<span class="sourceLineNo">2406</span>    }<a name="line.2406"></a>
-<span class="sourceLineNo">2407</span>    ProcedureEvent.wakeEvents(getProcedureScheduler(), events);<a name="line.2407"></a>
-<span class="sourceLineNo">2408</span><a name="line.2408"></a>
-<span class="sourceLineNo">2409</span>    final long et = EnvironmentEdgeManager.currentTime();<a name="line.2409"></a>
-<span class="sourceLineNo">2410</span>    if (LOG.isTraceEnabled()) {<a name="line.2410"></a>
-<span class="sourceLineNo">2411</span>      LOG.trace("ASSIGN ACCEPT " + events.length + " -&gt; " + StringUtils.humanTimeDiff(et - st));<a name="line.2411"></a>
-<span class="sourceLineNo">2412</span>    }<a name="line.2412"></a>
-<span class="sourceLineNo">2413</span>  }<a name="line.2413"></a>
-<span class="sourceLineNo">2414</span><a name="line.2414"></a>
-<span class="sourceLineNo">2415</span>  private void addToPendingAssignment(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2415"></a>
-<span class="sourceLineNo">2416</span>    final Collection&lt;RegionInfo&gt; pendingRegions) {<a name="line.2416"></a>
-<span class="sourceLineNo">2417</span>    assignQueueLock.lock();<a name="line.2417"></a>
-<span class="sourceLineNo">2418</span>    try {<a name="line.2418"></a>
-<span class="sourceLineNo">2419</span>      for (RegionInfo hri : pendingRegions) {<a name="line.2419"></a>
-<span class="sourceLineNo">2420</span>        pendingAssignQueue.add(regions.get(hri));<a name="line.2420"></a>
-<span class="sourceLineNo">2421</span>      }<a name="line.2421"></a>
-<span class="sourceLineNo">2422</span>    } finally {<a name="line.2422"></a>
-<span class="sourceLineNo">2423</span>      assignQueueLock.unlock();<a name="line.2423"></a>
-<span class="sourceLineNo">2424</span>    }<a name="line.2424"></a>
-<span class="sourceLineNo">2425</span>  }<a name="line.2425"></a>
-<span class="sourceLineNo">2426</span><a name="line.2426"></a>
-<span class="sourceLineNo">2427</span>  /**<a name="line.2427"></a>
-<span class="sourceLineNo">2428</span>   * For a given cluster with mixed versions of servers, get a list of servers with lower versions,<a name="line.2428"></a>
-<span class="sourceLineNo">2429</span>   * where system table regions should not be assigned to. For system table, we must assign regions<a name="line.2429"></a>
-<span class="sourceLineNo">2430</span>   * to a server with highest version. However, we can disable this exclusion using config:<a name="line.2430"></a>
-<span class="sourceLineNo">2431</span>   * "hbase.min.version.move.system.tables" if checkForMinVersion is true. Detailed explanation<a name="line.2431"></a>
-<span class="sourceLineNo">2432</span>   * available with definition of minVersionToMoveSysTables.<a name="line.2432"></a>
-<span class="sourceLineNo">2433</span>   * @return List of Excluded servers for System table regions.<a name="line.2433"></a>
-<span class="sourceLineNo">2434</span>   */<a name="line.2434"></a>
-<span class="sourceLineNo">2435</span>  public List&lt;ServerName&gt; getExcludedServersForSystemTable() {<a name="line.2435"></a>
-<span class="sourceLineNo">2436</span>    // TODO: This should be a cached list kept by the ServerManager rather than calculated on each<a name="line.2436"></a>
-<span class="sourceLineNo">2437</span>    // move or system region assign. The RegionServerTracker keeps list of online Servers with<a name="line.2437"></a>
-<span class="sourceLineNo">2438</span>    // RegionServerInfo that includes Version.<a name="line.2438"></a>
-<span class="sourceLineNo">2439</span>    List&lt;Pair&lt;ServerName, String&gt;&gt; serverList =<a name="line.2439"></a>
-<span class="sourceLineNo">2440</span>      master.getServerManager().getOnlineServersList().stream()<a name="line.2440"></a>
-<span class="sourceLineNo">2441</span>        .map(s -&gt; new Pair&lt;&gt;(s, master.getRegionServerVersion(s))).collect(Collectors.toList());<a name="line.2441"></a>
-<span class="sourceLineNo">2442</span>    if (serverList.isEmpty()) {<a name="line.2442"></a>
-<span class="sourceLineNo">2443</span>      return new ArrayList&lt;&gt;();<a name="line.2443"></a>
-<span class="sourceLineNo">2444</span>    }<a name="line.2444"></a>
-<span class="sourceLineNo">2445</span>    String highestVersion = Collections<a name="line.2445"></a>
-<span class="sourceLineNo">2446</span>      .max(serverList, (o1, o2) -&gt; VersionInfo.compareVersion(o1.getSecond(), o2.getSecond()))<a name="line.2446"></a>
-<span class="sourceLineNo">2447</span>      .getSecond();<a name="line.2447"></a>
-<span class="sourceLineNo">2448</span>    if (!DEFAULT_MIN_VERSION_MOVE_SYS_TABLES_CONFIG.equals(minVersionToMoveSysTables)) {<a name="line.2448"></a>
-<span class="sourceLineNo">2449</span>      int comparedValue = VersionInfo.compareVersion(minVersionToMoveSysTables, highestVersion);<a name="line.2449"></a>
-<span class="sourceLineNo">2450</span>      if (comparedValue &gt; 0) {<a name="line.2450"></a>
-<span class="sourceLineNo">2451</span>        return new ArrayList&lt;&gt;();<a name="line.2451"></a>
-<span class="sourceLineNo">2452</span>      }<a name="line.2452"></a>
-<span class="sourceLineNo">2453</span>    }<a name="line.2453"></a>
-<span class="sourceLineNo">2454</span>    return serverList.stream().filter(pair -&gt; !pair.getSecond().equals(highestVersion))<a name="line.2454"></a>
-<span class="sourceLineNo">2455</span>      .map(Pair::getFirst).collect(Collectors.toList());<a name="line.2455"></a>
-<span class="sourceLineNo">2456</span>  }<a name="line.2456"></a>
-<span class="sourceLineNo">2457</span><a name="line.2457"></a>
-<span class="sourceLineNo">2458</span>  MasterServices getMaster() {<a name="line.2458"></a>
-<span class="sourceLineNo">2459</span>    return master;<a name="line.2459"></a>
-<span class="sourceLineNo">2460</span>  }<a name="line.2460"></a>
-<span class="sourceLineNo">2461</span><a name="line.2461"></a>
-<span class="sourceLineNo">2462</span>  /** Returns a snapshot of rsReports */<a name="line.2462"></a>
-<span class="sourceLineNo">2463</span>  public Map&lt;ServerName, Set&lt;byte[]&gt;&gt; getRSReports() {<a name="line.2463"></a>
-<span class="sourceLineNo">2464</span>    Map&lt;ServerName, Set&lt;byte[]&gt;&gt; rsReportsSnapshot = new HashMap&lt;&gt;();<a name="line.2464"></a>
-<span class="sourceLineNo">2465</span>    synchronized (rsReports) {<a name="line.2465"></a>
-<span class="sourceLineNo">2466</span>      rsReports.entrySet().forEach(e -&gt; rsReportsSnapshot.put(e.getKey(), e.getValue()));<a name="line.2466"></a>
-<span class="sourceLineNo">2467</span>    }<a name="line.2467"></a>
-<span class="sourceLineNo">2468</span>    return rsReportsSnapshot;<a name="line.2468"></a>
-<span class="sourceLineNo">2469</span>  }<a name="line.2469"></a>
-<span class="sourceLineNo">2470</span><a name="line.2470"></a>
-<span class="sourceLineNo">2471</span>  /**<a name="line.2471"></a>
-<span class="sourceLineNo">2472</span>   * Provide regions state count for given table. e.g howmany regions of give table are<a name="line.2472"></a>
-<span class="sourceLineNo">2473</span>   * opened/closed/rit etc<a name="line.2473"></a>
-<span class="sourceLineNo">2474</span>   * @param tableName TableName<a name="line.2474"></a>
-<span class="sourceLineNo">2475</span>   * @return region states count<a name="line.2475"></a>
-<span class="sourceLineNo">2476</span>   */<a name="line.2476"></a>
-<span class="sourceLineNo">2477</span>  public RegionStatesCount getRegionStatesCount(TableName tableName) {<a name="line.2477"></a>
-<span class="sourceLineNo">2478</span>    int openRegionsCount = 0;<a name="line.2478"></a>
-<span class="sourceLineNo">2479</span>    int closedRegionCount = 0;<a name="line.2479"></a>
-<span class="sourceLineNo">2480</span>    int ritCount = 0;<a name="line.2480"></a>
-<span class="sourceLineNo">2481</span>    int splitRegionCount = 0;<a name="line.2481"></a>
-<span class="sourceLineNo">2482</span>    int totalRegionCount = 0;<a name="line.2482"></a>
-<span class="sourceLineNo">2483</span>    if (!isTableDisabled(tableName)) {<a name="line.2483"></a>
-<span class="sourceLineNo">2484</span>      final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.2484"></a>
-<span class="sourceLineNo">2485</span>      for (RegionState regionState : states) {<a name="line.2485"></a>
-<span class="sourceLineNo">2486</span>        if (regionState.isOpened()) {<a name="line.2486"></a>
-<span class="sourceLineNo">2487</span>          openRegionsCount++;<a name="line.2487"></a>
-<span class="sourceLineNo">2488</span>        } else if (regionState.isClosed()) {<a name="line.2488"></a>
-<span class="sourceLineNo">2489</span>          closedRegionCount++;<a name="line.2489"></a>
-<span class="sourceLineNo">2490</span>        } else if (regionState.isSplit()) {<a name="line.2490"></a>
-<span class="sourceLineNo">2491</span>          splitRegionCount++;<a name="line.2491"></a>
-<span class="sourceLineNo">2492</span>        }<a name="line.2492"></a>
-<span class="sourceLineNo">2493</span>      }<a name="line.2493"></a>
-<span class="sourceLineNo">2494</span>      totalRegionCount = states.size();<a name="line.2494"></a>
-<span class="sourceLineNo">2495</span>      ritCount = totalRegionCount - openRegionsCount - splitRegionCount;<a name="line.2495"></a>
-<span class="sourceLineNo">2496</span>    }<a name="line.2496"></a>
-<span class="sourceLineNo">2497</span>    return new RegionStatesCount.RegionStatesCountBuilder().setOpenRegions(openRegionsCount)<a name="line.2497"></a>
-<span class="sourceLineNo">2498</span>      .setClosedRegions(closedRegionCount).setSplitRegions(splitRegionCount)<a name="line.2498"></a>
-<span class="sourceLineNo">2499</span>      .setRegionsInTransition(ritCount).setTotalRegions(totalRegionCount).build();<a name="line.2499"></a>
-<span class="sourceLineNo">2500</span>  }<a name="line.2500"></a>
-<span class="sourceLineNo">2501</span><a name="line.2501"></a>
-<span class="sourceLineNo">2502</span>}<a name="line.2502"></a>
+<span class="sourceLineNo">2290</span>    // TODO use events<a name="line.2290"></a>
+<span class="sourceLineNo">2291</span>    List&lt;ServerName&gt; servers = master.getServerManager().createDestinationServersList();<a name="line.2291"></a>
+<span class="sourceLineNo">2292</span>    for (int i = 0; servers.size() &lt; 1; ++i) {<a name="line.2292"></a>
+<span class="sourceLineNo">2293</span>      // Report every fourth time around this loop; try not to flood log.<a name="line.2293"></a>
+<span class="sourceLineNo">2294</span>      if (i % 4 == 0) {<a name="line.2294"></a>
+<span class="sourceLineNo">2295</span>        LOG.warn("No servers available; cannot place " + regions.size() + " unassigned regions.");<a name="line.2295"></a>
+<span class="sourceLineNo">2296</span>      }<a name="line.2296"></a>
+<span class="sourceLineNo">2297</span><a name="line.2297"></a>
+<span class="sourceLineNo">2298</span>      if (!isRunning()) {<a name="line.2298"></a>
+<span class="sourceLineNo">2299</span>        LOG.debug("Stopped! Dropping assign of " + regions.size() + " queued regions.");<a name="line.2299"></a>
+<span class="sourceLineNo">2300</span>        return;<a name="line.2300"></a>
+<span class="sourceLineNo">2301</span>      }<a name="line.2301"></a>
+<span class="sourceLineNo">2302</span>      Threads.sleep(250);<a name="line.2302"></a>
+<span class="sourceLineNo">2303</span>      servers = master.getServerManager().createDestinationServersList();<a name="line.2303"></a>
+<span class="sourceLineNo">2304</span>    }<a name="line.2304"></a>
+<span class="sourceLineNo">2305</span><a name="line.2305"></a>
+<span class="sourceLineNo">2306</span>    if (!systemHRIs.isEmpty()) {<a name="line.2306"></a>
+<span class="sourceLineNo">2307</span>      // System table regions requiring reassignment are present, get region servers<a name="line.2307"></a>
+<span class="sourceLineNo">2308</span>      // not available for system table regions<a name="line.2308"></a>
+<span class="sourceLineNo">2309</span>      final List&lt;ServerName&gt; excludeServers = getExcludedServersForSystemTable();<a name="line.2309"></a>
+<span class="sourceLineNo">2310</span>      List&lt;ServerName&gt; serversForSysTables =<a name="line.2310"></a>
+<span class="sourceLineNo">2311</span>        servers.stream().filter(s -&gt; !excludeServers.contains(s)).collect(Collectors.toList());<a name="line.2311"></a>
+<span class="sourceLineNo">2312</span>      if (serversForSysTables.isEmpty()) {<a name="line.2312"></a>
+<span class="sourceLineNo">2313</span>        LOG.warn("Filtering old server versions and the excluded produced an empty set; "<a name="line.2313"></a>
+<span class="sourceLineNo">2314</span>          + "instead considering all candidate servers!");<a name="line.2314"></a>
+<span class="sourceLineNo">2315</span>      }<a name="line.2315"></a>
+<span class="sourceLineNo">2316</span>      LOG.debug("Processing assignQueue; systemServersCount=" + serversForSysTables.size()<a name="line.2316"></a>
+<span class="sourceLineNo">2317</span>        + ", allServersCount=" + servers.size());<a name="line.2317"></a>
+<span class="sourceLineNo">2318</span>      processAssignmentPlans(regions, null, systemHRIs,<a name="line.2318"></a>
+<span class="sourceLineNo">2319</span>        serversForSysTables.isEmpty() &amp;&amp; !containsBogusAssignments(regions, systemHRIs)<a name="line.2319"></a>
+<span class="sourceLineNo">2320</span>          ? servers<a name="line.2320"></a>
+<span class="sourceLineNo">2321</span>          : serversForSysTables);<a name="line.2321"></a>
+<span class="sourceLineNo">2322</span>    }<a name="line.2322"></a>
+<span class="sourceLineNo">2323</span><a name="line.2323"></a>
+<span class="sourceLineNo">2324</span>    processAssignmentPlans(regions, retainMap, userHRIs, servers);<a name="line.2324"></a>
+<span class="sourceLineNo">2325</span>  }<a name="line.2325"></a>
+<span class="sourceLineNo">2326</span><a name="line.2326"></a>
+<span class="sourceLineNo">2327</span>  private boolean containsBogusAssignments(Map&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2327"></a>
+<span class="sourceLineNo">2328</span>    List&lt;RegionInfo&gt; hirs) {<a name="line.2328"></a>
+<span class="sourceLineNo">2329</span>    for (RegionInfo ri : hirs) {<a name="line.2329"></a>
+<span class="sourceLineNo">2330</span>      if (<a name="line.2330"></a>
+<span class="sourceLineNo">2331</span>        regions.get(ri).getRegionLocation() != null<a name="line.2331"></a>
+<span class="sourceLineNo">2332</span>          &amp;&amp; regions.get(ri).getRegionLocation().equals(LoadBalancer.BOGUS_SERVER_NAME)<a name="line.2332"></a>
+<span class="sourceLineNo">2333</span>      ) {<a name="line.2333"></a>
+<span class="sourceLineNo">2334</span>        return true;<a name="line.2334"></a>
+<span class="sourceLineNo">2335</span>      }<a name="line.2335"></a>
+<span class="sourceLineNo">2336</span>    }<a name="line.2336"></a>
+<span class="sourceLineNo">2337</span>    return false;<a name="line.2337"></a>
+<span class="sourceLineNo">2338</span>  }<a name="line.2338"></a>
+<span class="sourceLineNo">2339</span><a name="line.2339"></a>
+<span class="sourceLineNo">2340</span>  private void processAssignmentPlans(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2340"></a>
+<span class="sourceLineNo">2341</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap, final List&lt;RegionInfo&gt; hris,<a name="line.2341"></a>
+<span class="sourceLineNo">2342</span>    final List&lt;ServerName&gt; servers) {<a name="line.2342"></a>
+<span class="sourceLineNo">2343</span>    boolean isTraceEnabled = LOG.isTraceEnabled();<a name="line.2343"></a>
+<span class="sourceLineNo">2344</span>    if (isTraceEnabled) {<a name="line.2344"></a>
+<span class="sourceLineNo">2345</span>      LOG.trace("Available servers count=" + servers.size() + ": " + servers);<a name="line.2345"></a>
+<span class="sourceLineNo">2346</span>    }<a name="line.2346"></a>
+<span class="sourceLineNo">2347</span><a name="line.2347"></a>
+<span class="sourceLineNo">2348</span>    final LoadBalancer balancer = getBalancer();<a name="line.2348"></a>
+<span class="sourceLineNo">2349</span>    // ask the balancer where to place regions<a name="line.2349"></a>
+<span class="sourceLineNo">2350</span>    if (retainMap != null &amp;&amp; !retainMap.isEmpty()) {<a name="line.2350"></a>
+<span class="sourceLineNo">2351</span>      if (isTraceEnabled) {<a name="line.2351"></a>
+<span class="sourceLineNo">2352</span>        LOG.trace("retain assign regions=" + retainMap);<a name="line.2352"></a>
+<span class="sourceLineNo">2353</span>      }<a name="line.2353"></a>
+<span class="sourceLineNo">2354</span>      try {<a name="line.2354"></a>
+<span class="sourceLineNo">2355</span>        acceptPlan(regions, balancer.retainAssignment(retainMap, servers));<a name="line.2355"></a>
+<span class="sourceLineNo">2356</span>      } catch (IOException e) {<a name="line.2356"></a>
+<span class="sourceLineNo">2357</span>        LOG.warn("unable to retain assignment", e);<a name="line.2357"></a>
+<span class="sourceLineNo">2358</span>        addToPendingAssignment(regions, retainMap.keySet());<a name="line.2358"></a>
+<span class="sourceLineNo">2359</span>      }<a name="line.2359"></a>
+<span class="sourceLineNo">2360</span>    }<a name="line.2360"></a>
+<span class="sourceLineNo">2361</span><a name="line.2361"></a>
+<span class="sourceLineNo">2362</span>    // TODO: Do we need to split retain and round-robin?<a name="line.2362"></a>
+<span class="sourceLineNo">2363</span>    // the retain seems to fallback to round-robin/random if the region is not in the map.<a name="line.2363"></a>
+<span class="sourceLineNo">2364</span>    if (!hris.isEmpty()) {<a name="line.2364"></a>
+<span class="sourceLineNo">2365</span>      Collections.sort(hris, RegionInfo.COMPARATOR);<a name="line.2365"></a>
+<span class="sourceLineNo">2366</span>      if (isTraceEnabled) {<a name="line.2366"></a>
+<span class="sourceLineNo">2367</span>        LOG.trace("round robin regions=" + hris);<a name="line.2367"></a>
+<span class="sourceLineNo">2368</span>      }<a name="line.2368"></a>
+<span class="sourceLineNo">2369</span>      try {<a name="line.2369"></a>
+<span class="sourceLineNo">2370</span>        acceptPlan(regions, balancer.roundRobinAssignment(hris, servers));<a name="line.2370"></a>
+<span class="sourceLineNo">2371</span>      } catch (IOException e) {<a name="line.2371"></a>
+<span class="sourceLineNo">2372</span>        LOG.warn("unable to round-robin assignment", e);<a name="line.2372"></a>
+<span class="sourceLineNo">2373</span>        addToPendingAssignment(regions, hris);<a name="line.2373"></a>
+<span class="sourceLineNo">2374</span>      }<a name="line.2374"></a>
+<span class="sourceLineNo">2375</span>    }<a name="line.2375"></a>
+<span class="sourceLineNo">2376</span>  }<a name="line.2376"></a>
+<span class="sourceLineNo">2377</span><a name="line.2377"></a>
+<span class="sourceLineNo">2378</span>  private void acceptPlan(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2378"></a>
+<span class="sourceLineNo">2379</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; plan) throws HBaseIOException {<a name="line.2379"></a>
+<span class="sourceLineNo">2380</span>    final ProcedureEvent&lt;?&gt;[] events = new ProcedureEvent[regions.size()];<a name="line.2380"></a>
+<span class="sourceLineNo">2381</span>    final long st = EnvironmentEdgeManager.currentTime();<a name="line.2381"></a>
+<span class="sourceLineNo">2382</span><a name="line.2382"></a>
+<span class="sourceLineNo">2383</span>    if (plan.isEmpty()) {<a name="line.2383"></a>
+<span class="sourceLineNo">2384</span>      throw new HBaseIOException("unable to compute plans for regions=" + regions.size());<a name="line.2384"></a>
+<span class="sourceLineNo">2385</span>    }<a name="line.2385"></a>
+<span class="sourceLineNo">2386</span><a name="line.2386"></a>
+<span class="sourceLineNo">2387</span>    int evcount = 0;<a name="line.2387"></a>
+<span class="sourceLineNo">2388</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : plan.entrySet()) {<a name="line.2388"></a>
+<span class="sourceLineNo">2389</span>      final ServerName server = entry.getKey();<a name="line.2389"></a>
+<span class="sourceLineNo">2390</span>      for (RegionInfo hri : entry.getValue()) {<a name="line.2390"></a>
+<span class="sourceLineNo">2391</span>        final RegionStateNode regionNode = regions.get(hri);<a name="line.2391"></a>
+<span class="sourceLineNo">2392</span>        regionNode.setRegionLocation(server);<a name="line.2392"></a>
+<span class="sourceLineNo">2393</span>        if (server.equals(LoadBalancer.BOGUS_SERVER_NAME) &amp;&amp; regionNode.isSystemTable()) {<a name="line.2393"></a>
+<span class="sourceLineNo">2394</span>          assignQueueLock.lock();<a name="line.2394"></a>
+<span class="sourceLineNo">2395</span>          try {<a name="line.2395"></a>
+<span class="sourceLineNo">2396</span>            pendingAssignQueue.add(regionNode);<a name="line.2396"></a>
+<span class="sourceLineNo">2397</span>          } finally {<a name="line.2397"></a>
+<span class="sourceLineNo">2398</span>            assignQueueLock.unlock();<a name="line.2398"></a>
+<span class="sourceLineNo">2399</span>          }<a name="line.2399"></a>
+<span class="sourceLineNo">2400</span>        } else {<a name="line.2400"></a>
+<span class="sourceLineNo">2401</span>          events[evcount++] = regionNode.getProcedureEvent();<a name="line.2401"></a>
+<span class="sourceLineNo">2402</span>        }<a name="line.2402"></a>
+<span class="sourceLineNo">2403</span>      }<a name="line.2403"></a>
+<span class="sourceLineNo">2404</span>    }<a name="line.2404"></a>
+<span class="sourceLineNo">2405</span>    ProcedureEvent.wakeEvents(getProcedureScheduler(), events);<a name="line.2405"></a>
+<span class="sourceLineNo">2406</span><a name="line.2406"></a>
+<span class="sourceLineNo">2407</span>    final long et = EnvironmentEdgeManager.currentTime();<a name="line.2407"></a>
+<span class="sourceLineNo">2408</span>    if (LOG.isTraceEnabled()) {<a name="line.2408"></a>
+<span class="sourceLineNo">2409</span>      LOG.trace("ASSIGN ACCEPT " + events.length + " -&gt; " + StringUtils.humanTimeDiff(et - st));<a name="line.2409"></a>
+<span class="sourceLineNo">2410</span>    }<a name="line.2410"></a>
+<span class="sourceLineNo">2411</span>  }<a name="line.2411"></a>
+<span class="sourceLineNo">2412</span><a name="line.2412"></a>
+<span class="sourceLineNo">2413</span>  private void addToPendingAssignment(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2413"></a>
+<span class="sourceLineNo">2414</span>    final Collection&lt;RegionInfo&gt; pendingRegions) {<a name="line.2414"></a>
+<span class="sourceLineNo">2415</span>    assignQueueLock.lock();<a name="line.2415"></a>
+<span class="sourceLineNo">2416</span>    try {<a name="line.2416"></a>
+<span class="sourceLineNo">2417</span>      for (RegionInfo hri : pendingRegions) {<a name="line.2417"></a>
+<span class="sourceLineNo">2418</span>        pendingAssignQueue.add(regions.get(hri));<a name="line.2418"></a>
+<span class="sourceLineNo">2419</span>      }<a name="line.2419"></a>
+<span class="sourceLineNo">2420</span>    } finally {<a name="line.2420"></a>
+<span class="sourceLineNo">2421</span>      assignQueueLock.unlock();<a name="line.2421"></a>
+<span class="sourceLineNo">2422</span>    }<a name="line.2422"></a>
+<span class="sourceLineNo">2423</span>  }<a name="line.2423"></a>
+<span class="sourceLineNo">2424</span><a name="line.2424"></a>
+<span class="sourceLineNo">2425</span>  /**<a name="line.2425"></a>
+<span class="sourceLineNo">2426</span>   * For a given cluster with mixed versions of servers, get a list of servers with lower versions,<a name="line.2426"></a>
+<span class="sourceLineNo">2427</span>   * where system table regions should not be assigned to. For system table, we must assign regions<a name="line.2427"></a>
+<span class="sourceLineNo">2428</span>   * to a server with highest version. However, we can disable this exclusion using config:<a name="line.2428"></a>
+<span class="sourceLineNo">2429</span>   * "hbase.min.version.move.system.tables" if checkForMinVersion is true. Detailed explanation<a name="line.2429"></a>
+<span class="sourceLineNo">2430</span>   * available with definition of minVersionToMoveSysTables.<a name="line.2430"></a>
+<span class="sourceLineNo">2431</span>   * @return List of Excluded servers for System table regions.<a name="line.2431"></a>
+<span class="sourceLineNo">2432</span>   */<a name="line.2432"></a>
+<span class="sourceLineNo">2433</span>  public List&lt;ServerName&gt; getExcludedServersForSystemTable() {<a name="line.2433"></a>
+<span class="sourceLineNo">2434</span>    // TODO: This should be a cached list kept by the ServerManager rather than calculated on each<a name="line.2434"></a>
+<span class="sourceLineNo">2435</span>    // move or system region assign. The RegionServerTracker keeps list of online Servers with<a name="line.2435"></a>
+<span class="sourceLineNo">2436</span>    // RegionServerInfo that includes Version.<a name="line.2436"></a>
+<span class="sourceLineNo">2437</span>    List&lt;Pair&lt;ServerName, String&gt;&gt; serverList =<a name="line.2437"></a>
+<span class="sourceLineNo">2438</span>      master.getServerManager().getOnlineServersList().stream()<a name="line.2438"></a>
+<span class="sourceLineNo">2439</span>        .map(s -&gt; new Pair&lt;&gt;(s, master.getRegionServerVersion(s))).collect(Collectors.toList());<a name="line.2439"></a>
+<span class="sourceLineNo">2440</span>    if (serverList.isEmpty()) {<a name="line.2440"></a>
+<span class="sourceLineNo">2441</span>      return new ArrayList&lt;&gt;();<a name="line.2441"></a>
+<span class="sourceLineNo">2442</span>    }<a name="line.2442"></a>
+<span class="sourceLineNo">2443</span>    String highestVersion = Collections<a name="line.2443"></a>
+<span class="sourceLineNo">2444</span>      .max(serverList, (o1, o2) -&gt; VersionInfo.compareVersion(o1.getSecond(), o2.getSecond()))<a name="line.2444"></a>
+<span class="sourceLineNo">2445</span>      .getSecond();<a name="line.2445"></a>
+<span class="sourceLineNo">2446</span>    if (!DEFAULT_MIN_VERSION_MOVE_SYS_TABLES_CONFIG.equals(minVersionToMoveSysTables)) {<a name="line.2446"></a>
+<span class="sourceLineNo">2447</span>      int comparedValue = VersionInfo.compareVersion(minVersionToMoveSysTables, highestVersion);<a name="line.2447"></a>
+<span class="sourceLineNo">2448</span>      if (comparedValue &gt; 0) {<a name="line.2448"></a>
+<span class="sourceLineNo">2449</span>        return new ArrayList&lt;&gt;();<a name="line.2449"></a>
+<span class="sourceLineNo">2450</span>      }<a name="line.2450"></a>
+<span class="sourceLineNo">2451</span>    }<a name="line.2451"></a>
+<span class="sourceLineNo">2452</span>    return serverList.stream().filter(pair -&gt; !pair.getSecond().equals(highestVersion))<a name="line.2452"></a>
+<span class="sourceLineNo">2453</span>      .map(Pair::getFirst).collect(Collectors.toList());<a name="line.2453"></a>
+<span class="sourceLineNo">2454</span>  }<a name="line.2454"></a>
+<span class="sourceLineNo">2455</span><a name="line.2455"></a>
+<span class="sourceLineNo">2456</span>  MasterServices getMaster() {<a name="line.2456"></a>
+<span class="sourceLineNo">2457</span>    return master;<a name="line.2457"></a>
+<span class="sourceLineNo">2458</span>  }<a name="line.2458"></a>
+<span class="sourceLineNo">2459</span><a name="line.2459"></a>
+<span class="sourceLineNo">2460</span>  /** Returns a snapshot of rsReports */<a name="line.2460"></a>
+<span class="sourceLineNo">2461</span>  public Map&lt;ServerName, Set&lt;byte[]&gt;&gt; getRSReports() {<a name="line.2461"></a>
+<span class="sourceLineNo">2462</span>    Map&lt;ServerName, Set&lt;byte[]&gt;&gt; rsReportsSnapshot = new HashMap&lt;&gt;();<a name="line.2462"></a>
+<span class="sourceLineNo">2463</span>    synchronized (rsReports) {<a name="line.2463"></a>
+<span class="sourceLineNo">2464</span>      rsReports.entrySet().forEach(e -&gt; rsReportsSnapshot.put(e.getKey(), e.getValue()));<a name="line.2464"></a>
+<span class="sourceLineNo">2465</span>    }<a name="line.2465"></a>
+<span class="sourceLineNo">2466</span>    return rsReportsSnapshot;<a name="line.2466"></a>
+<span class="sourceLineNo">2467</span>  }<a name="line.2467"></a>
+<span class="sourceLineNo">2468</span><a name="line.2468"></a>
+<span class="sourceLineNo">2469</span>  /**<a name="line.2469"></a>
+<span class="sourceLineNo">2470</span>   * Provide regions state count for given table. e.g howmany regions of give table are<a name="line.2470"></a>
+<span class="sourceLineNo">2471</span>   * opened/closed/rit etc<a name="line.2471"></a>
+<span class="sourceLineNo">2472</span>   * @param tableName TableName<a name="line.2472"></a>
+<span class="sourceLineNo">2473</span>   * @return region states count<a name="line.2473"></a>
+<span class="sourceLineNo">2474</span>   */<a name="line.2474"></a>
+<span class="sourceLineNo">2475</span>  public RegionStatesCount getRegionStatesCount(TableName tableName) {<a name="line.2475"></a>
+<span class="sourceLineNo">2476</span>    int openRegionsCount = 0;<a name="line.2476"></a>
+<span class="sourceLineNo">2477</span>    int closedRegionCount = 0;<a name="line.2477"></a>
+<span class="sourceLineNo">2478</span>    int ritCount = 0;<a name="line.2478"></a>
+<span class="sourceLineNo">2479</span>    int splitRegionCount = 0;<a name="line.2479"></a>
+<span class="sourceLineNo">2480</span>    int totalRegionCount = 0;<a name="line.2480"></a>
+<span class="sourceLineNo">2481</span>    if (!isTableDisabled(tableName)) {<a name="line.2481"></a>
+<span class="sourceLineNo">2482</span>      final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.2482"></a>
+<span class="sourceLineNo">2483</span>      for (RegionState regionState : states) {<a name="line.2483"></a>
+<span class="sourceLineNo">2484</span>        if (regionState.isOpened()) {<a name="line.2484"></a>
+<span class="sourceLineNo">2485</span>          openRegionsCount++;<a name="line.2485"></a>
+<span class="sourceLineNo">2486</span>        } else if (regionState.isClosed()) {<a name="line.2486"></a>
+<span class="sourceLineNo">2487</span>          closedRegionCount++;<a name="line.2487"></a>
+<span class="sourceLineNo">2488</span>        } else if (regionState.isSplit()) {<a name="line.2488"></a>
+<span class="sourceLineNo">2489</span>          splitRegionCount++;<a name="line.2489"></a>
+<span class="sourceLineNo">2490</span>        }<a name="line.2490"></a>
+<span class="sourceLineNo">2491</span>      }<a name="line.2491"></a>
+<span class="sourceLineNo">2492</span>      totalRegionCount = states.size();<a name="line.2492"></a>
+<span class="sourceLineNo">2493</span>      ritCount = totalRegionCount - openRegionsCount - splitRegionCount;<a name="line.2493"></a>
+<span class="sourceLineNo">2494</span>    }<a name="line.2494"></a>
+<span class="sourceLineNo">2495</span>    return new RegionStatesCount.RegionStatesCountBuilder().setOpenRegions(openRegionsCount)<a name="line.2495"></a>
+<span class="sourceLineNo">2496</span>      .setClosedRegions(closedRegionCount).setSplitRegions(splitRegionCount)<a name="line.2496"></a>
+<span class="sourceLineNo">2497</span>      .setRegionsInTransition(ritCount).setTotalRegions(totalRegionCount).build();<a name="line.2497"></a>
+<span class="sourceLineNo">2498</span>  }<a name="line.2498"></a>
+<span class="sourceLineNo">2499</span><a name="line.2499"></a>
+<span class="sourceLineNo">2500</span>}<a name="line.2500"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
index ea172726b4e..09f2091a100 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionChore.html
@@ -1102,1412 +1102,1410 @@
 <span class="sourceLineNo">1094</span>    regionStateStore.deleteRegions(regions);<a name="line.1094"></a>
 <span class="sourceLineNo">1095</span>    for (int i = 0; i &lt; regions.size(); ++i) {<a name="line.1095"></a>
 <span class="sourceLineNo">1096</span>      final RegionInfo regionInfo = regions.get(i);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // we expect the region to be offline<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      regionStates.removeFromOfflineRegions(regionInfo);<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      regionStates.deleteRegion(regionInfo);<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    }<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
+<span class="sourceLineNo">1097</span>      regionStates.deleteRegion(regionInfo);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span>    }<a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>  }<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span><a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>  // ============================================================================================<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>  // RS Region Transition Report helpers<a name="line.1102"></a>
 <span class="sourceLineNo">1103</span>  // ============================================================================================<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>  // RS Region Transition Report helpers<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  // ============================================================================================<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      switch (transition.getTransitionCode()) {<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>        case OPENED:<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        case FAILED_OPEN:<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        case CLOSED:<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>          long procId =<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>          break;<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>        case READY_TO_SPLIT:<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>        case SPLIT:<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>        case SPLIT_REVERTED:<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>            splitB);<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>          break;<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>        case READY_TO_MERGE:<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>        case MERGED:<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>        case MERGE_REVERTED:<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>            mergeB);<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>          break;<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      }<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span>    }<a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>  }<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span><a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    // lock protection to wait for meta online...<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    serverNode.readLock().lock();<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span>    try {<a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1158"></a>
-<span class="sourceLineNo">1159</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>        try {<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>        } catch (PleaseHoldException e) {<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>          LOG.trace("Failed transition ", e);<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>          throw e;<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>          // if the master says that one of the region transitions failed.<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span>          LOG.warn("Failed transition", e);<a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>        }<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      } else {<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          serverName);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span>        builder.setErrorMessage("You are dead");<a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      }<a name="line.1176"></a>
-<span class="sourceLineNo">1177</span>    } finally {<a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      serverNode.readLock().unlock();<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>    }<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span><a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>    return builder.build();<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>  }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>    checkMetaLoaded(regionInfo);<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>    if (regionNode == null) {<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>      throw new UnexpectedStateException(String.format(<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>        regionInfo, state));<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>    }<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span>      regionNode, state);<a name="line.1196"></a>
-<span class="sourceLineNo">1197</span><a name="line.1197"></a>
-<span class="sourceLineNo">1198</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    regionNode.lock();<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>    try {<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>        // to CLOSED<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span>        if (<a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        ) {<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span>        } else {<a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>            regionNode, state);<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>        }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span>      }<a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>    } finally {<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>      regionNode.unlock();<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>    }<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>  }<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span><a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    ServerName serverName = serverNode.getServerName();<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    if (proc == null) {<a name="line.1228"></a>
-<span class="sourceLineNo">1229</span>      return false;<a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    }<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      serverName, state, seqId, procId);<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>    return true;<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>  }<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span><a name="line.1235"></a>
-<span class="sourceLineNo">1236</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    checkMetaLoaded(parent);<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span><a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      throw new UnexpectedStateException(<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>    }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>    // sanity check on the request<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>    }<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span><a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span>      throw new DoNotRetryIOException(<a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span><a name="line.1257"></a>
-<span class="sourceLineNo">1258</span>    // Submit the Split procedure<a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>    if (LOG.isDebugEnabled()) {<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>        + Bytes.toStringBinary(splitKey));<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>    }<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    // ignore it in that case.<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>    // initialization and report failure with WARN level logging.<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    } else {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>        + " because parent is unknown or not open");<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      return;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span>    }<a name="line.1279"></a>
-<span class="sourceLineNo">1280</span><a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span>      throw new UnsupportedOperationException(<a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>    }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span>  }<a name="line.1287"></a>
-<span class="sourceLineNo">1288</span><a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>    checkMetaLoaded(merged);<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span><a name="line.1292"></a>
-<span class="sourceLineNo">1293</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>      throw new UnexpectedStateException(<a name="line.1294"></a>
-<span class="sourceLineNo">1295</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    }<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1299"></a>
-<span class="sourceLineNo">1300</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>      throw new DoNotRetryIOException(<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>    }<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span><a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>    // Submit the Merge procedure<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>    if (LOG.isDebugEnabled()) {<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>    }<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span><a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span>      throw new UnsupportedOperationException(<a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>          merged, hriA, hriB));<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>    }<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>  }<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
+<span class="sourceLineNo">1104</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1106"></a>
+<span class="sourceLineNo">1107</span>      switch (transition.getTransitionCode()) {<a name="line.1107"></a>
+<span class="sourceLineNo">1108</span>        case OPENED:<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span>        case FAILED_OPEN:<a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>        case CLOSED:<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>          long procId =<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span>          break;<a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>        case READY_TO_SPLIT:<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>        case SPLIT:<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>        case SPLIT_REVERTED:<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>            splitB);<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>          break;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>        case READY_TO_MERGE:<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>        case MERGED:<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>        case MERGE_REVERTED:<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>            mergeB);<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>          break;<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>      }<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>    }<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>  }<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span><a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    // lock protection to wait for meta online...<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    serverNode.readLock().lock();<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>    try {<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1158"></a>
+<span class="sourceLineNo">1159</span>        try {<a name="line.1159"></a>
+<span class="sourceLineNo">1160</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span>        } catch (PleaseHoldException e) {<a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>          LOG.trace("Failed transition ", e);<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>          throw e;<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>          // if the master says that one of the region transitions failed.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>          LOG.warn("Failed transition", e);<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>        }<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>      } else {<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>          serverName);<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>        builder.setErrorMessage("You are dead");<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      }<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>    } finally {<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>      serverNode.readLock().unlock();<a name="line.1176"></a>
+<span class="sourceLineNo">1177</span>    }<a name="line.1177"></a>
+<span class="sourceLineNo">1178</span><a name="line.1178"></a>
+<span class="sourceLineNo">1179</span>    return builder.build();<a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>  }<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span><a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>    checkMetaLoaded(regionInfo);<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    if (regionNode == null) {<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span>      throw new UnexpectedStateException(String.format(<a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>        regionInfo, state));<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>    }<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>      regionNode, state);<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span><a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    regionNode.lock();<a name="line.1197"></a>
+<span class="sourceLineNo">1198</span>    try {<a name="line.1198"></a>
+<span class="sourceLineNo">1199</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>        // to CLOSED<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>        if (<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        ) {<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span>        } else {<a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>            regionNode, state);<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>        }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span>      }<a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>    } finally {<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>      regionNode.unlock();<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>    }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span>  }<a name="line.1220"></a>
+<span class="sourceLineNo">1221</span><a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>    ServerName serverName = serverNode.getServerName();<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    if (proc == null) {<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>      return false;<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    }<a name="line.1228"></a>
+<span class="sourceLineNo">1229</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1229"></a>
+<span class="sourceLineNo">1230</span>      serverName, state, seqId, procId);<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span>    return true;<a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>  }<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span><a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>    checkMetaLoaded(parent);<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span><a name="line.1237"></a>
+<span class="sourceLineNo">1238</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>      throw new UnexpectedStateException(<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>    }<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span><a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>    // sanity check on the request<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>    }<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span><a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>      throw new DoNotRetryIOException(<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>    }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span><a name="line.1255"></a>
+<span class="sourceLineNo">1256</span>    // Submit the Split procedure<a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    if (LOG.isDebugEnabled()) {<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span>        + Bytes.toStringBinary(splitKey));<a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>    }<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>    // ignore it in that case.<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    // initialization and report failure with WARN level logging.<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>    } else {<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span>        + " because parent is unknown or not open");<a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>      return;<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    }<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span><a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span>      throw new UnsupportedOperationException(<a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>    }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span>  }<a name="line.1285"></a>
+<span class="sourceLineNo">1286</span><a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span>    checkMetaLoaded(merged);<a name="line.1289"></a>
+<span class="sourceLineNo">1290</span><a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>      throw new UnexpectedStateException(<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1294"></a>
+<span class="sourceLineNo">1295</span>    }<a name="line.1295"></a>
+<span class="sourceLineNo">1296</span><a name="line.1296"></a>
+<span class="sourceLineNo">1297</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>      throw new DoNotRetryIOException(<a name="line.1299"></a>
+<span class="sourceLineNo">1300</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1300"></a>
+<span class="sourceLineNo">1301</span>    }<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    // Submit the Merge procedure<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>    if (LOG.isDebugEnabled()) {<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>    }<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span><a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      throw new UnsupportedOperationException(<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>          merged, hriA, hriB));<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span>  }<a name="line.1315"></a>
+<span class="sourceLineNo">1316</span><a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>  // ============================================================================================<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>  // RS Status update (report online regions) helpers<a name="line.1318"></a>
 <span class="sourceLineNo">1319</span>  // ============================================================================================<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>  // RS Status update (report online regions) helpers<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>  // ============================================================================================<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span>  /**<a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span>   * actually there is no problem.<a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>   * &lt;p/&gt;<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>   */<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span>    if (!isRunning()) {<a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      return;<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>    }<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>    if (LOG.isTraceEnabled()) {<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span>        regionNames.size(), isMetaLoaded(),<a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>    }<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span><a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    synchronized (serverNode) {<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>        return;<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      }<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>    }<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span><a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>    // Track the regionserver reported online regions in memory.<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>    synchronized (rsReports) {<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      rsReports.put(serverName, regionNames);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>    }<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span><a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    if (regionNames.isEmpty()) {<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span>      // nothing to do if we don't have regions<a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>      return;<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>    }<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    if (!isMetaLoaded()) {<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span>      // we are still on startup, skip checking<a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>      return;<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>    }<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>  }<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span><a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>  /**<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1370"></a>
-<span class="sourceLineNo">1371</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1371"></a>
-<span class="sourceLineNo">1372</span>   * accounting.<a name="line.1372"></a>
-<span class="sourceLineNo">1373</span>   */<a name="line.1373"></a>
-<span class="sourceLineNo">1374</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span>    try {<a name="line.1375"></a>
-<span class="sourceLineNo">1376</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1376"></a>
-<span class="sourceLineNo">1377</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1377"></a>
-<span class="sourceLineNo">1378</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span>    } catch (Exception e) {<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span>    }<a name="line.1381"></a>
-<span class="sourceLineNo">1382</span>  }<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span><a name="line.1383"></a>
-<span class="sourceLineNo">1384</span>  /**<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1385"></a>
-<span class="sourceLineNo">1386</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1386"></a>
-<span class="sourceLineNo">1387</span>   */<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1388"></a>
-<span class="sourceLineNo">1389</span>    ServerName serverName = serverNode.getServerName();<a name="line.1389"></a>
-<span class="sourceLineNo">1390</span>    for (byte[] regionName : regionNames) {<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span>      if (!isRunning()) {<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span>        return;<a name="line.1392"></a>
-<span class="sourceLineNo">1393</span>      }<a name="line.1393"></a>
-<span class="sourceLineNo">1394</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1394"></a>
-<span class="sourceLineNo">1395</span>      if (regionNode == null) {<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1396"></a>
-<span class="sourceLineNo">1397</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1397"></a>
-<span class="sourceLineNo">1398</span>          serverName);<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span>        continue;<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span>      }<a name="line.1401"></a>
-<span class="sourceLineNo">1402</span>      final long lag = 1000;<a name="line.1402"></a>
-<span class="sourceLineNo">1403</span>      regionNode.lock();<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span>      try {<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1406"></a>
-<span class="sourceLineNo">1407</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1407"></a>
-<span class="sourceLineNo">1408</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1408"></a>
-<span class="sourceLineNo">1409</span>          // is some elapsed time so less false alarms.<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1410"></a>
-<span class="sourceLineNo">1411</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1413"></a>
-<span class="sourceLineNo">1414</span>          }<a name="line.1414"></a>
-<span class="sourceLineNo">1415</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1415"></a>
-<span class="sourceLineNo">1416</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1416"></a>
-<span class="sourceLineNo">1417</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1417"></a>
-<span class="sourceLineNo">1418</span>          // elapsed time so less false alarms.<a name="line.1418"></a>
-<span class="sourceLineNo">1419</span>          if (diff &gt; lag) {<a name="line.1419"></a>
-<span class="sourceLineNo">1420</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1420"></a>
-<span class="sourceLineNo">1421</span>              serverName, regionNode, diff);<a name="line.1421"></a>
-<span class="sourceLineNo">1422</span>          }<a name="line.1422"></a>
-<span class="sourceLineNo">1423</span>        }<a name="line.1423"></a>
-<span class="sourceLineNo">1424</span>      } finally {<a name="line.1424"></a>
-<span class="sourceLineNo">1425</span>        regionNode.unlock();<a name="line.1425"></a>
-<span class="sourceLineNo">1426</span>      }<a name="line.1426"></a>
-<span class="sourceLineNo">1427</span>    }<a name="line.1427"></a>
-<span class="sourceLineNo">1428</span>  }<a name="line.1428"></a>
-<span class="sourceLineNo">1429</span><a name="line.1429"></a>
+<span class="sourceLineNo">1320</span>  /**<a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>   * actually there is no problem.<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>   * &lt;p/&gt;<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>   */<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>    if (!isRunning()) {<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      return;<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>    }<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>    if (LOG.isTraceEnabled()) {<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>        regionNames.size(), isMetaLoaded(),<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>    }<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span><a name="line.1339"></a>
+<span class="sourceLineNo">1340</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>    synchronized (serverNode) {<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>        return;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>      }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span>    }<a name="line.1346"></a>
+<span class="sourceLineNo">1347</span><a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    // Track the regionserver reported online regions in memory.<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>    synchronized (rsReports) {<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      rsReports.put(serverName, regionNames);<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>    }<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span><a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>    if (regionNames.isEmpty()) {<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      // nothing to do if we don't have regions<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1355"></a>
+<span class="sourceLineNo">1356</span>      return;<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span>    }<a name="line.1357"></a>
+<span class="sourceLineNo">1358</span>    if (!isMetaLoaded()) {<a name="line.1358"></a>
+<span class="sourceLineNo">1359</span>      // we are still on startup, skip checking<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span>      return;<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span>    }<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1363"></a>
+<span class="sourceLineNo">1364</span>  }<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span><a name="line.1365"></a>
+<span class="sourceLineNo">1366</span>  /**<a name="line.1366"></a>
+<span class="sourceLineNo">1367</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1367"></a>
+<span class="sourceLineNo">1368</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1369"></a>
+<span class="sourceLineNo">1370</span>   * accounting.<a name="line.1370"></a>
+<span class="sourceLineNo">1371</span>   */<a name="line.1371"></a>
+<span class="sourceLineNo">1372</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1372"></a>
+<span class="sourceLineNo">1373</span>    try {<a name="line.1373"></a>
+<span class="sourceLineNo">1374</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1374"></a>
+<span class="sourceLineNo">1375</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1375"></a>
+<span class="sourceLineNo">1376</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1376"></a>
+<span class="sourceLineNo">1377</span>    } catch (Exception e) {<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1378"></a>
+<span class="sourceLineNo">1379</span>    }<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span>  }<a name="line.1380"></a>
+<span class="sourceLineNo">1381</span><a name="line.1381"></a>
+<span class="sourceLineNo">1382</span>  /**<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1384"></a>
+<span class="sourceLineNo">1385</span>   */<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span>    ServerName serverName = serverNode.getServerName();<a name="line.1387"></a>
+<span class="sourceLineNo">1388</span>    for (byte[] regionName : regionNames) {<a name="line.1388"></a>
+<span class="sourceLineNo">1389</span>      if (!isRunning()) {<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span>        return;<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span>      }<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span>      if (regionNode == null) {<a name="line.1393"></a>
+<span class="sourceLineNo">1394</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1394"></a>
+<span class="sourceLineNo">1395</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1395"></a>
+<span class="sourceLineNo">1396</span>          serverName);<a name="line.1396"></a>
+<span class="sourceLineNo">1397</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span>        continue;<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span>      }<a name="line.1399"></a>
+<span class="sourceLineNo">1400</span>      final long lag = 1000;<a name="line.1400"></a>
+<span class="sourceLineNo">1401</span>      regionNode.lock();<a name="line.1401"></a>
+<span class="sourceLineNo">1402</span>      try {<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1405"></a>
+<span class="sourceLineNo">1406</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1406"></a>
+<span class="sourceLineNo">1407</span>          // is some elapsed time so less false alarms.<a name="line.1407"></a>
+<span class="sourceLineNo">1408</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1409"></a>
+<span class="sourceLineNo">1410</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>          }<a name="line.1412"></a>
+<span class="sourceLineNo">1413</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1413"></a>
+<span class="sourceLineNo">1414</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1414"></a>
+<span class="sourceLineNo">1415</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1415"></a>
+<span class="sourceLineNo">1416</span>          // elapsed time so less false alarms.<a name="line.1416"></a>
+<span class="sourceLineNo">1417</span>          if (diff &gt; lag) {<a name="line.1417"></a>
+<span class="sourceLineNo">1418</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1418"></a>
+<span class="sourceLineNo">1419</span>              serverName, regionNode, diff);<a name="line.1419"></a>
+<span class="sourceLineNo">1420</span>          }<a name="line.1420"></a>
+<span class="sourceLineNo">1421</span>        }<a name="line.1421"></a>
+<span class="sourceLineNo">1422</span>      } finally {<a name="line.1422"></a>
+<span class="sourceLineNo">1423</span>        regionNode.unlock();<a name="line.1423"></a>
+<span class="sourceLineNo">1424</span>      }<a name="line.1424"></a>
+<span class="sourceLineNo">1425</span>    }<a name="line.1425"></a>
+<span class="sourceLineNo">1426</span>  }<a name="line.1426"></a>
+<span class="sourceLineNo">1427</span><a name="line.1427"></a>
+<span class="sourceLineNo">1428</span>  // ============================================================================================<a name="line.1428"></a>
+<span class="sourceLineNo">1429</span>  // RIT chore<a name="line.1429"></a>
 <span class="sourceLineNo">1430</span>  // ============================================================================================<a name="line.1430"></a>
-<span class="sourceLineNo">1431</span>  // RIT chore<a name="line.1431"></a>
-<span class="sourceLineNo">1432</span>  // ============================================================================================<a name="line.1432"></a>
-<span class="sourceLineNo">1433</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1433"></a>
-<span class="sourceLineNo">1434</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1434"></a>
-<span class="sourceLineNo">1435</span>      super(timeoutMsec);<a name="line.1435"></a>
-<span class="sourceLineNo">1436</span>    }<a name="line.1436"></a>
-<span class="sourceLineNo">1437</span><a name="line.1437"></a>
-<span class="sourceLineNo">1438</span>    @Override<a name="line.1438"></a>
-<span class="sourceLineNo">1439</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1439"></a>
-<span class="sourceLineNo">1440</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1440"></a>
-<span class="sourceLineNo">1441</span><a name="line.1441"></a>
-<span class="sourceLineNo">1442</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1442"></a>
-<span class="sourceLineNo">1443</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1443"></a>
-<span class="sourceLineNo">1444</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1444"></a>
-<span class="sourceLineNo">1445</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1445"></a>
-<span class="sourceLineNo">1446</span>        }<a name="line.1446"></a>
-<span class="sourceLineNo">1447</span>      }<a name="line.1447"></a>
-<span class="sourceLineNo">1448</span><a name="line.1448"></a>
-<span class="sourceLineNo">1449</span>      // update metrics<a name="line.1449"></a>
-<span class="sourceLineNo">1450</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1450"></a>
-<span class="sourceLineNo">1451</span>    }<a name="line.1451"></a>
-<span class="sourceLineNo">1452</span>  }<a name="line.1452"></a>
-<span class="sourceLineNo">1453</span><a name="line.1453"></a>
-<span class="sourceLineNo">1454</span>  private static class DeadServerMetricRegionChore<a name="line.1454"></a>
-<span class="sourceLineNo">1455</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1455"></a>
-<span class="sourceLineNo">1456</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1456"></a>
-<span class="sourceLineNo">1457</span>      super(timeoutMsec);<a name="line.1457"></a>
-<span class="sourceLineNo">1458</span>    }<a name="line.1458"></a>
-<span class="sourceLineNo">1459</span><a name="line.1459"></a>
-<span class="sourceLineNo">1460</span>    @Override<a name="line.1460"></a>
-<span class="sourceLineNo">1461</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1461"></a>
-<span class="sourceLineNo">1462</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1462"></a>
-<span class="sourceLineNo">1463</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1463"></a>
-<span class="sourceLineNo">1464</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1464"></a>
-<span class="sourceLineNo">1465</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1465"></a>
-<span class="sourceLineNo">1466</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1466"></a>
-<span class="sourceLineNo">1467</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1467"></a>
-<span class="sourceLineNo">1468</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1468"></a>
-<span class="sourceLineNo">1469</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1469"></a>
-<span class="sourceLineNo">1470</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1470"></a>
-<span class="sourceLineNo">1471</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1471"></a>
-<span class="sourceLineNo">1472</span>        if (rsn.getState() != State.OPEN) {<a name="line.1472"></a>
-<span class="sourceLineNo">1473</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1473"></a>
-<span class="sourceLineNo">1474</span>        }<a name="line.1474"></a>
-<span class="sourceLineNo">1475</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1475"></a>
-<span class="sourceLineNo">1476</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1476"></a>
-<span class="sourceLineNo">1477</span>        State state = rsn.getState();<a name="line.1477"></a>
-<span class="sourceLineNo">1478</span>        if (state != State.OPEN) {<a name="line.1478"></a>
-<span class="sourceLineNo">1479</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1479"></a>
-<span class="sourceLineNo">1480</span>        }<a name="line.1480"></a>
-<span class="sourceLineNo">1481</span>        if (sn == null) {<a name="line.1481"></a>
-<span class="sourceLineNo">1482</span>          ++unknownRegions; // Opened on null?<a name="line.1482"></a>
-<span class="sourceLineNo">1483</span>          continue;<a name="line.1483"></a>
-<span class="sourceLineNo">1484</span>        }<a name="line.1484"></a>
-<span class="sourceLineNo">1485</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1485"></a>
-<span class="sourceLineNo">1486</span>          continue;<a name="line.1486"></a>
-<span class="sourceLineNo">1487</span>        }<a name="line.1487"></a>
-<span class="sourceLineNo">1488</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1488"></a>
-<span class="sourceLineNo">1489</span>        switch (sls) {<a name="line.1489"></a>
-<span class="sourceLineNo">1490</span>          case LIVE:<a name="line.1490"></a>
-<span class="sourceLineNo">1491</span>            recentlyLiveServers.add(sn);<a name="line.1491"></a>
-<span class="sourceLineNo">1492</span>            break;<a name="line.1492"></a>
-<span class="sourceLineNo">1493</span>          case DEAD:<a name="line.1493"></a>
-<span class="sourceLineNo">1494</span>            ++deadRegions;<a name="line.1494"></a>
-<span class="sourceLineNo">1495</span>            break;<a name="line.1495"></a>
-<span class="sourceLineNo">1496</span>          case UNKNOWN:<a name="line.1496"></a>
-<span class="sourceLineNo">1497</span>            ++unknownRegions;<a name="line.1497"></a>
-<span class="sourceLineNo">1498</span>            break;<a name="line.1498"></a>
-<span class="sourceLineNo">1499</span>          default:<a name="line.1499"></a>
-<span class="sourceLineNo">1500</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1500"></a>
-<span class="sourceLineNo">1501</span>        }<a name="line.1501"></a>
-<span class="sourceLineNo">1502</span>      }<a name="line.1502"></a>
-<span class="sourceLineNo">1503</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1503"></a>
-<span class="sourceLineNo">1504</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1504"></a>
-<span class="sourceLineNo">1505</span>          deadRegions, unknownRegions);<a name="line.1505"></a>
-<span class="sourceLineNo">1506</span>      }<a name="line.1506"></a>
-<span class="sourceLineNo">1507</span><a name="line.1507"></a>
-<span class="sourceLineNo">1508</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1508"></a>
-<span class="sourceLineNo">1509</span>    }<a name="line.1509"></a>
-<span class="sourceLineNo">1510</span>  }<a name="line.1510"></a>
-<span class="sourceLineNo">1511</span><a name="line.1511"></a>
-<span class="sourceLineNo">1512</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1512"></a>
-<span class="sourceLineNo">1513</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1513"></a>
-<span class="sourceLineNo">1514</span>    rit.update(this);<a name="line.1514"></a>
-<span class="sourceLineNo">1515</span>    return rit;<a name="line.1515"></a>
-<span class="sourceLineNo">1516</span>  }<a name="line.1516"></a>
-<span class="sourceLineNo">1517</span><a name="line.1517"></a>
-<span class="sourceLineNo">1518</span>  public static class RegionInTransitionStat {<a name="line.1518"></a>
-<span class="sourceLineNo">1519</span>    private final int ritThreshold;<a name="line.1519"></a>
-<span class="sourceLineNo">1520</span><a name="line.1520"></a>
-<span class="sourceLineNo">1521</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1521"></a>
-<span class="sourceLineNo">1522</span>    private long statTimestamp;<a name="line.1522"></a>
-<span class="sourceLineNo">1523</span>    private long oldestRITTime = 0;<a name="line.1523"></a>
-<span class="sourceLineNo">1524</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1524"></a>
-<span class="sourceLineNo">1525</span>    private int totalRITs = 0;<a name="line.1525"></a>
-<span class="sourceLineNo">1526</span><a name="line.1526"></a>
-<span class="sourceLineNo">1527</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1527"></a>
-<span class="sourceLineNo">1528</span>      this.ritThreshold =<a name="line.1528"></a>
-<span class="sourceLineNo">1529</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1529"></a>
-<span class="sourceLineNo">1530</span>    }<a name="line.1530"></a>
-<span class="sourceLineNo">1531</span><a name="line.1531"></a>
-<span class="sourceLineNo">1532</span>    public int getRITThreshold() {<a name="line.1532"></a>
-<span class="sourceLineNo">1533</span>      return ritThreshold;<a name="line.1533"></a>
-<span class="sourceLineNo">1534</span>    }<a name="line.1534"></a>
-<span class="sourceLineNo">1535</span><a name="line.1535"></a>
-<span class="sourceLineNo">1536</span>    public long getTimestamp() {<a name="line.1536"></a>
-<span class="sourceLineNo">1537</span>      return statTimestamp;<a name="line.1537"></a>
-<span class="sourceLineNo">1538</span>    }<a name="line.1538"></a>
-<span class="sourceLineNo">1539</span><a name="line.1539"></a>
-<span class="sourceLineNo">1540</span>    public int getTotalRITs() {<a name="line.1540"></a>
-<span class="sourceLineNo">1541</span>      return totalRITs;<a name="line.1541"></a>
-<span class="sourceLineNo">1542</span>    }<a name="line.1542"></a>
-<span class="sourceLineNo">1543</span><a name="line.1543"></a>
-<span class="sourceLineNo">1544</span>    public long getOldestRITTime() {<a name="line.1544"></a>
-<span class="sourceLineNo">1545</span>      return oldestRITTime;<a name="line.1545"></a>
-<span class="sourceLineNo">1546</span>    }<a name="line.1546"></a>
-<span class="sourceLineNo">1547</span><a name="line.1547"></a>
-<span class="sourceLineNo">1548</span>    public int getTotalRITsOverThreshold() {<a name="line.1548"></a>
-<span class="sourceLineNo">1549</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1549"></a>
-<span class="sourceLineNo">1550</span>      return m != null ? m.size() : 0;<a name="line.1550"></a>
-<span class="sourceLineNo">1551</span>    }<a name="line.1551"></a>
-<span class="sourceLineNo">1552</span><a name="line.1552"></a>
-<span class="sourceLineNo">1553</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1553"></a>
-<span class="sourceLineNo">1554</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1554"></a>
-<span class="sourceLineNo">1555</span>    }<a name="line.1555"></a>
-<span class="sourceLineNo">1556</span><a name="line.1556"></a>
-<span class="sourceLineNo">1557</span>    public boolean hasRegionsOverThreshold() {<a name="line.1557"></a>
-<span class="sourceLineNo">1558</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1558"></a>
-<span class="sourceLineNo">1559</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1559"></a>
-<span class="sourceLineNo">1560</span>    }<a name="line.1560"></a>
-<span class="sourceLineNo">1561</span><a name="line.1561"></a>
-<span class="sourceLineNo">1562</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1562"></a>
-<span class="sourceLineNo">1563</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1563"></a>
-<span class="sourceLineNo">1564</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1564"></a>
-<span class="sourceLineNo">1565</span>    }<a name="line.1565"></a>
-<span class="sourceLineNo">1566</span><a name="line.1566"></a>
-<span class="sourceLineNo">1567</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1567"></a>
-<span class="sourceLineNo">1568</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1568"></a>
-<span class="sourceLineNo">1569</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1569"></a>
-<span class="sourceLineNo">1570</span>    }<a name="line.1570"></a>
-<span class="sourceLineNo">1571</span><a name="line.1571"></a>
-<span class="sourceLineNo">1572</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1572"></a>
-<span class="sourceLineNo">1573</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>      if (m == null) {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>        return false;<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>      }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1577"></a>
-<span class="sourceLineNo">1578</span>      if (state == null) {<a name="line.1578"></a>
-<span class="sourceLineNo">1579</span>        return false;<a name="line.1579"></a>
-<span class="sourceLineNo">1580</span>      }<a name="line.1580"></a>
-<span class="sourceLineNo">1581</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1581"></a>
-<span class="sourceLineNo">1582</span>    }<a name="line.1582"></a>
-<span class="sourceLineNo">1583</span><a name="line.1583"></a>
-<span class="sourceLineNo">1584</span>    protected void update(final AssignmentManager am) {<a name="line.1584"></a>
-<span class="sourceLineNo">1585</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1585"></a>
-<span class="sourceLineNo">1586</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1586"></a>
-<span class="sourceLineNo">1587</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1587"></a>
-<span class="sourceLineNo">1588</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1588"></a>
-<span class="sourceLineNo">1589</span><a name="line.1589"></a>
-<span class="sourceLineNo">1590</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1590"></a>
-<span class="sourceLineNo">1591</span>        LOG.debug("RITs over threshold: {}",<a name="line.1591"></a>
-<span class="sourceLineNo">1592</span>          ritsOverThreshold.entrySet().stream()<a name="line.1592"></a>
-<span class="sourceLineNo">1593</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1593"></a>
-<span class="sourceLineNo">1594</span>            .collect(Collectors.joining("\n")));<a name="line.1594"></a>
-<span class="sourceLineNo">1595</span>      }<a name="line.1595"></a>
-<span class="sourceLineNo">1596</span>    }<a name="line.1596"></a>
-<span class="sourceLineNo">1597</span><a name="line.1597"></a>
-<span class="sourceLineNo">1598</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1598"></a>
-<span class="sourceLineNo">1599</span>      for (RegionState state : regions) {<a name="line.1599"></a>
-<span class="sourceLineNo">1600</span>        totalRITs++;<a name="line.1600"></a>
-<span class="sourceLineNo">1601</span>        final long ritStartedMs = state.getStamp();<a name="line.1601"></a>
-<span class="sourceLineNo">1602</span>        if (ritStartedMs == 0) {<a name="line.1602"></a>
-<span class="sourceLineNo">1603</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1603"></a>
-<span class="sourceLineNo">1604</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1604"></a>
-<span class="sourceLineNo">1605</span>          continue;<a name="line.1605"></a>
-<span class="sourceLineNo">1606</span>        }<a name="line.1606"></a>
-<span class="sourceLineNo">1607</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1607"></a>
-<span class="sourceLineNo">1608</span>        if (ritTime &gt; ritThreshold) {<a name="line.1608"></a>
-<span class="sourceLineNo">1609</span>          if (ritsOverThreshold == null) {<a name="line.1609"></a>
-<span class="sourceLineNo">1610</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1610"></a>
-<span class="sourceLineNo">1611</span>          }<a name="line.1611"></a>
-<span class="sourceLineNo">1612</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1612"></a>
-<span class="sourceLineNo">1613</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1613"></a>
-<span class="sourceLineNo">1614</span>        }<a name="line.1614"></a>
-<span class="sourceLineNo">1615</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1615"></a>
-<span class="sourceLineNo">1616</span>          oldestRITTime = ritTime;<a name="line.1616"></a>
-<span class="sourceLineNo">1617</span>        }<a name="line.1617"></a>
-<span class="sourceLineNo">1618</span>      }<a name="line.1618"></a>
-<span class="sourceLineNo">1619</span>    }<a name="line.1619"></a>
-<span class="sourceLineNo">1620</span>  }<a name="line.1620"></a>
-<span class="sourceLineNo">1621</span><a name="line.1621"></a>
-<span class="sourceLineNo">1622</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1622"></a>
-<span class="sourceLineNo">1623</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1623"></a>
-<span class="sourceLineNo">1624</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1624"></a>
-<span class="sourceLineNo">1625</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1625"></a>
-<span class="sourceLineNo">1626</span>  }<a name="line.1626"></a>
-<span class="sourceLineNo">1627</span><a name="line.1627"></a>
-<span class="sourceLineNo">1628</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1628"></a>
-<span class="sourceLineNo">1629</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1629"></a>
-<span class="sourceLineNo">1630</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1630"></a>
-<span class="sourceLineNo">1631</span>  }<a name="line.1631"></a>
-<span class="sourceLineNo">1632</span><a name="line.1632"></a>
-<span class="sourceLineNo">1633</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1633"></a>
-<span class="sourceLineNo">1634</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1634"></a>
-<span class="sourceLineNo">1635</span>    // if (regionNode.isStuck()) {<a name="line.1635"></a>
-<span class="sourceLineNo">1636</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1636"></a>
-<span class="sourceLineNo">1637</span>  }<a name="line.1637"></a>
-<span class="sourceLineNo">1638</span><a name="line.1638"></a>
+<span class="sourceLineNo">1431</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1431"></a>
+<span class="sourceLineNo">1432</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1432"></a>
+<span class="sourceLineNo">1433</span>      super(timeoutMsec);<a name="line.1433"></a>
+<span class="sourceLineNo">1434</span>    }<a name="line.1434"></a>
+<span class="sourceLineNo">1435</span><a name="line.1435"></a>
+<span class="sourceLineNo">1436</span>    @Override<a name="line.1436"></a>
+<span class="sourceLineNo">1437</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1437"></a>
+<span class="sourceLineNo">1438</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1438"></a>
+<span class="sourceLineNo">1439</span><a name="line.1439"></a>
+<span class="sourceLineNo">1440</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1440"></a>
+<span class="sourceLineNo">1441</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1441"></a>
+<span class="sourceLineNo">1442</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1442"></a>
+<span class="sourceLineNo">1443</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1443"></a>
+<span class="sourceLineNo">1444</span>        }<a name="line.1444"></a>
+<span class="sourceLineNo">1445</span>      }<a name="line.1445"></a>
+<span class="sourceLineNo">1446</span><a name="line.1446"></a>
+<span class="sourceLineNo">1447</span>      // update metrics<a name="line.1447"></a>
+<span class="sourceLineNo">1448</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1448"></a>
+<span class="sourceLineNo">1449</span>    }<a name="line.1449"></a>
+<span class="sourceLineNo">1450</span>  }<a name="line.1450"></a>
+<span class="sourceLineNo">1451</span><a name="line.1451"></a>
+<span class="sourceLineNo">1452</span>  private static class DeadServerMetricRegionChore<a name="line.1452"></a>
+<span class="sourceLineNo">1453</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1453"></a>
+<span class="sourceLineNo">1454</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1454"></a>
+<span class="sourceLineNo">1455</span>      super(timeoutMsec);<a name="line.1455"></a>
+<span class="sourceLineNo">1456</span>    }<a name="line.1456"></a>
+<span class="sourceLineNo">1457</span><a name="line.1457"></a>
+<span class="sourceLineNo">1458</span>    @Override<a name="line.1458"></a>
+<span class="sourceLineNo">1459</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1459"></a>
+<span class="sourceLineNo">1460</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1460"></a>
+<span class="sourceLineNo">1461</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1461"></a>
+<span class="sourceLineNo">1462</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1462"></a>
+<span class="sourceLineNo">1463</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1463"></a>
+<span class="sourceLineNo">1464</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1464"></a>
+<span class="sourceLineNo">1465</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1465"></a>
+<span class="sourceLineNo">1466</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1466"></a>
+<span class="sourceLineNo">1467</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1467"></a>
+<span class="sourceLineNo">1468</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1468"></a>
+<span class="sourceLineNo">1469</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1469"></a>
+<span class="sourceLineNo">1470</span>        if (rsn.getState() != State.OPEN) {<a name="line.1470"></a>
+<span class="sourceLineNo">1471</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1471"></a>
+<span class="sourceLineNo">1472</span>        }<a name="line.1472"></a>
+<span class="sourceLineNo">1473</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1473"></a>
+<span class="sourceLineNo">1474</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1474"></a>
+<span class="sourceLineNo">1475</span>        State state = rsn.getState();<a name="line.1475"></a>
+<span class="sourceLineNo">1476</span>        if (state != State.OPEN) {<a name="line.1476"></a>
+<span class="sourceLineNo">1477</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1477"></a>
+<span class="sourceLineNo">1478</span>        }<a name="line.1478"></a>
+<span class="sourceLineNo">1479</span>        if (sn == null) {<a name="line.1479"></a>
+<span class="sourceLineNo">1480</span>          ++unknownRegions; // Opened on null?<a name="line.1480"></a>
+<span class="sourceLineNo">1481</span>          continue;<a name="line.1481"></a>
+<span class="sourceLineNo">1482</span>        }<a name="line.1482"></a>
+<span class="sourceLineNo">1483</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1483"></a>
+<span class="sourceLineNo">1484</span>          continue;<a name="line.1484"></a>
+<span class="sourceLineNo">1485</span>        }<a name="line.1485"></a>
+<span class="sourceLineNo">1486</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1486"></a>
+<span class="sourceLineNo">1487</span>        switch (sls) {<a name="line.1487"></a>
+<span class="sourceLineNo">1488</span>          case LIVE:<a name="line.1488"></a>
+<span class="sourceLineNo">1489</span>            recentlyLiveServers.add(sn);<a name="line.1489"></a>
+<span class="sourceLineNo">1490</span>            break;<a name="line.1490"></a>
+<span class="sourceLineNo">1491</span>          case DEAD:<a name="line.1491"></a>
+<span class="sourceLineNo">1492</span>            ++deadRegions;<a name="line.1492"></a>
+<span class="sourceLineNo">1493</span>            break;<a name="line.1493"></a>
+<span class="sourceLineNo">1494</span>          case UNKNOWN:<a name="line.1494"></a>
+<span class="sourceLineNo">1495</span>            ++unknownRegions;<a name="line.1495"></a>
+<span class="sourceLineNo">1496</span>            break;<a name="line.1496"></a>
+<span class="sourceLineNo">1497</span>          default:<a name="line.1497"></a>
+<span class="sourceLineNo">1498</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1498"></a>
+<span class="sourceLineNo">1499</span>        }<a name="line.1499"></a>
+<span class="sourceLineNo">1500</span>      }<a name="line.1500"></a>
+<span class="sourceLineNo">1501</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1501"></a>
+<span class="sourceLineNo">1502</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1502"></a>
+<span class="sourceLineNo">1503</span>          deadRegions, unknownRegions);<a name="line.1503"></a>
+<span class="sourceLineNo">1504</span>      }<a name="line.1504"></a>
+<span class="sourceLineNo">1505</span><a name="line.1505"></a>
+<span class="sourceLineNo">1506</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1506"></a>
+<span class="sourceLineNo">1507</span>    }<a name="line.1507"></a>
+<span class="sourceLineNo">1508</span>  }<a name="line.1508"></a>
+<span class="sourceLineNo">1509</span><a name="line.1509"></a>
+<span class="sourceLineNo">1510</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1510"></a>
+<span class="sourceLineNo">1511</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1511"></a>
+<span class="sourceLineNo">1512</span>    rit.update(this);<a name="line.1512"></a>
+<span class="sourceLineNo">1513</span>    return rit;<a name="line.1513"></a>
+<span class="sourceLineNo">1514</span>  }<a name="line.1514"></a>
+<span class="sourceLineNo">1515</span><a name="line.1515"></a>
+<span class="sourceLineNo">1516</span>  public static class RegionInTransitionStat {<a name="line.1516"></a>
+<span class="sourceLineNo">1517</span>    private final int ritThreshold;<a name="line.1517"></a>
+<span class="sourceLineNo">1518</span><a name="line.1518"></a>
+<span class="sourceLineNo">1519</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1519"></a>
+<span class="sourceLineNo">1520</span>    private long statTimestamp;<a name="line.1520"></a>
+<span class="sourceLineNo">1521</span>    private long oldestRITTime = 0;<a name="line.1521"></a>
+<span class="sourceLineNo">1522</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1522"></a>
+<span class="sourceLineNo">1523</span>    private int totalRITs = 0;<a name="line.1523"></a>
+<span class="sourceLineNo">1524</span><a name="line.1524"></a>
+<span class="sourceLineNo">1525</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1525"></a>
+<span class="sourceLineNo">1526</span>      this.ritThreshold =<a name="line.1526"></a>
+<span class="sourceLineNo">1527</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1527"></a>
+<span class="sourceLineNo">1528</span>    }<a name="line.1528"></a>
+<span class="sourceLineNo">1529</span><a name="line.1529"></a>
+<span class="sourceLineNo">1530</span>    public int getRITThreshold() {<a name="line.1530"></a>
+<span class="sourceLineNo">1531</span>      return ritThreshold;<a name="line.1531"></a>
+<span class="sourceLineNo">1532</span>    }<a name="line.1532"></a>
+<span class="sourceLineNo">1533</span><a name="line.1533"></a>
+<span class="sourceLineNo">1534</span>    public long getTimestamp() {<a name="line.1534"></a>
+<span class="sourceLineNo">1535</span>      return statTimestamp;<a name="line.1535"></a>
+<span class="sourceLineNo">1536</span>    }<a name="line.1536"></a>
+<span class="sourceLineNo">1537</span><a name="line.1537"></a>
+<span class="sourceLineNo">1538</span>    public int getTotalRITs() {<a name="line.1538"></a>
+<span class="sourceLineNo">1539</span>      return totalRITs;<a name="line.1539"></a>
+<span class="sourceLineNo">1540</span>    }<a name="line.1540"></a>
+<span class="sourceLineNo">1541</span><a name="line.1541"></a>
+<span class="sourceLineNo">1542</span>    public long getOldestRITTime() {<a name="line.1542"></a>
+<span class="sourceLineNo">1543</span>      return oldestRITTime;<a name="line.1543"></a>
+<span class="sourceLineNo">1544</span>    }<a name="line.1544"></a>
+<span class="sourceLineNo">1545</span><a name="line.1545"></a>
+<span class="sourceLineNo">1546</span>    public int getTotalRITsOverThreshold() {<a name="line.1546"></a>
+<span class="sourceLineNo">1547</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1547"></a>
+<span class="sourceLineNo">1548</span>      return m != null ? m.size() : 0;<a name="line.1548"></a>
+<span class="sourceLineNo">1549</span>    }<a name="line.1549"></a>
+<span class="sourceLineNo">1550</span><a name="line.1550"></a>
+<span class="sourceLineNo">1551</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1551"></a>
+<span class="sourceLineNo">1552</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1552"></a>
+<span class="sourceLineNo">1553</span>    }<a name="line.1553"></a>
+<span class="sourceLineNo">1554</span><a name="line.1554"></a>
+<span class="sourceLineNo">1555</span>    public boolean hasRegionsOverThreshold() {<a name="line.1555"></a>
+<span class="sourceLineNo">1556</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1556"></a>
+<span class="sourceLineNo">1557</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1557"></a>
+<span class="sourceLineNo">1558</span>    }<a name="line.1558"></a>
+<span class="sourceLineNo">1559</span><a name="line.1559"></a>
+<span class="sourceLineNo">1560</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1560"></a>
+<span class="sourceLineNo">1561</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1561"></a>
+<span class="sourceLineNo">1562</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1562"></a>
+<span class="sourceLineNo">1563</span>    }<a name="line.1563"></a>
+<span class="sourceLineNo">1564</span><a name="line.1564"></a>
+<span class="sourceLineNo">1565</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1565"></a>
+<span class="sourceLineNo">1566</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1566"></a>
+<span class="sourceLineNo">1567</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1567"></a>
+<span class="sourceLineNo">1568</span>    }<a name="line.1568"></a>
+<span class="sourceLineNo">1569</span><a name="line.1569"></a>
+<span class="sourceLineNo">1570</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1570"></a>
+<span class="sourceLineNo">1571</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1571"></a>
+<span class="sourceLineNo">1572</span>      if (m == null) {<a name="line.1572"></a>
+<span class="sourceLineNo">1573</span>        return false;<a name="line.1573"></a>
+<span class="sourceLineNo">1574</span>      }<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>      if (state == null) {<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>        return false;<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>      }<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>    }<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span><a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>    protected void update(final AssignmentManager am) {<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span><a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span>        LOG.debug("RITs over threshold: {}",<a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>          ritsOverThreshold.entrySet().stream()<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>            .collect(Collectors.joining("\n")));<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>      }<a name="line.1593"></a>
+<span class="sourceLineNo">1594</span>    }<a name="line.1594"></a>
+<span class="sourceLineNo">1595</span><a name="line.1595"></a>
+<span class="sourceLineNo">1596</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1596"></a>
+<span class="sourceLineNo">1597</span>      for (RegionState state : regions) {<a name="line.1597"></a>
+<span class="sourceLineNo">1598</span>        totalRITs++;<a name="line.1598"></a>
+<span class="sourceLineNo">1599</span>        final long ritStartedMs = state.getStamp();<a name="line.1599"></a>
+<span class="sourceLineNo">1600</span>        if (ritStartedMs == 0) {<a name="line.1600"></a>
+<span class="sourceLineNo">1601</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1601"></a>
+<span class="sourceLineNo">1602</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1602"></a>
+<span class="sourceLineNo">1603</span>          continue;<a name="line.1603"></a>
+<span class="sourceLineNo">1604</span>        }<a name="line.1604"></a>
+<span class="sourceLineNo">1605</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1605"></a>
+<span class="sourceLineNo">1606</span>        if (ritTime &gt; ritThreshold) {<a name="line.1606"></a>
+<span class="sourceLineNo">1607</span>          if (ritsOverThreshold == null) {<a name="line.1607"></a>
+<span class="sourceLineNo">1608</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1608"></a>
+<span class="sourceLineNo">1609</span>          }<a name="line.1609"></a>
+<span class="sourceLineNo">1610</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1610"></a>
+<span class="sourceLineNo">1611</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1611"></a>
+<span class="sourceLineNo">1612</span>        }<a name="line.1612"></a>
+<span class="sourceLineNo">1613</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1613"></a>
+<span class="sourceLineNo">1614</span>          oldestRITTime = ritTime;<a name="line.1614"></a>
+<span class="sourceLineNo">1615</span>        }<a name="line.1615"></a>
+<span class="sourceLineNo">1616</span>      }<a name="line.1616"></a>
+<span class="sourceLineNo">1617</span>    }<a name="line.1617"></a>
+<span class="sourceLineNo">1618</span>  }<a name="line.1618"></a>
+<span class="sourceLineNo">1619</span><a name="line.1619"></a>
+<span class="sourceLineNo">1620</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1620"></a>
+<span class="sourceLineNo">1621</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1621"></a>
+<span class="sourceLineNo">1622</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1622"></a>
+<span class="sourceLineNo">1623</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1623"></a>
+<span class="sourceLineNo">1624</span>  }<a name="line.1624"></a>
+<span class="sourceLineNo">1625</span><a name="line.1625"></a>
+<span class="sourceLineNo">1626</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1626"></a>
+<span class="sourceLineNo">1627</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1627"></a>
+<span class="sourceLineNo">1628</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1628"></a>
+<span class="sourceLineNo">1629</span>  }<a name="line.1629"></a>
+<span class="sourceLineNo">1630</span><a name="line.1630"></a>
+<span class="sourceLineNo">1631</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1631"></a>
+<span class="sourceLineNo">1632</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1632"></a>
+<span class="sourceLineNo">1633</span>    // if (regionNode.isStuck()) {<a name="line.1633"></a>
+<span class="sourceLineNo">1634</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1634"></a>
+<span class="sourceLineNo">1635</span>  }<a name="line.1635"></a>
+<span class="sourceLineNo">1636</span><a name="line.1636"></a>
+<span class="sourceLineNo">1637</span>  // ============================================================================================<a name="line.1637"></a>
+<span class="sourceLineNo">1638</span>  // TODO: Master load/bootstrap<a name="line.1638"></a>
 <span class="sourceLineNo">1639</span>  // ============================================================================================<a name="line.1639"></a>
-<span class="sourceLineNo">1640</span>  // TODO: Master load/bootstrap<a name="line.1640"></a>
-<span class="sourceLineNo">1641</span>  // ============================================================================================<a name="line.1641"></a>
-<span class="sourceLineNo">1642</span>  public void joinCluster() throws IOException {<a name="line.1642"></a>
-<span class="sourceLineNo">1643</span>    long startTime = System.nanoTime();<a name="line.1643"></a>
-<span class="sourceLineNo">1644</span>    LOG.debug("Joining cluster...");<a name="line.1644"></a>
-<span class="sourceLineNo">1645</span><a name="line.1645"></a>
-<span class="sourceLineNo">1646</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1646"></a>
-<span class="sourceLineNo">1647</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1647"></a>
-<span class="sourceLineNo">1648</span>    // w/o meta.<a name="line.1648"></a>
-<span class="sourceLineNo">1649</span>    loadMeta();<a name="line.1649"></a>
-<span class="sourceLineNo">1650</span><a name="line.1650"></a>
-<span class="sourceLineNo">1651</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1651"></a>
-<span class="sourceLineNo">1652</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1652"></a>
-<span class="sourceLineNo">1653</span>        master.getServerManager().countOfRegionServers());<a name="line.1653"></a>
-<span class="sourceLineNo">1654</span>      Threads.sleep(250);<a name="line.1654"></a>
-<span class="sourceLineNo">1655</span>    }<a name="line.1655"></a>
-<span class="sourceLineNo">1656</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1656"></a>
-<span class="sourceLineNo">1657</span><a name="line.1657"></a>
-<span class="sourceLineNo">1658</span>    // Start the chores<a name="line.1658"></a>
-<span class="sourceLineNo">1659</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1659"></a>
-<span class="sourceLineNo">1660</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1660"></a>
-<span class="sourceLineNo">1661</span><a name="line.1661"></a>
-<span class="sourceLineNo">1662</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1662"></a>
-<span class="sourceLineNo">1663</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1663"></a>
-<span class="sourceLineNo">1664</span>  }<a name="line.1664"></a>
-<span class="sourceLineNo">1665</span><a name="line.1665"></a>
-<span class="sourceLineNo">1666</span>  /**<a name="line.1666"></a>
-<span class="sourceLineNo">1667</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1667"></a>
-<span class="sourceLineNo">1668</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1668"></a>
-<span class="sourceLineNo">1669</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1669"></a>
-<span class="sourceLineNo">1670</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1670"></a>
-<span class="sourceLineNo">1671</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1671"></a>
-<span class="sourceLineNo">1672</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1672"></a>
-<span class="sourceLineNo">1673</span>   * method any more. Need to revisit later.<a name="line.1673"></a>
-<span class="sourceLineNo">1674</span>   */<a name="line.1674"></a>
-<span class="sourceLineNo">1675</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1675"></a>
-<span class="sourceLineNo">1676</span>  // Needs to be done after the table state manager has been started.<a name="line.1676"></a>
-<span class="sourceLineNo">1677</span>  public void processOfflineRegions() {<a name="line.1677"></a>
-<span class="sourceLineNo">1678</span>    TransitRegionStateProcedure[] procs =<a name="line.1678"></a>
-<span class="sourceLineNo">1679</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1679"></a>
-<span class="sourceLineNo">1680</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1680"></a>
-<span class="sourceLineNo">1681</span>          rsn.lock();<a name="line.1681"></a>
-<span class="sourceLineNo">1682</span>          try {<a name="line.1682"></a>
-<span class="sourceLineNo">1683</span>            if (rsn.getProcedure() != null) {<a name="line.1683"></a>
-<span class="sourceLineNo">1684</span>              return null;<a name="line.1684"></a>
-<span class="sourceLineNo">1685</span>            } else {<a name="line.1685"></a>
-<span class="sourceLineNo">1686</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1686"></a>
-<span class="sourceLineNo">1687</span>                rsn.getRegionInfo(), null));<a name="line.1687"></a>
-<span class="sourceLineNo">1688</span>            }<a name="line.1688"></a>
-<span class="sourceLineNo">1689</span>          } finally {<a name="line.1689"></a>
-<span class="sourceLineNo">1690</span>            rsn.unlock();<a name="line.1690"></a>
-<span class="sourceLineNo">1691</span>          }<a name="line.1691"></a>
-<span class="sourceLineNo">1692</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1692"></a>
-<span class="sourceLineNo">1693</span>    if (procs.length &gt; 0) {<a name="line.1693"></a>
-<span class="sourceLineNo">1694</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1694"></a>
-<span class="sourceLineNo">1695</span>    }<a name="line.1695"></a>
-<span class="sourceLineNo">1696</span>  }<a name="line.1696"></a>
-<span class="sourceLineNo">1697</span><a name="line.1697"></a>
-<span class="sourceLineNo">1698</span>  /*<a name="line.1698"></a>
-<span class="sourceLineNo">1699</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1699"></a>
-<span class="sourceLineNo">1700</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1700"></a>
-<span class="sourceLineNo">1701</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1701"></a>
-<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1702"></a>
-<span class="sourceLineNo">1703</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1703"></a>
-<span class="sourceLineNo">1704</span>   * AssignmentManager.regionStates.<a name="line.1704"></a>
-<span class="sourceLineNo">1705</span>   */<a name="line.1705"></a>
-<span class="sourceLineNo">1706</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1706"></a>
-<span class="sourceLineNo">1707</span><a name="line.1707"></a>
-<span class="sourceLineNo">1708</span>    @Override<a name="line.1708"></a>
-<span class="sourceLineNo">1709</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1709"></a>
-<span class="sourceLineNo">1710</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1710"></a>
-<span class="sourceLineNo">1711</span>      if (<a name="line.1711"></a>
-<span class="sourceLineNo">1712</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1712"></a>
-<span class="sourceLineNo">1713</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1713"></a>
-<span class="sourceLineNo">1714</span>      ) {<a name="line.1714"></a>
-<span class="sourceLineNo">1715</span>        // This is a row with nothing in it.<a name="line.1715"></a>
-<span class="sourceLineNo">1716</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1716"></a>
-<span class="sourceLineNo">1717</span>        return;<a name="line.1717"></a>
-<span class="sourceLineNo">1718</span>      }<a name="line.1718"></a>
-<span class="sourceLineNo">1719</span>      State localState = state;<a name="line.1719"></a>
-<span class="sourceLineNo">1720</span>      if (localState == null) {<a name="line.1720"></a>
-<span class="sourceLineNo">1721</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1721"></a>
-<span class="sourceLineNo">1722</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1722"></a>
-<span class="sourceLineNo">1723</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1723"></a>
-<span class="sourceLineNo">1724</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1724"></a>
-<span class="sourceLineNo">1725</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1725"></a>
-<span class="sourceLineNo">1726</span>        localState = State.OFFLINE;<a name="line.1726"></a>
-<span class="sourceLineNo">1727</span>      }<a name="line.1727"></a>
-<span class="sourceLineNo">1728</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1728"></a>
-<span class="sourceLineNo">1729</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1729"></a>
-<span class="sourceLineNo">1730</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1730"></a>
-<span class="sourceLineNo">1731</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1731"></a>
-<span class="sourceLineNo">1732</span>      regionNode.setState(localState);<a name="line.1732"></a>
-<span class="sourceLineNo">1733</span>      regionNode.setLastHost(lastHost);<a name="line.1733"></a>
-<span class="sourceLineNo">1734</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1734"></a>
-<span class="sourceLineNo">1735</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1735"></a>
-<span class="sourceLineNo">1736</span><a name="line.1736"></a>
-<span class="sourceLineNo">1737</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1737"></a>
-<span class="sourceLineNo">1738</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1738"></a>
-<span class="sourceLineNo">1739</span>      if (<a name="line.1739"></a>
-<span class="sourceLineNo">1740</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1740"></a>
-<span class="sourceLineNo">1741</span>      ) {<a name="line.1741"></a>
-<span class="sourceLineNo">1742</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1742"></a>
-<span class="sourceLineNo">1743</span>        regionStates.addRegionToServer(regionNode);<a name="line.1743"></a>
-<span class="sourceLineNo">1744</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1744"></a>
-<span class="sourceLineNo">1745</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1745"></a>
-<span class="sourceLineNo">1746</span>      }<a name="line.1746"></a>
-<span class="sourceLineNo">1747</span>      if (regionNode.getProcedure() != null) {<a name="line.1747"></a>
-<span class="sourceLineNo">1748</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1748"></a>
-<span class="sourceLineNo">1749</span>      }<a name="line.1749"></a>
-<span class="sourceLineNo">1750</span>    }<a name="line.1750"></a>
-<span class="sourceLineNo">1751</span>  };<a name="line.1751"></a>
-<span class="sourceLineNo">1752</span><a name="line.1752"></a>
-<span class="sourceLineNo">1753</span>  /**<a name="line.1753"></a>
-<span class="sourceLineNo">1754</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1754"></a>
-<span class="sourceLineNo">1755</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1755"></a>
-<span class="sourceLineNo">1756</span>   * @param regionInfo the region to be loaded from META.<a name="line.1756"></a>
-<span class="sourceLineNo">1757</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1757"></a>
-<span class="sourceLineNo">1758</span>   */<a name="line.1758"></a>
-<span class="sourceLineNo">1759</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1759"></a>
-<span class="sourceLineNo">1760</span>    throws IOException {<a name="line.1760"></a>
-<span class="sourceLineNo">1761</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1761"></a>
-<span class="sourceLineNo">1762</span>      ? regionInfo.getEncodedName()<a name="line.1762"></a>
-<span class="sourceLineNo">1763</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1763"></a>
-<span class="sourceLineNo">1764</span>        .getEncodedName();<a name="line.1764"></a>
-<span class="sourceLineNo">1765</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1765"></a>
-<span class="sourceLineNo">1766</span>  }<a name="line.1766"></a>
-<span class="sourceLineNo">1767</span><a name="line.1767"></a>
-<span class="sourceLineNo">1768</span>  /**<a name="line.1768"></a>
-<span class="sourceLineNo">1769</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1769"></a>
-<span class="sourceLineNo">1770</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1770"></a>
-<span class="sourceLineNo">1771</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1771"></a>
-<span class="sourceLineNo">1772</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1772"></a>
-<span class="sourceLineNo">1773</span>   */<a name="line.1773"></a>
-<span class="sourceLineNo">1774</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1774"></a>
-<span class="sourceLineNo">1775</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1775"></a>
-<span class="sourceLineNo">1776</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1776"></a>
-<span class="sourceLineNo">1777</span>  }<a name="line.1777"></a>
-<span class="sourceLineNo">1778</span><a name="line.1778"></a>
-<span class="sourceLineNo">1779</span>  private void loadMeta() throws IOException {<a name="line.1779"></a>
-<span class="sourceLineNo">1780</span>    // TODO: use a thread pool<a name="line.1780"></a>
-<span class="sourceLineNo">1781</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1781"></a>
-<span class="sourceLineNo">1782</span>  }<a name="line.1782"></a>
-<span class="sourceLineNo">1783</span><a name="line.1783"></a>
-<span class="sourceLineNo">1784</span>  /**<a name="line.1784"></a>
-<span class="sourceLineNo">1785</span>   * Used to check if the meta loading is done.<a name="line.1785"></a>
-<span class="sourceLineNo">1786</span>   * &lt;p/&gt;<a name="line.1786"></a>
-<span class="sourceLineNo">1787</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1787"></a>
-<span class="sourceLineNo">1788</span>   * @param hri region to check if it is already rebuild<a name="line.1788"></a>
-<span class="sourceLineNo">1789</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1789"></a>
-<span class="sourceLineNo">1790</span>   */<a name="line.1790"></a>
-<span class="sourceLineNo">1791</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1791"></a>
-<span class="sourceLineNo">1792</span>    if (!isRunning()) {<a name="line.1792"></a>
-<span class="sourceLineNo">1793</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1793"></a>
-<span class="sourceLineNo">1794</span>    }<a name="line.1794"></a>
-<span class="sourceLineNo">1795</span>    boolean meta = isMetaRegion(hri);<a name="line.1795"></a>
-<span class="sourceLineNo">1796</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1796"></a>
-<span class="sourceLineNo">1797</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1797"></a>
-<span class="sourceLineNo">1798</span>      throw new PleaseHoldException(<a name="line.1798"></a>
-<span class="sourceLineNo">1799</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1799"></a>
-<span class="sourceLineNo">1800</span>    }<a name="line.1800"></a>
-<span class="sourceLineNo">1801</span>  }<a name="line.1801"></a>
-<span class="sourceLineNo">1802</span><a name="line.1802"></a>
+<span class="sourceLineNo">1640</span>  public void joinCluster() throws IOException {<a name="line.1640"></a>
+<span class="sourceLineNo">1641</span>    long startTime = System.nanoTime();<a name="line.1641"></a>
+<span class="sourceLineNo">1642</span>    LOG.debug("Joining cluster...");<a name="line.1642"></a>
+<span class="sourceLineNo">1643</span><a name="line.1643"></a>
+<span class="sourceLineNo">1644</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1644"></a>
+<span class="sourceLineNo">1645</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1645"></a>
+<span class="sourceLineNo">1646</span>    // w/o meta.<a name="line.1646"></a>
+<span class="sourceLineNo">1647</span>    loadMeta();<a name="line.1647"></a>
+<span class="sourceLineNo">1648</span><a name="line.1648"></a>
+<span class="sourceLineNo">1649</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1649"></a>
+<span class="sourceLineNo">1650</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1650"></a>
+<span class="sourceLineNo">1651</span>        master.getServerManager().countOfRegionServers());<a name="line.1651"></a>
+<span class="sourceLineNo">1652</span>      Threads.sleep(250);<a name="line.1652"></a>
+<span class="sourceLineNo">1653</span>    }<a name="line.1653"></a>
+<span class="sourceLineNo">1654</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1654"></a>
+<span class="sourceLineNo">1655</span><a name="line.1655"></a>
+<span class="sourceLineNo">1656</span>    // Start the chores<a name="line.1656"></a>
+<span class="sourceLineNo">1657</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1657"></a>
+<span class="sourceLineNo">1658</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1658"></a>
+<span class="sourceLineNo">1659</span><a name="line.1659"></a>
+<span class="sourceLineNo">1660</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1660"></a>
+<span class="sourceLineNo">1661</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1661"></a>
+<span class="sourceLineNo">1662</span>  }<a name="line.1662"></a>
+<span class="sourceLineNo">1663</span><a name="line.1663"></a>
+<span class="sourceLineNo">1664</span>  /**<a name="line.1664"></a>
+<span class="sourceLineNo">1665</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1665"></a>
+<span class="sourceLineNo">1666</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1666"></a>
+<span class="sourceLineNo">1667</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1667"></a>
+<span class="sourceLineNo">1668</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1668"></a>
+<span class="sourceLineNo">1669</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1669"></a>
+<span class="sourceLineNo">1670</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1670"></a>
+<span class="sourceLineNo">1671</span>   * method any more. Need to revisit later.<a name="line.1671"></a>
+<span class="sourceLineNo">1672</span>   */<a name="line.1672"></a>
+<span class="sourceLineNo">1673</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1673"></a>
+<span class="sourceLineNo">1674</span>  // Needs to be done after the table state manager has been started.<a name="line.1674"></a>
+<span class="sourceLineNo">1675</span>  public void processOfflineRegions() {<a name="line.1675"></a>
+<span class="sourceLineNo">1676</span>    TransitRegionStateProcedure[] procs =<a name="line.1676"></a>
+<span class="sourceLineNo">1677</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1677"></a>
+<span class="sourceLineNo">1678</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1678"></a>
+<span class="sourceLineNo">1679</span>          rsn.lock();<a name="line.1679"></a>
+<span class="sourceLineNo">1680</span>          try {<a name="line.1680"></a>
+<span class="sourceLineNo">1681</span>            if (rsn.getProcedure() != null) {<a name="line.1681"></a>
+<span class="sourceLineNo">1682</span>              return null;<a name="line.1682"></a>
+<span class="sourceLineNo">1683</span>            } else {<a name="line.1683"></a>
+<span class="sourceLineNo">1684</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1684"></a>
+<span class="sourceLineNo">1685</span>                rsn.getRegionInfo(), null));<a name="line.1685"></a>
+<span class="sourceLineNo">1686</span>            }<a name="line.1686"></a>
+<span class="sourceLineNo">1687</span>          } finally {<a name="line.1687"></a>
+<span class="sourceLineNo">1688</span>            rsn.unlock();<a name="line.1688"></a>
+<span class="sourceLineNo">1689</span>          }<a name="line.1689"></a>
+<span class="sourceLineNo">1690</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1690"></a>
+<span class="sourceLineNo">1691</span>    if (procs.length &gt; 0) {<a name="line.1691"></a>
+<span class="sourceLineNo">1692</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1692"></a>
+<span class="sourceLineNo">1693</span>    }<a name="line.1693"></a>
+<span class="sourceLineNo">1694</span>  }<a name="line.1694"></a>
+<span class="sourceLineNo">1695</span><a name="line.1695"></a>
+<span class="sourceLineNo">1696</span>  /*<a name="line.1696"></a>
+<span class="sourceLineNo">1697</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1697"></a>
+<span class="sourceLineNo">1698</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1698"></a>
+<span class="sourceLineNo">1699</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1699"></a>
+<span class="sourceLineNo">1700</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1700"></a>
+<span class="sourceLineNo">1701</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1701"></a>
+<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates.<a name="line.1702"></a>
+<span class="sourceLineNo">1703</span>   */<a name="line.1703"></a>
+<span class="sourceLineNo">1704</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1704"></a>
+<span class="sourceLineNo">1705</span><a name="line.1705"></a>
+<span class="sourceLineNo">1706</span>    @Override<a name="line.1706"></a>
+<span class="sourceLineNo">1707</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1707"></a>
+<span class="sourceLineNo">1708</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1708"></a>
+<span class="sourceLineNo">1709</span>      if (<a name="line.1709"></a>
+<span class="sourceLineNo">1710</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1710"></a>
+<span class="sourceLineNo">1711</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1711"></a>
+<span class="sourceLineNo">1712</span>      ) {<a name="line.1712"></a>
+<span class="sourceLineNo">1713</span>        // This is a row with nothing in it.<a name="line.1713"></a>
+<span class="sourceLineNo">1714</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1714"></a>
+<span class="sourceLineNo">1715</span>        return;<a name="line.1715"></a>
+<span class="sourceLineNo">1716</span>      }<a name="line.1716"></a>
+<span class="sourceLineNo">1717</span>      State localState = state;<a name="line.1717"></a>
+<span class="sourceLineNo">1718</span>      if (localState == null) {<a name="line.1718"></a>
+<span class="sourceLineNo">1719</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1719"></a>
+<span class="sourceLineNo">1720</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1720"></a>
+<span class="sourceLineNo">1721</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1721"></a>
+<span class="sourceLineNo">1722</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1722"></a>
+<span class="sourceLineNo">1723</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1723"></a>
+<span class="sourceLineNo">1724</span>        localState = State.OFFLINE;<a name="line.1724"></a>
+<span class="sourceLineNo">1725</span>      }<a name="line.1725"></a>
+<span class="sourceLineNo">1726</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1726"></a>
+<span class="sourceLineNo">1727</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1727"></a>
+<span class="sourceLineNo">1728</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1728"></a>
+<span class="sourceLineNo">1729</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1729"></a>
+<span class="sourceLineNo">1730</span>      regionNode.setState(localState);<a name="line.1730"></a>
+<span class="sourceLineNo">1731</span>      regionNode.setLastHost(lastHost);<a name="line.1731"></a>
+<span class="sourceLineNo">1732</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1732"></a>
+<span class="sourceLineNo">1733</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1733"></a>
+<span class="sourceLineNo">1734</span><a name="line.1734"></a>
+<span class="sourceLineNo">1735</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1735"></a>
+<span class="sourceLineNo">1736</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1736"></a>
+<span class="sourceLineNo">1737</span>      if (<a name="line.1737"></a>
+<span class="sourceLineNo">1738</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1738"></a>
+<span class="sourceLineNo">1739</span>      ) {<a name="line.1739"></a>
+<span class="sourceLineNo">1740</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1740"></a>
+<span class="sourceLineNo">1741</span>        regionStates.addRegionToServer(regionNode);<a name="line.1741"></a>
+<span class="sourceLineNo">1742</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1742"></a>
+<span class="sourceLineNo">1743</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1743"></a>
+<span class="sourceLineNo">1744</span>      }<a name="line.1744"></a>
+<span class="sourceLineNo">1745</span>      if (regionNode.getProcedure() != null) {<a name="line.1745"></a>
+<span class="sourceLineNo">1746</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1746"></a>
+<span class="sourceLineNo">1747</span>      }<a name="line.1747"></a>
+<span class="sourceLineNo">1748</span>    }<a name="line.1748"></a>
+<span class="sourceLineNo">1749</span>  };<a name="line.1749"></a>
+<span class="sourceLineNo">1750</span><a name="line.1750"></a>
+<span class="sourceLineNo">1751</span>  /**<a name="line.1751"></a>
+<span class="sourceLineNo">1752</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1752"></a>
+<span class="sourceLineNo">1753</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1753"></a>
+<span class="sourceLineNo">1754</span>   * @param regionInfo the region to be loaded from META.<a name="line.1754"></a>
+<span class="sourceLineNo">1755</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1755"></a>
+<span class="sourceLineNo">1756</span>   */<a name="line.1756"></a>
+<span class="sourceLineNo">1757</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1757"></a>
+<span class="sourceLineNo">1758</span>    throws IOException {<a name="line.1758"></a>
+<span class="sourceLineNo">1759</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1759"></a>
+<span class="sourceLineNo">1760</span>      ? regionInfo.getEncodedName()<a name="line.1760"></a>
+<span class="sourceLineNo">1761</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1761"></a>
+<span class="sourceLineNo">1762</span>        .getEncodedName();<a name="line.1762"></a>
+<span class="sourceLineNo">1763</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1763"></a>
+<span class="sourceLineNo">1764</span>  }<a name="line.1764"></a>
+<span class="sourceLineNo">1765</span><a name="line.1765"></a>
+<span class="sourceLineNo">1766</span>  /**<a name="line.1766"></a>
+<span class="sourceLineNo">1767</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1767"></a>
+<span class="sourceLineNo">1768</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1768"></a>
+<span class="sourceLineNo">1769</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1769"></a>
+<span class="sourceLineNo">1770</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1770"></a>
+<span class="sourceLineNo">1771</span>   */<a name="line.1771"></a>
+<span class="sourceLineNo">1772</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1772"></a>
+<span class="sourceLineNo">1773</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1773"></a>
+<span class="sourceLineNo">1774</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1774"></a>
+<span class="sourceLineNo">1775</span>  }<a name="line.1775"></a>
+<span class="sourceLineNo">1776</span><a name="line.1776"></a>
+<span class="sourceLineNo">1777</span>  private void loadMeta() throws IOException {<a name="line.1777"></a>
+<span class="sourceLineNo">1778</span>    // TODO: use a thread pool<a name="line.1778"></a>
+<span class="sourceLineNo">1779</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1779"></a>
+<span class="sourceLineNo">1780</span>  }<a name="line.1780"></a>
+<span class="sourceLineNo">1781</span><a name="line.1781"></a>
+<span class="sourceLineNo">1782</span>  /**<a name="line.1782"></a>
+<span class="sourceLineNo">1783</span>   * Used to check if the meta loading is done.<a name="line.1783"></a>
+<span class="sourceLineNo">1784</span>   * &lt;p/&gt;<a name="line.1784"></a>
+<span class="sourceLineNo">1785</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1785"></a>
+<span class="sourceLineNo">1786</span>   * @param hri region to check if it is already rebuild<a name="line.1786"></a>
+<span class="sourceLineNo">1787</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1787"></a>
+<span class="sourceLineNo">1788</span>   */<a name="line.1788"></a>
+<span class="sourceLineNo">1789</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1789"></a>
+<span class="sourceLineNo">1790</span>    if (!isRunning()) {<a name="line.1790"></a>
+<span class="sourceLineNo">1791</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1791"></a>
+<span class="sourceLineNo">1792</span>    }<a name="line.1792"></a>
+<span class="sourceLineNo">1793</span>    boolean meta = isMetaRegion(hri);<a name="line.1793"></a>
+<span class="sourceLineNo">1794</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1794"></a>
+<span class="sourceLineNo">1795</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1795"></a>
+<span class="sourceLineNo">1796</span>      throw new PleaseHoldException(<a name="line.1796"></a>
+<span class="sourceLineNo">1797</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1797"></a>
+<span class="sourceLineNo">1798</span>    }<a name="line.1798"></a>
+<span class="sourceLineNo">1799</span>  }<a name="line.1799"></a>
+<span class="sourceLineNo">1800</span><a name="line.1800"></a>
+<span class="sourceLineNo">1801</span>  // ============================================================================================<a name="line.1801"></a>
+<span class="sourceLineNo">1802</span>  // TODO: Metrics<a name="line.1802"></a>
 <span class="sourceLineNo">1803</span>  // ============================================================================================<a name="line.1803"></a>
-<span class="sourceLineNo">1804</span>  // TODO: Metrics<a name="line.1804"></a>
-<span class="sourceLineNo">1805</span>  // ============================================================================================<a name="line.1805"></a>
-<span class="sourceLineNo">1806</span>  public int getNumRegionsOpened() {<a name="line.1806"></a>
-<span class="sourceLineNo">1807</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1807"></a>
-<span class="sourceLineNo">1808</span>    return 0;<a name="line.1808"></a>
-<span class="sourceLineNo">1809</span>  }<a name="line.1809"></a>
-<span class="sourceLineNo">1810</span><a name="line.1810"></a>
-<span class="sourceLineNo">1811</span>  /**<a name="line.1811"></a>
-<span class="sourceLineNo">1812</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1812"></a>
-<span class="sourceLineNo">1813</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1813"></a>
-<span class="sourceLineNo">1814</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1814"></a>
-<span class="sourceLineNo">1815</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1815"></a>
-<span class="sourceLineNo">1816</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1816"></a>
-<span class="sourceLineNo">1817</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1817"></a>
-<span class="sourceLineNo">1818</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1818"></a>
-<span class="sourceLineNo">1819</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1819"></a>
-<span class="sourceLineNo">1820</span>   */<a name="line.1820"></a>
-<span class="sourceLineNo">1821</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1821"></a>
-<span class="sourceLineNo">1822</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1822"></a>
-<span class="sourceLineNo">1823</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1823"></a>
-<span class="sourceLineNo">1824</span>    // Remove the in-memory rsReports result<a name="line.1824"></a>
-<span class="sourceLineNo">1825</span>    synchronized (rsReports) {<a name="line.1825"></a>
-<span class="sourceLineNo">1826</span>      rsReports.remove(serverName);<a name="line.1826"></a>
-<span class="sourceLineNo">1827</span>    }<a name="line.1827"></a>
-<span class="sourceLineNo">1828</span><a name="line.1828"></a>
-<span class="sourceLineNo">1829</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1829"></a>
-<span class="sourceLineNo">1830</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1830"></a>
-<span class="sourceLineNo">1831</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1831"></a>
-<span class="sourceLineNo">1832</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1832"></a>
-<span class="sourceLineNo">1833</span>    if (serverNode != null) {<a name="line.1833"></a>
-<span class="sourceLineNo">1834</span>      serverNode.writeLock().lock();<a name="line.1834"></a>
-<span class="sourceLineNo">1835</span>    }<a name="line.1835"></a>
-<span class="sourceLineNo">1836</span>    boolean carryingMeta;<a name="line.1836"></a>
-<span class="sourceLineNo">1837</span>    long pid;<a name="line.1837"></a>
-<span class="sourceLineNo">1838</span>    try {<a name="line.1838"></a>
-<span class="sourceLineNo">1839</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1839"></a>
-<span class="sourceLineNo">1840</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1840"></a>
-<span class="sourceLineNo">1841</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1841"></a>
-<span class="sourceLineNo">1842</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1842"></a>
-<span class="sourceLineNo">1843</span>          carryingMeta);<a name="line.1843"></a>
-<span class="sourceLineNo">1844</span>        return Procedure.NO_PROC_ID;<a name="line.1844"></a>
-<span class="sourceLineNo">1845</span>      } else {<a name="line.1845"></a>
-<span class="sourceLineNo">1846</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1846"></a>
-<span class="sourceLineNo">1847</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1847"></a>
-<span class="sourceLineNo">1848</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1848"></a>
-<span class="sourceLineNo">1849</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1849"></a>
-<span class="sourceLineNo">1850</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1850"></a>
-<span class="sourceLineNo">1851</span>        ServerState oldState = null;<a name="line.1851"></a>
-<span class="sourceLineNo">1852</span>        if (serverNode != null) {<a name="line.1852"></a>
-<span class="sourceLineNo">1853</span>          oldState = serverNode.getState();<a name="line.1853"></a>
-<span class="sourceLineNo">1854</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1854"></a>
-<span class="sourceLineNo">1855</span>        }<a name="line.1855"></a>
-<span class="sourceLineNo">1856</span><a name="line.1856"></a>
-<span class="sourceLineNo">1857</span>        if (force) {<a name="line.1857"></a>
-<span class="sourceLineNo">1858</span>          pid = procExec.submitProcedure(<a name="line.1858"></a>
-<span class="sourceLineNo">1859</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1859"></a>
-<span class="sourceLineNo">1860</span>        } else {<a name="line.1860"></a>
-<span class="sourceLineNo">1861</span>          pid = procExec.submitProcedure(<a name="line.1861"></a>
-<span class="sourceLineNo">1862</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1862"></a>
-<span class="sourceLineNo">1863</span>        }<a name="line.1863"></a>
-<span class="sourceLineNo">1864</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1864"></a>
-<span class="sourceLineNo">1865</span>          serverName, carryingMeta,<a name="line.1865"></a>
-<span class="sourceLineNo">1866</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1866"></a>
-<span class="sourceLineNo">1867</span>      }<a name="line.1867"></a>
-<span class="sourceLineNo">1868</span>    } finally {<a name="line.1868"></a>
-<span class="sourceLineNo">1869</span>      if (serverNode != null) {<a name="line.1869"></a>
-<span class="sourceLineNo">1870</span>        serverNode.writeLock().unlock();<a name="line.1870"></a>
-<span class="sourceLineNo">1871</span>      }<a name="line.1871"></a>
-<span class="sourceLineNo">1872</span>    }<a name="line.1872"></a>
-<span class="sourceLineNo">1873</span>    return pid;<a name="line.1873"></a>
-<span class="sourceLineNo">1874</span>  }<a name="line.1874"></a>
-<span class="sourceLineNo">1875</span><a name="line.1875"></a>
-<span class="sourceLineNo">1876</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1876"></a>
-<span class="sourceLineNo">1877</span>    // TODO used by MasterRpcServices<a name="line.1877"></a>
-<span class="sourceLineNo">1878</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1878"></a>
-<span class="sourceLineNo">1879</span>    if (node != null) {<a name="line.1879"></a>
-<span class="sourceLineNo">1880</span>      node.offline();<a name="line.1880"></a>
-<span class="sourceLineNo">1881</span>    }<a name="line.1881"></a>
-<span class="sourceLineNo">1882</span>  }<a name="line.1882"></a>
-<span class="sourceLineNo">1883</span><a name="line.1883"></a>
-<span class="sourceLineNo">1884</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1884"></a>
-<span class="sourceLineNo">1885</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1885"></a>
-<span class="sourceLineNo">1886</span>  }<a name="line.1886"></a>
-<span class="sourceLineNo">1887</span><a name="line.1887"></a>
-<span class="sourceLineNo">1888</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1888"></a>
-<span class="sourceLineNo">1889</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1889"></a>
-<span class="sourceLineNo">1890</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1890"></a>
-<span class="sourceLineNo">1891</span>  }<a name="line.1891"></a>
-<span class="sourceLineNo">1892</span><a name="line.1892"></a>
+<span class="sourceLineNo">1804</span>  public int getNumRegionsOpened() {<a name="line.1804"></a>
+<span class="sourceLineNo">1805</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1805"></a>
+<span class="sourceLineNo">1806</span>    return 0;<a name="line.1806"></a>
+<span class="sourceLineNo">1807</span>  }<a name="line.1807"></a>
+<span class="sourceLineNo">1808</span><a name="line.1808"></a>
+<span class="sourceLineNo">1809</span>  /**<a name="line.1809"></a>
+<span class="sourceLineNo">1810</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1810"></a>
+<span class="sourceLineNo">1811</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1811"></a>
+<span class="sourceLineNo">1812</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1812"></a>
+<span class="sourceLineNo">1813</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1813"></a>
+<span class="sourceLineNo">1814</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1814"></a>
+<span class="sourceLineNo">1815</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1815"></a>
+<span class="sourceLineNo">1816</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1816"></a>
+<span class="sourceLineNo">1817</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1817"></a>
+<span class="sourceLineNo">1818</span>   */<a name="line.1818"></a>
+<span class="sourceLineNo">1819</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1819"></a>
+<span class="sourceLineNo">1820</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1820"></a>
+<span class="sourceLineNo">1821</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1821"></a>
+<span class="sourceLineNo">1822</span>    // Remove the in-memory rsReports result<a name="line.1822"></a>
+<span class="sourceLineNo">1823</span>    synchronized (rsReports) {<a name="line.1823"></a>
+<span class="sourceLineNo">1824</span>      rsReports.remove(serverName);<a name="line.1824"></a>
+<span class="sourceLineNo">1825</span>    }<a name="line.1825"></a>
+<span class="sourceLineNo">1826</span><a name="line.1826"></a>
+<span class="sourceLineNo">1827</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1827"></a>
+<span class="sourceLineNo">1828</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1828"></a>
+<span class="sourceLineNo">1829</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1829"></a>
+<span class="sourceLineNo">1830</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1830"></a>
+<span class="sourceLineNo">1831</span>    if (serverNode != null) {<a name="line.1831"></a>
+<span class="sourceLineNo">1832</span>      serverNode.writeLock().lock();<a name="line.1832"></a>
+<span class="sourceLineNo">1833</span>    }<a name="line.1833"></a>
+<span class="sourceLineNo">1834</span>    boolean carryingMeta;<a name="line.1834"></a>
+<span class="sourceLineNo">1835</span>    long pid;<a name="line.1835"></a>
+<span class="sourceLineNo">1836</span>    try {<a name="line.1836"></a>
+<span class="sourceLineNo">1837</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1837"></a>
+<span class="sourceLineNo">1838</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1838"></a>
+<span class="sourceLineNo">1839</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1839"></a>
+<span class="sourceLineNo">1840</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1840"></a>
+<span class="sourceLineNo">1841</span>          carryingMeta);<a name="line.1841"></a>
+<span class="sourceLineNo">1842</span>        return Procedure.NO_PROC_ID;<a name="line.1842"></a>
+<span class="sourceLineNo">1843</span>      } else {<a name="line.1843"></a>
+<span class="sourceLineNo">1844</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1844"></a>
+<span class="sourceLineNo">1845</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1845"></a>
+<span class="sourceLineNo">1846</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1846"></a>
+<span class="sourceLineNo">1847</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1847"></a>
+<span class="sourceLineNo">1848</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1848"></a>
+<span class="sourceLineNo">1849</span>        ServerState oldState = null;<a name="line.1849"></a>
+<span class="sourceLineNo">1850</span>        if (serverNode != null) {<a name="line.1850"></a>
+<span class="sourceLineNo">1851</span>          oldState = serverNode.getState();<a name="line.1851"></a>
+<span class="sourceLineNo">1852</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1852"></a>
+<span class="sourceLineNo">1853</span>        }<a name="line.1853"></a>
+<span class="sourceLineNo">1854</span><a name="line.1854"></a>
+<span class="sourceLineNo">1855</span>        if (force) {<a name="line.1855"></a>
+<span class="sourceLineNo">1856</span>          pid = procExec.submitProcedure(<a name="line.1856"></a>
+<span class="sourceLineNo">1857</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1857"></a>
+<span class="sourceLineNo">1858</span>        } else {<a name="line.1858"></a>
+<span class="sourceLineNo">1859</span>          pid = procExec.submitProcedure(<a name="line.1859"></a>
+<span class="sourceLineNo">1860</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1860"></a>
+<span class="sourceLineNo">1861</span>        }<a name="line.1861"></a>
+<span class="sourceLineNo">1862</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1862"></a>
+<span class="sourceLineNo">1863</span>          serverName, carryingMeta,<a name="line.1863"></a>
+<span class="sourceLineNo">1864</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1864"></a>
+<span class="sourceLineNo">1865</span>      }<a name="line.1865"></a>
+<span class="sourceLineNo">1866</span>    } finally {<a name="line.1866"></a>
+<span class="sourceLineNo">1867</span>      if (serverNode != null) {<a name="line.1867"></a>
+<span class="sourceLineNo">1868</span>        serverNode.writeLock().unlock();<a name="line.1868"></a>
+<span class="sourceLineNo">1869</span>      }<a name="line.1869"></a>
+<span class="sourceLineNo">1870</span>    }<a name="line.1870"></a>
+<span class="sourceLineNo">1871</span>    return pid;<a name="line.1871"></a>
+<span class="sourceLineNo">1872</span>  }<a name="line.1872"></a>
+<span class="sourceLineNo">1873</span><a name="line.1873"></a>
+<span class="sourceLineNo">1874</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1874"></a>
+<span class="sourceLineNo">1875</span>    // TODO used by MasterRpcServices<a name="line.1875"></a>
+<span class="sourceLineNo">1876</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1876"></a>
+<span class="sourceLineNo">1877</span>    if (node != null) {<a name="line.1877"></a>
+<span class="sourceLineNo">1878</span>      node.offline();<a name="line.1878"></a>
+<span class="sourceLineNo">1879</span>    }<a name="line.1879"></a>
+<span class="sourceLineNo">1880</span>  }<a name="line.1880"></a>
+<span class="sourceLineNo">1881</span><a name="line.1881"></a>
+<span class="sourceLineNo">1882</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1882"></a>
+<span class="sourceLineNo">1883</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1883"></a>
+<span class="sourceLineNo">1884</span>  }<a name="line.1884"></a>
+<span class="sourceLineNo">1885</span><a name="line.1885"></a>
+<span class="sourceLineNo">1886</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1886"></a>
+<span class="sourceLineNo">1887</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1887"></a>
+<span class="sourceLineNo">1888</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1888"></a>
+<span class="sourceLineNo">1889</span>  }<a name="line.1889"></a>
+<span class="sourceLineNo">1890</span><a name="line.1890"></a>
+<span class="sourceLineNo">1891</span>  // ============================================================================================<a name="line.1891"></a>
+<span class="sourceLineNo">1892</span>  // TODO: UTILS/HELPERS?<a name="line.1892"></a>
 <span class="sourceLineNo">1893</span>  // ============================================================================================<a name="line.1893"></a>
-<span class="sourceLineNo">1894</span>  // TODO: UTILS/HELPERS?<a name="line.1894"></a>
-<span class="sourceLineNo">1895</span>  // ============================================================================================<a name="line.1895"></a>
-<span class="sourceLineNo">1896</span>  /**<a name="line.1896"></a>
-<span class="sourceLineNo">1897</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1897"></a>
-<span class="sourceLineNo">1898</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1898"></a>
-<span class="sourceLineNo">1899</span>   */<a name="line.1899"></a>
-<span class="sourceLineNo">1900</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1900"></a>
-<span class="sourceLineNo">1901</span>    if (isTableDisabled(tableName)) {<a name="line.1901"></a>
-<span class="sourceLineNo">1902</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1902"></a>
-<span class="sourceLineNo">1903</span>    }<a name="line.1903"></a>
-<span class="sourceLineNo">1904</span><a name="line.1904"></a>
-<span class="sourceLineNo">1905</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1905"></a>
-<span class="sourceLineNo">1906</span>    int ritCount = 0;<a name="line.1906"></a>
-<span class="sourceLineNo">1907</span>    for (RegionState regionState : states) {<a name="line.1907"></a>
-<span class="sourceLineNo">1908</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1908"></a>
-<span class="sourceLineNo">1909</span>        ritCount++;<a name="line.1909"></a>
-<span class="sourceLineNo">1910</span>      }<a name="line.1910"></a>
-<span class="sourceLineNo">1911</span>    }<a name="line.1911"></a>
-<span class="sourceLineNo">1912</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1912"></a>
-<span class="sourceLineNo">1913</span>  }<a name="line.1913"></a>
-<span class="sourceLineNo">1914</span><a name="line.1914"></a>
+<span class="sourceLineNo">1894</span>  /**<a name="line.1894"></a>
+<span class="sourceLineNo">1895</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1895"></a>
+<span class="sourceLineNo">1896</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1896"></a>
+<span class="sourceLineNo">1897</span>   */<a name="line.1897"></a>
+<span class="sourceLineNo">1898</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1898"></a>
+<span class="sourceLineNo">1899</span>    if (isTableDisabled(tableName)) {<a name="line.1899"></a>
+<span class="sourceLineNo">1900</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1900"></a>
+<span class="sourceLineNo">1901</span>    }<a name="line.1901"></a>
+<span class="sourceLineNo">1902</span><a name="line.1902"></a>
+<span class="sourceLineNo">1903</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1903"></a>
+<span class="sourceLineNo">1904</span>    int ritCount = 0;<a name="line.1904"></a>
+<span class="sourceLineNo">1905</span>    for (RegionState regionState : states) {<a name="line.1905"></a>
+<span class="sourceLineNo">1906</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1906"></a>
+<span class="sourceLineNo">1907</span>        ritCount++;<a name="line.1907"></a>
+<span class="sourceLineNo">1908</span>      }<a name="line.1908"></a>
+<span class="sourceLineNo">1909</span>    }<a name="line.1909"></a>
+<span class="sourceLineNo">1910</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1910"></a>
+<span class="sourceLineNo">1911</span>  }<a name="line.1911"></a>
+<span class="sourceLineNo">1912</span><a name="line.1912"></a>
+<span class="sourceLineNo">1913</span>  // ============================================================================================<a name="line.1913"></a>
+<span class="sourceLineNo">1914</span>  // TODO: Region State In Transition<a name="line.1914"></a>
 <span class="sourceLineNo">1915</span>  // ============================================================================================<a name="line.1915"></a>
-<span class="sourceLineNo">1916</span>  // TODO: Region State In Transition<a name="line.1916"></a>
-<span class="sourceLineNo">1917</span>  // ============================================================================================<a name="line.1917"></a>
-<span class="sourceLineNo">1918</span>  public boolean hasRegionsInTransition() {<a name="line.1918"></a>
-<span class="sourceLineNo">1919</span>    return regionStates.hasRegionsInTransition();<a name="line.1919"></a>
-<span class="sourceLineNo">1920</span>  }<a name="line.1920"></a>
-<span class="sourceLineNo">1921</span><a name="line.1921"></a>
-<span class="sourceLineNo">1922</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1922"></a>
-<span class="sourceLineNo">1923</span>    return regionStates.getRegionsInTransition();<a name="line.1923"></a>
-<span class="sourceLineNo">1924</span>  }<a name="line.1924"></a>
-<span class="sourceLineNo">1925</span><a name="line.1925"></a>
-<span class="sourceLineNo">1926</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1926"></a>
-<span class="sourceLineNo">1927</span>    return regionStates.getAssignedRegions();<a name="line.1927"></a>
-<span class="sourceLineNo">1928</span>  }<a name="line.1928"></a>
-<span class="sourceLineNo">1929</span><a name="line.1929"></a>
-<span class="sourceLineNo">1930</span>  /**<a name="line.1930"></a>
-<span class="sourceLineNo">1931</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1931"></a>
-<span class="sourceLineNo">1932</span>   */<a name="line.1932"></a>
-<span class="sourceLineNo">1933</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1933"></a>
-<span class="sourceLineNo">1934</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1934"></a>
-<span class="sourceLineNo">1935</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1935"></a>
-<span class="sourceLineNo">1936</span>  }<a name="line.1936"></a>
-<span class="sourceLineNo">1937</span><a name="line.1937"></a>
-<span class="sourceLineNo">1938</span>  /**<a name="line.1938"></a>
-<span class="sourceLineNo">1939</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1939"></a>
-<span class="sourceLineNo">1940</span>   */<a name="line.1940"></a>
-<span class="sourceLineNo">1941</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1941"></a>
-<span class="sourceLineNo">1942</span>    final RegionStateNode regionState =<a name="line.1942"></a>
-<span class="sourceLineNo">1943</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1943"></a>
-<span class="sourceLineNo">1944</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1944"></a>
-<span class="sourceLineNo">1945</span>  }<a name="line.1945"></a>
-<span class="sourceLineNo">1946</span><a name="line.1946"></a>
-<span class="sourceLineNo">1947</span>  // ============================================================================================<a name="line.1947"></a>
-<span class="sourceLineNo">1948</span>  // Expected states on region state transition.<a name="line.1948"></a>
-<span class="sourceLineNo">1949</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1949"></a>
-<span class="sourceLineNo">1950</span>  // See the comments in regionOpening method for more details.<a name="line.1950"></a>
-<span class="sourceLineNo">1951</span>  // ============================================================================================<a name="line.1951"></a>
-<span class="sourceLineNo">1952</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1952"></a>
-<span class="sourceLineNo">1953</span>    State.OPEN // Retrying<a name="line.1953"></a>
-<span class="sourceLineNo">1954</span>  };<a name="line.1954"></a>
-<span class="sourceLineNo">1955</span><a name="line.1955"></a>
-<span class="sourceLineNo">1956</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1956"></a>
-<span class="sourceLineNo">1957</span>    State.CLOSING, // Retrying<a name="line.1957"></a>
-<span class="sourceLineNo">1958</span>    State.SPLITTING, // Offline the split parent<a name="line.1958"></a>
-<span class="sourceLineNo">1959</span>    State.MERGING // Offline the merge parents<a name="line.1959"></a>
-<span class="sourceLineNo">1960</span>  };<a name="line.1960"></a>
-<span class="sourceLineNo">1961</span><a name="line.1961"></a>
-<span class="sourceLineNo">1962</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1962"></a>
-<span class="sourceLineNo">1963</span>    State.CLOSED // Retrying<a name="line.1963"></a>
-<span class="sourceLineNo">1964</span>  };<a name="line.1964"></a>
-<span class="sourceLineNo">1965</span><a name="line.1965"></a>
-<span class="sourceLineNo">1966</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1966"></a>
-<span class="sourceLineNo">1967</span>  // usages<a name="line.1967"></a>
-<span class="sourceLineNo">1968</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1968"></a>
-<span class="sourceLineNo">1969</span><a name="line.1969"></a>
-<span class="sourceLineNo">1970</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1970"></a>
-<span class="sourceLineNo">1971</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1971"></a>
-<span class="sourceLineNo">1972</span><a name="line.1972"></a>
-<span class="sourceLineNo">1973</span>  // ============================================================================================<a name="line.1973"></a>
-<span class="sourceLineNo">1974</span>  // Region Status update<a name="line.1974"></a>
-<span class="sourceLineNo">1975</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1975"></a>
-<span class="sourceLineNo">1976</span>  // and pre-assumptions are very tricky.<a name="line.1976"></a>
-<span class="sourceLineNo">1977</span>  // ============================================================================================<a name="line.1977"></a>
-<span class="sourceLineNo">1978</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1978"></a>
-<span class="sourceLineNo">1979</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1979"></a>
-<span class="sourceLineNo">1980</span>    RegionState.State state = regionNode.getState();<a name="line.1980"></a>
-<span class="sourceLineNo">1981</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1981"></a>
-<span class="sourceLineNo">1982</span>    boolean succ = false;<a name="line.1982"></a>
-<span class="sourceLineNo">1983</span>    try {<a name="line.1983"></a>
-<span class="sourceLineNo">1984</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1984"></a>
-<span class="sourceLineNo">1985</span>      succ = true;<a name="line.1985"></a>
-<span class="sourceLineNo">1986</span>    } finally {<a name="line.1986"></a>
-<span class="sourceLineNo">1987</span>      if (!succ) {<a name="line.1987"></a>
-<span class="sourceLineNo">1988</span>        // revert<a name="line.1988"></a>
-<span class="sourceLineNo">1989</span>        regionNode.setState(state);<a name="line.1989"></a>
-<span class="sourceLineNo">1990</span>      }<a name="line.1990"></a>
-<span class="sourceLineNo">1991</span>    }<a name="line.1991"></a>
-<span class="sourceLineNo">1992</span>  }<a name="line.1992"></a>
-<span class="sourceLineNo">1993</span><a name="line.1993"></a>
-<span class="sourceLineNo">1994</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1994"></a>
-<span class="sourceLineNo">1995</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1995"></a>
-<span class="sourceLineNo">1996</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1996"></a>
-<span class="sourceLineNo">1997</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1997"></a>
-<span class="sourceLineNo">1998</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1998"></a>
-<span class="sourceLineNo">1999</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1999"></a>
-<span class="sourceLineNo">2000</span>    regionStates.addRegionToServer(regionNode);<a name="line.2000"></a>
-<span class="sourceLineNo">2001</span>    // update the operation count metrics<a name="line.2001"></a>
-<span class="sourceLineNo">2002</span>    metrics.incrementOperationCounter();<a name="line.2002"></a>
-<span class="sourceLineNo">2003</span>  }<a name="line.2003"></a>
-<span class="sourceLineNo">2004</span><a name="line.2004"></a>
-<span class="sourceLineNo">2005</span>  // should be called under the RegionStateNode lock<a name="line.2005"></a>
-<span class="sourceLineNo">2006</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2006"></a>
-<span class="sourceLineNo">2007</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2007"></a>
-<span class="sourceLineNo">2008</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2008"></a>
-<span class="sourceLineNo">2009</span>    RegionState.State state = regionNode.getState();<a name="line.2009"></a>
-<span class="sourceLineNo">2010</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2010"></a>
-<span class="sourceLineNo">2011</span>    if (giveUp) {<a name="line.2011"></a>
-<span class="sourceLineNo">2012</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2012"></a>
-<span class="sourceLineNo">2013</span>      regionNode.setRegionLocation(null);<a name="line.2013"></a>
-<span class="sourceLineNo">2014</span>      boolean succ = false;<a name="line.2014"></a>
-<span class="sourceLineNo">2015</span>      try {<a name="line.2015"></a>
-<span class="sourceLineNo">2016</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2016"></a>
-<span class="sourceLineNo">2017</span>        succ = true;<a name="line.2017"></a>
-<span class="sourceLineNo">2018</span>      } finally {<a name="line.2018"></a>
-<span class="sourceLineNo">2019</span>        if (!succ) {<a name="line.2019"></a>
-<span class="sourceLineNo">2020</span>          // revert<a name="line.2020"></a>
-<span class="sourceLineNo">2021</span>          regionNode.setState(state);<a name="line.2021"></a>
-<span class="sourceLineNo">2022</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2022"></a>
-<span class="sourceLineNo">2023</span>        }<a name="line.2023"></a>
-<span class="sourceLineNo">2024</span>      }<a name="line.2024"></a>
-<span class="sourceLineNo">2025</span>    }<a name="line.2025"></a>
-<span class="sourceLineNo">2026</span>    if (regionLocation != null) {<a name="line.2026"></a>
-<span class="sourceLineNo">2027</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2027"></a>
-<span class="sourceLineNo">2028</span>    }<a name="line.2028"></a>
-<span class="sourceLineNo">2029</span>  }<a name="line.2029"></a>
-<span class="sourceLineNo">2030</span><a name="line.2030"></a>
-<span class="sourceLineNo">2031</span>  // should be called under the RegionStateNode lock<a name="line.2031"></a>
-<span class="sourceLineNo">2032</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2032"></a>
-<span class="sourceLineNo">2033</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2033"></a>
-<span class="sourceLineNo">2034</span><a name="line.2034"></a>
-<span class="sourceLineNo">2035</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2035"></a>
-<span class="sourceLineNo">2036</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2036"></a>
-<span class="sourceLineNo">2037</span>    if (isMetaRegion(hri)) {<a name="line.2037"></a>
-<span class="sourceLineNo">2038</span>      setMetaAssigned(hri, false);<a name="line.2038"></a>
-<span class="sourceLineNo">2039</span>    }<a name="line.2039"></a>
-<span class="sourceLineNo">2040</span>    regionStates.addRegionToServer(regionNode);<a name="line.2040"></a>
-<span class="sourceLineNo">2041</span>    // update the operation count metrics<a name="line.2041"></a>
-<span class="sourceLineNo">2042</span>    metrics.incrementOperationCounter();<a name="line.2042"></a>
-<span class="sourceLineNo">2043</span>  }<a name="line.2043"></a>
-<span class="sourceLineNo">2044</span><a name="line.2044"></a>
-<span class="sourceLineNo">2045</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2045"></a>
-<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2046"></a>
-<span class="sourceLineNo">2047</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2047"></a>
-<span class="sourceLineNo">2048</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2048"></a>
-<span class="sourceLineNo">2049</span><a name="line.2049"></a>
-<span class="sourceLineNo">2050</span>  // should be called under the RegionStateNode lock<a name="line.2050"></a>
-<span class="sourceLineNo">2051</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2051"></a>
-<span class="sourceLineNo">2052</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2052"></a>
-<span class="sourceLineNo">2053</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2053"></a>
-<span class="sourceLineNo">2054</span>    regionStates.addRegionToServer(regionNode);<a name="line.2054"></a>
-<span class="sourceLineNo">2055</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2055"></a>
-<span class="sourceLineNo">2056</span>  }<a name="line.2056"></a>
-<span class="sourceLineNo">2057</span><a name="line.2057"></a>
-<span class="sourceLineNo">2058</span>  // should be called under the RegionStateNode lock<a name="line.2058"></a>
-<span class="sourceLineNo">2059</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2059"></a>
-<span class="sourceLineNo">2060</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2060"></a>
-<span class="sourceLineNo">2061</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2061"></a>
-<span class="sourceLineNo">2062</span>    regionNode.setRegionLocation(null);<a name="line.2062"></a>
-<span class="sourceLineNo">2063</span>    if (regionLocation != null) {<a name="line.2063"></a>
-<span class="sourceLineNo">2064</span>      regionNode.setLastHost(regionLocation);<a name="line.2064"></a>
-<span class="sourceLineNo">2065</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2065"></a>
-<span class="sourceLineNo">2066</span>    }<a name="line.2066"></a>
-<span class="sourceLineNo">2067</span>  }<a name="line.2067"></a>
-<span class="sourceLineNo">2068</span><a name="line.2068"></a>
-<span class="sourceLineNo">2069</span>  // should be called under the RegionStateNode lock<a name="line.2069"></a>
-<span class="sourceLineNo">2070</span>  // for SCP<a name="line.2070"></a>
-<span class="sourceLineNo">2071</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2071"></a>
-<span class="sourceLineNo">2072</span>    RegionState.State state = regionNode.getState();<a name="line.2072"></a>
-<span class="sourceLineNo">2073</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2073"></a>
-<span class="sourceLineNo">2074</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2074"></a>
-<span class="sourceLineNo">2075</span>    regionNode.setRegionLocation(null);<a name="line.2075"></a>
-<span class="sourceLineNo">2076</span>    boolean succ = false;<a name="line.2076"></a>
-<span class="sourceLineNo">2077</span>    try {<a name="line.2077"></a>
-<span class="sourceLineNo">2078</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2078"></a>
-<span class="sourceLineNo">2079</span>      succ = true;<a name="line.2079"></a>
-<span class="sourceLineNo">2080</span>    } finally {<a name="line.2080"></a>
-<span class="sourceLineNo">2081</span>      if (!succ) {<a name="line.2081"></a>
-<span class="sourceLineNo">2082</span>        // revert<a name="line.2082"></a>
-<span class="sourceLineNo">2083</span>        regionNode.setState(state);<a name="line.2083"></a>
-<span class="sourceLineNo">2084</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2084"></a>
-<span class="sourceLineNo">2085</span>      }<a name="line.2085"></a>
-<span class="sourceLineNo">2086</span>    }<a name="line.2086"></a>
-<span class="sourceLineNo">2087</span>    if (regionLocation != null) {<a name="line.2087"></a>
-<span class="sourceLineNo">2088</span>      regionNode.setLastHost(regionLocation);<a name="line.2088"></a>
-<span class="sourceLineNo">2089</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2089"></a>
-<span class="sourceLineNo">2090</span>    }<a name="line.2090"></a>
-<span class="sourceLineNo">2091</span>  }<a name="line.2091"></a>
-<span class="sourceLineNo">2092</span><a name="line.2092"></a>
-<span class="sourceLineNo">2093</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2093"></a>
-<span class="sourceLineNo">2094</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2094"></a>
-<span class="sourceLineNo">2095</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2095"></a>
-<span class="sourceLineNo">2096</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2096"></a>
-<span class="sourceLineNo">2097</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2097"></a>
-<span class="sourceLineNo">2098</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2098"></a>
-<span class="sourceLineNo">2099</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2099"></a>
-<span class="sourceLineNo">2100</span>      // on table that contains state.<a name="line.2100"></a>
-<span class="sourceLineNo">2101</span>      setMetaAssigned(regionInfo, true);<a name="line.2101"></a>
-<span class="sourceLineNo">2102</span>    }<a name="line.2102"></a>
-<span class="sourceLineNo">2103</span>  }<a name="line.2103"></a>
-<span class="sourceLineNo">2104</span><a name="line.2104"></a>
+<span class="sourceLineNo">1916</span>  public boolean hasRegionsInTransition() {<a name="line.1916"></a>
+<span class="sourceLineNo">1917</span>    return regionStates.hasRegionsInTransition();<a name="line.1917"></a>
+<span class="sourceLineNo">1918</span>  }<a name="line.1918"></a>
+<span class="sourceLineNo">1919</span><a name="line.1919"></a>
+<span class="sourceLineNo">1920</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1920"></a>
+<span class="sourceLineNo">1921</span>    return regionStates.getRegionsInTransition();<a name="line.1921"></a>
+<span class="sourceLineNo">1922</span>  }<a name="line.1922"></a>
+<span class="sourceLineNo">1923</span><a name="line.1923"></a>
+<span class="sourceLineNo">1924</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1924"></a>
+<span class="sourceLineNo">1925</span>    return regionStates.getAssignedRegions();<a name="line.1925"></a>
+<span class="sourceLineNo">1926</span>  }<a name="line.1926"></a>
+<span class="sourceLineNo">1927</span><a name="line.1927"></a>
+<span class="sourceLineNo">1928</span>  /**<a name="line.1928"></a>
+<span class="sourceLineNo">1929</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1929"></a>
+<span class="sourceLineNo">1930</span>   */<a name="line.1930"></a>
+<span class="sourceLineNo">1931</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1931"></a>
+<span class="sourceLineNo">1932</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1932"></a>
+<span class="sourceLineNo">1933</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1933"></a>
+<span class="sourceLineNo">1934</span>  }<a name="line.1934"></a>
+<span class="sourceLineNo">1935</span><a name="line.1935"></a>
+<span class="sourceLineNo">1936</span>  /**<a name="line.1936"></a>
+<span class="sourceLineNo">1937</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1937"></a>
+<span class="sourceLineNo">1938</span>   */<a name="line.1938"></a>
+<span class="sourceLineNo">1939</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1939"></a>
+<span class="sourceLineNo">1940</span>    final RegionStateNode regionState =<a name="line.1940"></a>
+<span class="sourceLineNo">1941</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1941"></a>
+<span class="sourceLineNo">1942</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1942"></a>
+<span class="sourceLineNo">1943</span>  }<a name="line.1943"></a>
+<span class="sourceLineNo">1944</span><a name="line.1944"></a>
+<span class="sourceLineNo">1945</span>  // ============================================================================================<a name="line.1945"></a>
+<span class="sourceLineNo">1946</span>  // Expected states on region state transition.<a name="line.1946"></a>
+<span class="sourceLineNo">1947</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1947"></a>
+<span class="sourceLineNo">1948</span>  // See the comments in regionOpening method for more details.<a name="line.1948"></a>
+<span class="sourceLineNo">1949</span>  // ============================================================================================<a name="line.1949"></a>
+<span class="sourceLineNo">1950</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1950"></a>
+<span class="sourceLineNo">1951</span>    State.OPEN // Retrying<a name="line.1951"></a>
+<span class="sourceLineNo">1952</span>  };<a name="line.1952"></a>
+<span class="sourceLineNo">1953</span><a name="line.1953"></a>
+<span class="sourceLineNo">1954</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1954"></a>
+<span class="sourceLineNo">1955</span>    State.CLOSING, // Retrying<a name="line.1955"></a>
+<span class="sourceLineNo">1956</span>    State.SPLITTING, // Offline the split parent<a name="line.1956"></a>
+<span class="sourceLineNo">1957</span>    State.MERGING // Offline the merge parents<a name="line.1957"></a>
+<span class="sourceLineNo">1958</span>  };<a name="line.1958"></a>
+<span class="sourceLineNo">1959</span><a name="line.1959"></a>
+<span class="sourceLineNo">1960</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1960"></a>
+<span class="sourceLineNo">1961</span>    State.CLOSED // Retrying<a name="line.1961"></a>
+<span class="sourceLineNo">1962</span>  };<a name="line.1962"></a>
+<span class="sourceLineNo">1963</span><a name="line.1963"></a>
+<span class="sourceLineNo">1964</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1964"></a>
+<span class="sourceLineNo">1965</span>  // usages<a name="line.1965"></a>
+<span class="sourceLineNo">1966</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1966"></a>
+<span class="sourceLineNo">1967</span><a name="line.1967"></a>
+<span class="sourceLineNo">1968</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1968"></a>
+<span class="sourceLineNo">1969</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1969"></a>
+<span class="sourceLineNo">1970</span><a name="line.1970"></a>
+<span class="sourceLineNo">1971</span>  // ============================================================================================<a name="line.1971"></a>
+<span class="sourceLineNo">1972</span>  // Region Status update<a name="line.1972"></a>
+<span class="sourceLineNo">1973</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1973"></a>
+<span class="sourceLineNo">1974</span>  // and pre-assumptions are very tricky.<a name="line.1974"></a>
+<span class="sourceLineNo">1975</span>  // ============================================================================================<a name="line.1975"></a>
+<span class="sourceLineNo">1976</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1976"></a>
+<span class="sourceLineNo">1977</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1977"></a>
+<span class="sourceLineNo">1978</span>    RegionState.State state = regionNode.getState();<a name="line.1978"></a>
+<span class="sourceLineNo">1979</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1979"></a>
+<span class="sourceLineNo">1980</span>    boolean succ = false;<a name="line.1980"></a>
+<span class="sourceLineNo">1981</span>    try {<a name="line.1981"></a>
+<span class="sourceLineNo">1982</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1982"></a>
+<span class="sourceLineNo">1983</span>      succ = true;<a name="line.1983"></a>
+<span class="sourceLineNo">1984</span>    } finally {<a name="line.1984"></a>
+<span class="sourceLineNo">1985</span>      if (!succ) {<a name="line.1985"></a>
+<span class="sourceLineNo">1986</span>        // revert<a name="line.1986"></a>
+<span class="sourceLineNo">1987</span>        regionNode.setState(state);<a name="line.1987"></a>
+<span class="sourceLineNo">1988</span>      }<a name="line.1988"></a>
+<span class="sourceLineNo">1989</span>    }<a name="line.1989"></a>
+<span class="sourceLineNo">1990</span>  }<a name="line.1990"></a>
+<span class="sourceLineNo">1991</span><a name="line.1991"></a>
+<span class="sourceLineNo">1992</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1992"></a>
+<span class="sourceLineNo">1993</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1993"></a>
+<span class="sourceLineNo">1994</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1994"></a>
+<span class="sourceLineNo">1995</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1995"></a>
+<span class="sourceLineNo">1996</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1996"></a>
+<span class="sourceLineNo">1997</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1997"></a>
+<span class="sourceLineNo">1998</span>    regionStates.addRegionToServer(regionNode);<a name="line.1998"></a>
+<span class="sourceLineNo">1999</span>    // update the operation count metrics<a name="line.1999"></a>
+<span class="sourceLineNo">2000</span>    metrics.incrementOperationCounter();<a name="line.2000"></a>
+<span class="sourceLineNo">2001</span>  }<a name="line.2001"></a>
+<span class="sourceLineNo">2002</span><a name="line.2002"></a>
+<span class="sourceLineNo">2003</span>  // should be called under the RegionStateNode lock<a name="line.2003"></a>
+<span class="sourceLineNo">2004</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2004"></a>
+<span class="sourceLineNo">2005</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2005"></a>
+<span class="sourceLineNo">2006</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2006"></a>
+<span class="sourceLineNo">2007</span>    RegionState.State state = regionNode.getState();<a name="line.2007"></a>
+<span class="sourceLineNo">2008</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2008"></a>
+<span class="sourceLineNo">2009</span>    if (giveUp) {<a name="line.2009"></a>
+<span class="sourceLineNo">2010</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2010"></a>
+<span class="sourceLineNo">2011</span>      regionNode.setRegionLocation(null);<a name="line.2011"></a>
+<span class="sourceLineNo">2012</span>      boolean succ = false;<a name="line.2012"></a>
+<span class="sourceLineNo">2013</span>      try {<a name="line.2013"></a>
+<span class="sourceLineNo">2014</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2014"></a>
+<span class="sourceLineNo">2015</span>        succ = true;<a name="line.2015"></a>
+<span class="sourceLineNo">2016</span>      } finally {<a name="line.2016"></a>
+<span class="sourceLineNo">2017</span>        if (!succ) {<a name="line.2017"></a>
+<span class="sourceLineNo">2018</span>          // revert<a name="line.2018"></a>
+<span class="sourceLineNo">2019</span>          regionNode.setState(state);<a name="line.2019"></a>
+<span class="sourceLineNo">2020</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2020"></a>
+<span class="sourceLineNo">2021</span>        }<a name="line.2021"></a>
+<span class="sourceLineNo">2022</span>      }<a name="line.2022"></a>
+<span class="sourceLineNo">2023</span>    }<a name="line.2023"></a>
+<span class="sourceLineNo">2024</span>    if (regionLocation != null) {<a name="line.2024"></a>
+<span class="sourceLineNo">2025</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2025"></a>
+<span class="sourceLineNo">2026</span>    }<a name="line.2026"></a>
+<span class="sourceLineNo">2027</span>  }<a name="line.2027"></a>
+<span class="sourceLineNo">2028</span><a name="line.2028"></a>
+<span class="sourceLineNo">2029</span>  // should be called under the RegionStateNode lock<a name="line.2029"></a>
+<span class="sourceLineNo">2030</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2030"></a>
+<span class="sourceLineNo">2031</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2031"></a>
+<span class="sourceLineNo">2032</span><a name="line.2032"></a>
+<span class="sourceLineNo">2033</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2033"></a>
+<span class="sourceLineNo">2034</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2034"></a>
+<span class="sourceLineNo">2035</span>    if (isMetaRegion(hri)) {<a name="line.2035"></a>
+<span class="sourceLineNo">2036</span>      setMetaAssigned(hri, false);<a name="line.2036"></a>
+<span class="sourceLineNo">2037</span>    }<a name="line.2037"></a>
+<span class="sourceLineNo">2038</span>    regionStates.addRegionToServer(regionNode);<a name="line.2038"></a>
+<span class="sourceLineNo">2039</span>    // update the operation count metrics<a name="line.2039"></a>
+<span class="sourceLineNo">2040</span>    metrics.incrementOperationCounter();<a name="line.2040"></a>
+<span class="sourceLineNo">2041</span>  }<a name="line.2041"></a>
+<span class="sourceLineNo">2042</span><a name="line.2042"></a>
+<span class="sourceLineNo">2043</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2043"></a>
+<span class="sourceLineNo">2044</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2044"></a>
+<span class="sourceLineNo">2045</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2045"></a>
+<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2046"></a>
+<span class="sourceLineNo">2047</span><a name="line.2047"></a>
+<span class="sourceLineNo">2048</span>  // should be called under the RegionStateNode lock<a name="line.2048"></a>
+<span class="sourceLineNo">2049</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2049"></a>
+<span class="sourceLineNo">2050</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2050"></a>
+<span class="sourceLineNo">2051</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2051"></a>
+<span class="sourceLineNo">2052</span>    regionStates.addRegionToServer(regionNode);<a name="line.2052"></a>
+<span class="sourceLineNo">2053</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2053"></a>
+<span class="sourceLineNo">2054</span>  }<a name="line.2054"></a>
+<span class="sourceLineNo">2055</span><a name="line.2055"></a>
+<span class="sourceLineNo">2056</span>  // should be called under the RegionStateNode lock<a name="line.2056"></a>
+<span class="sourceLineNo">2057</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2057"></a>
+<span class="sourceLineNo">2058</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2058"></a>
+<span class="sourceLineNo">2059</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2059"></a>
+<span class="sourceLineNo">2060</span>    regionNode.setRegionLocation(null);<a name="line.2060"></a>
+<span class="sourceLineNo">2061</span>    if (regionLocation != null) {<a name="line.2061"></a>
+<span class="sourceLineNo">2062</span>      regionNode.setLastHost(regionLocation);<a name="line.2062"></a>
+<span class="sourceLineNo">2063</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2063"></a>
+<span class="sourceLineNo">2064</span>    }<a name="line.2064"></a>
+<span class="sourceLineNo">2065</span>  }<a name="line.2065"></a>
+<span class="sourceLineNo">2066</span><a name="line.2066"></a>
+<span class="sourceLineNo">2067</span>  // should be called under the RegionStateNode lock<a name="line.2067"></a>
+<span class="sourceLineNo">2068</span>  // for SCP<a name="line.2068"></a>
+<span class="sourceLineNo">2069</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2069"></a>
+<span class="sourceLineNo">2070</span>    RegionState.State state = regionNode.getState();<a name="line.2070"></a>
+<span class="sourceLineNo">2071</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2071"></a>
+<span class="sourceLineNo">2072</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2072"></a>
+<span class="sourceLineNo">2073</span>    regionNode.setRegionLocation(null);<a name="line.2073"></a>
+<span class="sourceLineNo">2074</span>    boolean succ = false;<a name="line.2074"></a>
+<span class="sourceLineNo">2075</span>    try {<a name="line.2075"></a>
+<span class="sourceLineNo">2076</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2076"></a>
+<span class="sourceLineNo">2077</span>      succ = true;<a name="line.2077"></a>
+<span class="sourceLineNo">2078</span>    } finally {<a name="line.2078"></a>
+<span class="sourceLineNo">2079</span>      if (!succ) {<a name="line.2079"></a>
+<span class="sourceLineNo">2080</span>        // revert<a name="line.2080"></a>
+<span class="sourceLineNo">2081</span>        regionNode.setState(state);<a name="line.2081"></a>
+<span class="sourceLineNo">2082</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2082"></a>
+<span class="sourceLineNo">2083</span>      }<a name="line.2083"></a>
+<span class="sourceLineNo">2084</span>    }<a name="line.2084"></a>
+<span class="sourceLineNo">2085</span>    if (regionLocation != null) {<a name="line.2085"></a>
+<span class="sourceLineNo">2086</span>      regionNode.setLastHost(regionLocation);<a name="line.2086"></a>
+<span class="sourceLineNo">2087</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2087"></a>
+<span class="sourceLineNo">2088</span>    }<a name="line.2088"></a>
+<span class="sourceLineNo">2089</span>  }<a name="line.2089"></a>
+<span class="sourceLineNo">2090</span><a name="line.2090"></a>
+<span class="sourceLineNo">2091</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2091"></a>
+<span class="sourceLineNo">2092</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2092"></a>
+<span class="sourceLineNo">2093</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2093"></a>
+<span class="sourceLineNo">2094</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2094"></a>
+<span class="sourceLineNo">2095</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2095"></a>
+<span class="sourceLineNo">2096</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2096"></a>
+<span class="sourceLineNo">2097</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2097"></a>
+<span class="sourceLineNo">2098</span>      // on table that contains state.<a name="line.2098"></a>
+<span class="sourceLineNo">2099</span>      setMetaAssigned(regionInfo, true);<a name="line.2099"></a>
+<span class="sourceLineNo">2100</span>    }<a name="line.2100"></a>
+<span class="sourceLineNo">2101</span>  }<a name="line.2101"></a>
+<span class="sourceLineNo">2102</span><a name="line.2102"></a>
+<span class="sourceLineNo">2103</span>  // ============================================================================================<a name="line.2103"></a>
+<span class="sourceLineNo">2104</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2104"></a>
 <span class="sourceLineNo">2105</span>  // ============================================================================================<a name="line.2105"></a>
-<span class="sourceLineNo">2106</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2106"></a>
-<span class="sourceLineNo">2107</span>  // ============================================================================================<a name="line.2107"></a>
-<span class="sourceLineNo">2108</span><a name="line.2108"></a>
-<span class="sourceLineNo">2109</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2109"></a>
-<span class="sourceLineNo">2110</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2110"></a>
-<span class="sourceLineNo">2111</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2111"></a>
-<span class="sourceLineNo">2112</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2112"></a>
-<span class="sourceLineNo">2113</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2113"></a>
-<span class="sourceLineNo">2114</span>    // later figuring what regions are in a table and what are not: see<a name="line.2114"></a>
-<span class="sourceLineNo">2115</span>    // regionStates#getRegionsOfTable<a name="line.2115"></a>
-<span class="sourceLineNo">2116</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2116"></a>
-<span class="sourceLineNo">2117</span>    node.setState(State.SPLIT);<a name="line.2117"></a>
-<span class="sourceLineNo">2118</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2118"></a>
-<span class="sourceLineNo">2119</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
-<span class="sourceLineNo">2120</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2120"></a>
-<span class="sourceLineNo">2121</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2121"></a>
-<span class="sourceLineNo">2122</span><a name="line.2122"></a>
-<span class="sourceLineNo">2123</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2123"></a>
-<span class="sourceLineNo">2124</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2124"></a>
-<span class="sourceLineNo">2125</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2125"></a>
-<span class="sourceLineNo">2126</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2126"></a>
-<span class="sourceLineNo">2127</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2127"></a>
-<span class="sourceLineNo">2128</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2128"></a>
-<span class="sourceLineNo">2129</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2129"></a>
-<span class="sourceLineNo">2130</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2130"></a>
-<span class="sourceLineNo">2131</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2131"></a>
-<span class="sourceLineNo">2132</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2132"></a>
-<span class="sourceLineNo">2133</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2133"></a>
-<span class="sourceLineNo">2134</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2134"></a>
-<span class="sourceLineNo">2135</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2135"></a>
-<span class="sourceLineNo">2136</span>        daughterB);<a name="line.2136"></a>
-<span class="sourceLineNo">2137</span>    }<a name="line.2137"></a>
-<span class="sourceLineNo">2138</span>  }<a name="line.2138"></a>
-<span class="sourceLineNo">2139</span><a name="line.2139"></a>
-<span class="sourceLineNo">2140</span>  /**<a name="line.2140"></a>
-<span class="sourceLineNo">2141</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2141"></a>
-<span class="sourceLineNo">2142</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2142"></a>
-<span class="sourceLineNo">2143</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2143"></a>
-<span class="sourceLineNo">2144</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2144"></a>
-<span class="sourceLineNo">2145</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2145"></a>
-<span class="sourceLineNo">2146</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2146"></a>
-<span class="sourceLineNo">2147</span>   * the archiver chore runs, are the References removed).<a name="line.2147"></a>
-<span class="sourceLineNo">2148</span>   */<a name="line.2148"></a>
-<span class="sourceLineNo">2149</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2149"></a>
-<span class="sourceLineNo">2150</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2150"></a>
-<span class="sourceLineNo">2151</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2151"></a>
-<span class="sourceLineNo">2152</span>    node.setState(State.MERGED);<a name="line.2152"></a>
-<span class="sourceLineNo">2153</span>    for (RegionInfo ri : mergeParents) {<a name="line.2153"></a>
-<span class="sourceLineNo">2154</span>      regionStates.deleteRegion(ri);<a name="line.2154"></a>
-<span class="sourceLineNo">2155</span>    }<a name="line.2155"></a>
-<span class="sourceLineNo">2156</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2156"></a>
-<span class="sourceLineNo">2157</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2157"></a>
-<span class="sourceLineNo">2158</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2158"></a>
-<span class="sourceLineNo">2159</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2159"></a>
-<span class="sourceLineNo">2160</span>    }<a name="line.2160"></a>
-<span class="sourceLineNo">2161</span>  }<a name="line.2161"></a>
-<span class="sourceLineNo">2162</span><a name="line.2162"></a>
-<span class="sourceLineNo">2163</span>  /*<a name="line.2163"></a>
-<span class="sourceLineNo">2164</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2164"></a>
-<span class="sourceLineNo">2165</span>   * belongs to a non-system table.<a name="line.2165"></a>
-<span class="sourceLineNo">2166</span>   */<a name="line.2166"></a>
-<span class="sourceLineNo">2167</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2167"></a>
-<span class="sourceLineNo">2168</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2168"></a>
-<span class="sourceLineNo">2169</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2169"></a>
-<span class="sourceLineNo">2170</span>  }<a name="line.2170"></a>
-<span class="sourceLineNo">2171</span><a name="line.2171"></a>
+<span class="sourceLineNo">2106</span><a name="line.2106"></a>
+<span class="sourceLineNo">2107</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2107"></a>
+<span class="sourceLineNo">2108</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2108"></a>
+<span class="sourceLineNo">2109</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2109"></a>
+<span class="sourceLineNo">2110</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2110"></a>
+<span class="sourceLineNo">2111</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2111"></a>
+<span class="sourceLineNo">2112</span>    // later figuring what regions are in a table and what are not: see<a name="line.2112"></a>
+<span class="sourceLineNo">2113</span>    // regionStates#getRegionsOfTable<a name="line.2113"></a>
+<span class="sourceLineNo">2114</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2114"></a>
+<span class="sourceLineNo">2115</span>    node.setState(State.SPLIT);<a name="line.2115"></a>
+<span class="sourceLineNo">2116</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2116"></a>
+<span class="sourceLineNo">2117</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2117"></a>
+<span class="sourceLineNo">2118</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2118"></a>
+<span class="sourceLineNo">2119</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
+<span class="sourceLineNo">2120</span><a name="line.2120"></a>
+<span class="sourceLineNo">2121</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2121"></a>
+<span class="sourceLineNo">2122</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2122"></a>
+<span class="sourceLineNo">2123</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2123"></a>
+<span class="sourceLineNo">2124</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2124"></a>
+<span class="sourceLineNo">2125</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2125"></a>
+<span class="sourceLineNo">2126</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2126"></a>
+<span class="sourceLineNo">2127</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2127"></a>
+<span class="sourceLineNo">2128</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2128"></a>
+<span class="sourceLineNo">2129</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2129"></a>
+<span class="sourceLineNo">2130</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2130"></a>
+<span class="sourceLineNo">2131</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2131"></a>
+<span class="sourceLineNo">2132</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2132"></a>
+<span class="sourceLineNo">2133</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2133"></a>
+<span class="sourceLineNo">2134</span>        daughterB);<a name="line.2134"></a>
+<span class="sourceLineNo">2135</span>    }<a name="line.2135"></a>
+<span class="sourceLineNo">2136</span>  }<a name="line.2136"></a>
+<span class="sourceLineNo">2137</span><a name="line.2137"></a>
+<span class="sourceLineNo">2138</span>  /**<a name="line.2138"></a>
+<span class="sourceLineNo">2139</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2139"></a>
+<span class="sourceLineNo">2140</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2140"></a>
+<span class="sourceLineNo">2141</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2141"></a>
+<span class="sourceLineNo">2142</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2142"></a>
+<span class="sourceLineNo">2143</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2143"></a>
+<span class="sourceLineNo">2144</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2144"></a>
+<span class="sourceLineNo">2145</span>   * the archiver chore runs, are the References removed).<a name="line.2145"></a>
+<span class="sourceLineNo">2146</span>   */<a name="line.2146"></a>
+<span class="sourceLineNo">2147</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2147"></a>
+<span class="sourceLineNo">2148</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2148"></a>
+<span class="sourceLineNo">2149</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2149"></a>
+<span class="sourceLineNo">2150</span>    node.setState(State.MERGED);<a name="line.2150"></a>
+<span class="sourceLineNo">2151</span>    for (RegionInfo ri : mergeParents) {<a name="line.2151"></a>
+<span class="sourceLineNo">2152</span>      regionStates.deleteRegion(ri);<a name="line.2152"></a>
+<span class="sourceLineNo">2153</span>    }<a name="line.2153"></a>
+<span class="sourceLineNo">2154</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2154"></a>
+<span class="sourceLineNo">2155</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2155"></a>
+<span class="sourceLineNo">2156</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2156"></a>
+<span class="sourceLineNo">2157</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2157"></a>
+<span class="sourceLineNo">2158</span>    }<a name="line.2158"></a>
+<span class="sourceLineNo">2159</span>  }<a name="line.2159"></a>
+<span class="sourceLineNo">2160</span><a name="line.2160"></a>
+<span class="sourceLineNo">2161</span>  /*<a name="line.2161"></a>
+<span class="sourceLineNo">2162</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2162"></a>
+<span class="sourceLineNo">2163</span>   * belongs to a non-system table.<a name="line.2163"></a>
+<span class="sourceLineNo">2164</span>   */<a name="line.2164"></a>
+<span class="sourceLineNo">2165</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2165"></a>
+<span class="sourceLineNo">2166</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2166"></a>
+<span class="sourceLineNo">2167</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2167"></a>
+<span class="sourceLineNo">2168</span>  }<a name="line.2168"></a>
+<span class="sourceLineNo">2169</span><a name="line.2169"></a>
+<span class="sourceLineNo">2170</span>  // ============================================================================================<a name="line.2170"></a>
+<span class="sourceLineNo">2171</span>  // Assign Queue (Assign/Balance)<a name="line.2171"></a>
 <span class="sourceLineNo">2172</span>  // ============================================================================================<a name="line.2172"></a>
-<span class="sourceLineNo">2173</span>  // Assign Queue (Assign/Balance)<a name="line.2173"></a>
-<span class="sourceLineNo">2174</span>  // ============================================================================================<a name="line.2174"></a>
-<span class="sourceLineNo">2175</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2175"></a>
-<span class="sourceLineNo">2176</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2176"></a>
-<span class="sourceLineNo">2177</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2177"></a>
-<span class="sourceLineNo">2178</span><a name="line.2178"></a>
-<span class="sourceLineNo">2179</span>  /**<a name="line.2179"></a>
-<span class="sourceLineNo">2180</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2180"></a>
-<span class="sourceLineNo">2181</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2181"></a>
-<span class="sourceLineNo">2182</span>   */<a name="line.2182"></a>
-<span class="sourceLineNo">2183</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2183"></a>
-<span class="sourceLineNo">2184</span>    regionNode.getProcedureEvent().suspend();<a name="line.2184"></a>
-<span class="sourceLineNo">2185</span><a name="line.2185"></a>
-<span class="sourceLineNo">2186</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2186"></a>
-<span class="sourceLineNo">2187</span>    assignQueueLock.lock();<a name="line.2187"></a>
-<span class="sourceLineNo">2188</span>    try {<a name="line.2188"></a>
-<span class="sourceLineNo">2189</span>      pendingAssignQueue.add(regionNode);<a name="line.2189"></a>
-<span class="sourceLineNo">2190</span>      if (<a name="line.2190"></a>
-<span class="sourceLineNo">2191</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2191"></a>
-<span class="sourceLineNo">2192</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2192"></a>
-<span class="sourceLineNo">2193</span>      ) {<a name="line.2193"></a>
-<span class="sourceLineNo">2194</span>        assignQueueFullCond.signal();<a name="line.2194"></a>
-<span class="sourceLineNo">2195</span>      }<a name="line.2195"></a>
-<span class="sourceLineNo">2196</span>    } finally {<a name="line.2196"></a>
-<span class="sourceLineNo">2197</span>      assignQueueLock.unlock();<a name="line.2197"></a>
-<span class="sourceLineNo">2198</span>    }<a name="line.2198"></a>
-<span class="sourceLineNo">2199</span>  }<a name="line.2199"></a>
-<span class="sourceLineNo">2200</span><a name="line.2200"></a>
-<span class="sourceLineNo">2201</span>  private void startAssignmentThread() {<a name="line.2201"></a>
-<span class="sourceLineNo">2202</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2202"></a>
-<span class="sourceLineNo">2203</span>      @Override<a name="line.2203"></a>
-<span class="sourceLineNo">2204</span>      public void run() {<a name="line.2204"></a>
-<span class="sourceLineNo">2205</span>        while (isRunning()) {<a name="line.2205"></a>
-<span class="sourceLineNo">2206</span>          processAssignQueue();<a name="line.2206"></a>
-<span class="sourceLineNo">2207</span>        }<a name="line.2207"></a>
-<span class="sourceLineNo">2208</span>        pendingAssignQueue.clear();<a name="line.2208"></a>
-<span class="sourceLineNo">2209</span>      }<a name="line.2209"></a>
-<span class="sourceLineNo">2210</span>    };<a name="line.2210"></a>
-<span class="sourceLineNo">2211</span>    assignThread.setDaemon(true);<a name="line.2211"></a>
-<span class="sourceLineNo">2212</span>    assignThread.start();<a name="line.2212"></a>
-<span class="sourceLineNo">2213</span>  }<a name="line.2213"></a>
-<span class="sourceLineNo">2214</span><a name="line.2214"></a>
-<span class="sourceLineNo">2215</span>  private void stopAssignmentThread() {<a name="line.2215"></a>
-<span class="sourceLineNo">2216</span>    assignQueueSignal();<a name="line.2216"></a>
-<span class="sourceLineNo">2217</span>    try {<a name="line.2217"></a>
-<span class="sourceLineNo">2218</span>      while (assignThread.isAlive()) {<a name="line.2218"></a>
-<span class="sourceLineNo">2219</span>        assignQueueSignal();<a name="line.2219"></a>
-<span class="sourceLineNo">2220</span>        assignThread.join(250);<a name="line.2220"></a>
-<span class="sourceLineNo">2221</span>      }<a name="line.2221"></a>
-<span class="sourceLineNo">2222</span>    } catch (InterruptedException e) {<a name="line.2222"></a>
-<span class="sourceLineNo">2223</span>      LOG.warn("join interrupted", e);<a name="line.2223"></a>
-<span class="sourceLineNo">2224</span>      Thread.currentThread().interrupt();<a name="line.2224"></a>
-<span class="sourceLineNo">2225</span>    }<a name="line.2225"></a>
-<span class="sourceLineNo">2226</span>  }<a name="line.2226"></a>
-<span class="sourceLineNo">2227</span><a name="line.2227"></a>
-<span class="sourceLineNo">2228</span>  private void assignQueueSignal() {<a name="line.2228"></a>
-<span class="sourceLineNo">2229</span>    assignQueueLock.lock();<a name="line.2229"></a>
-<span class="sourceLineNo">2230</span>    try {<a name="line.2230"></a>
-<span class="sourceLineNo">2231</span>      assignQueueFullCond.signal();<a name="line.2231"></a>
-<span class="sourceLineNo">2232</span>    } finally {<a name="line.2232"></a>
-<span class="sourceLineNo">2233</span>      assignQueueLock.unlock();<a name="line.2233"></a>
-<span class="sourceLineNo">2234</span>    }<a name="line.2234"></a>
-<span class="sourceLineNo">2235</span>  }<a name="line.2235"></a>
-<span class="sourceLineNo">2236</span><a name="line.2236"></a>
-<span class="sourceLineNo">2237</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2237"></a>
-<span class="sourceLineNo">2238</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2238"></a>
-<span class="sourceLineNo">2239</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2239"></a>
-<span class="sourceLineNo">2240</span><a name="line.2240"></a>
-<span class="sourceLineNo">2241</span>    assignQueueLock.lock();<a name="line.2241"></a>
-<span class="sourceLineNo">2242</span>    try {<a name="line.2242"></a>
-<span class="sourceLineNo">2243</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2243"></a>
-<span class="sourceLineNo">2244</span>        assignQueueFullCond.await();<a name="line.2244"></a>
-<span class="sourceLineNo">2245</span>      }<a name="line.2245"></a>
-<span class="sourceLineNo">2246</span><a name="line.2246"></a>
-<span class="sourceLineNo">2247</span>      if (!isRunning()) {<a name="line.2247"></a>
-<span class="sourceLineNo">2248</span>        return null;<a name="line.2248"></a>
-<span class="sourceLineNo">2249</span>      }<a name="line.2249"></a>
-<span class="sourceLineNo">2250</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2250"></a>
-<span class="sourceLineNo">2251</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2251"></a>
-<span class="sourceLineNo">2252</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2252"></a>
-<span class="sourceLineNo">2253</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2253"></a>
-<span class="sourceLineNo">2254</span>      }<a name="line.2254"></a>
-<span class="sourceLineNo">2255</span>      pendingAssignQueue.clear();<a name="line.2255"></a>
-<span class="sourceLineNo">2256</span>    } catch (InterruptedException e) {<a name="line.2256"></a>
-<span class="sourceLineNo">2257</span>      LOG.warn("got interrupted ", e);<a name="line.2257"></a>
-<span class="sourceLineNo">2258</span>      Thread.currentThread().interrupt();<a name="line.2258"></a>
-<span class="sourceLineNo">2259</span>    } finally {<a name="line.2259"></a>
-<span class="sourceLineNo">2260</span>      assignQueueLock.unlock();<a name="line.2260"></a>
-<span class="sourceLineNo">2261</span>    }<a name="line.2261"></a>
-<span class="sourceLineNo">2262</span>    return regions;<a name="line.2262"></a>
-<span class="sourceLineNo">2263</span>  }<a name="line.2263"></a>
-<span class="sourceLineNo">2264</span><a name="line.2264"></a>
-<span class="sourceLineNo">2265</span>  private void processAssignQueue() {<a name="line.2265"></a>
-<span class="sourceLineNo">2266</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2266"></a>
-<span class="sourceLineNo">2267</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2267"></a>
-<span class="sourceLineNo">2268</span>      return;<a name="line.2268"></a>
-<span class="sourceLineNo">2269</span>    }<a name="line.2269"></a>
-<span class="sourceLineNo">2270</span><a name="line.2270"></a>
-<span class="sourceLineNo">2271</span>    if (LOG.isTraceEnabled()) {<a name="line.2271"></a>
-<span class="sourceLineNo">2272</span>      LOG.trace("PROCESS ASSIGN QUEUE regionCount=" + regions.size());<a name="line.2272"></a>
-<span class="sourceLineNo">2273</span>    }<a name="line.2273"></a>
-<span class="sourceLineNo">2274</span><a name="line.2274"></a>
-<span class="sourceLineNo">2275</span>    // TODO: Optimize balancer. pass a RegionPlan?<a name="line.2275"></a>
-<span class="sourceLineNo">2276</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap = new HashMap&lt;&gt;();<a name="line.2276"></a>
-<span class="sourceLineNo">2277</span>    final List&lt;RegionInfo&gt; userHRIs = new ArrayList&lt;&gt;(regions.size());<a name="line.2277"></a>
-<span class="sourceLineNo">2278</span>    // Regions for system tables requiring reassignment<a name="line.2278"></a>
-<span class="sourceLineNo">2279</span>    final List&lt;RegionInfo&gt; systemHRIs = new ArrayList&lt;&gt;();<a name="line.2279"></a>
-<span class="sourceLineNo">2280</span>    for (RegionStateNode regionStateNode : regions.values()) {<a name="line.2280"></a>
-<span class="sourceLineNo">2281</span>      boolean sysTable = regionStateNode.isSystemTable();<a name="line.2281"></a>
-<span class="sourceLineNo">2282</span>      final List&lt;RegionInfo&gt; hris = sysTable ? systemHRIs : userHRIs;<a name="line.2282"></a>
-<span class="sourceLineNo">2283</span>      if (regionStateNode.getRegionLocation() != null) {<a name="line.2283"></a>
-<span class="sourceLineNo">2284</span>        retainMap.put(regionStateNode.getRegionInfo(), regionStateNode.getRegionLocation());<a name="line.2284"></a>
-<span class="sourceLineNo">2285</span>      } else {<a name="line.2285"></a>
-<span class="sourceLineNo">2286</span>        hris.add(regionStateNode.getRegionInfo());<a name="line.2286"></a>
-<span class="sourceLineNo">2287</span>      }<a name="line.2287"></a>
-<span class="sourceLineNo">2288</span>    }<a name="line.2288"></a>
+<span class="sourceLineNo">2173</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2173"></a>
+<span class="sourceLineNo">2174</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2174"></a>
+<span class="sourceLineNo">2175</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2175"></a>
+<span class="sourceLineNo">2176</span><a name="line.2176"></a>
+<span class="sourceLineNo">2177</span>  /**<a name="line.2177"></a>
+<span class="sourceLineNo">2178</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2178"></a>
+<span class="sourceLineNo">2179</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2179"></a>
+<span class="sourceLineNo">2180</span>   */<a name="line.2180"></a>
+<span class="sourceLineNo">2181</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2181"></a>
+<span class="sourceLineNo">2182</span>    regionNode.getProcedureEvent().suspend();<a name="line.2182"></a>
+<span class="sourceLineNo">2183</span><a name="line.2183"></a>
+<span class="sourceLineNo">2184</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2184"></a>
+<span class="sourceLineNo">2185</span>    assignQueueLock.lock();<a name="line.2185"></a>
+<span class="sourceLineNo">2186</span>    try {<a name="line.2186"></a>
+<span class="sourceLineNo">2187</span>      pendingAssignQueue.add(regionNode);<a name="line.2187"></a>
+<span class="sourceLineNo">2188</span>      if (<a name="line.2188"></a>
+<span class="sourceLineNo">2189</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2189"></a>
+<span class="sourceLineNo">2190</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2190"></a>
+<span class="sourceLineNo">2191</span>      ) {<a name="line.2191"></a>
+<span class="sourceLineNo">2192</span>        assignQueueFullCond.signal();<a name="line.2192"></a>
+<span class="sourceLineNo">2193</span>      }<a name="line.2193"></a>
+<span class="sourceLineNo">2194</span>    } finally {<a name="line.2194"></a>
+<span class="sourceLineNo">2195</span>      assignQueueLock.unlock();<a name="line.2195"></a>
+<span class="sourceLineNo">2196</span>    }<a name="line.2196"></a>
+<span class="sourceLineNo">2197</span>  }<a name="line.2197"></a>
+<span class="sourceLineNo">2198</span><a name="line.2198"></a>
+<span class="sourceLineNo">2199</span>  private void startAssignmentThread() {<a name="line.2199"></a>
+<span class="sourceLineNo">2200</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2200"></a>
+<span class="sourceLineNo">2201</span>      @Override<a name="line.2201"></a>
+<span class="sourceLineNo">2202</span>      public void run() {<a name="line.2202"></a>
+<span class="sourceLineNo">2203</span>        while (isRunning()) {<a name="line.2203"></a>
+<span class="sourceLineNo">2204</span>          processAssignQueue();<a name="line.2204"></a>
+<span class="sourceLineNo">2205</span>        }<a name="line.2205"></a>
+<span class="sourceLineNo">2206</span>        pendingAssignQueue.clear();<a name="line.2206"></a>
+<span class="sourceLineNo">2207</span>      }<a name="line.2207"></a>
+<span class="sourceLineNo">2208</span>    };<a name="line.2208"></a>
+<span class="sourceLineNo">2209</span>    assignThread.setDaemon(true);<a name="line.2209"></a>
+<span class="sourceLineNo">2210</span>    assignThread.start();<a name="line.2210"></a>
+<span class="sourceLineNo">2211</span>  }<a name="line.2211"></a>
+<span class="sourceLineNo">2212</span><a name="line.2212"></a>
+<span class="sourceLineNo">2213</span>  private void stopAssignmentThread() {<a name="line.2213"></a>
+<span class="sourceLineNo">2214</span>    assignQueueSignal();<a name="line.2214"></a>
+<span class="sourceLineNo">2215</span>    try {<a name="line.2215"></a>
+<span class="sourceLineNo">2216</span>      while (assignThread.isAlive()) {<a name="line.2216"></a>
+<span class="sourceLineNo">2217</span>        assignQueueSignal();<a name="line.2217"></a>
+<span class="sourceLineNo">2218</span>        assignThread.join(250);<a name="line.2218"></a>
+<span class="sourceLineNo">2219</span>      }<a name="line.2219"></a>
+<span class="sourceLineNo">2220</span>    } catch (InterruptedException e) {<a name="line.2220"></a>
+<span class="sourceLineNo">2221</span>      LOG.warn("join interrupted", e);<a name="line.2221"></a>
+<span class="sourceLineNo">2222</span>      Thread.currentThread().interrupt();<a name="line.2222"></a>
+<span class="sourceLineNo">2223</span>    }<a name="line.2223"></a>
+<span class="sourceLineNo">2224</span>  }<a name="line.2224"></a>
+<span class="sourceLineNo">2225</span><a name="line.2225"></a>
+<span class="sourceLineNo">2226</span>  private void assignQueueSignal() {<a name="line.2226"></a>
+<span class="sourceLineNo">2227</span>    assignQueueLock.lock();<a name="line.2227"></a>
+<span class="sourceLineNo">2228</span>    try {<a name="line.2228"></a>
+<span class="sourceLineNo">2229</span>      assignQueueFullCond.signal();<a name="line.2229"></a>
+<span class="sourceLineNo">2230</span>    } finally {<a name="line.2230"></a>
+<span class="sourceLineNo">2231</span>      assignQueueLock.unlock();<a name="line.2231"></a>
+<span class="sourceLineNo">2232</span>    }<a name="line.2232"></a>
+<span class="sourceLineNo">2233</span>  }<a name="line.2233"></a>
+<span class="sourceLineNo">2234</span><a name="line.2234"></a>
+<span class="sourceLineNo">2235</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2235"></a>
+<span class="sourceLineNo">2236</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2236"></a>
+<span class="sourceLineNo">2237</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2237"></a>
+<span class="sourceLineNo">2238</span><a name="line.2238"></a>
+<span class="sourceLineNo">2239</span>    assignQueueLock.lock();<a name="line.2239"></a>
+<span class="sourceLineNo">2240</span>    try {<a name="line.2240"></a>
+<span class="sourceLineNo">2241</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2241"></a>
+<span class="sourceLineNo">2242</span>        assignQueueFullCond.await();<a name="line.2242"></a>
+<span class="sourceLineNo">2243</span>      }<a name="line.2243"></a>
+<span class="sourceLineNo">2244</span><a name="line.2244"></a>
+<span class="sourceLineNo">2245</span>      if (!isRunning()) {<a name="line.2245"></a>
+<span class="sourceLineNo">2246</span>        return null;<a name="line.2246"></a>
+<span class="sourceLineNo">2247</span>      }<a name="line.2247"></a>
+<span class="sourceLineNo">2248</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2248"></a>
+<span class="sourceLineNo">2249</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2249"></a>
+<span class="sourceLineNo">2250</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2250"></a>
+<span class="sourceLineNo">2251</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2251"></a>
+<span class="sourceLineNo">2252</span>      }<a name="line.2252"></a>
+<span class="sourceLineNo">2253</span>      pendingAssignQueue.clear();<a name="line.2253"></a>
+<span class="sourceLineNo">2254</span>    } catch (InterruptedException e) {<a name="line.2254"></a>
+<span class="sourceLineNo">2255</span>      LOG.warn("got interrupted ", e);<a name="line.2255"></a>
+<span class="sourceLineNo">2256</span>      Thread.currentThread().interrupt();<a name="line.2256"></a>
+<span class="sourceLineNo">2257</span>    } finally {<a name="line.2257"></a>
+<span class="sourceLineNo">2258</span>      assignQueueLock.unlock();<a name="line.2258"></a>
+<span class="sourceLineNo">2259</span>    }<a name="line.2259"></a>
+<span class="sourceLineNo">2260</span>    return regions;<a name="line.2260"></a>
+<span class="sourceLineNo">2261</span>  }<a name="line.2261"></a>
+<span class="sourceLineNo">2262</span><a name="line.2262"></a>
+<span class="sourceLineNo">2263</span>  private void processAssignQueue() {<a name="line.2263"></a>
+<span class="sourceLineNo">2264</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2264"></a>
+<span class="sourceLineNo">2265</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2265"></a>
+<span class="sourceLineNo">2266</span>      return;<a name="line.2266"></a>
+<span class="sourceLineNo">2267</span>    }<a name="line.2267"></a>
+<span class="sourceLineNo">2268</span><a name="line.2268"></a>
+<span class="sourceLineNo">2269</span>    if (LOG.isTraceEnabled()) {<a name="line.2269"></a>
+<span class="sourceLineNo">2270</span>      LOG.trace("PROCESS ASSIGN QUEUE regionCount=" + regions.size());<a name="line.2270"></a>
+<span class="sourceLineNo">2271</span>    }<a name="line.2271"></a>
+<span class="sourceLineNo">2272</span><a name="line.2272"></a>
+<span class="sourceLineNo">2273</span>    // TODO: Optimize balancer. pass a RegionPlan?<a name="line.2273"></a>
+<span class="sourceLineNo">2274</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap = new HashMap&lt;&gt;();<a name="line.2274"></a>
+<span class="sourceLineNo">2275</span>    final List&lt;RegionInfo&gt; userHRIs = new ArrayList&lt;&gt;(regions.size());<a name="line.2275"></a>
+<span class="sourceLineNo">2276</span>    // Regions for system tables requiring reassignment<a name="line.2276"></a>
+<span class="sourceLineNo">2277</span>    final List&lt;RegionInfo&gt; systemHRIs = new ArrayList&lt;&gt;();<a name="line.2277"></a>
+<span class="sourceLineNo">2278</span>    for (RegionStateNode regionStateNode : regions.values()) {<a name="line.2278"></a>
+<span class="sourceLineNo">2279</span>      boolean sysTable = regionStateNode.isSystemTable();<a name="line.2279"></a>
+<span class="sourceLineNo">2280</span>      final List&lt;RegionInfo&gt; hris = sysTable ? systemHRIs : userHRIs;<a name="line.2280"></a>
+<span class="sourceLineNo">2281</span>      if (regionStateNode.getRegionLocation() != null) {<a name="line.2281"></a>
+<span class="sourceLineNo">2282</span>        retainMap.put(regionStateNode.getRegionInfo(), regionStateNode.getRegionLocation());<a name="line.2282"></a>
+<span class="sourceLineNo">2283</span>      } else {<a name="line.2283"></a>
+<span class="sourceLineNo">2284</span>        hris.add(regionStateNode.getRegionInfo());<a name="line.2284"></a>
+<span class="sourceLineNo">2285</span>      }<a name="line.2285"></a>
+<span class="sourceLineNo">2286</span>    }<a name="line.2286"></a>
+<span class="sourceLineNo">2287</span><a name="line.2287"></a>
+<span class="sourceLineNo">2288</span>    // TODO: connect with the listener to invalidate the cache<a name="line.2288"></a>
 <span class="sourceLineNo">2289</span><a name="line.2289"></a>
-<span class="sourceLineNo">2290</span>    // TODO: connect with the listener to invalidate the cache<a name="line.2290"></a>
-<span class="sourceLineNo">2291</span><a name="line.2291"></a>
-<span class="sourceLineNo">2292</span>    // TODO use events<a name="line.2292"></a>
-<span class="sourceLineNo">2293</span>    List&lt;ServerName&gt; servers = master.getServerManager().createDestinationServersList();<a name="line.2293"></a>
-<span class="sourceLineNo">2294</span>    for (int i = 0; servers.size() &lt; 1; ++i) {<a name="line.2294"></a>
-<span class="sourceLineNo">2295</span>      // Report every fourth time around this loop; try not to flood log.<a name="line.2295"></a>
-<span class="sourceLineNo">2296</span>      if (i % 4 == 0) {<a name="line.2296"></a>
-<span class="sourceLineNo">2297</span>        LOG.warn("No servers available; cannot place " + regions.size() + " unassigned regions.");<a name="line.2297"></a>
-<span class="sourceLineNo">2298</span>      }<a name="line.2298"></a>
-<span class="sourceLineNo">2299</span><a name="line.2299"></a>
-<span class="sourceLineNo">2300</span>      if (!isRunning()) {<a name="line.2300"></a>
-<span class="sourceLineNo">2301</span>        LOG.debug("Stopped! Dropping assign of " + regions.size() + " queued regions.");<a name="line.2301"></a>
-<span class="sourceLineNo">2302</span>        return;<a name="line.2302"></a>
-<span class="sourceLineNo">2303</span>      }<a name="line.2303"></a>
-<span class="sourceLineNo">2304</span>      Threads.sleep(250);<a name="line.2304"></a>
-<span class="sourceLineNo">2305</span>      servers = master.getServerManager().createDestinationServersList();<a name="line.2305"></a>
-<span class="sourceLineNo">2306</span>    }<a name="line.2306"></a>
-<span class="sourceLineNo">2307</span><a name="line.2307"></a>
-<span class="sourceLineNo">2308</span>    if (!systemHRIs.isEmpty()) {<a name="line.2308"></a>
-<span class="sourceLineNo">2309</span>      // System table regions requiring reassignment are present, get region servers<a name="line.2309"></a>
-<span class="sourceLineNo">2310</span>      // not available for system table regions<a name="line.2310"></a>
-<span class="sourceLineNo">2311</span>      final List&lt;ServerName&gt; excludeServers = getExcludedServersForSystemTable();<a name="line.2311"></a>
-<span class="sourceLineNo">2312</span>      List&lt;ServerName&gt; serversForSysTables =<a name="line.2312"></a>
-<span class="sourceLineNo">2313</span>        servers.stream().filter(s -&gt; !excludeServers.contains(s)).collect(Collectors.toList());<a name="line.2313"></a>
-<span class="sourceLineNo">2314</span>      if (serversForSysTables.isEmpty()) {<a name="line.2314"></a>
-<span class="sourceLineNo">2315</span>        LOG.warn("Filtering old server versions and the excluded produced an empty set; "<a name="line.2315"></a>
-<span class="sourceLineNo">2316</span>          + "instead considering all candidate servers!");<a name="line.2316"></a>
-<span class="sourceLineNo">2317</span>      }<a name="line.2317"></a>
-<span class="sourceLineNo">2318</span>      LOG.debug("Processing assignQueue; systemServersCount=" + serversForSysTables.size()<a name="line.2318"></a>
-<span class="sourceLineNo">2319</span>        + ", allServersCount=" + servers.size());<a name="line.2319"></a>
-<span class="sourceLineNo">2320</span>      processAssignmentPlans(regions, null, systemHRIs,<a name="line.2320"></a>
-<span class="sourceLineNo">2321</span>        serversForSysTables.isEmpty() &amp;&amp; !containsBogusAssignments(regions, systemHRIs)<a name="line.2321"></a>
-<span class="sourceLineNo">2322</span>          ? servers<a name="line.2322"></a>
-<span class="sourceLineNo">2323</span>          : serversForSysTables);<a name="line.2323"></a>
-<span class="sourceLineNo">2324</span>    }<a name="line.2324"></a>
-<span class="sourceLineNo">2325</span><a name="line.2325"></a>
-<span class="sourceLineNo">2326</span>    processAssignmentPlans(regions, retainMap, userHRIs, servers);<a name="line.2326"></a>
-<span class="sourceLineNo">2327</span>  }<a name="line.2327"></a>
-<span class="sourceLineNo">2328</span><a name="line.2328"></a>
-<span class="sourceLineNo">2329</span>  private boolean containsBogusAssignments(Map&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2329"></a>
-<span class="sourceLineNo">2330</span>    List&lt;RegionInfo&gt; hirs) {<a name="line.2330"></a>
-<span class="sourceLineNo">2331</span>    for (RegionInfo ri : hirs) {<a name="line.2331"></a>
-<span class="sourceLineNo">2332</span>      if (<a name="line.2332"></a>
-<span class="sourceLineNo">2333</span>        regions.get(ri).getRegionLocation() != null<a name="line.2333"></a>
-<span class="sourceLineNo">2334</span>          &amp;&amp; regions.get(ri).getRegionLocation().equals(LoadBalancer.BOGUS_SERVER_NAME)<a name="line.2334"></a>
-<span class="sourceLineNo">2335</span>      ) {<a name="line.2335"></a>
-<span class="sourceLineNo">2336</span>        return true;<a name="line.2336"></a>
-<span class="sourceLineNo">2337</span>      }<a name="line.2337"></a>
-<span class="sourceLineNo">2338</span>    }<a name="line.2338"></a>
-<span class="sourceLineNo">2339</span>    return false;<a name="line.2339"></a>
-<span class="sourceLineNo">2340</span>  }<a name="line.2340"></a>
-<span class="sourceLineNo">2341</span><a name="line.2341"></a>
-<span class="sourceLineNo">2342</span>  private void processAssignmentPlans(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2342"></a>
-<span class="sourceLineNo">2343</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap, final List&lt;RegionInfo&gt; hris,<a name="line.2343"></a>
-<span class="sourceLineNo">2344</span>    final List&lt;ServerName&gt; servers) {<a name="line.2344"></a>
-<span class="sourceLineNo">2345</span>    boolean isTraceEnabled = LOG.isTraceEnabled();<a name="line.2345"></a>
-<span class="sourceLineNo">2346</span>    if (isTraceEnabled) {<a name="line.2346"></a>
-<span class="sourceLineNo">2347</span>      LOG.trace("Available servers count=" + servers.size() + ": " + servers);<a name="line.2347"></a>
-<span class="sourceLineNo">2348</span>    }<a name="line.2348"></a>
-<span class="sourceLineNo">2349</span><a name="line.2349"></a>
-<span class="sourceLineNo">2350</span>    final LoadBalancer balancer = getBalancer();<a name="line.2350"></a>
-<span class="sourceLineNo">2351</span>    // ask the balancer where to place regions<a name="line.2351"></a>
-<span class="sourceLineNo">2352</span>    if (retainMap != null &amp;&amp; !retainMap.isEmpty()) {<a name="line.2352"></a>
-<span class="sourceLineNo">2353</span>      if (isTraceEnabled) {<a name="line.2353"></a>
-<span class="sourceLineNo">2354</span>        LOG.trace("retain assign regions=" + retainMap);<a name="line.2354"></a>
-<span class="sourceLineNo">2355</span>      }<a name="line.2355"></a>
-<span class="sourceLineNo">2356</span>      try {<a name="line.2356"></a>
-<span class="sourceLineNo">2357</span>        acceptPlan(regions, balancer.retainAssignment(retainMap, servers));<a name="line.2357"></a>
-<span class="sourceLineNo">2358</span>      } catch (IOException e) {<a name="line.2358"></a>
-<span class="sourceLineNo">2359</span>        LOG.warn("unable to retain assignment", e);<a name="line.2359"></a>
-<span class="sourceLineNo">2360</span>        addToPendingAssignment(regions, retainMap.keySet());<a name="line.2360"></a>
-<span class="sourceLineNo">2361</span>      }<a name="line.2361"></a>
-<span class="sourceLineNo">2362</span>    }<a name="line.2362"></a>
-<span class="sourceLineNo">2363</span><a name="line.2363"></a>
-<span class="sourceLineNo">2364</span>    // TODO: Do we need to split retain and round-robin?<a name="line.2364"></a>
-<span class="sourceLineNo">2365</span>    // the retain seems to fallback to round-robin/random if the region is not in the map.<a name="line.2365"></a>
-<span class="sourceLineNo">2366</span>    if (!hris.isEmpty()) {<a name="line.2366"></a>
-<span class="sourceLineNo">2367</span>      Collections.sort(hris, RegionInfo.COMPARATOR);<a name="line.2367"></a>
-<span class="sourceLineNo">2368</span>      if (isTraceEnabled) {<a name="line.2368"></a>
-<span class="sourceLineNo">2369</span>        LOG.trace("round robin regions=" + hris);<a name="line.2369"></a>
-<span class="sourceLineNo">2370</span>      }<a name="line.2370"></a>
-<span class="sourceLineNo">2371</span>      try {<a name="line.2371"></a>
-<span class="sourceLineNo">2372</span>        acceptPlan(regions, balancer.roundRobinAssignment(hris, servers));<a name="line.2372"></a>
-<span class="sourceLineNo">2373</span>      } catch (IOException e) {<a name="line.2373"></a>
-<span class="sourceLineNo">2374</span>        LOG.warn("unable to round-robin assignment", e);<a name="line.2374"></a>
-<span class="sourceLineNo">2375</span>        addToPendingAssignment(regions, hris);<a name="line.2375"></a>
-<span class="sourceLineNo">2376</span>      }<a name="line.2376"></a>
-<span class="sourceLineNo">2377</span>    }<a name="line.2377"></a>
-<span class="sourceLineNo">2378</span>  }<a name="line.2378"></a>
-<span class="sourceLineNo">2379</span><a name="line.2379"></a>
-<span class="sourceLineNo">2380</span>  private void acceptPlan(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2380"></a>
-<span class="sourceLineNo">2381</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; plan) throws HBaseIOException {<a name="line.2381"></a>
-<span class="sourceLineNo">2382</span>    final ProcedureEvent&lt;?&gt;[] events = new ProcedureEvent[regions.size()];<a name="line.2382"></a>
-<span class="sourceLineNo">2383</span>    final long st = EnvironmentEdgeManager.currentTime();<a name="line.2383"></a>
-<span class="sourceLineNo">2384</span><a name="line.2384"></a>
-<span class="sourceLineNo">2385</span>    if (plan.isEmpty()) {<a name="line.2385"></a>
-<span class="sourceLineNo">2386</span>      throw new HBaseIOException("unable to compute plans for regions=" + regions.size());<a name="line.2386"></a>
-<span class="sourceLineNo">2387</span>    }<a name="line.2387"></a>
-<span class="sourceLineNo">2388</span><a name="line.2388"></a>
-<span class="sourceLineNo">2389</span>    int evcount = 0;<a name="line.2389"></a>
-<span class="sourceLineNo">2390</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : plan.entrySet()) {<a name="line.2390"></a>
-<span class="sourceLineNo">2391</span>      final ServerName server = entry.getKey();<a name="line.2391"></a>
-<span class="sourceLineNo">2392</span>      for (RegionInfo hri : entry.getValue()) {<a name="line.2392"></a>
-<span class="sourceLineNo">2393</span>        final RegionStateNode regionNode = regions.get(hri);<a name="line.2393"></a>
-<span class="sourceLineNo">2394</span>        regionNode.setRegionLocation(server);<a name="line.2394"></a>
-<span class="sourceLineNo">2395</span>        if (server.equals(LoadBalancer.BOGUS_SERVER_NAME) &amp;&amp; regionNode.isSystemTable()) {<a name="line.2395"></a>
-<span class="sourceLineNo">2396</span>          assignQueueLock.lock();<a name="line.2396"></a>
-<span class="sourceLineNo">2397</span>          try {<a name="line.2397"></a>
-<span class="sourceLineNo">2398</span>            pendingAssignQueue.add(regionNode);<a name="line.2398"></a>
-<span class="sourceLineNo">2399</span>          } finally {<a name="line.2399"></a>
-<span class="sourceLineNo">2400</span>            assignQueueLock.unlock();<a name="line.2400"></a>
-<span class="sourceLineNo">2401</span>          }<a name="line.2401"></a>
-<span class="sourceLineNo">2402</span>        } else {<a name="line.2402"></a>
-<span class="sourceLineNo">2403</span>          events[evcount++] = regionNode.getProcedureEvent();<a name="line.2403"></a>
-<span class="sourceLineNo">2404</span>        }<a name="line.2404"></a>
-<span class="sourceLineNo">2405</span>      }<a name="line.2405"></a>
-<span class="sourceLineNo">2406</span>    }<a name="line.2406"></a>
-<span class="sourceLineNo">2407</span>    ProcedureEvent.wakeEvents(getProcedureScheduler(), events);<a name="line.2407"></a>
-<span class="sourceLineNo">2408</span><a name="line.2408"></a>
-<span class="sourceLineNo">2409</span>    final long et = EnvironmentEdgeManager.currentTime();<a name="line.2409"></a>
-<span class="sourceLineNo">2410</span>    if (LOG.isTraceEnabled()) {<a name="line.2410"></a>
-<span class="sourceLineNo">2411</span>      LOG.trace("ASSIGN ACCEPT " + events.length + " -&gt; " + StringUtils.humanTimeDiff(et - st));<a name="line.2411"></a>
-<span class="sourceLineNo">2412</span>    }<a name="line.2412"></a>
-<span class="sourceLineNo">2413</span>  }<a name="line.2413"></a>
-<span class="sourceLineNo">2414</span><a name="line.2414"></a>
-<span class="sourceLineNo">2415</span>  private void addToPendingAssignment(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2415"></a>
-<span class="sourceLineNo">2416</span>    final Collection&lt;RegionInfo&gt; pendingRegions) {<a name="line.2416"></a>
-<span class="sourceLineNo">2417</span>    assignQueueLock.lock();<a name="line.2417"></a>
-<span class="sourceLineNo">2418</span>    try {<a name="line.2418"></a>
-<span class="sourceLineNo">2419</span>      for (RegionInfo hri : pendingRegions) {<a name="line.2419"></a>
-<span class="sourceLineNo">2420</span>        pendingAssignQueue.add(regions.get(hri));<a name="line.2420"></a>
-<span class="sourceLineNo">2421</span>      }<a name="line.2421"></a>
-<span class="sourceLineNo">2422</span>    } finally {<a name="line.2422"></a>
-<span class="sourceLineNo">2423</span>      assignQueueLock.unlock();<a name="line.2423"></a>
-<span class="sourceLineNo">2424</span>    }<a name="line.2424"></a>
-<span class="sourceLineNo">2425</span>  }<a name="line.2425"></a>
-<span class="sourceLineNo">2426</span><a name="line.2426"></a>
-<span class="sourceLineNo">2427</span>  /**<a name="line.2427"></a>
-<span class="sourceLineNo">2428</span>   * For a given cluster with mixed versions of servers, get a list of servers with lower versions,<a name="line.2428"></a>
-<span class="sourceLineNo">2429</span>   * where system table regions should not be assigned to. For system table, we must assign regions<a name="line.2429"></a>
-<span class="sourceLineNo">2430</span>   * to a server with highest version. However, we can disable this exclusion using config:<a name="line.2430"></a>
-<span class="sourceLineNo">2431</span>   * "hbase.min.version.move.system.tables" if checkForMinVersion is true. Detailed explanation<a name="line.2431"></a>
-<span class="sourceLineNo">2432</span>   * available with definition of minVersionToMoveSysTables.<a name="line.2432"></a>
-<span class="sourceLineNo">2433</span>   * @return List of Excluded servers for System table regions.<a name="line.2433"></a>
-<span class="sourceLineNo">2434</span>   */<a name="line.2434"></a>
-<span class="sourceLineNo">2435</span>  public List&lt;ServerName&gt; getExcludedServersForSystemTable() {<a name="line.2435"></a>
-<span class="sourceLineNo">2436</span>    // TODO: This should be a cached list kept by the ServerManager rather than calculated on each<a name="line.2436"></a>
-<span class="sourceLineNo">2437</span>    // move or system region assign. The RegionServerTracker keeps list of online Servers with<a name="line.2437"></a>
-<span class="sourceLineNo">2438</span>    // RegionServerInfo that includes Version.<a name="line.2438"></a>
-<span class="sourceLineNo">2439</span>    List&lt;Pair&lt;ServerName, String&gt;&gt; serverList =<a name="line.2439"></a>
-<span class="sourceLineNo">2440</span>      master.getServerManager().getOnlineServersList().stream()<a name="line.2440"></a>
-<span class="sourceLineNo">2441</span>        .map(s -&gt; new Pair&lt;&gt;(s, master.getRegionServerVersion(s))).collect(Collectors.toList());<a name="line.2441"></a>
-<span class="sourceLineNo">2442</span>    if (serverList.isEmpty()) {<a name="line.2442"></a>
-<span class="sourceLineNo">2443</span>      return new ArrayList&lt;&gt;();<a name="line.2443"></a>
-<span class="sourceLineNo">2444</span>    }<a name="line.2444"></a>
-<span class="sourceLineNo">2445</span>    String highestVersion = Collections<a name="line.2445"></a>
-<span class="sourceLineNo">2446</span>      .max(serverList, (o1, o2) -&gt; VersionInfo.compareVersion(o1.getSecond(), o2.getSecond()))<a name="line.2446"></a>
-<span class="sourceLineNo">2447</span>      .getSecond();<a name="line.2447"></a>
-<span class="sourceLineNo">2448</span>    if (!DEFAULT_MIN_VERSION_MOVE_SYS_TABLES_CONFIG.equals(minVersionToMoveSysTables)) {<a name="line.2448"></a>
-<span class="sourceLineNo">2449</span>      int comparedValue = VersionInfo.compareVersion(minVersionToMoveSysTables, highestVersion);<a name="line.2449"></a>
-<span class="sourceLineNo">2450</span>      if (comparedValue &gt; 0) {<a name="line.2450"></a>
-<span class="sourceLineNo">2451</span>        return new ArrayList&lt;&gt;();<a name="line.2451"></a>
-<span class="sourceLineNo">2452</span>      }<a name="line.2452"></a>
-<span class="sourceLineNo">2453</span>    }<a name="line.2453"></a>
-<span class="sourceLineNo">2454</span>    return serverList.stream().filter(pair -&gt; !pair.getSecond().equals(highestVersion))<a name="line.2454"></a>
-<span class="sourceLineNo">2455</span>      .map(Pair::getFirst).collect(Collectors.toList());<a name="line.2455"></a>
-<span class="sourceLineNo">2456</span>  }<a name="line.2456"></a>
-<span class="sourceLineNo">2457</span><a name="line.2457"></a>
-<span class="sourceLineNo">2458</span>  MasterServices getMaster() {<a name="line.2458"></a>
-<span class="sourceLineNo">2459</span>    return master;<a name="line.2459"></a>
-<span class="sourceLineNo">2460</span>  }<a name="line.2460"></a>
-<span class="sourceLineNo">2461</span><a name="line.2461"></a>
-<span class="sourceLineNo">2462</span>  /** Returns a snapshot of rsReports */<a name="line.2462"></a>
-<span class="sourceLineNo">2463</span>  public Map&lt;ServerName, Set&lt;byte[]&gt;&gt; getRSReports() {<a name="line.2463"></a>
-<span class="sourceLineNo">2464</span>    Map&lt;ServerName, Set&lt;byte[]&gt;&gt; rsReportsSnapshot = new HashMap&lt;&gt;();<a name="line.2464"></a>
-<span class="sourceLineNo">2465</span>    synchronized (rsReports) {<a name="line.2465"></a>
-<span class="sourceLineNo">2466</span>      rsReports.entrySet().forEach(e -&gt; rsReportsSnapshot.put(e.getKey(), e.getValue()));<a name="line.2466"></a>
-<span class="sourceLineNo">2467</span>    }<a name="line.2467"></a>
-<span class="sourceLineNo">2468</span>    return rsReportsSnapshot;<a name="line.2468"></a>
-<span class="sourceLineNo">2469</span>  }<a name="line.2469"></a>
-<span class="sourceLineNo">2470</span><a name="line.2470"></a>
-<span class="sourceLineNo">2471</span>  /**<a name="line.2471"></a>
-<span class="sourceLineNo">2472</span>   * Provide regions state count for given table. e.g howmany regions of give table are<a name="line.2472"></a>
-<span class="sourceLineNo">2473</span>   * opened/closed/rit etc<a name="line.2473"></a>
-<span class="sourceLineNo">2474</span>   * @param tableName TableName<a name="line.2474"></a>
-<span class="sourceLineNo">2475</span>   * @return region states count<a name="line.2475"></a>
-<span class="sourceLineNo">2476</span>   */<a name="line.2476"></a>
-<span class="sourceLineNo">2477</span>  public RegionStatesCount getRegionStatesCount(TableName tableName) {<a name="line.2477"></a>
-<span class="sourceLineNo">2478</span>    int openRegionsCount = 0;<a name="line.2478"></a>
-<span class="sourceLineNo">2479</span>    int closedRegionCount = 0;<a name="line.2479"></a>
-<span class="sourceLineNo">2480</span>    int ritCount = 0;<a name="line.2480"></a>
-<span class="sourceLineNo">2481</span>    int splitRegionCount = 0;<a name="line.2481"></a>
-<span class="sourceLineNo">2482</span>    int totalRegionCount = 0;<a name="line.2482"></a>
-<span class="sourceLineNo">2483</span>    if (!isTableDisabled(tableName)) {<a name="line.2483"></a>
-<span class="sourceLineNo">2484</span>      final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.2484"></a>
-<span class="sourceLineNo">2485</span>      for (RegionState regionState : states) {<a name="line.2485"></a>
-<span class="sourceLineNo">2486</span>        if (regionState.isOpened()) {<a name="line.2486"></a>
-<span class="sourceLineNo">2487</span>          openRegionsCount++;<a name="line.2487"></a>
-<span class="sourceLineNo">2488</span>        } else if (regionState.isClosed()) {<a name="line.2488"></a>
-<span class="sourceLineNo">2489</span>          closedRegionCount++;<a name="line.2489"></a>
-<span class="sourceLineNo">2490</span>        } else if (regionState.isSplit()) {<a name="line.2490"></a>
-<span class="sourceLineNo">2491</span>          splitRegionCount++;<a name="line.2491"></a>
-<span class="sourceLineNo">2492</span>        }<a name="line.2492"></a>
-<span class="sourceLineNo">2493</span>      }<a name="line.2493"></a>
-<span class="sourceLineNo">2494</span>      totalRegionCount = states.size();<a name="line.2494"></a>
-<span class="sourceLineNo">2495</span>      ritCount = totalRegionCount - openRegionsCount - splitRegionCount;<a name="line.2495"></a>
-<span class="sourceLineNo">2496</span>    }<a name="line.2496"></a>
-<span class="sourceLineNo">2497</span>    return new RegionStatesCount.RegionStatesCountBuilder().setOpenRegions(openRegionsCount)<a name="line.2497"></a>
-<span class="sourceLineNo">2498</span>      .setClosedRegions(closedRegionCount).setSplitRegions(splitRegionCount)<a name="line.2498"></a>
-<span class="sourceLineNo">2499</span>      .setRegionsInTransition(ritCount).setTotalRegions(totalRegionCount).build();<a name="line.2499"></a>
-<span class="sourceLineNo">2500</span>  }<a name="line.2500"></a>
-<span class="sourceLineNo">2501</span><a name="line.2501"></a>
-<span class="sourceLineNo">2502</span>}<a name="line.2502"></a>
+<span class="sourceLineNo">2290</span>    // TODO use events<a name="line.2290"></a>
+<span class="sourceLineNo">2291</span>    List&lt;ServerName&gt; servers = master.getServerManager().createDestinationServersList();<a name="line.2291"></a>
+<span class="sourceLineNo">2292</span>    for (int i = 0; servers.size() &lt; 1; ++i) {<a name="line.2292"></a>
+<span class="sourceLineNo">2293</span>      // Report every fourth time around this loop; try not to flood log.<a name="line.2293"></a>
+<span class="sourceLineNo">2294</span>      if (i % 4 == 0) {<a name="line.2294"></a>
+<span class="sourceLineNo">2295</span>        LOG.warn("No servers available; cannot place " + regions.size() + " unassigned regions.");<a name="line.2295"></a>
+<span class="sourceLineNo">2296</span>      }<a name="line.2296"></a>
+<span class="sourceLineNo">2297</span><a name="line.2297"></a>
+<span class="sourceLineNo">2298</span>      if (!isRunning()) {<a name="line.2298"></a>
+<span class="sourceLineNo">2299</span>        LOG.debug("Stopped! Dropping assign of " + regions.size() + " queued regions.");<a name="line.2299"></a>
+<span class="sourceLineNo">2300</span>        return;<a name="line.2300"></a>
+<span class="sourceLineNo">2301</span>      }<a name="line.2301"></a>
+<span class="sourceLineNo">2302</span>      Threads.sleep(250);<a name="line.2302"></a>
+<span class="sourceLineNo">2303</span>      servers = master.getServerManager().createDestinationServersList();<a name="line.2303"></a>
+<span class="sourceLineNo">2304</span>    }<a name="line.2304"></a>
+<span class="sourceLineNo">2305</span><a name="line.2305"></a>
+<span class="sourceLineNo">2306</span>    if (!systemHRIs.isEmpty()) {<a name="line.2306"></a>
+<span class="sourceLineNo">2307</span>      // System table regions requiring reassignment are present, get region servers<a name="line.2307"></a>
+<span class="sourceLineNo">2308</span>      // not available for system table regions<a name="line.2308"></a>
+<span class="sourceLineNo">2309</span>      final List&lt;ServerName&gt; excludeServers = getExcludedServersForSystemTable();<a name="line.2309"></a>
+<span class="sourceLineNo">2310</span>      List&lt;ServerName&gt; serversForSysTables =<a name="line.2310"></a>
+<span class="sourceLineNo">2311</span>        servers.stream().filter(s -&gt; !excludeServers.contains(s)).collect(Collectors.toList());<a name="line.2311"></a>
+<span class="sourceLineNo">2312</span>      if (serversForSysTables.isEmpty()) {<a name="line.2312"></a>
+<span class="sourceLineNo">2313</span>        LOG.warn("Filtering old server versions and the excluded produced an empty set; "<a name="line.2313"></a>
+<span class="sourceLineNo">2314</span>          + "instead considering all candidate servers!");<a name="line.2314"></a>
+<span class="sourceLineNo">2315</span>      }<a name="line.2315"></a>
+<span class="sourceLineNo">2316</span>      LOG.debug("Processing assignQueue; systemServersCount=" + serversForSysTables.size()<a name="line.2316"></a>
+<span class="sourceLineNo">2317</span>        + ", allServersCount=" + servers.size());<a name="line.2317"></a>
+<span class="sourceLineNo">2318</span>      processAssignmentPlans(regions, null, systemHRIs,<a name="line.2318"></a>
+<span class="sourceLineNo">2319</span>        serversForSysTables.isEmpty() &amp;&amp; !containsBogusAssignments(regions, systemHRIs)<a name="line.2319"></a>
+<span class="sourceLineNo">2320</span>          ? servers<a name="line.2320"></a>
+<span class="sourceLineNo">2321</span>          : serversForSysTables);<a name="line.2321"></a>
+<span class="sourceLineNo">2322</span>    }<a name="line.2322"></a>
+<span class="sourceLineNo">2323</span><a name="line.2323"></a>
+<span class="sourceLineNo">2324</span>    processAssignmentPlans(regions, retainMap, userHRIs, servers);<a name="line.2324"></a>
+<span class="sourceLineNo">2325</span>  }<a name="line.2325"></a>
+<span class="sourceLineNo">2326</span><a name="line.2326"></a>
+<span class="sourceLineNo">2327</span>  private boolean containsBogusAssignments(Map&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2327"></a>
+<span class="sourceLineNo">2328</span>    List&lt;RegionInfo&gt; hirs) {<a name="line.2328"></a>
+<span class="sourceLineNo">2329</span>    for (RegionInfo ri : hirs) {<a name="line.2329"></a>
+<span class="sourceLineNo">2330</span>      if (<a name="line.2330"></a>
+<span class="sourceLineNo">2331</span>        regions.get(ri).getRegionLocation() != null<a name="line.2331"></a>
+<span class="sourceLineNo">2332</span>          &amp;&amp; regions.get(ri).getRegionLocation().equals(LoadBalancer.BOGUS_SERVER_NAME)<a name="line.2332"></a>
+<span class="sourceLineNo">2333</span>      ) {<a name="line.2333"></a>
+<span class="sourceLineNo">2334</span>        return true;<a name="line.2334"></a>
+<span class="sourceLineNo">2335</span>      }<a name="line.2335"></a>
+<span class="sourceLineNo">2336</span>    }<a name="line.2336"></a>
+<span class="sourceLineNo">2337</span>    return false;<a name="line.2337"></a>
+<span class="sourceLineNo">2338</span>  }<a name="line.2338"></a>
+<span class="sourceLineNo">2339</span><a name="line.2339"></a>
+<span class="sourceLineNo">2340</span>  private void processAssignmentPlans(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2340"></a>
+<span class="sourceLineNo">2341</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap, final List&lt;RegionInfo&gt; hris,<a name="line.2341"></a>
+<span class="sourceLineNo">2342</span>    final List&lt;ServerName&gt; servers) {<a name="line.2342"></a>
+<span class="sourceLineNo">2343</span>    boolean isTraceEnabled = LOG.isTraceEnabled();<a name="line.2343"></a>
+<span class="sourceLineNo">2344</span>    if (isTraceEnabled) {<a name="line.2344"></a>
+<span class="sourceLineNo">2345</span>      LOG.trace("Available servers count=" + servers.size() + ": " + servers);<a name="line.2345"></a>
+<span class="sourceLineNo">2346</span>    }<a name="line.2346"></a>
+<span class="sourceLineNo">2347</span><a name="line.2347"></a>
+<span class="sourceLineNo">2348</span>    final LoadBalancer balancer = getBalancer();<a name="line.2348"></a>
+<span class="sourceLineNo">2349</span>    // ask the balancer where to place regions<a name="line.2349"></a>
+<span class="sourceLineNo">2350</span>    if (retainMap != null &amp;&amp; !retainMap.isEmpty()) {<a name="line.2350"></a>
+<span class="sourceLineNo">2351</span>      if (isTraceEnabled) {<a name="line.2351"></a>
+<span class="sourceLineNo">2352</span>        LOG.trace("retain assign regions=" + retainMap);<a name="line.2352"></a>
+<span class="sourceLineNo">2353</span>      }<a name="line.2353"></a>
+<span class="sourceLineNo">2354</span>      try {<a name="line.2354"></a>
+<span class="sourceLineNo">2355</span>        acceptPlan(regions, balancer.retainAssignment(retainMap, servers));<a name="line.2355"></a>
+<span class="sourceLineNo">2356</span>      } catch (IOException e) {<a name="line.2356"></a>
+<span class="sourceLineNo">2357</span>        LOG.warn("unable to retain assignment", e);<a name="line.2357"></a>
+<span class="sourceLineNo">2358</span>        addToPendingAssignment(regions, retainMap.keySet());<a name="line.2358"></a>
+<span class="sourceLineNo">2359</span>      }<a name="line.2359"></a>
+<span class="sourceLineNo">2360</span>    }<a name="line.2360"></a>
+<span class="sourceLineNo">2361</span><a name="line.2361"></a>
+<span class="sourceLineNo">2362</span>    // TODO: Do we need to split retain and round-robin?<a name="line.2362"></a>
+<span class="sourceLineNo">2363</span>    // the retain seems to fallback to round-robin/random if the region is not in the map.<a name="line.2363"></a>
+<span class="sourceLineNo">2364</span>    if (!hris.isEmpty()) {<a name="line.2364"></a>
+<span class="sourceLineNo">2365</span>      Collections.sort(hris, RegionInfo.COMPARATOR);<a name="line.2365"></a>
+<span class="sourceLineNo">2366</span>      if (isTraceEnabled) {<a name="line.2366"></a>
+<span class="sourceLineNo">2367</span>        LOG.trace("round robin regions=" + hris);<a name="line.2367"></a>
+<span class="sourceLineNo">2368</span>      }<a name="line.2368"></a>
+<span class="sourceLineNo">2369</span>      try {<a name="line.2369"></a>
+<span class="sourceLineNo">2370</span>        acceptPlan(regions, balancer.roundRobinAssignment(hris, servers));<a name="line.2370"></a>
+<span class="sourceLineNo">2371</span>      } catch (IOException e) {<a name="line.2371"></a>
+<span class="sourceLineNo">2372</span>        LOG.warn("unable to round-robin assignment", e);<a name="line.2372"></a>
+<span class="sourceLineNo">2373</span>        addToPendingAssignment(regions, hris);<a name="line.2373"></a>
+<span class="sourceLineNo">2374</span>      }<a name="line.2374"></a>
+<span class="sourceLineNo">2375</span>    }<a name="line.2375"></a>
+<span class="sourceLineNo">2376</span>  }<a name="line.2376"></a>
+<span class="sourceLineNo">2377</span><a name="line.2377"></a>
+<span class="sourceLineNo">2378</span>  private void acceptPlan(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2378"></a>
+<span class="sourceLineNo">2379</span>    final Map&lt;ServerName, List&lt;RegionInfo&gt;&gt; plan) throws HBaseIOException {<a name="line.2379"></a>
+<span class="sourceLineNo">2380</span>    final ProcedureEvent&lt;?&gt;[] events = new ProcedureEvent[regions.size()];<a name="line.2380"></a>
+<span class="sourceLineNo">2381</span>    final long st = EnvironmentEdgeManager.currentTime();<a name="line.2381"></a>
+<span class="sourceLineNo">2382</span><a name="line.2382"></a>
+<span class="sourceLineNo">2383</span>    if (plan.isEmpty()) {<a name="line.2383"></a>
+<span class="sourceLineNo">2384</span>      throw new HBaseIOException("unable to compute plans for regions=" + regions.size());<a name="line.2384"></a>
+<span class="sourceLineNo">2385</span>    }<a name="line.2385"></a>
+<span class="sourceLineNo">2386</span><a name="line.2386"></a>
+<span class="sourceLineNo">2387</span>    int evcount = 0;<a name="line.2387"></a>
+<span class="sourceLineNo">2388</span>    for (Map.Entry&lt;ServerName, List&lt;RegionInfo&gt;&gt; entry : plan.entrySet()) {<a name="line.2388"></a>
+<span class="sourceLineNo">2389</span>      final ServerName server = entry.getKey();<a name="line.2389"></a>
+<span class="sourceLineNo">2390</span>      for (RegionInfo hri : entry.getValue()) {<a name="line.2390"></a>
+<span class="sourceLineNo">2391</span>        final RegionStateNode regionNode = regions.get(hri);<a name="line.2391"></a>
+<span class="sourceLineNo">2392</span>        regionNode.setRegionLocation(server);<a name="line.2392"></a>
+<span class="sourceLineNo">2393</span>        if (server.equals(LoadBalancer.BOGUS_SERVER_NAME) &amp;&amp; regionNode.isSystemTable()) {<a name="line.2393"></a>
+<span class="sourceLineNo">2394</span>          assignQueueLock.lock();<a name="line.2394"></a>
+<span class="sourceLineNo">2395</span>          try {<a name="line.2395"></a>
+<span class="sourceLineNo">2396</span>            pendingAssignQueue.add(regionNode);<a name="line.2396"></a>
+<span class="sourceLineNo">2397</span>          } finally {<a name="line.2397"></a>
+<span class="sourceLineNo">2398</span>            assignQueueLock.unlock();<a name="line.2398"></a>
+<span class="sourceLineNo">2399</span>          }<a name="line.2399"></a>
+<span class="sourceLineNo">2400</span>        } else {<a name="line.2400"></a>
+<span class="sourceLineNo">2401</span>          events[evcount++] = regionNode.getProcedureEvent();<a name="line.2401"></a>
+<span class="sourceLineNo">2402</span>        }<a name="line.2402"></a>
+<span class="sourceLineNo">2403</span>      }<a name="line.2403"></a>
+<span class="sourceLineNo">2404</span>    }<a name="line.2404"></a>
+<span class="sourceLineNo">2405</span>    ProcedureEvent.wakeEvents(getProcedureScheduler(), events);<a name="line.2405"></a>
+<span class="sourceLineNo">2406</span><a name="line.2406"></a>
+<span class="sourceLineNo">2407</span>    final long et = EnvironmentEdgeManager.currentTime();<a name="line.2407"></a>
+<span class="sourceLineNo">2408</span>    if (LOG.isTraceEnabled()) {<a name="line.2408"></a>
+<span class="sourceLineNo">2409</span>      LOG.trace("ASSIGN ACCEPT " + events.length + " -&gt; " + StringUtils.humanTimeDiff(et - st));<a name="line.2409"></a>
+<span class="sourceLineNo">2410</span>    }<a name="line.2410"></a>
+<span class="sourceLineNo">2411</span>  }<a name="line.2411"></a>
+<span class="sourceLineNo">2412</span><a name="line.2412"></a>
+<span class="sourceLineNo">2413</span>  private void addToPendingAssignment(final HashMap&lt;RegionInfo, RegionStateNode&gt; regions,<a name="line.2413"></a>
+<span class="sourceLineNo">2414</span>    final Collection&lt;RegionInfo&gt; pendingRegions) {<a name="line.2414"></a>
+<span class="sourceLineNo">2415</span>    assignQueueLock.lock();<a name="line.2415"></a>
+<span class="sourceLineNo">2416</span>    try {<a name="line.2416"></a>
+<span class="sourceLineNo">2417</span>      for (RegionInfo hri : pendingRegions) {<a name="line.2417"></a>
+<span class="sourceLineNo">2418</span>        pendingAssignQueue.add(regions.get(hri));<a name="line.2418"></a>
+<span class="sourceLineNo">2419</span>      }<a name="line.2419"></a>
+<span class="sourceLineNo">2420</span>    } finally {<a name="line.2420"></a>
+<span class="sourceLineNo">2421</span>      assignQueueLock.unlock();<a name="line.2421"></a>
+<span class="sourceLineNo">2422</span>    }<a name="line.2422"></a>
+<span class="sourceLineNo">2423</span>  }<a name="line.2423"></a>
+<span class="sourceLineNo">2424</span><a name="line.2424"></a>
+<span class="sourceLineNo">2425</span>  /**<a name="line.2425"></a>
+<span class="sourceLineNo">2426</span>   * For a given cluster with mixed versions of servers, get a list of servers with lower versions,<a name="line.2426"></a>
+<span class="sourceLineNo">2427</span>   * where system table regions should not be assigned to. For system table, we must assign regions<a name="line.2427"></a>
+<span class="sourceLineNo">2428</span>   * to a server with highest version. However, we can disable this exclusion using config:<a name="line.2428"></a>
+<span class="sourceLineNo">2429</span>   * "hbase.min.version.move.system.tables" if checkForMinVersion is true. Detailed explanation<a name="line.2429"></a>
+<span class="sourceLineNo">2430</span>   * available with definition of minVersionToMoveSysTables.<a name="line.2430"></a>
+<span class="sourceLineNo">2431</span>   * @return List of Excluded servers for System table regions.<a name="line.2431"></a>
+<span class="sourceLineNo">2432</span>   */<a name="line.2432"></a>
+<span class="sourceLineNo">2433</span>  public List&lt;ServerName&gt; getExcludedServersForSystemTable() {<a name="line.2433"></a>
+<span class="sourceLineNo">2434</span>    // TODO: This should be a cached list kept by the ServerManager rather than calculated on each<a name="line.2434"></a>
+<span class="sourceLineNo">2435</span>    // move or system region assign. The RegionServerTracker keeps list of online Servers with<a name="line.2435"></a>
+<span class="sourceLineNo">2436</span>    // RegionServerInfo that includes Version.<a name="line.2436"></a>
+<span class="sourceLineNo">2437</span>    List&lt;Pair&lt;ServerName, String&gt;&gt; serverList =<a name="line.2437"></a>
+<span class="sourceLineNo">2438</span>      master.getServerManager().getOnlineServersList().stream()<a name="line.2438"></a>
+<span class="sourceLineNo">2439</span>        .map(s -&gt; new Pair&lt;&gt;(s, master.getRegionServerVersion(s))).collect(Collectors.toList());<a name="line.2439"></a>
+<span class="sourceLineNo">2440</span>    if (serverList.isEmpty()) {<a name="line.2440"></a>
+<span class="sourceLineNo">2441</span>      return new ArrayList&lt;&gt;();<a name="line.2441"></a>
+<span class="sourceLineNo">2442</span>    }<a name="line.2442"></a>
+<span class="sourceLineNo">2443</span>    String highestVersion = Collections<a name="line.2443"></a>
+<span class="sourceLineNo">2444</span>      .max(serverList, (o1, o2) -&gt; VersionInfo.compareVersion(o1.getSecond(), o2.getSecond()))<a name="line.2444"></a>
+<span class="sourceLineNo">2445</span>      .getSecond();<a name="line.2445"></a>
+<span class="sourceLineNo">2446</span>    if (!DEFAULT_MIN_VERSION_MOVE_SYS_TABLES_CONFIG.equals(minVersionToMoveSysTables)) {<a name="line.2446"></a>
+<span class="sourceLineNo">2447</span>      int comparedValue = VersionInfo.compareVersion(minVersionToMoveSysTables, highestVersion);<a name="line.2447"></a>
+<span class="sourceLineNo">2448</span>      if (comparedValue &gt; 0) {<a name="line.2448"></a>
+<span class="sourceLineNo">2449</span>        return new ArrayList&lt;&gt;();<a name="line.2449"></a>
+<span class="sourceLineNo">2450</span>      }<a name="line.2450"></a>
+<span class="sourceLineNo">2451</span>    }<a name="line.2451"></a>
+<span class="sourceLineNo">2452</span>    return serverList.stream().filter(pair -&gt; !pair.getSecond().equals(highestVersion))<a name="line.2452"></a>
+<span class="sourceLineNo">2453</span>      .map(Pair::getFirst).collect(Collectors.toList());<a name="line.2453"></a>
+<span class="sourceLineNo">2454</span>  }<a name="line.2454"></a>
+<span class="sourceLineNo">2455</span><a name="line.2455"></a>
+<span class="sourceLineNo">2456</span>  MasterServices getMaster() {<a name="line.2456"></a>
+<span class="sourceLineNo">2457</span>    return master;<a name="line.2457"></a>
+<span class="sourceLineNo">2458</span>  }<a name="line.2458"></a>
+<span class="sourceLineNo">2459</span><a name="line.2459"></a>
+<span class="sourceLineNo">2460</span>  /** Returns a snapshot of rsReports */<a name="line.2460"></a>
+<span class="sourceLineNo">2461</span>  public Map&lt;ServerName, Set&lt;byte[]&gt;&gt; getRSReports() {<a name="line.2461"></a>
+<span class="sourceLineNo">2462</span>    Map&lt;ServerName, Set&lt;byte[]&gt;&gt; rsReportsSnapshot = new HashMap&lt;&gt;();<a name="line.2462"></a>
+<span class="sourceLineNo">2463</span>    synchronized (rsReports) {<a name="line.2463"></a>
+<span class="sourceLineNo">2464</span>      rsReports.entrySet().forEach(e -&gt; rsReportsSnapshot.put(e.getKey(), e.getValue()));<a name="line.2464"></a>
+<span class="sourceLineNo">2465</span>    }<a name="line.2465"></a>
+<span class="sourceLineNo">2466</span>    return rsReportsSnapshot;<a name="line.2466"></a>
+<span class="sourceLineNo">2467</span>  }<a name="line.2467"></a>
+<span class="sourceLineNo">2468</span><a name="line.2468"></a>
+<span class="sourceLineNo">2469</span>  /**<a name="line.2469"></a>
+<span class="sourceLineNo">2470</span>   * Provide regions state count for given table. e.g howmany regions of give table are<a name="line.2470"></a>
+<span class="sourceLineNo">2471</span>   * opened/closed/rit etc<a name="line.2471"></a>
+<span class="sourceLineNo">2472</span>   * @param tableName TableName<a name="line.2472"></a>
+<span class="sourceLineNo">2473</span>   * @return region states count<a name="line.2473"></a>
+<span class="sourceLineNo">2474</span>   */<a name="line.2474"></a>
+<span class="sourceLineNo">2475</span>  public RegionStatesCount getRegionStatesCount(TableName tableName) {<a name="line.2475"></a>
+<span class="sourceLineNo">2476</span>    int openRegionsCount = 0;<a name="line.2476"></a>
+<span class="sourceLineNo">2477</span>    int closedRegionCount = 0;<a name="line.2477"></a>
+<span class="sourceLineNo">2478</span>    int ritCount = 0;<a name="line.2478"></a>
+<span class="sourceLineNo">2479</span>    int splitRegionCount = 0;<a name="line.2479"></a>
+<span class="sourceLineNo">2480</span>    int totalRegionCount = 0;<a name="line.2480"></a>
+<span class="sourceLineNo">2481</span>    if (!isTableDisabled(tableName)) {<a name="line.2481"></a>
+<span class="sourceLineNo">2482</span>      final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.2482"></a>
+<span class="sourceLineNo">2483</span>      for (RegionState regionState : states) {<a name="line.2483"></a>
+<span class="sourceLineNo">2484</span>        if (regionState.isOpened()) {<a name="line.2484"></a>
+<span class="sourceLineNo">2485</span>          openRegionsCount++;<a name="line.2485"></a>
+<span class="sourceLineNo">2486</span>        } else if (regionState.isClosed()) {<a name="line.2486"></a>
+<span class="sourceLineNo">2487</span>          closedRegionCount++;<a name="line.2487"></a>
+<span class="sourceLineNo">2488</span>        } else if (regionState.isSplit()) {<a name="line.2488"></a>
+<span class="sourceLineNo">2489</span>          splitRegionCount++;<a name="line.2489"></a>
+<span class="sourceLineNo">2490</span>        }<a name="line.2490"></a>
+<span class="sourceLineNo">2491</span>      }<a name="line.2491"></a>
+<span class="sourceLineNo">2492</span>      totalRegionCount = states.size();<a name="line.2492"></a>
+<span class="sourceLineNo">2493</span>      ritCount = totalRegionCount - openRegionsCount - splitRegionCount;<a name="line.2493"></a>
+<span class="sourceLineNo">2494</span>    }<a name="line.2494"></a>
+<span class="sourceLineNo">2495</span>    return new RegionStatesCount.RegionStatesCountBuilder().setOpenRegions(openRegionsCount)<a name="line.2495"></a>
+<span class="sourceLineNo">2496</span>      .setClosedRegions(closedRegionCount).setSplitRegions(splitRegionCount)<a name="line.2496"></a>
+<span class="sourceLineNo">2497</span>      .setRegionsInTransition(ritCount).setTotalRegions(totalRegionCount).build();<a name="line.2497"></a>
+<span class="sourceLineNo">2498</span>  }<a name="line.2498"></a>
+<span class="sourceLineNo">2499</span><a name="line.2499"></a>
+<span class="sourceLineNo">2500</span>}<a name="line.2500"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
index ea172726b4e..09f2091a100 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/AssignmentManager.RegionInTransitionStat.html
@@ -1102,1412 +1102,1410 @@
 <span class="sourceLineNo">1094</span>    regionStateStore.deleteRegions(regions);<a name="line.1094"></a>
 <span class="sourceLineNo">1095</span>    for (int i = 0; i &lt; regions.size(); ++i) {<a name="line.1095"></a>
 <span class="sourceLineNo">1096</span>      final RegionInfo regionInfo = regions.get(i);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>      // we expect the region to be offline<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>      regionStates.removeFromOfflineRegions(regionInfo);<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>      regionStates.deleteRegion(regionInfo);<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>    }<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>  }<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span><a name="line.1102"></a>
+<span class="sourceLineNo">1097</span>      regionStates.deleteRegion(regionInfo);<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span>    }<a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>  }<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span><a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>  // ============================================================================================<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>  // RS Region Transition Report helpers<a name="line.1102"></a>
 <span class="sourceLineNo">1103</span>  // ============================================================================================<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>  // RS Region Transition Report helpers<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>  // ============================================================================================<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>      switch (transition.getTransitionCode()) {<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>        case OPENED:<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>        case FAILED_OPEN:<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>        case CLOSED:<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>          long procId =<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>          break;<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>        case READY_TO_SPLIT:<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>        case SPLIT:<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>        case SPLIT_REVERTED:<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1127"></a>
-<span class="sourceLineNo">1128</span>            splitB);<a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>          break;<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>        case READY_TO_MERGE:<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>        case MERGED:<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>        case MERGE_REVERTED:<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>            mergeB);<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>          break;<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>      }<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span>    }<a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>  }<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span><a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>    // lock protection to wait for meta online...<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>    serverNode.readLock().lock();<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span>    try {<a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1158"></a>
-<span class="sourceLineNo">1159</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>        try {<a name="line.1161"></a>
-<span class="sourceLineNo">1162</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1162"></a>
-<span class="sourceLineNo">1163</span>        } catch (PleaseHoldException e) {<a name="line.1163"></a>
-<span class="sourceLineNo">1164</span>          LOG.trace("Failed transition ", e);<a name="line.1164"></a>
-<span class="sourceLineNo">1165</span>          throw e;<a name="line.1165"></a>
-<span class="sourceLineNo">1166</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1166"></a>
-<span class="sourceLineNo">1167</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1167"></a>
-<span class="sourceLineNo">1168</span>          // if the master says that one of the region transitions failed.<a name="line.1168"></a>
-<span class="sourceLineNo">1169</span>          LOG.warn("Failed transition", e);<a name="line.1169"></a>
-<span class="sourceLineNo">1170</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1170"></a>
-<span class="sourceLineNo">1171</span>        }<a name="line.1171"></a>
-<span class="sourceLineNo">1172</span>      } else {<a name="line.1172"></a>
-<span class="sourceLineNo">1173</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1173"></a>
-<span class="sourceLineNo">1174</span>          serverName);<a name="line.1174"></a>
-<span class="sourceLineNo">1175</span>        builder.setErrorMessage("You are dead");<a name="line.1175"></a>
-<span class="sourceLineNo">1176</span>      }<a name="line.1176"></a>
-<span class="sourceLineNo">1177</span>    } finally {<a name="line.1177"></a>
-<span class="sourceLineNo">1178</span>      serverNode.readLock().unlock();<a name="line.1178"></a>
-<span class="sourceLineNo">1179</span>    }<a name="line.1179"></a>
-<span class="sourceLineNo">1180</span><a name="line.1180"></a>
-<span class="sourceLineNo">1181</span>    return builder.build();<a name="line.1181"></a>
-<span class="sourceLineNo">1182</span>  }<a name="line.1182"></a>
-<span class="sourceLineNo">1183</span><a name="line.1183"></a>
-<span class="sourceLineNo">1184</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1184"></a>
-<span class="sourceLineNo">1185</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1185"></a>
-<span class="sourceLineNo">1186</span>    checkMetaLoaded(regionInfo);<a name="line.1186"></a>
-<span class="sourceLineNo">1187</span><a name="line.1187"></a>
-<span class="sourceLineNo">1188</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1188"></a>
-<span class="sourceLineNo">1189</span>    if (regionNode == null) {<a name="line.1189"></a>
-<span class="sourceLineNo">1190</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1190"></a>
-<span class="sourceLineNo">1191</span>      throw new UnexpectedStateException(String.format(<a name="line.1191"></a>
-<span class="sourceLineNo">1192</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1192"></a>
-<span class="sourceLineNo">1193</span>        regionInfo, state));<a name="line.1193"></a>
-<span class="sourceLineNo">1194</span>    }<a name="line.1194"></a>
-<span class="sourceLineNo">1195</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1195"></a>
-<span class="sourceLineNo">1196</span>      regionNode, state);<a name="line.1196"></a>
-<span class="sourceLineNo">1197</span><a name="line.1197"></a>
-<span class="sourceLineNo">1198</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1198"></a>
-<span class="sourceLineNo">1199</span>    regionNode.lock();<a name="line.1199"></a>
-<span class="sourceLineNo">1200</span>    try {<a name="line.1200"></a>
-<span class="sourceLineNo">1201</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1201"></a>
-<span class="sourceLineNo">1202</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1202"></a>
-<span class="sourceLineNo">1203</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1203"></a>
-<span class="sourceLineNo">1204</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1204"></a>
-<span class="sourceLineNo">1205</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1205"></a>
-<span class="sourceLineNo">1206</span>        // to CLOSED<a name="line.1206"></a>
-<span class="sourceLineNo">1207</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1207"></a>
-<span class="sourceLineNo">1208</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1208"></a>
-<span class="sourceLineNo">1209</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1209"></a>
-<span class="sourceLineNo">1210</span>        if (<a name="line.1210"></a>
-<span class="sourceLineNo">1211</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1211"></a>
-<span class="sourceLineNo">1212</span>        ) {<a name="line.1212"></a>
-<span class="sourceLineNo">1213</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1213"></a>
-<span class="sourceLineNo">1214</span>        } else {<a name="line.1214"></a>
-<span class="sourceLineNo">1215</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1215"></a>
-<span class="sourceLineNo">1216</span>            regionNode, state);<a name="line.1216"></a>
-<span class="sourceLineNo">1217</span>        }<a name="line.1217"></a>
-<span class="sourceLineNo">1218</span>      }<a name="line.1218"></a>
-<span class="sourceLineNo">1219</span>    } finally {<a name="line.1219"></a>
-<span class="sourceLineNo">1220</span>      regionNode.unlock();<a name="line.1220"></a>
-<span class="sourceLineNo">1221</span>    }<a name="line.1221"></a>
-<span class="sourceLineNo">1222</span>  }<a name="line.1222"></a>
-<span class="sourceLineNo">1223</span><a name="line.1223"></a>
-<span class="sourceLineNo">1224</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1224"></a>
-<span class="sourceLineNo">1225</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1225"></a>
-<span class="sourceLineNo">1226</span>    ServerName serverName = serverNode.getServerName();<a name="line.1226"></a>
-<span class="sourceLineNo">1227</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1227"></a>
-<span class="sourceLineNo">1228</span>    if (proc == null) {<a name="line.1228"></a>
-<span class="sourceLineNo">1229</span>      return false;<a name="line.1229"></a>
-<span class="sourceLineNo">1230</span>    }<a name="line.1230"></a>
-<span class="sourceLineNo">1231</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1231"></a>
-<span class="sourceLineNo">1232</span>      serverName, state, seqId, procId);<a name="line.1232"></a>
-<span class="sourceLineNo">1233</span>    return true;<a name="line.1233"></a>
-<span class="sourceLineNo">1234</span>  }<a name="line.1234"></a>
-<span class="sourceLineNo">1235</span><a name="line.1235"></a>
-<span class="sourceLineNo">1236</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1236"></a>
-<span class="sourceLineNo">1237</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1237"></a>
-<span class="sourceLineNo">1238</span>    checkMetaLoaded(parent);<a name="line.1238"></a>
-<span class="sourceLineNo">1239</span><a name="line.1239"></a>
-<span class="sourceLineNo">1240</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1240"></a>
-<span class="sourceLineNo">1241</span>      throw new UnexpectedStateException(<a name="line.1241"></a>
-<span class="sourceLineNo">1242</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1242"></a>
-<span class="sourceLineNo">1243</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1243"></a>
-<span class="sourceLineNo">1244</span>    }<a name="line.1244"></a>
-<span class="sourceLineNo">1245</span><a name="line.1245"></a>
-<span class="sourceLineNo">1246</span>    // sanity check on the request<a name="line.1246"></a>
-<span class="sourceLineNo">1247</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1247"></a>
-<span class="sourceLineNo">1248</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1248"></a>
-<span class="sourceLineNo">1249</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1249"></a>
-<span class="sourceLineNo">1250</span>    }<a name="line.1250"></a>
-<span class="sourceLineNo">1251</span><a name="line.1251"></a>
-<span class="sourceLineNo">1252</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1252"></a>
-<span class="sourceLineNo">1253</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1253"></a>
-<span class="sourceLineNo">1254</span>      throw new DoNotRetryIOException(<a name="line.1254"></a>
-<span class="sourceLineNo">1255</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1255"></a>
-<span class="sourceLineNo">1256</span>    }<a name="line.1256"></a>
-<span class="sourceLineNo">1257</span><a name="line.1257"></a>
-<span class="sourceLineNo">1258</span>    // Submit the Split procedure<a name="line.1258"></a>
-<span class="sourceLineNo">1259</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1259"></a>
-<span class="sourceLineNo">1260</span>    if (LOG.isDebugEnabled()) {<a name="line.1260"></a>
-<span class="sourceLineNo">1261</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1261"></a>
-<span class="sourceLineNo">1262</span>        + Bytes.toStringBinary(splitKey));<a name="line.1262"></a>
-<span class="sourceLineNo">1263</span>    }<a name="line.1263"></a>
-<span class="sourceLineNo">1264</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1264"></a>
-<span class="sourceLineNo">1265</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1265"></a>
-<span class="sourceLineNo">1266</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1266"></a>
-<span class="sourceLineNo">1267</span>    // ignore it in that case.<a name="line.1267"></a>
-<span class="sourceLineNo">1268</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1268"></a>
-<span class="sourceLineNo">1269</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1269"></a>
-<span class="sourceLineNo">1270</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1270"></a>
-<span class="sourceLineNo">1271</span>    // initialization and report failure with WARN level logging.<a name="line.1271"></a>
-<span class="sourceLineNo">1272</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1272"></a>
-<span class="sourceLineNo">1273</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1273"></a>
-<span class="sourceLineNo">1274</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1274"></a>
-<span class="sourceLineNo">1275</span>    } else {<a name="line.1275"></a>
-<span class="sourceLineNo">1276</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1276"></a>
-<span class="sourceLineNo">1277</span>        + " because parent is unknown or not open");<a name="line.1277"></a>
-<span class="sourceLineNo">1278</span>      return;<a name="line.1278"></a>
-<span class="sourceLineNo">1279</span>    }<a name="line.1279"></a>
-<span class="sourceLineNo">1280</span><a name="line.1280"></a>
-<span class="sourceLineNo">1281</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1281"></a>
-<span class="sourceLineNo">1282</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1282"></a>
-<span class="sourceLineNo">1283</span>      throw new UnsupportedOperationException(<a name="line.1283"></a>
-<span class="sourceLineNo">1284</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1284"></a>
-<span class="sourceLineNo">1285</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1285"></a>
-<span class="sourceLineNo">1286</span>    }<a name="line.1286"></a>
-<span class="sourceLineNo">1287</span>  }<a name="line.1287"></a>
-<span class="sourceLineNo">1288</span><a name="line.1288"></a>
-<span class="sourceLineNo">1289</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1289"></a>
-<span class="sourceLineNo">1290</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1290"></a>
-<span class="sourceLineNo">1291</span>    checkMetaLoaded(merged);<a name="line.1291"></a>
-<span class="sourceLineNo">1292</span><a name="line.1292"></a>
-<span class="sourceLineNo">1293</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1293"></a>
-<span class="sourceLineNo">1294</span>      throw new UnexpectedStateException(<a name="line.1294"></a>
-<span class="sourceLineNo">1295</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1295"></a>
-<span class="sourceLineNo">1296</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1296"></a>
-<span class="sourceLineNo">1297</span>    }<a name="line.1297"></a>
-<span class="sourceLineNo">1298</span><a name="line.1298"></a>
-<span class="sourceLineNo">1299</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1299"></a>
-<span class="sourceLineNo">1300</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1300"></a>
-<span class="sourceLineNo">1301</span>      throw new DoNotRetryIOException(<a name="line.1301"></a>
-<span class="sourceLineNo">1302</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1302"></a>
-<span class="sourceLineNo">1303</span>    }<a name="line.1303"></a>
-<span class="sourceLineNo">1304</span><a name="line.1304"></a>
-<span class="sourceLineNo">1305</span>    // Submit the Merge procedure<a name="line.1305"></a>
-<span class="sourceLineNo">1306</span>    if (LOG.isDebugEnabled()) {<a name="line.1306"></a>
-<span class="sourceLineNo">1307</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1307"></a>
-<span class="sourceLineNo">1308</span>    }<a name="line.1308"></a>
-<span class="sourceLineNo">1309</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1309"></a>
-<span class="sourceLineNo">1310</span><a name="line.1310"></a>
-<span class="sourceLineNo">1311</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1311"></a>
-<span class="sourceLineNo">1312</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1312"></a>
-<span class="sourceLineNo">1313</span>      throw new UnsupportedOperationException(<a name="line.1313"></a>
-<span class="sourceLineNo">1314</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1314"></a>
-<span class="sourceLineNo">1315</span>          merged, hriA, hriB));<a name="line.1315"></a>
-<span class="sourceLineNo">1316</span>    }<a name="line.1316"></a>
-<span class="sourceLineNo">1317</span>  }<a name="line.1317"></a>
-<span class="sourceLineNo">1318</span><a name="line.1318"></a>
+<span class="sourceLineNo">1104</span>  private void reportRegionStateTransition(ReportRegionStateTransitionResponse.Builder builder,<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>    ServerName serverName, List&lt;RegionStateTransition&gt; transitionList) throws IOException {<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>    for (RegionStateTransition transition : transitionList) {<a name="line.1106"></a>
+<span class="sourceLineNo">1107</span>      switch (transition.getTransitionCode()) {<a name="line.1107"></a>
+<span class="sourceLineNo">1108</span>        case OPENED:<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span>        case FAILED_OPEN:<a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>        case CLOSED:<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>          assert transition.getRegionInfoCount() == 1 : transition;<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>          final RegionInfo hri = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>          long procId =<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>            transition.getProcIdCount() &gt; 0 ? transition.getProcId(0) : Procedure.NO_PROC_ID;<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>          updateRegionTransition(serverName, transition.getTransitionCode(), hri,<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>            transition.hasOpenSeqNum() ? transition.getOpenSeqNum() : HConstants.NO_SEQNUM, procId);<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span>          break;<a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>        case READY_TO_SPLIT:<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>        case SPLIT:<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>        case SPLIT_REVERTED:<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>          final RegionInfo parent = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>          final RegionInfo splitA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>          final RegionInfo splitB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>          updateRegionSplitTransition(serverName, transition.getTransitionCode(), parent, splitA,<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>            splitB);<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>          break;<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>        case READY_TO_MERGE:<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>        case MERGED:<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>        case MERGE_REVERTED:<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>          assert transition.getRegionInfoCount() == 3 : transition;<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>          final RegionInfo merged = ProtobufUtil.toRegionInfo(transition.getRegionInfo(0));<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span>          final RegionInfo mergeA = ProtobufUtil.toRegionInfo(transition.getRegionInfo(1));<a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>          final RegionInfo mergeB = ProtobufUtil.toRegionInfo(transition.getRegionInfo(2));<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>          updateRegionMergeTransition(serverName, transition.getTransitionCode(), merged, mergeA,<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>            mergeB);<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>          break;<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>      }<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>    }<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>  }<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span><a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>  public ReportRegionStateTransitionResponse reportRegionStateTransition(<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>    final ReportRegionStateTransitionRequest req) throws PleaseHoldException {<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>    ReportRegionStateTransitionResponse.Builder builder =<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>      ReportRegionStateTransitionResponse.newBuilder();<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>    ServerName serverName = ProtobufUtil.toServerName(req.getServer());<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    // here we have to acquire a read lock instead of a simple exclusive lock. This is because that<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>    // we should not block other reportRegionStateTransition call from the same region server. This<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span>    // is not only about performance, but also to prevent dead lock. Think of the meta region is<a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>    // also on the same region server and you hold the lock which blocks the<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span>    // reportRegionStateTransition for meta, and since meta is not online, you will block inside the<a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    // lock protection to wait for meta online...<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>    serverNode.readLock().lock();<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>    try {<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span>      // we only accept reportRegionStateTransition if the region server is online, see the comment<a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>      // above in submitServerCrash method and HBASE-21508 for more details.<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>      if (serverNode.isInState(ServerState.ONLINE)) {<a name="line.1158"></a>
+<span class="sourceLineNo">1159</span>        try {<a name="line.1159"></a>
+<span class="sourceLineNo">1160</span>          reportRegionStateTransition(builder, serverName, req.getTransitionList());<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span>        } catch (PleaseHoldException e) {<a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>          LOG.trace("Failed transition ", e);<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>          throw e;<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span>        } catch (UnsupportedOperationException | IOException e) {<a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>          // TODO: at the moment we have a single error message and the RS will abort<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>          // if the master says that one of the region transitions failed.<a name="line.1166"></a>
+<span class="sourceLineNo">1167</span>          LOG.warn("Failed transition", e);<a name="line.1167"></a>
+<span class="sourceLineNo">1168</span>          builder.setErrorMessage("Failed transition " + e.getMessage());<a name="line.1168"></a>
+<span class="sourceLineNo">1169</span>        }<a name="line.1169"></a>
+<span class="sourceLineNo">1170</span>      } else {<a name="line.1170"></a>
+<span class="sourceLineNo">1171</span>        LOG.warn("The region server {} is already dead, skip reportRegionStateTransition call",<a name="line.1171"></a>
+<span class="sourceLineNo">1172</span>          serverName);<a name="line.1172"></a>
+<span class="sourceLineNo">1173</span>        builder.setErrorMessage("You are dead");<a name="line.1173"></a>
+<span class="sourceLineNo">1174</span>      }<a name="line.1174"></a>
+<span class="sourceLineNo">1175</span>    } finally {<a name="line.1175"></a>
+<span class="sourceLineNo">1176</span>      serverNode.readLock().unlock();<a name="line.1176"></a>
+<span class="sourceLineNo">1177</span>    }<a name="line.1177"></a>
+<span class="sourceLineNo">1178</span><a name="line.1178"></a>
+<span class="sourceLineNo">1179</span>    return builder.build();<a name="line.1179"></a>
+<span class="sourceLineNo">1180</span>  }<a name="line.1180"></a>
+<span class="sourceLineNo">1181</span><a name="line.1181"></a>
+<span class="sourceLineNo">1182</span>  private void updateRegionTransition(ServerName serverName, TransitionCode state,<a name="line.1182"></a>
+<span class="sourceLineNo">1183</span>    RegionInfo regionInfo, long seqId, long procId) throws IOException {<a name="line.1183"></a>
+<span class="sourceLineNo">1184</span>    checkMetaLoaded(regionInfo);<a name="line.1184"></a>
+<span class="sourceLineNo">1185</span><a name="line.1185"></a>
+<span class="sourceLineNo">1186</span>    RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1186"></a>
+<span class="sourceLineNo">1187</span>    if (regionNode == null) {<a name="line.1187"></a>
+<span class="sourceLineNo">1188</span>      // the table/region is gone. maybe a delete, split, merge<a name="line.1188"></a>
+<span class="sourceLineNo">1189</span>      throw new UnexpectedStateException(String.format(<a name="line.1189"></a>
+<span class="sourceLineNo">1190</span>        "Server %s was trying to transition region %s to %s. but Region is not known.", serverName,<a name="line.1190"></a>
+<span class="sourceLineNo">1191</span>        regionInfo, state));<a name="line.1191"></a>
+<span class="sourceLineNo">1192</span>    }<a name="line.1192"></a>
+<span class="sourceLineNo">1193</span>    LOG.trace("Update region transition serverName={} region={} regionState={}", serverName,<a name="line.1193"></a>
+<span class="sourceLineNo">1194</span>      regionNode, state);<a name="line.1194"></a>
+<span class="sourceLineNo">1195</span><a name="line.1195"></a>
+<span class="sourceLineNo">1196</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1196"></a>
+<span class="sourceLineNo">1197</span>    regionNode.lock();<a name="line.1197"></a>
+<span class="sourceLineNo">1198</span>    try {<a name="line.1198"></a>
+<span class="sourceLineNo">1199</span>      if (!reportTransition(regionNode, serverNode, state, seqId, procId)) {<a name="line.1199"></a>
+<span class="sourceLineNo">1200</span>        // Don't log WARN if shutting down cluster; during shutdown. Avoid the below messages:<a name="line.1200"></a>
+<span class="sourceLineNo">1201</span>        // 2018-08-13 10:45:10,551 WARN ...AssignmentManager: No matching procedure found for<a name="line.1201"></a>
+<span class="sourceLineNo">1202</span>        // rit=OPEN, location=ve0538.halxg.cloudera.com,16020,1533493000958,<a name="line.1202"></a>
+<span class="sourceLineNo">1203</span>        // table=IntegrationTestBigLinkedList, region=65ab289e2fc1530df65f6c3d7cde7aa5 transition<a name="line.1203"></a>
+<span class="sourceLineNo">1204</span>        // to CLOSED<a name="line.1204"></a>
+<span class="sourceLineNo">1205</span>        // These happen because on cluster shutdown, we currently let the RegionServers close<a name="line.1205"></a>
+<span class="sourceLineNo">1206</span>        // regions. This is the only time that region close is not run by the Master (so cluster<a name="line.1206"></a>
+<span class="sourceLineNo">1207</span>        // goes down fast). Consider changing it so Master runs all shutdowns.<a name="line.1207"></a>
+<span class="sourceLineNo">1208</span>        if (<a name="line.1208"></a>
+<span class="sourceLineNo">1209</span>          this.master.getServerManager().isClusterShutdown() &amp;&amp; state.equals(TransitionCode.CLOSED)<a name="line.1209"></a>
+<span class="sourceLineNo">1210</span>        ) {<a name="line.1210"></a>
+<span class="sourceLineNo">1211</span>          LOG.info("RegionServer {} {}", state, regionNode.getRegionInfo().getEncodedName());<a name="line.1211"></a>
+<span class="sourceLineNo">1212</span>        } else {<a name="line.1212"></a>
+<span class="sourceLineNo">1213</span>          LOG.warn("No matching procedure found for {} transition on {} to {}", serverName,<a name="line.1213"></a>
+<span class="sourceLineNo">1214</span>            regionNode, state);<a name="line.1214"></a>
+<span class="sourceLineNo">1215</span>        }<a name="line.1215"></a>
+<span class="sourceLineNo">1216</span>      }<a name="line.1216"></a>
+<span class="sourceLineNo">1217</span>    } finally {<a name="line.1217"></a>
+<span class="sourceLineNo">1218</span>      regionNode.unlock();<a name="line.1218"></a>
+<span class="sourceLineNo">1219</span>    }<a name="line.1219"></a>
+<span class="sourceLineNo">1220</span>  }<a name="line.1220"></a>
+<span class="sourceLineNo">1221</span><a name="line.1221"></a>
+<span class="sourceLineNo">1222</span>  private boolean reportTransition(RegionStateNode regionNode, ServerStateNode serverNode,<a name="line.1222"></a>
+<span class="sourceLineNo">1223</span>    TransitionCode state, long seqId, long procId) throws IOException {<a name="line.1223"></a>
+<span class="sourceLineNo">1224</span>    ServerName serverName = serverNode.getServerName();<a name="line.1224"></a>
+<span class="sourceLineNo">1225</span>    TransitRegionStateProcedure proc = regionNode.getProcedure();<a name="line.1225"></a>
+<span class="sourceLineNo">1226</span>    if (proc == null) {<a name="line.1226"></a>
+<span class="sourceLineNo">1227</span>      return false;<a name="line.1227"></a>
+<span class="sourceLineNo">1228</span>    }<a name="line.1228"></a>
+<span class="sourceLineNo">1229</span>    proc.reportTransition(master.getMasterProcedureExecutor().getEnvironment(), regionNode,<a name="line.1229"></a>
+<span class="sourceLineNo">1230</span>      serverName, state, seqId, procId);<a name="line.1230"></a>
+<span class="sourceLineNo">1231</span>    return true;<a name="line.1231"></a>
+<span class="sourceLineNo">1232</span>  }<a name="line.1232"></a>
+<span class="sourceLineNo">1233</span><a name="line.1233"></a>
+<span class="sourceLineNo">1234</span>  private void updateRegionSplitTransition(final ServerName serverName, final TransitionCode state,<a name="line.1234"></a>
+<span class="sourceLineNo">1235</span>    final RegionInfo parent, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1235"></a>
+<span class="sourceLineNo">1236</span>    checkMetaLoaded(parent);<a name="line.1236"></a>
+<span class="sourceLineNo">1237</span><a name="line.1237"></a>
+<span class="sourceLineNo">1238</span>    if (state != TransitionCode.READY_TO_SPLIT) {<a name="line.1238"></a>
+<span class="sourceLineNo">1239</span>      throw new UnexpectedStateException(<a name="line.1239"></a>
+<span class="sourceLineNo">1240</span>        "unsupported split regionState=" + state + " for parent region " + parent<a name="line.1240"></a>
+<span class="sourceLineNo">1241</span>          + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1241"></a>
+<span class="sourceLineNo">1242</span>    }<a name="line.1242"></a>
+<span class="sourceLineNo">1243</span><a name="line.1243"></a>
+<span class="sourceLineNo">1244</span>    // sanity check on the request<a name="line.1244"></a>
+<span class="sourceLineNo">1245</span>    if (!Bytes.equals(hriA.getEndKey(), hriB.getStartKey())) {<a name="line.1245"></a>
+<span class="sourceLineNo">1246</span>      throw new UnsupportedOperationException("unsupported split request with bad keys: parent="<a name="line.1246"></a>
+<span class="sourceLineNo">1247</span>        + parent + " hriA=" + hriA + " hriB=" + hriB);<a name="line.1247"></a>
+<span class="sourceLineNo">1248</span>    }<a name="line.1248"></a>
+<span class="sourceLineNo">1249</span><a name="line.1249"></a>
+<span class="sourceLineNo">1250</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.SPLIT)) {<a name="line.1250"></a>
+<span class="sourceLineNo">1251</span>      LOG.warn("Split switch is off! skip split of " + parent);<a name="line.1251"></a>
+<span class="sourceLineNo">1252</span>      throw new DoNotRetryIOException(<a name="line.1252"></a>
+<span class="sourceLineNo">1253</span>        "Split region " + parent.getRegionNameAsString() + " failed due to split switch off");<a name="line.1253"></a>
+<span class="sourceLineNo">1254</span>    }<a name="line.1254"></a>
+<span class="sourceLineNo">1255</span><a name="line.1255"></a>
+<span class="sourceLineNo">1256</span>    // Submit the Split procedure<a name="line.1256"></a>
+<span class="sourceLineNo">1257</span>    final byte[] splitKey = hriB.getStartKey();<a name="line.1257"></a>
+<span class="sourceLineNo">1258</span>    if (LOG.isDebugEnabled()) {<a name="line.1258"></a>
+<span class="sourceLineNo">1259</span>      LOG.debug("Split request from " + serverName + ", parent=" + parent + " splitKey="<a name="line.1259"></a>
+<span class="sourceLineNo">1260</span>        + Bytes.toStringBinary(splitKey));<a name="line.1260"></a>
+<span class="sourceLineNo">1261</span>    }<a name="line.1261"></a>
+<span class="sourceLineNo">1262</span>    // Processing this report happens asynchronously from other activities which can mutate<a name="line.1262"></a>
+<span class="sourceLineNo">1263</span>    // the region state. For example, a split procedure may already be running for this parent.<a name="line.1263"></a>
+<span class="sourceLineNo">1264</span>    // A split procedure cannot succeed if the parent region is no longer open, so we can<a name="line.1264"></a>
+<span class="sourceLineNo">1265</span>    // ignore it in that case.<a name="line.1265"></a>
+<span class="sourceLineNo">1266</span>    // Note that submitting more than one split procedure for a given region is<a name="line.1266"></a>
+<span class="sourceLineNo">1267</span>    // harmless -- the split is fenced in the procedure handling -- but it would be noisy in<a name="line.1267"></a>
+<span class="sourceLineNo">1268</span>    // the logs. Only one procedure can succeed. The other procedure(s) would abort during<a name="line.1268"></a>
+<span class="sourceLineNo">1269</span>    // initialization and report failure with WARN level logging.<a name="line.1269"></a>
+<span class="sourceLineNo">1270</span>    RegionState parentState = regionStates.getRegionState(parent);<a name="line.1270"></a>
+<span class="sourceLineNo">1271</span>    if (parentState != null &amp;&amp; parentState.isOpened()) {<a name="line.1271"></a>
+<span class="sourceLineNo">1272</span>      master.getMasterProcedureExecutor().submitProcedure(createSplitProcedure(parent, splitKey));<a name="line.1272"></a>
+<span class="sourceLineNo">1273</span>    } else {<a name="line.1273"></a>
+<span class="sourceLineNo">1274</span>      LOG.info("Ignoring split request from " + serverName + ", parent=" + parent<a name="line.1274"></a>
+<span class="sourceLineNo">1275</span>        + " because parent is unknown or not open");<a name="line.1275"></a>
+<span class="sourceLineNo">1276</span>      return;<a name="line.1276"></a>
+<span class="sourceLineNo">1277</span>    }<a name="line.1277"></a>
+<span class="sourceLineNo">1278</span><a name="line.1278"></a>
+<span class="sourceLineNo">1279</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the split<a name="line.1279"></a>
+<span class="sourceLineNo">1280</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1280"></a>
+<span class="sourceLineNo">1281</span>      throw new UnsupportedOperationException(<a name="line.1281"></a>
+<span class="sourceLineNo">1282</span>        String.format("Split handled by the master: " + "parent=%s hriA=%s hriB=%s",<a name="line.1282"></a>
+<span class="sourceLineNo">1283</span>          parent.getShortNameToLog(), hriA, hriB));<a name="line.1283"></a>
+<span class="sourceLineNo">1284</span>    }<a name="line.1284"></a>
+<span class="sourceLineNo">1285</span>  }<a name="line.1285"></a>
+<span class="sourceLineNo">1286</span><a name="line.1286"></a>
+<span class="sourceLineNo">1287</span>  private void updateRegionMergeTransition(final ServerName serverName, final TransitionCode state,<a name="line.1287"></a>
+<span class="sourceLineNo">1288</span>    final RegionInfo merged, final RegionInfo hriA, final RegionInfo hriB) throws IOException {<a name="line.1288"></a>
+<span class="sourceLineNo">1289</span>    checkMetaLoaded(merged);<a name="line.1289"></a>
+<span class="sourceLineNo">1290</span><a name="line.1290"></a>
+<span class="sourceLineNo">1291</span>    if (state != TransitionCode.READY_TO_MERGE) {<a name="line.1291"></a>
+<span class="sourceLineNo">1292</span>      throw new UnexpectedStateException(<a name="line.1292"></a>
+<span class="sourceLineNo">1293</span>        "Unsupported merge regionState=" + state + " for regionA=" + hriA + " regionB=" + hriB<a name="line.1293"></a>
+<span class="sourceLineNo">1294</span>          + " merged=" + merged + " maybe an old RS (&lt; 2.0) had the operation in progress");<a name="line.1294"></a>
+<span class="sourceLineNo">1295</span>    }<a name="line.1295"></a>
+<span class="sourceLineNo">1296</span><a name="line.1296"></a>
+<span class="sourceLineNo">1297</span>    if (!master.isSplitOrMergeEnabled(MasterSwitchType.MERGE)) {<a name="line.1297"></a>
+<span class="sourceLineNo">1298</span>      LOG.warn("Merge switch is off! skip merge of regionA=" + hriA + " regionB=" + hriB);<a name="line.1298"></a>
+<span class="sourceLineNo">1299</span>      throw new DoNotRetryIOException(<a name="line.1299"></a>
+<span class="sourceLineNo">1300</span>        "Merge of regionA=" + hriA + " regionB=" + hriB + " failed because merge switch is off");<a name="line.1300"></a>
+<span class="sourceLineNo">1301</span>    }<a name="line.1301"></a>
+<span class="sourceLineNo">1302</span><a name="line.1302"></a>
+<span class="sourceLineNo">1303</span>    // Submit the Merge procedure<a name="line.1303"></a>
+<span class="sourceLineNo">1304</span>    if (LOG.isDebugEnabled()) {<a name="line.1304"></a>
+<span class="sourceLineNo">1305</span>      LOG.debug("Handling merge request from RS=" + merged + ", merged=" + merged);<a name="line.1305"></a>
+<span class="sourceLineNo">1306</span>    }<a name="line.1306"></a>
+<span class="sourceLineNo">1307</span>    master.getMasterProcedureExecutor().submitProcedure(createMergeProcedure(hriA, hriB));<a name="line.1307"></a>
+<span class="sourceLineNo">1308</span><a name="line.1308"></a>
+<span class="sourceLineNo">1309</span>    // If the RS is &lt; 2.0 throw an exception to abort the operation, we are handling the merge<a name="line.1309"></a>
+<span class="sourceLineNo">1310</span>    if (master.getServerManager().getVersionNumber(serverName) &lt; 0x0200000) {<a name="line.1310"></a>
+<span class="sourceLineNo">1311</span>      throw new UnsupportedOperationException(<a name="line.1311"></a>
+<span class="sourceLineNo">1312</span>        String.format("Merge not handled yet: regionState=%s merged=%s hriA=%s hriB=%s", state,<a name="line.1312"></a>
+<span class="sourceLineNo">1313</span>          merged, hriA, hriB));<a name="line.1313"></a>
+<span class="sourceLineNo">1314</span>    }<a name="line.1314"></a>
+<span class="sourceLineNo">1315</span>  }<a name="line.1315"></a>
+<span class="sourceLineNo">1316</span><a name="line.1316"></a>
+<span class="sourceLineNo">1317</span>  // ============================================================================================<a name="line.1317"></a>
+<span class="sourceLineNo">1318</span>  // RS Status update (report online regions) helpers<a name="line.1318"></a>
 <span class="sourceLineNo">1319</span>  // ============================================================================================<a name="line.1319"></a>
-<span class="sourceLineNo">1320</span>  // RS Status update (report online regions) helpers<a name="line.1320"></a>
-<span class="sourceLineNo">1321</span>  // ============================================================================================<a name="line.1321"></a>
-<span class="sourceLineNo">1322</span>  /**<a name="line.1322"></a>
-<span class="sourceLineNo">1323</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1323"></a>
-<span class="sourceLineNo">1324</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1324"></a>
-<span class="sourceLineNo">1325</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1325"></a>
-<span class="sourceLineNo">1326</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1326"></a>
-<span class="sourceLineNo">1327</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1327"></a>
-<span class="sourceLineNo">1328</span>   * actually there is no problem.<a name="line.1328"></a>
-<span class="sourceLineNo">1329</span>   * &lt;p/&gt;<a name="line.1329"></a>
-<span class="sourceLineNo">1330</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1330"></a>
-<span class="sourceLineNo">1331</span>   */<a name="line.1331"></a>
-<span class="sourceLineNo">1332</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1332"></a>
-<span class="sourceLineNo">1333</span>    if (!isRunning()) {<a name="line.1333"></a>
-<span class="sourceLineNo">1334</span>      return;<a name="line.1334"></a>
-<span class="sourceLineNo">1335</span>    }<a name="line.1335"></a>
-<span class="sourceLineNo">1336</span>    if (LOG.isTraceEnabled()) {<a name="line.1336"></a>
-<span class="sourceLineNo">1337</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1337"></a>
-<span class="sourceLineNo">1338</span>        regionNames.size(), isMetaLoaded(),<a name="line.1338"></a>
-<span class="sourceLineNo">1339</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1339"></a>
-<span class="sourceLineNo">1340</span>    }<a name="line.1340"></a>
-<span class="sourceLineNo">1341</span><a name="line.1341"></a>
-<span class="sourceLineNo">1342</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1342"></a>
-<span class="sourceLineNo">1343</span>    synchronized (serverNode) {<a name="line.1343"></a>
-<span class="sourceLineNo">1344</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1344"></a>
-<span class="sourceLineNo">1345</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1345"></a>
-<span class="sourceLineNo">1346</span>        return;<a name="line.1346"></a>
-<span class="sourceLineNo">1347</span>      }<a name="line.1347"></a>
-<span class="sourceLineNo">1348</span>    }<a name="line.1348"></a>
-<span class="sourceLineNo">1349</span><a name="line.1349"></a>
-<span class="sourceLineNo">1350</span>    // Track the regionserver reported online regions in memory.<a name="line.1350"></a>
-<span class="sourceLineNo">1351</span>    synchronized (rsReports) {<a name="line.1351"></a>
-<span class="sourceLineNo">1352</span>      rsReports.put(serverName, regionNames);<a name="line.1352"></a>
-<span class="sourceLineNo">1353</span>    }<a name="line.1353"></a>
-<span class="sourceLineNo">1354</span><a name="line.1354"></a>
-<span class="sourceLineNo">1355</span>    if (regionNames.isEmpty()) {<a name="line.1355"></a>
-<span class="sourceLineNo">1356</span>      // nothing to do if we don't have regions<a name="line.1356"></a>
-<span class="sourceLineNo">1357</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1357"></a>
-<span class="sourceLineNo">1358</span>      return;<a name="line.1358"></a>
-<span class="sourceLineNo">1359</span>    }<a name="line.1359"></a>
-<span class="sourceLineNo">1360</span>    if (!isMetaLoaded()) {<a name="line.1360"></a>
-<span class="sourceLineNo">1361</span>      // we are still on startup, skip checking<a name="line.1361"></a>
-<span class="sourceLineNo">1362</span>      return;<a name="line.1362"></a>
-<span class="sourceLineNo">1363</span>    }<a name="line.1363"></a>
-<span class="sourceLineNo">1364</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1364"></a>
-<span class="sourceLineNo">1365</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1365"></a>
-<span class="sourceLineNo">1366</span>  }<a name="line.1366"></a>
-<span class="sourceLineNo">1367</span><a name="line.1367"></a>
-<span class="sourceLineNo">1368</span>  /**<a name="line.1368"></a>
-<span class="sourceLineNo">1369</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1369"></a>
-<span class="sourceLineNo">1370</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1370"></a>
-<span class="sourceLineNo">1371</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1371"></a>
-<span class="sourceLineNo">1372</span>   * accounting.<a name="line.1372"></a>
-<span class="sourceLineNo">1373</span>   */<a name="line.1373"></a>
-<span class="sourceLineNo">1374</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1374"></a>
-<span class="sourceLineNo">1375</span>    try {<a name="line.1375"></a>
-<span class="sourceLineNo">1376</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1376"></a>
-<span class="sourceLineNo">1377</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1377"></a>
-<span class="sourceLineNo">1378</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1378"></a>
-<span class="sourceLineNo">1379</span>    } catch (Exception e) {<a name="line.1379"></a>
-<span class="sourceLineNo">1380</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1380"></a>
-<span class="sourceLineNo">1381</span>    }<a name="line.1381"></a>
-<span class="sourceLineNo">1382</span>  }<a name="line.1382"></a>
-<span class="sourceLineNo">1383</span><a name="line.1383"></a>
-<span class="sourceLineNo">1384</span>  /**<a name="line.1384"></a>
-<span class="sourceLineNo">1385</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1385"></a>
-<span class="sourceLineNo">1386</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1386"></a>
-<span class="sourceLineNo">1387</span>   */<a name="line.1387"></a>
-<span class="sourceLineNo">1388</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1388"></a>
-<span class="sourceLineNo">1389</span>    ServerName serverName = serverNode.getServerName();<a name="line.1389"></a>
-<span class="sourceLineNo">1390</span>    for (byte[] regionName : regionNames) {<a name="line.1390"></a>
-<span class="sourceLineNo">1391</span>      if (!isRunning()) {<a name="line.1391"></a>
-<span class="sourceLineNo">1392</span>        return;<a name="line.1392"></a>
-<span class="sourceLineNo">1393</span>      }<a name="line.1393"></a>
-<span class="sourceLineNo">1394</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1394"></a>
-<span class="sourceLineNo">1395</span>      if (regionNode == null) {<a name="line.1395"></a>
-<span class="sourceLineNo">1396</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1396"></a>
-<span class="sourceLineNo">1397</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1397"></a>
-<span class="sourceLineNo">1398</span>          serverName);<a name="line.1398"></a>
-<span class="sourceLineNo">1399</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1399"></a>
-<span class="sourceLineNo">1400</span>        continue;<a name="line.1400"></a>
-<span class="sourceLineNo">1401</span>      }<a name="line.1401"></a>
-<span class="sourceLineNo">1402</span>      final long lag = 1000;<a name="line.1402"></a>
-<span class="sourceLineNo">1403</span>      regionNode.lock();<a name="line.1403"></a>
-<span class="sourceLineNo">1404</span>      try {<a name="line.1404"></a>
-<span class="sourceLineNo">1405</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1405"></a>
-<span class="sourceLineNo">1406</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1406"></a>
-<span class="sourceLineNo">1407</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1407"></a>
-<span class="sourceLineNo">1408</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1408"></a>
-<span class="sourceLineNo">1409</span>          // is some elapsed time so less false alarms.<a name="line.1409"></a>
-<span class="sourceLineNo">1410</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1410"></a>
-<span class="sourceLineNo">1411</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1411"></a>
-<span class="sourceLineNo">1412</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1412"></a>
-<span class="sourceLineNo">1413</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1413"></a>
-<span class="sourceLineNo">1414</span>          }<a name="line.1414"></a>
-<span class="sourceLineNo">1415</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1415"></a>
-<span class="sourceLineNo">1416</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1416"></a>
-<span class="sourceLineNo">1417</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1417"></a>
-<span class="sourceLineNo">1418</span>          // elapsed time so less false alarms.<a name="line.1418"></a>
-<span class="sourceLineNo">1419</span>          if (diff &gt; lag) {<a name="line.1419"></a>
-<span class="sourceLineNo">1420</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1420"></a>
-<span class="sourceLineNo">1421</span>              serverName, regionNode, diff);<a name="line.1421"></a>
-<span class="sourceLineNo">1422</span>          }<a name="line.1422"></a>
-<span class="sourceLineNo">1423</span>        }<a name="line.1423"></a>
-<span class="sourceLineNo">1424</span>      } finally {<a name="line.1424"></a>
-<span class="sourceLineNo">1425</span>        regionNode.unlock();<a name="line.1425"></a>
-<span class="sourceLineNo">1426</span>      }<a name="line.1426"></a>
-<span class="sourceLineNo">1427</span>    }<a name="line.1427"></a>
-<span class="sourceLineNo">1428</span>  }<a name="line.1428"></a>
-<span class="sourceLineNo">1429</span><a name="line.1429"></a>
+<span class="sourceLineNo">1320</span>  /**<a name="line.1320"></a>
+<span class="sourceLineNo">1321</span>   * The master will call this method when the RS send the regionServerReport(). The report will<a name="line.1321"></a>
+<span class="sourceLineNo">1322</span>   * contains the "online regions". This method will check the the online regions against the<a name="line.1322"></a>
+<span class="sourceLineNo">1323</span>   * in-memory state of the AM, and we will log a warn message if there is a mismatch. This is<a name="line.1323"></a>
+<span class="sourceLineNo">1324</span>   * because that there is no fencing between the reportRegionStateTransition method and<a name="line.1324"></a>
+<span class="sourceLineNo">1325</span>   * regionServerReport method, so there could be race and introduce inconsistency here, but<a name="line.1325"></a>
+<span class="sourceLineNo">1326</span>   * actually there is no problem.<a name="line.1326"></a>
+<span class="sourceLineNo">1327</span>   * &lt;p/&gt;<a name="line.1327"></a>
+<span class="sourceLineNo">1328</span>   * Please see HBASE-21421 and HBASE-21463 for more details.<a name="line.1328"></a>
+<span class="sourceLineNo">1329</span>   */<a name="line.1329"></a>
+<span class="sourceLineNo">1330</span>  public void reportOnlineRegions(ServerName serverName, Set&lt;byte[]&gt; regionNames) {<a name="line.1330"></a>
+<span class="sourceLineNo">1331</span>    if (!isRunning()) {<a name="line.1331"></a>
+<span class="sourceLineNo">1332</span>      return;<a name="line.1332"></a>
+<span class="sourceLineNo">1333</span>    }<a name="line.1333"></a>
+<span class="sourceLineNo">1334</span>    if (LOG.isTraceEnabled()) {<a name="line.1334"></a>
+<span class="sourceLineNo">1335</span>      LOG.trace("ReportOnlineRegions {} regionCount={}, metaLoaded={} {}", serverName,<a name="line.1335"></a>
+<span class="sourceLineNo">1336</span>        regionNames.size(), isMetaLoaded(),<a name="line.1336"></a>
+<span class="sourceLineNo">1337</span>        regionNames.stream().map(Bytes::toStringBinary).collect(Collectors.toList()));<a name="line.1337"></a>
+<span class="sourceLineNo">1338</span>    }<a name="line.1338"></a>
+<span class="sourceLineNo">1339</span><a name="line.1339"></a>
+<span class="sourceLineNo">1340</span>    ServerStateNode serverNode = regionStates.getOrCreateServer(serverName);<a name="line.1340"></a>
+<span class="sourceLineNo">1341</span>    synchronized (serverNode) {<a name="line.1341"></a>
+<span class="sourceLineNo">1342</span>      if (!serverNode.isInState(ServerState.ONLINE)) {<a name="line.1342"></a>
+<span class="sourceLineNo">1343</span>        LOG.warn("Got a report from a server result in state " + serverNode.getState());<a name="line.1343"></a>
+<span class="sourceLineNo">1344</span>        return;<a name="line.1344"></a>
+<span class="sourceLineNo">1345</span>      }<a name="line.1345"></a>
+<span class="sourceLineNo">1346</span>    }<a name="line.1346"></a>
+<span class="sourceLineNo">1347</span><a name="line.1347"></a>
+<span class="sourceLineNo">1348</span>    // Track the regionserver reported online regions in memory.<a name="line.1348"></a>
+<span class="sourceLineNo">1349</span>    synchronized (rsReports) {<a name="line.1349"></a>
+<span class="sourceLineNo">1350</span>      rsReports.put(serverName, regionNames);<a name="line.1350"></a>
+<span class="sourceLineNo">1351</span>    }<a name="line.1351"></a>
+<span class="sourceLineNo">1352</span><a name="line.1352"></a>
+<span class="sourceLineNo">1353</span>    if (regionNames.isEmpty()) {<a name="line.1353"></a>
+<span class="sourceLineNo">1354</span>      // nothing to do if we don't have regions<a name="line.1354"></a>
+<span class="sourceLineNo">1355</span>      LOG.trace("no online region found on {}", serverName);<a name="line.1355"></a>
+<span class="sourceLineNo">1356</span>      return;<a name="line.1356"></a>
+<span class="sourceLineNo">1357</span>    }<a name="line.1357"></a>
+<span class="sourceLineNo">1358</span>    if (!isMetaLoaded()) {<a name="line.1358"></a>
+<span class="sourceLineNo">1359</span>      // we are still on startup, skip checking<a name="line.1359"></a>
+<span class="sourceLineNo">1360</span>      return;<a name="line.1360"></a>
+<span class="sourceLineNo">1361</span>    }<a name="line.1361"></a>
+<span class="sourceLineNo">1362</span>    // The Heartbeat tells us of what regions are on the region serve, check the state.<a name="line.1362"></a>
+<span class="sourceLineNo">1363</span>    checkOnlineRegionsReport(serverNode, regionNames);<a name="line.1363"></a>
+<span class="sourceLineNo">1364</span>  }<a name="line.1364"></a>
+<span class="sourceLineNo">1365</span><a name="line.1365"></a>
+<span class="sourceLineNo">1366</span>  /**<a name="line.1366"></a>
+<span class="sourceLineNo">1367</span>   * Close &lt;code&gt;regionName&lt;/code&gt; on &lt;code&gt;sn&lt;/code&gt; silently and immediately without using a<a name="line.1367"></a>
+<span class="sourceLineNo">1368</span>   * Procedure or going via hbase:meta. For case where a RegionServer's hosting of a Region is not<a name="line.1368"></a>
+<span class="sourceLineNo">1369</span>   * aligned w/ the Master's accounting of Region state. This is for cleaning up an error in<a name="line.1369"></a>
+<span class="sourceLineNo">1370</span>   * accounting.<a name="line.1370"></a>
+<span class="sourceLineNo">1371</span>   */<a name="line.1371"></a>
+<span class="sourceLineNo">1372</span>  private void closeRegionSilently(ServerName sn, byte[] regionName) {<a name="line.1372"></a>
+<span class="sourceLineNo">1373</span>    try {<a name="line.1373"></a>
+<span class="sourceLineNo">1374</span>      RegionInfo ri = CatalogFamilyFormat.parseRegionInfoFromRegionName(regionName);<a name="line.1374"></a>
+<span class="sourceLineNo">1375</span>      // Pass -1 for timeout. Means do not wait.<a name="line.1375"></a>
+<span class="sourceLineNo">1376</span>      ServerManager.closeRegionSilentlyAndWait(this.master.getAsyncClusterConnection(), sn, ri, -1);<a name="line.1376"></a>
+<span class="sourceLineNo">1377</span>    } catch (Exception e) {<a name="line.1377"></a>
+<span class="sourceLineNo">1378</span>      LOG.error("Failed trying to close {} on {}", Bytes.toStringBinary(regionName), sn, e);<a name="line.1378"></a>
+<span class="sourceLineNo">1379</span>    }<a name="line.1379"></a>
+<span class="sourceLineNo">1380</span>  }<a name="line.1380"></a>
+<span class="sourceLineNo">1381</span><a name="line.1381"></a>
+<span class="sourceLineNo">1382</span>  /**<a name="line.1382"></a>
+<span class="sourceLineNo">1383</span>   * Check that what the RegionServer reports aligns with the Master's image. If disagreement, we<a name="line.1383"></a>
+<span class="sourceLineNo">1384</span>   * will tell the RegionServer to expediently close a Region we do not think it should have.<a name="line.1384"></a>
+<span class="sourceLineNo">1385</span>   */<a name="line.1385"></a>
+<span class="sourceLineNo">1386</span>  private void checkOnlineRegionsReport(ServerStateNode serverNode, Set&lt;byte[]&gt; regionNames) {<a name="line.1386"></a>
+<span class="sourceLineNo">1387</span>    ServerName serverName = serverNode.getServerName();<a name="line.1387"></a>
+<span class="sourceLineNo">1388</span>    for (byte[] regionName : regionNames) {<a name="line.1388"></a>
+<span class="sourceLineNo">1389</span>      if (!isRunning()) {<a name="line.1389"></a>
+<span class="sourceLineNo">1390</span>        return;<a name="line.1390"></a>
+<span class="sourceLineNo">1391</span>      }<a name="line.1391"></a>
+<span class="sourceLineNo">1392</span>      RegionStateNode regionNode = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1392"></a>
+<span class="sourceLineNo">1393</span>      if (regionNode == null) {<a name="line.1393"></a>
+<span class="sourceLineNo">1394</span>        String regionNameAsStr = Bytes.toStringBinary(regionName);<a name="line.1394"></a>
+<span class="sourceLineNo">1395</span>        LOG.warn("No RegionStateNode for {} but reported as up on {}; closing...", regionNameAsStr,<a name="line.1395"></a>
+<span class="sourceLineNo">1396</span>          serverName);<a name="line.1396"></a>
+<span class="sourceLineNo">1397</span>        closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1397"></a>
+<span class="sourceLineNo">1398</span>        continue;<a name="line.1398"></a>
+<span class="sourceLineNo">1399</span>      }<a name="line.1399"></a>
+<span class="sourceLineNo">1400</span>      final long lag = 1000;<a name="line.1400"></a>
+<span class="sourceLineNo">1401</span>      regionNode.lock();<a name="line.1401"></a>
+<span class="sourceLineNo">1402</span>      try {<a name="line.1402"></a>
+<span class="sourceLineNo">1403</span>        long diff = EnvironmentEdgeManager.currentTime() - regionNode.getLastUpdate();<a name="line.1403"></a>
+<span class="sourceLineNo">1404</span>        if (regionNode.isInState(State.OPENING, State.OPEN)) {<a name="line.1404"></a>
+<span class="sourceLineNo">1405</span>          // This is possible as a region server has just closed a region but the region server<a name="line.1405"></a>
+<span class="sourceLineNo">1406</span>          // report is generated before the closing, but arrive after the closing. Make sure there<a name="line.1406"></a>
+<span class="sourceLineNo">1407</span>          // is some elapsed time so less false alarms.<a name="line.1407"></a>
+<span class="sourceLineNo">1408</span>          if (!regionNode.getRegionLocation().equals(serverName) &amp;&amp; diff &gt; lag) {<a name="line.1408"></a>
+<span class="sourceLineNo">1409</span>            LOG.warn("Reporting {} server does not match {} (time since last "<a name="line.1409"></a>
+<span class="sourceLineNo">1410</span>              + "update={}ms); closing...", serverName, regionNode, diff);<a name="line.1410"></a>
+<span class="sourceLineNo">1411</span>            closeRegionSilently(serverNode.getServerName(), regionName);<a name="line.1411"></a>
+<span class="sourceLineNo">1412</span>          }<a name="line.1412"></a>
+<span class="sourceLineNo">1413</span>        } else if (!regionNode.isInState(State.CLOSING, State.SPLITTING)) {<a name="line.1413"></a>
+<span class="sourceLineNo">1414</span>          // So, we can get report that a region is CLOSED or SPLIT because a heartbeat<a name="line.1414"></a>
+<span class="sourceLineNo">1415</span>          // came in at about same time as a region transition. Make sure there is some<a name="line.1415"></a>
+<span class="sourceLineNo">1416</span>          // elapsed time so less false alarms.<a name="line.1416"></a>
+<span class="sourceLineNo">1417</span>          if (diff &gt; lag) {<a name="line.1417"></a>
+<span class="sourceLineNo">1418</span>            LOG.warn("Reporting {} state does not match {} (time since last update={}ms)",<a name="line.1418"></a>
+<span class="sourceLineNo">1419</span>              serverName, regionNode, diff);<a name="line.1419"></a>
+<span class="sourceLineNo">1420</span>          }<a name="line.1420"></a>
+<span class="sourceLineNo">1421</span>        }<a name="line.1421"></a>
+<span class="sourceLineNo">1422</span>      } finally {<a name="line.1422"></a>
+<span class="sourceLineNo">1423</span>        regionNode.unlock();<a name="line.1423"></a>
+<span class="sourceLineNo">1424</span>      }<a name="line.1424"></a>
+<span class="sourceLineNo">1425</span>    }<a name="line.1425"></a>
+<span class="sourceLineNo">1426</span>  }<a name="line.1426"></a>
+<span class="sourceLineNo">1427</span><a name="line.1427"></a>
+<span class="sourceLineNo">1428</span>  // ============================================================================================<a name="line.1428"></a>
+<span class="sourceLineNo">1429</span>  // RIT chore<a name="line.1429"></a>
 <span class="sourceLineNo">1430</span>  // ============================================================================================<a name="line.1430"></a>
-<span class="sourceLineNo">1431</span>  // RIT chore<a name="line.1431"></a>
-<span class="sourceLineNo">1432</span>  // ============================================================================================<a name="line.1432"></a>
-<span class="sourceLineNo">1433</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1433"></a>
-<span class="sourceLineNo">1434</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1434"></a>
-<span class="sourceLineNo">1435</span>      super(timeoutMsec);<a name="line.1435"></a>
-<span class="sourceLineNo">1436</span>    }<a name="line.1436"></a>
-<span class="sourceLineNo">1437</span><a name="line.1437"></a>
-<span class="sourceLineNo">1438</span>    @Override<a name="line.1438"></a>
-<span class="sourceLineNo">1439</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1439"></a>
-<span class="sourceLineNo">1440</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1440"></a>
-<span class="sourceLineNo">1441</span><a name="line.1441"></a>
-<span class="sourceLineNo">1442</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1442"></a>
-<span class="sourceLineNo">1443</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1443"></a>
-<span class="sourceLineNo">1444</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1444"></a>
-<span class="sourceLineNo">1445</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1445"></a>
-<span class="sourceLineNo">1446</span>        }<a name="line.1446"></a>
-<span class="sourceLineNo">1447</span>      }<a name="line.1447"></a>
-<span class="sourceLineNo">1448</span><a name="line.1448"></a>
-<span class="sourceLineNo">1449</span>      // update metrics<a name="line.1449"></a>
-<span class="sourceLineNo">1450</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1450"></a>
-<span class="sourceLineNo">1451</span>    }<a name="line.1451"></a>
-<span class="sourceLineNo">1452</span>  }<a name="line.1452"></a>
-<span class="sourceLineNo">1453</span><a name="line.1453"></a>
-<span class="sourceLineNo">1454</span>  private static class DeadServerMetricRegionChore<a name="line.1454"></a>
-<span class="sourceLineNo">1455</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1455"></a>
-<span class="sourceLineNo">1456</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1456"></a>
-<span class="sourceLineNo">1457</span>      super(timeoutMsec);<a name="line.1457"></a>
-<span class="sourceLineNo">1458</span>    }<a name="line.1458"></a>
-<span class="sourceLineNo">1459</span><a name="line.1459"></a>
-<span class="sourceLineNo">1460</span>    @Override<a name="line.1460"></a>
-<span class="sourceLineNo">1461</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1461"></a>
-<span class="sourceLineNo">1462</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1462"></a>
-<span class="sourceLineNo">1463</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1463"></a>
-<span class="sourceLineNo">1464</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1464"></a>
-<span class="sourceLineNo">1465</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1465"></a>
-<span class="sourceLineNo">1466</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1466"></a>
-<span class="sourceLineNo">1467</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1467"></a>
-<span class="sourceLineNo">1468</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1468"></a>
-<span class="sourceLineNo">1469</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1469"></a>
-<span class="sourceLineNo">1470</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1470"></a>
-<span class="sourceLineNo">1471</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1471"></a>
-<span class="sourceLineNo">1472</span>        if (rsn.getState() != State.OPEN) {<a name="line.1472"></a>
-<span class="sourceLineNo">1473</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1473"></a>
-<span class="sourceLineNo">1474</span>        }<a name="line.1474"></a>
-<span class="sourceLineNo">1475</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1475"></a>
-<span class="sourceLineNo">1476</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1476"></a>
-<span class="sourceLineNo">1477</span>        State state = rsn.getState();<a name="line.1477"></a>
-<span class="sourceLineNo">1478</span>        if (state != State.OPEN) {<a name="line.1478"></a>
-<span class="sourceLineNo">1479</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1479"></a>
-<span class="sourceLineNo">1480</span>        }<a name="line.1480"></a>
-<span class="sourceLineNo">1481</span>        if (sn == null) {<a name="line.1481"></a>
-<span class="sourceLineNo">1482</span>          ++unknownRegions; // Opened on null?<a name="line.1482"></a>
-<span class="sourceLineNo">1483</span>          continue;<a name="line.1483"></a>
-<span class="sourceLineNo">1484</span>        }<a name="line.1484"></a>
-<span class="sourceLineNo">1485</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1485"></a>
-<span class="sourceLineNo">1486</span>          continue;<a name="line.1486"></a>
-<span class="sourceLineNo">1487</span>        }<a name="line.1487"></a>
-<span class="sourceLineNo">1488</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1488"></a>
-<span class="sourceLineNo">1489</span>        switch (sls) {<a name="line.1489"></a>
-<span class="sourceLineNo">1490</span>          case LIVE:<a name="line.1490"></a>
-<span class="sourceLineNo">1491</span>            recentlyLiveServers.add(sn);<a name="line.1491"></a>
-<span class="sourceLineNo">1492</span>            break;<a name="line.1492"></a>
-<span class="sourceLineNo">1493</span>          case DEAD:<a name="line.1493"></a>
-<span class="sourceLineNo">1494</span>            ++deadRegions;<a name="line.1494"></a>
-<span class="sourceLineNo">1495</span>            break;<a name="line.1495"></a>
-<span class="sourceLineNo">1496</span>          case UNKNOWN:<a name="line.1496"></a>
-<span class="sourceLineNo">1497</span>            ++unknownRegions;<a name="line.1497"></a>
-<span class="sourceLineNo">1498</span>            break;<a name="line.1498"></a>
-<span class="sourceLineNo">1499</span>          default:<a name="line.1499"></a>
-<span class="sourceLineNo">1500</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1500"></a>
-<span class="sourceLineNo">1501</span>        }<a name="line.1501"></a>
-<span class="sourceLineNo">1502</span>      }<a name="line.1502"></a>
-<span class="sourceLineNo">1503</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1503"></a>
-<span class="sourceLineNo">1504</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1504"></a>
-<span class="sourceLineNo">1505</span>          deadRegions, unknownRegions);<a name="line.1505"></a>
-<span class="sourceLineNo">1506</span>      }<a name="line.1506"></a>
-<span class="sourceLineNo">1507</span><a name="line.1507"></a>
-<span class="sourceLineNo">1508</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1508"></a>
-<span class="sourceLineNo">1509</span>    }<a name="line.1509"></a>
-<span class="sourceLineNo">1510</span>  }<a name="line.1510"></a>
-<span class="sourceLineNo">1511</span><a name="line.1511"></a>
-<span class="sourceLineNo">1512</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1512"></a>
-<span class="sourceLineNo">1513</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1513"></a>
-<span class="sourceLineNo">1514</span>    rit.update(this);<a name="line.1514"></a>
-<span class="sourceLineNo">1515</span>    return rit;<a name="line.1515"></a>
-<span class="sourceLineNo">1516</span>  }<a name="line.1516"></a>
-<span class="sourceLineNo">1517</span><a name="line.1517"></a>
-<span class="sourceLineNo">1518</span>  public static class RegionInTransitionStat {<a name="line.1518"></a>
-<span class="sourceLineNo">1519</span>    private final int ritThreshold;<a name="line.1519"></a>
-<span class="sourceLineNo">1520</span><a name="line.1520"></a>
-<span class="sourceLineNo">1521</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1521"></a>
-<span class="sourceLineNo">1522</span>    private long statTimestamp;<a name="line.1522"></a>
-<span class="sourceLineNo">1523</span>    private long oldestRITTime = 0;<a name="line.1523"></a>
-<span class="sourceLineNo">1524</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1524"></a>
-<span class="sourceLineNo">1525</span>    private int totalRITs = 0;<a name="line.1525"></a>
-<span class="sourceLineNo">1526</span><a name="line.1526"></a>
-<span class="sourceLineNo">1527</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1527"></a>
-<span class="sourceLineNo">1528</span>      this.ritThreshold =<a name="line.1528"></a>
-<span class="sourceLineNo">1529</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1529"></a>
-<span class="sourceLineNo">1530</span>    }<a name="line.1530"></a>
-<span class="sourceLineNo">1531</span><a name="line.1531"></a>
-<span class="sourceLineNo">1532</span>    public int getRITThreshold() {<a name="line.1532"></a>
-<span class="sourceLineNo">1533</span>      return ritThreshold;<a name="line.1533"></a>
-<span class="sourceLineNo">1534</span>    }<a name="line.1534"></a>
-<span class="sourceLineNo">1535</span><a name="line.1535"></a>
-<span class="sourceLineNo">1536</span>    public long getTimestamp() {<a name="line.1536"></a>
-<span class="sourceLineNo">1537</span>      return statTimestamp;<a name="line.1537"></a>
-<span class="sourceLineNo">1538</span>    }<a name="line.1538"></a>
-<span class="sourceLineNo">1539</span><a name="line.1539"></a>
-<span class="sourceLineNo">1540</span>    public int getTotalRITs() {<a name="line.1540"></a>
-<span class="sourceLineNo">1541</span>      return totalRITs;<a name="line.1541"></a>
-<span class="sourceLineNo">1542</span>    }<a name="line.1542"></a>
-<span class="sourceLineNo">1543</span><a name="line.1543"></a>
-<span class="sourceLineNo">1544</span>    public long getOldestRITTime() {<a name="line.1544"></a>
-<span class="sourceLineNo">1545</span>      return oldestRITTime;<a name="line.1545"></a>
-<span class="sourceLineNo">1546</span>    }<a name="line.1546"></a>
-<span class="sourceLineNo">1547</span><a name="line.1547"></a>
-<span class="sourceLineNo">1548</span>    public int getTotalRITsOverThreshold() {<a name="line.1548"></a>
-<span class="sourceLineNo">1549</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1549"></a>
-<span class="sourceLineNo">1550</span>      return m != null ? m.size() : 0;<a name="line.1550"></a>
-<span class="sourceLineNo">1551</span>    }<a name="line.1551"></a>
-<span class="sourceLineNo">1552</span><a name="line.1552"></a>
-<span class="sourceLineNo">1553</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1553"></a>
-<span class="sourceLineNo">1554</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1554"></a>
-<span class="sourceLineNo">1555</span>    }<a name="line.1555"></a>
-<span class="sourceLineNo">1556</span><a name="line.1556"></a>
-<span class="sourceLineNo">1557</span>    public boolean hasRegionsOverThreshold() {<a name="line.1557"></a>
-<span class="sourceLineNo">1558</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1558"></a>
-<span class="sourceLineNo">1559</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1559"></a>
-<span class="sourceLineNo">1560</span>    }<a name="line.1560"></a>
-<span class="sourceLineNo">1561</span><a name="line.1561"></a>
-<span class="sourceLineNo">1562</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1562"></a>
-<span class="sourceLineNo">1563</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1563"></a>
-<span class="sourceLineNo">1564</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1564"></a>
-<span class="sourceLineNo">1565</span>    }<a name="line.1565"></a>
-<span class="sourceLineNo">1566</span><a name="line.1566"></a>
-<span class="sourceLineNo">1567</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1567"></a>
-<span class="sourceLineNo">1568</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1568"></a>
-<span class="sourceLineNo">1569</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1569"></a>
-<span class="sourceLineNo">1570</span>    }<a name="line.1570"></a>
-<span class="sourceLineNo">1571</span><a name="line.1571"></a>
-<span class="sourceLineNo">1572</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1572"></a>
-<span class="sourceLineNo">1573</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>      if (m == null) {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>        return false;<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>      }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1577"></a>
-<span class="sourceLineNo">1578</span>      if (state == null) {<a name="line.1578"></a>
-<span class="sourceLineNo">1579</span>        return false;<a name="line.1579"></a>
-<span class="sourceLineNo">1580</span>      }<a name="line.1580"></a>
-<span class="sourceLineNo">1581</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1581"></a>
-<span class="sourceLineNo">1582</span>    }<a name="line.1582"></a>
-<span class="sourceLineNo">1583</span><a name="line.1583"></a>
-<span class="sourceLineNo">1584</span>    protected void update(final AssignmentManager am) {<a name="line.1584"></a>
-<span class="sourceLineNo">1585</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1585"></a>
-<span class="sourceLineNo">1586</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1586"></a>
-<span class="sourceLineNo">1587</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1587"></a>
-<span class="sourceLineNo">1588</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1588"></a>
-<span class="sourceLineNo">1589</span><a name="line.1589"></a>
-<span class="sourceLineNo">1590</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1590"></a>
-<span class="sourceLineNo">1591</span>        LOG.debug("RITs over threshold: {}",<a name="line.1591"></a>
-<span class="sourceLineNo">1592</span>          ritsOverThreshold.entrySet().stream()<a name="line.1592"></a>
-<span class="sourceLineNo">1593</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1593"></a>
-<span class="sourceLineNo">1594</span>            .collect(Collectors.joining("\n")));<a name="line.1594"></a>
-<span class="sourceLineNo">1595</span>      }<a name="line.1595"></a>
-<span class="sourceLineNo">1596</span>    }<a name="line.1596"></a>
-<span class="sourceLineNo">1597</span><a name="line.1597"></a>
-<span class="sourceLineNo">1598</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1598"></a>
-<span class="sourceLineNo">1599</span>      for (RegionState state : regions) {<a name="line.1599"></a>
-<span class="sourceLineNo">1600</span>        totalRITs++;<a name="line.1600"></a>
-<span class="sourceLineNo">1601</span>        final long ritStartedMs = state.getStamp();<a name="line.1601"></a>
-<span class="sourceLineNo">1602</span>        if (ritStartedMs == 0) {<a name="line.1602"></a>
-<span class="sourceLineNo">1603</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1603"></a>
-<span class="sourceLineNo">1604</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1604"></a>
-<span class="sourceLineNo">1605</span>          continue;<a name="line.1605"></a>
-<span class="sourceLineNo">1606</span>        }<a name="line.1606"></a>
-<span class="sourceLineNo">1607</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1607"></a>
-<span class="sourceLineNo">1608</span>        if (ritTime &gt; ritThreshold) {<a name="line.1608"></a>
-<span class="sourceLineNo">1609</span>          if (ritsOverThreshold == null) {<a name="line.1609"></a>
-<span class="sourceLineNo">1610</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1610"></a>
-<span class="sourceLineNo">1611</span>          }<a name="line.1611"></a>
-<span class="sourceLineNo">1612</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1612"></a>
-<span class="sourceLineNo">1613</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1613"></a>
-<span class="sourceLineNo">1614</span>        }<a name="line.1614"></a>
-<span class="sourceLineNo">1615</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1615"></a>
-<span class="sourceLineNo">1616</span>          oldestRITTime = ritTime;<a name="line.1616"></a>
-<span class="sourceLineNo">1617</span>        }<a name="line.1617"></a>
-<span class="sourceLineNo">1618</span>      }<a name="line.1618"></a>
-<span class="sourceLineNo">1619</span>    }<a name="line.1619"></a>
-<span class="sourceLineNo">1620</span>  }<a name="line.1620"></a>
-<span class="sourceLineNo">1621</span><a name="line.1621"></a>
-<span class="sourceLineNo">1622</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1622"></a>
-<span class="sourceLineNo">1623</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1623"></a>
-<span class="sourceLineNo">1624</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1624"></a>
-<span class="sourceLineNo">1625</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1625"></a>
-<span class="sourceLineNo">1626</span>  }<a name="line.1626"></a>
-<span class="sourceLineNo">1627</span><a name="line.1627"></a>
-<span class="sourceLineNo">1628</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1628"></a>
-<span class="sourceLineNo">1629</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1629"></a>
-<span class="sourceLineNo">1630</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1630"></a>
-<span class="sourceLineNo">1631</span>  }<a name="line.1631"></a>
-<span class="sourceLineNo">1632</span><a name="line.1632"></a>
-<span class="sourceLineNo">1633</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1633"></a>
-<span class="sourceLineNo">1634</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1634"></a>
-<span class="sourceLineNo">1635</span>    // if (regionNode.isStuck()) {<a name="line.1635"></a>
-<span class="sourceLineNo">1636</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1636"></a>
-<span class="sourceLineNo">1637</span>  }<a name="line.1637"></a>
-<span class="sourceLineNo">1638</span><a name="line.1638"></a>
+<span class="sourceLineNo">1431</span>  private static class RegionInTransitionChore extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1431"></a>
+<span class="sourceLineNo">1432</span>    public RegionInTransitionChore(final int timeoutMsec) {<a name="line.1432"></a>
+<span class="sourceLineNo">1433</span>      super(timeoutMsec);<a name="line.1433"></a>
+<span class="sourceLineNo">1434</span>    }<a name="line.1434"></a>
+<span class="sourceLineNo">1435</span><a name="line.1435"></a>
+<span class="sourceLineNo">1436</span>    @Override<a name="line.1436"></a>
+<span class="sourceLineNo">1437</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1437"></a>
+<span class="sourceLineNo">1438</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1438"></a>
+<span class="sourceLineNo">1439</span><a name="line.1439"></a>
+<span class="sourceLineNo">1440</span>      final RegionInTransitionStat ritStat = am.computeRegionInTransitionStat();<a name="line.1440"></a>
+<span class="sourceLineNo">1441</span>      if (ritStat.hasRegionsOverThreshold()) {<a name="line.1441"></a>
+<span class="sourceLineNo">1442</span>        for (RegionState hri : ritStat.getRegionOverThreshold()) {<a name="line.1442"></a>
+<span class="sourceLineNo">1443</span>          am.handleRegionOverStuckWarningThreshold(hri.getRegion());<a name="line.1443"></a>
+<span class="sourceLineNo">1444</span>        }<a name="line.1444"></a>
+<span class="sourceLineNo">1445</span>      }<a name="line.1445"></a>
+<span class="sourceLineNo">1446</span><a name="line.1446"></a>
+<span class="sourceLineNo">1447</span>      // update metrics<a name="line.1447"></a>
+<span class="sourceLineNo">1448</span>      am.updateRegionsInTransitionMetrics(ritStat);<a name="line.1448"></a>
+<span class="sourceLineNo">1449</span>    }<a name="line.1449"></a>
+<span class="sourceLineNo">1450</span>  }<a name="line.1450"></a>
+<span class="sourceLineNo">1451</span><a name="line.1451"></a>
+<span class="sourceLineNo">1452</span>  private static class DeadServerMetricRegionChore<a name="line.1452"></a>
+<span class="sourceLineNo">1453</span>    extends ProcedureInMemoryChore&lt;MasterProcedureEnv&gt; {<a name="line.1453"></a>
+<span class="sourceLineNo">1454</span>    public DeadServerMetricRegionChore(final int timeoutMsec) {<a name="line.1454"></a>
+<span class="sourceLineNo">1455</span>      super(timeoutMsec);<a name="line.1455"></a>
+<span class="sourceLineNo">1456</span>    }<a name="line.1456"></a>
+<span class="sourceLineNo">1457</span><a name="line.1457"></a>
+<span class="sourceLineNo">1458</span>    @Override<a name="line.1458"></a>
+<span class="sourceLineNo">1459</span>    protected void periodicExecute(final MasterProcedureEnv env) {<a name="line.1459"></a>
+<span class="sourceLineNo">1460</span>      final ServerManager sm = env.getMasterServices().getServerManager();<a name="line.1460"></a>
+<span class="sourceLineNo">1461</span>      final AssignmentManager am = env.getAssignmentManager();<a name="line.1461"></a>
+<span class="sourceLineNo">1462</span>      // To minimize inconsistencies we are not going to snapshot live servers in advance in case<a name="line.1462"></a>
+<span class="sourceLineNo">1463</span>      // new servers are added; OTOH we don't want to add heavy sync for a consistent view since<a name="line.1463"></a>
+<span class="sourceLineNo">1464</span>      // this is for metrics. Instead, we're going to check each regions as we go; to avoid making<a name="line.1464"></a>
+<span class="sourceLineNo">1465</span>      // too many checks, we maintain a local lists of server, limiting us to false negatives. If<a name="line.1465"></a>
+<span class="sourceLineNo">1466</span>      // we miss some recently-dead server, we'll just see it next time.<a name="line.1466"></a>
+<span class="sourceLineNo">1467</span>      Set&lt;ServerName&gt; recentlyLiveServers = new HashSet&lt;&gt;();<a name="line.1467"></a>
+<span class="sourceLineNo">1468</span>      int deadRegions = 0, unknownRegions = 0;<a name="line.1468"></a>
+<span class="sourceLineNo">1469</span>      for (RegionStateNode rsn : am.getRegionStates().getRegionStateNodes()) {<a name="line.1469"></a>
+<span class="sourceLineNo">1470</span>        if (rsn.getState() != State.OPEN) {<a name="line.1470"></a>
+<span class="sourceLineNo">1471</span>          continue; // Opportunistic check, should quickly skip RITs, offline tables, etc.<a name="line.1471"></a>
+<span class="sourceLineNo">1472</span>        }<a name="line.1472"></a>
+<span class="sourceLineNo">1473</span>        // Do not need to acquire region state lock as this is only for showing metrics.<a name="line.1473"></a>
+<span class="sourceLineNo">1474</span>        ServerName sn = rsn.getRegionLocation();<a name="line.1474"></a>
+<span class="sourceLineNo">1475</span>        State state = rsn.getState();<a name="line.1475"></a>
+<span class="sourceLineNo">1476</span>        if (state != State.OPEN) {<a name="line.1476"></a>
+<span class="sourceLineNo">1477</span>          continue; // Mostly skipping RITs that are already being take care of.<a name="line.1477"></a>
+<span class="sourceLineNo">1478</span>        }<a name="line.1478"></a>
+<span class="sourceLineNo">1479</span>        if (sn == null) {<a name="line.1479"></a>
+<span class="sourceLineNo">1480</span>          ++unknownRegions; // Opened on null?<a name="line.1480"></a>
+<span class="sourceLineNo">1481</span>          continue;<a name="line.1481"></a>
+<span class="sourceLineNo">1482</span>        }<a name="line.1482"></a>
+<span class="sourceLineNo">1483</span>        if (recentlyLiveServers.contains(sn)) {<a name="line.1483"></a>
+<span class="sourceLineNo">1484</span>          continue;<a name="line.1484"></a>
+<span class="sourceLineNo">1485</span>        }<a name="line.1485"></a>
+<span class="sourceLineNo">1486</span>        ServerManager.ServerLiveState sls = sm.isServerKnownAndOnline(sn);<a name="line.1486"></a>
+<span class="sourceLineNo">1487</span>        switch (sls) {<a name="line.1487"></a>
+<span class="sourceLineNo">1488</span>          case LIVE:<a name="line.1488"></a>
+<span class="sourceLineNo">1489</span>            recentlyLiveServers.add(sn);<a name="line.1489"></a>
+<span class="sourceLineNo">1490</span>            break;<a name="line.1490"></a>
+<span class="sourceLineNo">1491</span>          case DEAD:<a name="line.1491"></a>
+<span class="sourceLineNo">1492</span>            ++deadRegions;<a name="line.1492"></a>
+<span class="sourceLineNo">1493</span>            break;<a name="line.1493"></a>
+<span class="sourceLineNo">1494</span>          case UNKNOWN:<a name="line.1494"></a>
+<span class="sourceLineNo">1495</span>            ++unknownRegions;<a name="line.1495"></a>
+<span class="sourceLineNo">1496</span>            break;<a name="line.1496"></a>
+<span class="sourceLineNo">1497</span>          default:<a name="line.1497"></a>
+<span class="sourceLineNo">1498</span>            throw new AssertionError("Unexpected " + sls);<a name="line.1498"></a>
+<span class="sourceLineNo">1499</span>        }<a name="line.1499"></a>
+<span class="sourceLineNo">1500</span>      }<a name="line.1500"></a>
+<span class="sourceLineNo">1501</span>      if (deadRegions &gt; 0 || unknownRegions &gt; 0) {<a name="line.1501"></a>
+<span class="sourceLineNo">1502</span>        LOG.info("Found {} OPEN regions on dead servers and {} OPEN regions on unknown servers",<a name="line.1502"></a>
+<span class="sourceLineNo">1503</span>          deadRegions, unknownRegions);<a name="line.1503"></a>
+<span class="sourceLineNo">1504</span>      }<a name="line.1504"></a>
+<span class="sourceLineNo">1505</span><a name="line.1505"></a>
+<span class="sourceLineNo">1506</span>      am.updateDeadServerRegionMetrics(deadRegions, unknownRegions);<a name="line.1506"></a>
+<span class="sourceLineNo">1507</span>    }<a name="line.1507"></a>
+<span class="sourceLineNo">1508</span>  }<a name="line.1508"></a>
+<span class="sourceLineNo">1509</span><a name="line.1509"></a>
+<span class="sourceLineNo">1510</span>  public RegionInTransitionStat computeRegionInTransitionStat() {<a name="line.1510"></a>
+<span class="sourceLineNo">1511</span>    final RegionInTransitionStat rit = new RegionInTransitionStat(getConfiguration());<a name="line.1511"></a>
+<span class="sourceLineNo">1512</span>    rit.update(this);<a name="line.1512"></a>
+<span class="sourceLineNo">1513</span>    return rit;<a name="line.1513"></a>
+<span class="sourceLineNo">1514</span>  }<a name="line.1514"></a>
+<span class="sourceLineNo">1515</span><a name="line.1515"></a>
+<span class="sourceLineNo">1516</span>  public static class RegionInTransitionStat {<a name="line.1516"></a>
+<span class="sourceLineNo">1517</span>    private final int ritThreshold;<a name="line.1517"></a>
+<span class="sourceLineNo">1518</span><a name="line.1518"></a>
+<span class="sourceLineNo">1519</span>    private HashMap&lt;String, RegionState&gt; ritsOverThreshold = null;<a name="line.1519"></a>
+<span class="sourceLineNo">1520</span>    private long statTimestamp;<a name="line.1520"></a>
+<span class="sourceLineNo">1521</span>    private long oldestRITTime = 0;<a name="line.1521"></a>
+<span class="sourceLineNo">1522</span>    private int totalRITsTwiceThreshold = 0;<a name="line.1522"></a>
+<span class="sourceLineNo">1523</span>    private int totalRITs = 0;<a name="line.1523"></a>
+<span class="sourceLineNo">1524</span><a name="line.1524"></a>
+<span class="sourceLineNo">1525</span>    public RegionInTransitionStat(final Configuration conf) {<a name="line.1525"></a>
+<span class="sourceLineNo">1526</span>      this.ritThreshold =<a name="line.1526"></a>
+<span class="sourceLineNo">1527</span>        conf.getInt(METRICS_RIT_STUCK_WARNING_THRESHOLD, DEFAULT_RIT_STUCK_WARNING_THRESHOLD);<a name="line.1527"></a>
+<span class="sourceLineNo">1528</span>    }<a name="line.1528"></a>
+<span class="sourceLineNo">1529</span><a name="line.1529"></a>
+<span class="sourceLineNo">1530</span>    public int getRITThreshold() {<a name="line.1530"></a>
+<span class="sourceLineNo">1531</span>      return ritThreshold;<a name="line.1531"></a>
+<span class="sourceLineNo">1532</span>    }<a name="line.1532"></a>
+<span class="sourceLineNo">1533</span><a name="line.1533"></a>
+<span class="sourceLineNo">1534</span>    public long getTimestamp() {<a name="line.1534"></a>
+<span class="sourceLineNo">1535</span>      return statTimestamp;<a name="line.1535"></a>
+<span class="sourceLineNo">1536</span>    }<a name="line.1536"></a>
+<span class="sourceLineNo">1537</span><a name="line.1537"></a>
+<span class="sourceLineNo">1538</span>    public int getTotalRITs() {<a name="line.1538"></a>
+<span class="sourceLineNo">1539</span>      return totalRITs;<a name="line.1539"></a>
+<span class="sourceLineNo">1540</span>    }<a name="line.1540"></a>
+<span class="sourceLineNo">1541</span><a name="line.1541"></a>
+<span class="sourceLineNo">1542</span>    public long getOldestRITTime() {<a name="line.1542"></a>
+<span class="sourceLineNo">1543</span>      return oldestRITTime;<a name="line.1543"></a>
+<span class="sourceLineNo">1544</span>    }<a name="line.1544"></a>
+<span class="sourceLineNo">1545</span><a name="line.1545"></a>
+<span class="sourceLineNo">1546</span>    public int getTotalRITsOverThreshold() {<a name="line.1546"></a>
+<span class="sourceLineNo">1547</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1547"></a>
+<span class="sourceLineNo">1548</span>      return m != null ? m.size() : 0;<a name="line.1548"></a>
+<span class="sourceLineNo">1549</span>    }<a name="line.1549"></a>
+<span class="sourceLineNo">1550</span><a name="line.1550"></a>
+<span class="sourceLineNo">1551</span>    public boolean hasRegionsTwiceOverThreshold() {<a name="line.1551"></a>
+<span class="sourceLineNo">1552</span>      return totalRITsTwiceThreshold &gt; 0;<a name="line.1552"></a>
+<span class="sourceLineNo">1553</span>    }<a name="line.1553"></a>
+<span class="sourceLineNo">1554</span><a name="line.1554"></a>
+<span class="sourceLineNo">1555</span>    public boolean hasRegionsOverThreshold() {<a name="line.1555"></a>
+<span class="sourceLineNo">1556</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1556"></a>
+<span class="sourceLineNo">1557</span>      return m != null &amp;&amp; !m.isEmpty();<a name="line.1557"></a>
+<span class="sourceLineNo">1558</span>    }<a name="line.1558"></a>
+<span class="sourceLineNo">1559</span><a name="line.1559"></a>
+<span class="sourceLineNo">1560</span>    public Collection&lt;RegionState&gt; getRegionOverThreshold() {<a name="line.1560"></a>
+<span class="sourceLineNo">1561</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1561"></a>
+<span class="sourceLineNo">1562</span>      return m != null ? m.values() : Collections.emptySet();<a name="line.1562"></a>
+<span class="sourceLineNo">1563</span>    }<a name="line.1563"></a>
+<span class="sourceLineNo">1564</span><a name="line.1564"></a>
+<span class="sourceLineNo">1565</span>    public boolean isRegionOverThreshold(final RegionInfo regionInfo) {<a name="line.1565"></a>
+<span class="sourceLineNo">1566</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1566"></a>
+<span class="sourceLineNo">1567</span>      return m != null &amp;&amp; m.containsKey(regionInfo.getEncodedName());<a name="line.1567"></a>
+<span class="sourceLineNo">1568</span>    }<a name="line.1568"></a>
+<span class="sourceLineNo">1569</span><a name="line.1569"></a>
+<span class="sourceLineNo">1570</span>    public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {<a name="line.1570"></a>
+<span class="sourceLineNo">1571</span>      Map&lt;String, RegionState&gt; m = this.ritsOverThreshold;<a name="line.1571"></a>
+<span class="sourceLineNo">1572</span>      if (m == null) {<a name="line.1572"></a>
+<span class="sourceLineNo">1573</span>        return false;<a name="line.1573"></a>
+<span class="sourceLineNo">1574</span>      }<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>      final RegionState state = m.get(regionInfo.getEncodedName());<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>      if (state == null) {<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>        return false;<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>      }<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>      return (statTimestamp - state.getStamp()) &gt; (ritThreshold * 2);<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>    }<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span><a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>    protected void update(final AssignmentManager am) {<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>      final RegionStates regionStates = am.getRegionStates();<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span>      this.statTimestamp = EnvironmentEdgeManager.currentTime();<a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>      update(regionStates.getRegionsStateInTransition(), statTimestamp);<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>      update(regionStates.getRegionFailedOpen(), statTimestamp);<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span><a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>      if (LOG.isDebugEnabled() &amp;&amp; ritsOverThreshold != null &amp;&amp; !ritsOverThreshold.isEmpty()) {<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span>        LOG.debug("RITs over threshold: {}",<a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>          ritsOverThreshold.entrySet().stream()<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>            .map(e -&gt; e.getKey() + ":" + e.getValue().getState().name())<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>            .collect(Collectors.joining("\n")));<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>      }<a name="line.1593"></a>
+<span class="sourceLineNo">1594</span>    }<a name="line.1594"></a>
+<span class="sourceLineNo">1595</span><a name="line.1595"></a>
+<span class="sourceLineNo">1596</span>    private void update(final Collection&lt;RegionState&gt; regions, final long currentTime) {<a name="line.1596"></a>
+<span class="sourceLineNo">1597</span>      for (RegionState state : regions) {<a name="line.1597"></a>
+<span class="sourceLineNo">1598</span>        totalRITs++;<a name="line.1598"></a>
+<span class="sourceLineNo">1599</span>        final long ritStartedMs = state.getStamp();<a name="line.1599"></a>
+<span class="sourceLineNo">1600</span>        if (ritStartedMs == 0) {<a name="line.1600"></a>
+<span class="sourceLineNo">1601</span>          // Don't output bogus values to metrics if they accidentally make it here.<a name="line.1601"></a>
+<span class="sourceLineNo">1602</span>          LOG.warn("The RIT {} has no start time", state.getRegion());<a name="line.1602"></a>
+<span class="sourceLineNo">1603</span>          continue;<a name="line.1603"></a>
+<span class="sourceLineNo">1604</span>        }<a name="line.1604"></a>
+<span class="sourceLineNo">1605</span>        final long ritTime = currentTime - ritStartedMs;<a name="line.1605"></a>
+<span class="sourceLineNo">1606</span>        if (ritTime &gt; ritThreshold) {<a name="line.1606"></a>
+<span class="sourceLineNo">1607</span>          if (ritsOverThreshold == null) {<a name="line.1607"></a>
+<span class="sourceLineNo">1608</span>            ritsOverThreshold = new HashMap&lt;String, RegionState&gt;();<a name="line.1608"></a>
+<span class="sourceLineNo">1609</span>          }<a name="line.1609"></a>
+<span class="sourceLineNo">1610</span>          ritsOverThreshold.put(state.getRegion().getEncodedName(), state);<a name="line.1610"></a>
+<span class="sourceLineNo">1611</span>          totalRITsTwiceThreshold += (ritTime &gt; (ritThreshold * 2)) ? 1 : 0;<a name="line.1611"></a>
+<span class="sourceLineNo">1612</span>        }<a name="line.1612"></a>
+<span class="sourceLineNo">1613</span>        if (oldestRITTime &lt; ritTime) {<a name="line.1613"></a>
+<span class="sourceLineNo">1614</span>          oldestRITTime = ritTime;<a name="line.1614"></a>
+<span class="sourceLineNo">1615</span>        }<a name="line.1615"></a>
+<span class="sourceLineNo">1616</span>      }<a name="line.1616"></a>
+<span class="sourceLineNo">1617</span>    }<a name="line.1617"></a>
+<span class="sourceLineNo">1618</span>  }<a name="line.1618"></a>
+<span class="sourceLineNo">1619</span><a name="line.1619"></a>
+<span class="sourceLineNo">1620</span>  private void updateRegionsInTransitionMetrics(final RegionInTransitionStat ritStat) {<a name="line.1620"></a>
+<span class="sourceLineNo">1621</span>    metrics.updateRITOldestAge(ritStat.getOldestRITTime());<a name="line.1621"></a>
+<span class="sourceLineNo">1622</span>    metrics.updateRITCount(ritStat.getTotalRITs());<a name="line.1622"></a>
+<span class="sourceLineNo">1623</span>    metrics.updateRITCountOverThreshold(ritStat.getTotalRITsOverThreshold());<a name="line.1623"></a>
+<span class="sourceLineNo">1624</span>  }<a name="line.1624"></a>
+<span class="sourceLineNo">1625</span><a name="line.1625"></a>
+<span class="sourceLineNo">1626</span>  private void updateDeadServerRegionMetrics(int deadRegions, int unknownRegions) {<a name="line.1626"></a>
+<span class="sourceLineNo">1627</span>    metrics.updateDeadServerOpenRegions(deadRegions);<a name="line.1627"></a>
+<span class="sourceLineNo">1628</span>    metrics.updateUnknownServerOpenRegions(unknownRegions);<a name="line.1628"></a>
+<span class="sourceLineNo">1629</span>  }<a name="line.1629"></a>
+<span class="sourceLineNo">1630</span><a name="line.1630"></a>
+<span class="sourceLineNo">1631</span>  private void handleRegionOverStuckWarningThreshold(final RegionInfo regionInfo) {<a name="line.1631"></a>
+<span class="sourceLineNo">1632</span>    final RegionStateNode regionNode = regionStates.getRegionStateNode(regionInfo);<a name="line.1632"></a>
+<span class="sourceLineNo">1633</span>    // if (regionNode.isStuck()) {<a name="line.1633"></a>
+<span class="sourceLineNo">1634</span>    LOG.warn("STUCK Region-In-Transition {}", regionNode);<a name="line.1634"></a>
+<span class="sourceLineNo">1635</span>  }<a name="line.1635"></a>
+<span class="sourceLineNo">1636</span><a name="line.1636"></a>
+<span class="sourceLineNo">1637</span>  // ============================================================================================<a name="line.1637"></a>
+<span class="sourceLineNo">1638</span>  // TODO: Master load/bootstrap<a name="line.1638"></a>
 <span class="sourceLineNo">1639</span>  // ============================================================================================<a name="line.1639"></a>
-<span class="sourceLineNo">1640</span>  // TODO: Master load/bootstrap<a name="line.1640"></a>
-<span class="sourceLineNo">1641</span>  // ============================================================================================<a name="line.1641"></a>
-<span class="sourceLineNo">1642</span>  public void joinCluster() throws IOException {<a name="line.1642"></a>
-<span class="sourceLineNo">1643</span>    long startTime = System.nanoTime();<a name="line.1643"></a>
-<span class="sourceLineNo">1644</span>    LOG.debug("Joining cluster...");<a name="line.1644"></a>
-<span class="sourceLineNo">1645</span><a name="line.1645"></a>
-<span class="sourceLineNo">1646</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1646"></a>
-<span class="sourceLineNo">1647</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1647"></a>
-<span class="sourceLineNo">1648</span>    // w/o meta.<a name="line.1648"></a>
-<span class="sourceLineNo">1649</span>    loadMeta();<a name="line.1649"></a>
-<span class="sourceLineNo">1650</span><a name="line.1650"></a>
-<span class="sourceLineNo">1651</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1651"></a>
-<span class="sourceLineNo">1652</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1652"></a>
-<span class="sourceLineNo">1653</span>        master.getServerManager().countOfRegionServers());<a name="line.1653"></a>
-<span class="sourceLineNo">1654</span>      Threads.sleep(250);<a name="line.1654"></a>
-<span class="sourceLineNo">1655</span>    }<a name="line.1655"></a>
-<span class="sourceLineNo">1656</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1656"></a>
-<span class="sourceLineNo">1657</span><a name="line.1657"></a>
-<span class="sourceLineNo">1658</span>    // Start the chores<a name="line.1658"></a>
-<span class="sourceLineNo">1659</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1659"></a>
-<span class="sourceLineNo">1660</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1660"></a>
-<span class="sourceLineNo">1661</span><a name="line.1661"></a>
-<span class="sourceLineNo">1662</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1662"></a>
-<span class="sourceLineNo">1663</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1663"></a>
-<span class="sourceLineNo">1664</span>  }<a name="line.1664"></a>
-<span class="sourceLineNo">1665</span><a name="line.1665"></a>
-<span class="sourceLineNo">1666</span>  /**<a name="line.1666"></a>
-<span class="sourceLineNo">1667</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1667"></a>
-<span class="sourceLineNo">1668</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1668"></a>
-<span class="sourceLineNo">1669</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1669"></a>
-<span class="sourceLineNo">1670</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1670"></a>
-<span class="sourceLineNo">1671</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1671"></a>
-<span class="sourceLineNo">1672</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1672"></a>
-<span class="sourceLineNo">1673</span>   * method any more. Need to revisit later.<a name="line.1673"></a>
-<span class="sourceLineNo">1674</span>   */<a name="line.1674"></a>
-<span class="sourceLineNo">1675</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1675"></a>
-<span class="sourceLineNo">1676</span>  // Needs to be done after the table state manager has been started.<a name="line.1676"></a>
-<span class="sourceLineNo">1677</span>  public void processOfflineRegions() {<a name="line.1677"></a>
-<span class="sourceLineNo">1678</span>    TransitRegionStateProcedure[] procs =<a name="line.1678"></a>
-<span class="sourceLineNo">1679</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1679"></a>
-<span class="sourceLineNo">1680</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1680"></a>
-<span class="sourceLineNo">1681</span>          rsn.lock();<a name="line.1681"></a>
-<span class="sourceLineNo">1682</span>          try {<a name="line.1682"></a>
-<span class="sourceLineNo">1683</span>            if (rsn.getProcedure() != null) {<a name="line.1683"></a>
-<span class="sourceLineNo">1684</span>              return null;<a name="line.1684"></a>
-<span class="sourceLineNo">1685</span>            } else {<a name="line.1685"></a>
-<span class="sourceLineNo">1686</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1686"></a>
-<span class="sourceLineNo">1687</span>                rsn.getRegionInfo(), null));<a name="line.1687"></a>
-<span class="sourceLineNo">1688</span>            }<a name="line.1688"></a>
-<span class="sourceLineNo">1689</span>          } finally {<a name="line.1689"></a>
-<span class="sourceLineNo">1690</span>            rsn.unlock();<a name="line.1690"></a>
-<span class="sourceLineNo">1691</span>          }<a name="line.1691"></a>
-<span class="sourceLineNo">1692</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1692"></a>
-<span class="sourceLineNo">1693</span>    if (procs.length &gt; 0) {<a name="line.1693"></a>
-<span class="sourceLineNo">1694</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1694"></a>
-<span class="sourceLineNo">1695</span>    }<a name="line.1695"></a>
-<span class="sourceLineNo">1696</span>  }<a name="line.1696"></a>
-<span class="sourceLineNo">1697</span><a name="line.1697"></a>
-<span class="sourceLineNo">1698</span>  /*<a name="line.1698"></a>
-<span class="sourceLineNo">1699</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1699"></a>
-<span class="sourceLineNo">1700</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1700"></a>
-<span class="sourceLineNo">1701</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1701"></a>
-<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1702"></a>
-<span class="sourceLineNo">1703</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1703"></a>
-<span class="sourceLineNo">1704</span>   * AssignmentManager.regionStates.<a name="line.1704"></a>
-<span class="sourceLineNo">1705</span>   */<a name="line.1705"></a>
-<span class="sourceLineNo">1706</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1706"></a>
-<span class="sourceLineNo">1707</span><a name="line.1707"></a>
-<span class="sourceLineNo">1708</span>    @Override<a name="line.1708"></a>
-<span class="sourceLineNo">1709</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1709"></a>
-<span class="sourceLineNo">1710</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1710"></a>
-<span class="sourceLineNo">1711</span>      if (<a name="line.1711"></a>
-<span class="sourceLineNo">1712</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1712"></a>
-<span class="sourceLineNo">1713</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1713"></a>
-<span class="sourceLineNo">1714</span>      ) {<a name="line.1714"></a>
-<span class="sourceLineNo">1715</span>        // This is a row with nothing in it.<a name="line.1715"></a>
-<span class="sourceLineNo">1716</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1716"></a>
-<span class="sourceLineNo">1717</span>        return;<a name="line.1717"></a>
-<span class="sourceLineNo">1718</span>      }<a name="line.1718"></a>
-<span class="sourceLineNo">1719</span>      State localState = state;<a name="line.1719"></a>
-<span class="sourceLineNo">1720</span>      if (localState == null) {<a name="line.1720"></a>
-<span class="sourceLineNo">1721</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1721"></a>
-<span class="sourceLineNo">1722</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1722"></a>
-<span class="sourceLineNo">1723</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1723"></a>
-<span class="sourceLineNo">1724</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1724"></a>
-<span class="sourceLineNo">1725</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1725"></a>
-<span class="sourceLineNo">1726</span>        localState = State.OFFLINE;<a name="line.1726"></a>
-<span class="sourceLineNo">1727</span>      }<a name="line.1727"></a>
-<span class="sourceLineNo">1728</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1728"></a>
-<span class="sourceLineNo">1729</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1729"></a>
-<span class="sourceLineNo">1730</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1730"></a>
-<span class="sourceLineNo">1731</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1731"></a>
-<span class="sourceLineNo">1732</span>      regionNode.setState(localState);<a name="line.1732"></a>
-<span class="sourceLineNo">1733</span>      regionNode.setLastHost(lastHost);<a name="line.1733"></a>
-<span class="sourceLineNo">1734</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1734"></a>
-<span class="sourceLineNo">1735</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1735"></a>
-<span class="sourceLineNo">1736</span><a name="line.1736"></a>
-<span class="sourceLineNo">1737</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1737"></a>
-<span class="sourceLineNo">1738</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1738"></a>
-<span class="sourceLineNo">1739</span>      if (<a name="line.1739"></a>
-<span class="sourceLineNo">1740</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1740"></a>
-<span class="sourceLineNo">1741</span>      ) {<a name="line.1741"></a>
-<span class="sourceLineNo">1742</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1742"></a>
-<span class="sourceLineNo">1743</span>        regionStates.addRegionToServer(regionNode);<a name="line.1743"></a>
-<span class="sourceLineNo">1744</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1744"></a>
-<span class="sourceLineNo">1745</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1745"></a>
-<span class="sourceLineNo">1746</span>      }<a name="line.1746"></a>
-<span class="sourceLineNo">1747</span>      if (regionNode.getProcedure() != null) {<a name="line.1747"></a>
-<span class="sourceLineNo">1748</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1748"></a>
-<span class="sourceLineNo">1749</span>      }<a name="line.1749"></a>
-<span class="sourceLineNo">1750</span>    }<a name="line.1750"></a>
-<span class="sourceLineNo">1751</span>  };<a name="line.1751"></a>
-<span class="sourceLineNo">1752</span><a name="line.1752"></a>
-<span class="sourceLineNo">1753</span>  /**<a name="line.1753"></a>
-<span class="sourceLineNo">1754</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1754"></a>
-<span class="sourceLineNo">1755</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1755"></a>
-<span class="sourceLineNo">1756</span>   * @param regionInfo the region to be loaded from META.<a name="line.1756"></a>
-<span class="sourceLineNo">1757</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1757"></a>
-<span class="sourceLineNo">1758</span>   */<a name="line.1758"></a>
-<span class="sourceLineNo">1759</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1759"></a>
-<span class="sourceLineNo">1760</span>    throws IOException {<a name="line.1760"></a>
-<span class="sourceLineNo">1761</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1761"></a>
-<span class="sourceLineNo">1762</span>      ? regionInfo.getEncodedName()<a name="line.1762"></a>
-<span class="sourceLineNo">1763</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1763"></a>
-<span class="sourceLineNo">1764</span>        .getEncodedName();<a name="line.1764"></a>
-<span class="sourceLineNo">1765</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1765"></a>
-<span class="sourceLineNo">1766</span>  }<a name="line.1766"></a>
-<span class="sourceLineNo">1767</span><a name="line.1767"></a>
-<span class="sourceLineNo">1768</span>  /**<a name="line.1768"></a>
-<span class="sourceLineNo">1769</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1769"></a>
-<span class="sourceLineNo">1770</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1770"></a>
-<span class="sourceLineNo">1771</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1771"></a>
-<span class="sourceLineNo">1772</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1772"></a>
-<span class="sourceLineNo">1773</span>   */<a name="line.1773"></a>
-<span class="sourceLineNo">1774</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1774"></a>
-<span class="sourceLineNo">1775</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1775"></a>
-<span class="sourceLineNo">1776</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1776"></a>
-<span class="sourceLineNo">1777</span>  }<a name="line.1777"></a>
-<span class="sourceLineNo">1778</span><a name="line.1778"></a>
-<span class="sourceLineNo">1779</span>  private void loadMeta() throws IOException {<a name="line.1779"></a>
-<span class="sourceLineNo">1780</span>    // TODO: use a thread pool<a name="line.1780"></a>
-<span class="sourceLineNo">1781</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1781"></a>
-<span class="sourceLineNo">1782</span>  }<a name="line.1782"></a>
-<span class="sourceLineNo">1783</span><a name="line.1783"></a>
-<span class="sourceLineNo">1784</span>  /**<a name="line.1784"></a>
-<span class="sourceLineNo">1785</span>   * Used to check if the meta loading is done.<a name="line.1785"></a>
-<span class="sourceLineNo">1786</span>   * &lt;p/&gt;<a name="line.1786"></a>
-<span class="sourceLineNo">1787</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1787"></a>
-<span class="sourceLineNo">1788</span>   * @param hri region to check if it is already rebuild<a name="line.1788"></a>
-<span class="sourceLineNo">1789</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1789"></a>
-<span class="sourceLineNo">1790</span>   */<a name="line.1790"></a>
-<span class="sourceLineNo">1791</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1791"></a>
-<span class="sourceLineNo">1792</span>    if (!isRunning()) {<a name="line.1792"></a>
-<span class="sourceLineNo">1793</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1793"></a>
-<span class="sourceLineNo">1794</span>    }<a name="line.1794"></a>
-<span class="sourceLineNo">1795</span>    boolean meta = isMetaRegion(hri);<a name="line.1795"></a>
-<span class="sourceLineNo">1796</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1796"></a>
-<span class="sourceLineNo">1797</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1797"></a>
-<span class="sourceLineNo">1798</span>      throw new PleaseHoldException(<a name="line.1798"></a>
-<span class="sourceLineNo">1799</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1799"></a>
-<span class="sourceLineNo">1800</span>    }<a name="line.1800"></a>
-<span class="sourceLineNo">1801</span>  }<a name="line.1801"></a>
-<span class="sourceLineNo">1802</span><a name="line.1802"></a>
+<span class="sourceLineNo">1640</span>  public void joinCluster() throws IOException {<a name="line.1640"></a>
+<span class="sourceLineNo">1641</span>    long startTime = System.nanoTime();<a name="line.1641"></a>
+<span class="sourceLineNo">1642</span>    LOG.debug("Joining cluster...");<a name="line.1642"></a>
+<span class="sourceLineNo">1643</span><a name="line.1643"></a>
+<span class="sourceLineNo">1644</span>    // Scan hbase:meta to build list of existing regions, servers, and assignment.<a name="line.1644"></a>
+<span class="sourceLineNo">1645</span>    // hbase:meta is online now or will be. Inside loadMeta, we keep trying. Can't make progress<a name="line.1645"></a>
+<span class="sourceLineNo">1646</span>    // w/o meta.<a name="line.1646"></a>
+<span class="sourceLineNo">1647</span>    loadMeta();<a name="line.1647"></a>
+<span class="sourceLineNo">1648</span><a name="line.1648"></a>
+<span class="sourceLineNo">1649</span>    while (master.getServerManager().countOfRegionServers() &lt; 1) {<a name="line.1649"></a>
+<span class="sourceLineNo">1650</span>      LOG.info("Waiting for RegionServers to join; current count={}",<a name="line.1650"></a>
+<span class="sourceLineNo">1651</span>        master.getServerManager().countOfRegionServers());<a name="line.1651"></a>
+<span class="sourceLineNo">1652</span>      Threads.sleep(250);<a name="line.1652"></a>
+<span class="sourceLineNo">1653</span>    }<a name="line.1653"></a>
+<span class="sourceLineNo">1654</span>    LOG.info("Number of RegionServers={}", master.getServerManager().countOfRegionServers());<a name="line.1654"></a>
+<span class="sourceLineNo">1655</span><a name="line.1655"></a>
+<span class="sourceLineNo">1656</span>    // Start the chores<a name="line.1656"></a>
+<span class="sourceLineNo">1657</span>    master.getMasterProcedureExecutor().addChore(this.ritChore);<a name="line.1657"></a>
+<span class="sourceLineNo">1658</span>    master.getMasterProcedureExecutor().addChore(this.deadMetricChore);<a name="line.1658"></a>
+<span class="sourceLineNo">1659</span><a name="line.1659"></a>
+<span class="sourceLineNo">1660</span>    long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime);<a name="line.1660"></a>
+<span class="sourceLineNo">1661</span>    LOG.info("Joined the cluster in {}", StringUtils.humanTimeDiff(costMs));<a name="line.1661"></a>
+<span class="sourceLineNo">1662</span>  }<a name="line.1662"></a>
+<span class="sourceLineNo">1663</span><a name="line.1663"></a>
+<span class="sourceLineNo">1664</span>  /**<a name="line.1664"></a>
+<span class="sourceLineNo">1665</span>   * Create assign procedure for offline regions. Just follow the old<a name="line.1665"></a>
+<span class="sourceLineNo">1666</span>   * processofflineServersWithOnlineRegions method. Since now we do not need to deal with dead<a name="line.1666"></a>
+<span class="sourceLineNo">1667</span>   * server any more, we only deal with the regions in OFFLINE state in this method. And this is a<a name="line.1667"></a>
+<span class="sourceLineNo">1668</span>   * bit strange, that for new regions, we will add it in CLOSED state instead of OFFLINE state, and<a name="line.1668"></a>
+<span class="sourceLineNo">1669</span>   * usually there will be a procedure to track them. The processofflineServersWithOnlineRegions is<a name="line.1669"></a>
+<span class="sourceLineNo">1670</span>   * a legacy from long ago, as things are going really different now, maybe we do not need this<a name="line.1670"></a>
+<span class="sourceLineNo">1671</span>   * method any more. Need to revisit later.<a name="line.1671"></a>
+<span class="sourceLineNo">1672</span>   */<a name="line.1672"></a>
+<span class="sourceLineNo">1673</span>  // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.<a name="line.1673"></a>
+<span class="sourceLineNo">1674</span>  // Needs to be done after the table state manager has been started.<a name="line.1674"></a>
+<span class="sourceLineNo">1675</span>  public void processOfflineRegions() {<a name="line.1675"></a>
+<span class="sourceLineNo">1676</span>    TransitRegionStateProcedure[] procs =<a name="line.1676"></a>
+<span class="sourceLineNo">1677</span>      regionStates.getRegionStateNodes().stream().filter(rsn -&gt; rsn.isInState(State.OFFLINE))<a name="line.1677"></a>
+<span class="sourceLineNo">1678</span>        .filter(rsn -&gt; isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -&gt; {<a name="line.1678"></a>
+<span class="sourceLineNo">1679</span>          rsn.lock();<a name="line.1679"></a>
+<span class="sourceLineNo">1680</span>          try {<a name="line.1680"></a>
+<span class="sourceLineNo">1681</span>            if (rsn.getProcedure() != null) {<a name="line.1681"></a>
+<span class="sourceLineNo">1682</span>              return null;<a name="line.1682"></a>
+<span class="sourceLineNo">1683</span>            } else {<a name="line.1683"></a>
+<span class="sourceLineNo">1684</span>              return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),<a name="line.1684"></a>
+<span class="sourceLineNo">1685</span>                rsn.getRegionInfo(), null));<a name="line.1685"></a>
+<span class="sourceLineNo">1686</span>            }<a name="line.1686"></a>
+<span class="sourceLineNo">1687</span>          } finally {<a name="line.1687"></a>
+<span class="sourceLineNo">1688</span>            rsn.unlock();<a name="line.1688"></a>
+<span class="sourceLineNo">1689</span>          }<a name="line.1689"></a>
+<span class="sourceLineNo">1690</span>        }).filter(p -&gt; p != null).toArray(TransitRegionStateProcedure[]::new);<a name="line.1690"></a>
+<span class="sourceLineNo">1691</span>    if (procs.length &gt; 0) {<a name="line.1691"></a>
+<span class="sourceLineNo">1692</span>      master.getMasterProcedureExecutor().submitProcedures(procs);<a name="line.1692"></a>
+<span class="sourceLineNo">1693</span>    }<a name="line.1693"></a>
+<span class="sourceLineNo">1694</span>  }<a name="line.1694"></a>
+<span class="sourceLineNo">1695</span><a name="line.1695"></a>
+<span class="sourceLineNo">1696</span>  /*<a name="line.1696"></a>
+<span class="sourceLineNo">1697</span>   * AM internal RegionStateStore.RegionStateVisitor implementation. To be used when scanning META<a name="line.1697"></a>
+<span class="sourceLineNo">1698</span>   * table for region rows, using RegionStateStore utility methods. RegionStateStore methods will<a name="line.1698"></a>
+<span class="sourceLineNo">1699</span>   * convert Result into proper RegionInfo instances, but those would still need to be added into<a name="line.1699"></a>
+<span class="sourceLineNo">1700</span>   * AssignmentManager.regionStates in-memory cache. RegionMetaLoadingVisitor.visitRegionState<a name="line.1700"></a>
+<span class="sourceLineNo">1701</span>   * method provides the logic for adding RegionInfo instances as loaded from latest META scan into<a name="line.1701"></a>
+<span class="sourceLineNo">1702</span>   * AssignmentManager.regionStates.<a name="line.1702"></a>
+<span class="sourceLineNo">1703</span>   */<a name="line.1703"></a>
+<span class="sourceLineNo">1704</span>  private class RegionMetaLoadingVisitor implements RegionStateStore.RegionStateVisitor {<a name="line.1704"></a>
+<span class="sourceLineNo">1705</span><a name="line.1705"></a>
+<span class="sourceLineNo">1706</span>    @Override<a name="line.1706"></a>
+<span class="sourceLineNo">1707</span>    public void visitRegionState(Result result, final RegionInfo regionInfo, final State state,<a name="line.1707"></a>
+<span class="sourceLineNo">1708</span>      final ServerName regionLocation, final ServerName lastHost, final long openSeqNum) {<a name="line.1708"></a>
+<span class="sourceLineNo">1709</span>      if (<a name="line.1709"></a>
+<span class="sourceLineNo">1710</span>        state == null &amp;&amp; regionLocation == null &amp;&amp; lastHost == null<a name="line.1710"></a>
+<span class="sourceLineNo">1711</span>          &amp;&amp; openSeqNum == SequenceId.NO_SEQUENCE_ID<a name="line.1711"></a>
+<span class="sourceLineNo">1712</span>      ) {<a name="line.1712"></a>
+<span class="sourceLineNo">1713</span>        // This is a row with nothing in it.<a name="line.1713"></a>
+<span class="sourceLineNo">1714</span>        LOG.warn("Skipping empty row={}", result);<a name="line.1714"></a>
+<span class="sourceLineNo">1715</span>        return;<a name="line.1715"></a>
+<span class="sourceLineNo">1716</span>      }<a name="line.1716"></a>
+<span class="sourceLineNo">1717</span>      State localState = state;<a name="line.1717"></a>
+<span class="sourceLineNo">1718</span>      if (localState == null) {<a name="line.1718"></a>
+<span class="sourceLineNo">1719</span>        // No region state column data in hbase:meta table! Are I doing a rolling upgrade from<a name="line.1719"></a>
+<span class="sourceLineNo">1720</span>        // hbase1 to hbase2? Am I restoring a SNAPSHOT or otherwise adding a region to hbase:meta?<a name="line.1720"></a>
+<span class="sourceLineNo">1721</span>        // In any of these cases, state is empty. For now, presume OFFLINE but there are probably<a name="line.1721"></a>
+<span class="sourceLineNo">1722</span>        // cases where we need to probe more to be sure this correct; TODO informed by experience.<a name="line.1722"></a>
+<span class="sourceLineNo">1723</span>        LOG.info(regionInfo.getEncodedName() + " regionState=null; presuming " + State.OFFLINE);<a name="line.1723"></a>
+<span class="sourceLineNo">1724</span>        localState = State.OFFLINE;<a name="line.1724"></a>
+<span class="sourceLineNo">1725</span>      }<a name="line.1725"></a>
+<span class="sourceLineNo">1726</span>      RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);<a name="line.1726"></a>
+<span class="sourceLineNo">1727</span>      // Do not need to lock on regionNode, as we can make sure that before we finish loading<a name="line.1727"></a>
+<span class="sourceLineNo">1728</span>      // meta, all the related procedures can not be executed. The only exception is for meta<a name="line.1728"></a>
+<span class="sourceLineNo">1729</span>      // region related operations, but here we do not load the informations for meta region.<a name="line.1729"></a>
+<span class="sourceLineNo">1730</span>      regionNode.setState(localState);<a name="line.1730"></a>
+<span class="sourceLineNo">1731</span>      regionNode.setLastHost(lastHost);<a name="line.1731"></a>
+<span class="sourceLineNo">1732</span>      regionNode.setRegionLocation(regionLocation);<a name="line.1732"></a>
+<span class="sourceLineNo">1733</span>      regionNode.setOpenSeqNum(openSeqNum);<a name="line.1733"></a>
+<span class="sourceLineNo">1734</span><a name="line.1734"></a>
+<span class="sourceLineNo">1735</span>      // Note: keep consistent with other methods, see region(Opening|Opened|Closing)<a name="line.1735"></a>
+<span class="sourceLineNo">1736</span>      // RIT/ServerCrash handling should take care of the transiting regions.<a name="line.1736"></a>
+<span class="sourceLineNo">1737</span>      if (<a name="line.1737"></a>
+<span class="sourceLineNo">1738</span>        localState.matches(State.OPEN, State.OPENING, State.CLOSING, State.SPLITTING, State.MERGING)<a name="line.1738"></a>
+<span class="sourceLineNo">1739</span>      ) {<a name="line.1739"></a>
+<span class="sourceLineNo">1740</span>        assert regionLocation != null : "found null region location for " + regionNode;<a name="line.1740"></a>
+<span class="sourceLineNo">1741</span>        regionStates.addRegionToServer(regionNode);<a name="line.1741"></a>
+<span class="sourceLineNo">1742</span>      } else if (localState == State.OFFLINE || regionInfo.isOffline()) {<a name="line.1742"></a>
+<span class="sourceLineNo">1743</span>        regionStates.addToOfflineRegions(regionNode);<a name="line.1743"></a>
+<span class="sourceLineNo">1744</span>      }<a name="line.1744"></a>
+<span class="sourceLineNo">1745</span>      if (regionNode.getProcedure() != null) {<a name="line.1745"></a>
+<span class="sourceLineNo">1746</span>        regionNode.getProcedure().stateLoaded(AssignmentManager.this, regionNode);<a name="line.1746"></a>
+<span class="sourceLineNo">1747</span>      }<a name="line.1747"></a>
+<span class="sourceLineNo">1748</span>    }<a name="line.1748"></a>
+<span class="sourceLineNo">1749</span>  };<a name="line.1749"></a>
+<span class="sourceLineNo">1750</span><a name="line.1750"></a>
+<span class="sourceLineNo">1751</span>  /**<a name="line.1751"></a>
+<span class="sourceLineNo">1752</span>   * Attempt to load {@code regionInfo} from META, adding any results to the<a name="line.1752"></a>
+<span class="sourceLineNo">1753</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1753"></a>
+<span class="sourceLineNo">1754</span>   * @param regionInfo the region to be loaded from META.<a name="line.1754"></a>
+<span class="sourceLineNo">1755</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1755"></a>
+<span class="sourceLineNo">1756</span>   */<a name="line.1756"></a>
+<span class="sourceLineNo">1757</span>  public void populateRegionStatesFromMeta(@NonNull final RegionInfo regionInfo)<a name="line.1757"></a>
+<span class="sourceLineNo">1758</span>    throws IOException {<a name="line.1758"></a>
+<span class="sourceLineNo">1759</span>    final String regionEncodedName = RegionInfo.DEFAULT_REPLICA_ID == regionInfo.getReplicaId()<a name="line.1759"></a>
+<span class="sourceLineNo">1760</span>      ? regionInfo.getEncodedName()<a name="line.1760"></a>
+<span class="sourceLineNo">1761</span>      : RegionInfoBuilder.newBuilder(regionInfo).setReplicaId(RegionInfo.DEFAULT_REPLICA_ID).build()<a name="line.1761"></a>
+<span class="sourceLineNo">1762</span>        .getEncodedName();<a name="line.1762"></a>
+<span class="sourceLineNo">1763</span>    populateRegionStatesFromMeta(regionEncodedName);<a name="line.1763"></a>
+<span class="sourceLineNo">1764</span>  }<a name="line.1764"></a>
+<span class="sourceLineNo">1765</span><a name="line.1765"></a>
+<span class="sourceLineNo">1766</span>  /**<a name="line.1766"></a>
+<span class="sourceLineNo">1767</span>   * Attempt to load {@code regionEncodedName} from META, adding any results to the<a name="line.1767"></a>
+<span class="sourceLineNo">1768</span>   * {@link #regionStateStore} Is NOT aware of replica regions.<a name="line.1768"></a>
+<span class="sourceLineNo">1769</span>   * @param regionEncodedName encoded name for the region to be loaded from META.<a name="line.1769"></a>
+<span class="sourceLineNo">1770</span>   * @throws IOException If some error occurs while querying META or parsing results.<a name="line.1770"></a>
+<span class="sourceLineNo">1771</span>   */<a name="line.1771"></a>
+<span class="sourceLineNo">1772</span>  public void populateRegionStatesFromMeta(@NonNull String regionEncodedName) throws IOException {<a name="line.1772"></a>
+<span class="sourceLineNo">1773</span>    final RegionMetaLoadingVisitor visitor = new RegionMetaLoadingVisitor();<a name="line.1773"></a>
+<span class="sourceLineNo">1774</span>    regionStateStore.visitMetaForRegion(regionEncodedName, visitor);<a name="line.1774"></a>
+<span class="sourceLineNo">1775</span>  }<a name="line.1775"></a>
+<span class="sourceLineNo">1776</span><a name="line.1776"></a>
+<span class="sourceLineNo">1777</span>  private void loadMeta() throws IOException {<a name="line.1777"></a>
+<span class="sourceLineNo">1778</span>    // TODO: use a thread pool<a name="line.1778"></a>
+<span class="sourceLineNo">1779</span>    regionStateStore.visitMeta(new RegionMetaLoadingVisitor());<a name="line.1779"></a>
+<span class="sourceLineNo">1780</span>  }<a name="line.1780"></a>
+<span class="sourceLineNo">1781</span><a name="line.1781"></a>
+<span class="sourceLineNo">1782</span>  /**<a name="line.1782"></a>
+<span class="sourceLineNo">1783</span>   * Used to check if the meta loading is done.<a name="line.1783"></a>
+<span class="sourceLineNo">1784</span>   * &lt;p/&gt;<a name="line.1784"></a>
+<span class="sourceLineNo">1785</span>   * if not we throw PleaseHoldException since we are rebuilding the RegionStates<a name="line.1785"></a>
+<span class="sourceLineNo">1786</span>   * @param hri region to check if it is already rebuild<a name="line.1786"></a>
+<span class="sourceLineNo">1787</span>   * @throws PleaseHoldException if meta has not been loaded yet<a name="line.1787"></a>
+<span class="sourceLineNo">1788</span>   */<a name="line.1788"></a>
+<span class="sourceLineNo">1789</span>  private void checkMetaLoaded(RegionInfo hri) throws PleaseHoldException {<a name="line.1789"></a>
+<span class="sourceLineNo">1790</span>    if (!isRunning()) {<a name="line.1790"></a>
+<span class="sourceLineNo">1791</span>      throw new PleaseHoldException("AssignmentManager not running");<a name="line.1791"></a>
+<span class="sourceLineNo">1792</span>    }<a name="line.1792"></a>
+<span class="sourceLineNo">1793</span>    boolean meta = isMetaRegion(hri);<a name="line.1793"></a>
+<span class="sourceLineNo">1794</span>    boolean metaLoaded = isMetaLoaded();<a name="line.1794"></a>
+<span class="sourceLineNo">1795</span>    if (!meta &amp;&amp; !metaLoaded) {<a name="line.1795"></a>
+<span class="sourceLineNo">1796</span>      throw new PleaseHoldException(<a name="line.1796"></a>
+<span class="sourceLineNo">1797</span>        "Master not fully online; hbase:meta=" + meta + ", metaLoaded=" + metaLoaded);<a name="line.1797"></a>
+<span class="sourceLineNo">1798</span>    }<a name="line.1798"></a>
+<span class="sourceLineNo">1799</span>  }<a name="line.1799"></a>
+<span class="sourceLineNo">1800</span><a name="line.1800"></a>
+<span class="sourceLineNo">1801</span>  // ============================================================================================<a name="line.1801"></a>
+<span class="sourceLineNo">1802</span>  // TODO: Metrics<a name="line.1802"></a>
 <span class="sourceLineNo">1803</span>  // ============================================================================================<a name="line.1803"></a>
-<span class="sourceLineNo">1804</span>  // TODO: Metrics<a name="line.1804"></a>
-<span class="sourceLineNo">1805</span>  // ============================================================================================<a name="line.1805"></a>
-<span class="sourceLineNo">1806</span>  public int getNumRegionsOpened() {<a name="line.1806"></a>
-<span class="sourceLineNo">1807</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1807"></a>
-<span class="sourceLineNo">1808</span>    return 0;<a name="line.1808"></a>
-<span class="sourceLineNo">1809</span>  }<a name="line.1809"></a>
-<span class="sourceLineNo">1810</span><a name="line.1810"></a>
-<span class="sourceLineNo">1811</span>  /**<a name="line.1811"></a>
-<span class="sourceLineNo">1812</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1812"></a>
-<span class="sourceLineNo">1813</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1813"></a>
-<span class="sourceLineNo">1814</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1814"></a>
-<span class="sourceLineNo">1815</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1815"></a>
-<span class="sourceLineNo">1816</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1816"></a>
-<span class="sourceLineNo">1817</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1817"></a>
-<span class="sourceLineNo">1818</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1818"></a>
-<span class="sourceLineNo">1819</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1819"></a>
-<span class="sourceLineNo">1820</span>   */<a name="line.1820"></a>
-<span class="sourceLineNo">1821</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1821"></a>
-<span class="sourceLineNo">1822</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1822"></a>
-<span class="sourceLineNo">1823</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1823"></a>
-<span class="sourceLineNo">1824</span>    // Remove the in-memory rsReports result<a name="line.1824"></a>
-<span class="sourceLineNo">1825</span>    synchronized (rsReports) {<a name="line.1825"></a>
-<span class="sourceLineNo">1826</span>      rsReports.remove(serverName);<a name="line.1826"></a>
-<span class="sourceLineNo">1827</span>    }<a name="line.1827"></a>
-<span class="sourceLineNo">1828</span><a name="line.1828"></a>
-<span class="sourceLineNo">1829</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1829"></a>
-<span class="sourceLineNo">1830</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1830"></a>
-<span class="sourceLineNo">1831</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1831"></a>
-<span class="sourceLineNo">1832</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1832"></a>
-<span class="sourceLineNo">1833</span>    if (serverNode != null) {<a name="line.1833"></a>
-<span class="sourceLineNo">1834</span>      serverNode.writeLock().lock();<a name="line.1834"></a>
-<span class="sourceLineNo">1835</span>    }<a name="line.1835"></a>
-<span class="sourceLineNo">1836</span>    boolean carryingMeta;<a name="line.1836"></a>
-<span class="sourceLineNo">1837</span>    long pid;<a name="line.1837"></a>
-<span class="sourceLineNo">1838</span>    try {<a name="line.1838"></a>
-<span class="sourceLineNo">1839</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1839"></a>
-<span class="sourceLineNo">1840</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1840"></a>
-<span class="sourceLineNo">1841</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1841"></a>
-<span class="sourceLineNo">1842</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1842"></a>
-<span class="sourceLineNo">1843</span>          carryingMeta);<a name="line.1843"></a>
-<span class="sourceLineNo">1844</span>        return Procedure.NO_PROC_ID;<a name="line.1844"></a>
-<span class="sourceLineNo">1845</span>      } else {<a name="line.1845"></a>
-<span class="sourceLineNo">1846</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1846"></a>
-<span class="sourceLineNo">1847</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1847"></a>
-<span class="sourceLineNo">1848</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1848"></a>
-<span class="sourceLineNo">1849</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1849"></a>
-<span class="sourceLineNo">1850</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1850"></a>
-<span class="sourceLineNo">1851</span>        ServerState oldState = null;<a name="line.1851"></a>
-<span class="sourceLineNo">1852</span>        if (serverNode != null) {<a name="line.1852"></a>
-<span class="sourceLineNo">1853</span>          oldState = serverNode.getState();<a name="line.1853"></a>
-<span class="sourceLineNo">1854</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1854"></a>
-<span class="sourceLineNo">1855</span>        }<a name="line.1855"></a>
-<span class="sourceLineNo">1856</span><a name="line.1856"></a>
-<span class="sourceLineNo">1857</span>        if (force) {<a name="line.1857"></a>
-<span class="sourceLineNo">1858</span>          pid = procExec.submitProcedure(<a name="line.1858"></a>
-<span class="sourceLineNo">1859</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1859"></a>
-<span class="sourceLineNo">1860</span>        } else {<a name="line.1860"></a>
-<span class="sourceLineNo">1861</span>          pid = procExec.submitProcedure(<a name="line.1861"></a>
-<span class="sourceLineNo">1862</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1862"></a>
-<span class="sourceLineNo">1863</span>        }<a name="line.1863"></a>
-<span class="sourceLineNo">1864</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1864"></a>
-<span class="sourceLineNo">1865</span>          serverName, carryingMeta,<a name="line.1865"></a>
-<span class="sourceLineNo">1866</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1866"></a>
-<span class="sourceLineNo">1867</span>      }<a name="line.1867"></a>
-<span class="sourceLineNo">1868</span>    } finally {<a name="line.1868"></a>
-<span class="sourceLineNo">1869</span>      if (serverNode != null) {<a name="line.1869"></a>
-<span class="sourceLineNo">1870</span>        serverNode.writeLock().unlock();<a name="line.1870"></a>
-<span class="sourceLineNo">1871</span>      }<a name="line.1871"></a>
-<span class="sourceLineNo">1872</span>    }<a name="line.1872"></a>
-<span class="sourceLineNo">1873</span>    return pid;<a name="line.1873"></a>
-<span class="sourceLineNo">1874</span>  }<a name="line.1874"></a>
-<span class="sourceLineNo">1875</span><a name="line.1875"></a>
-<span class="sourceLineNo">1876</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1876"></a>
-<span class="sourceLineNo">1877</span>    // TODO used by MasterRpcServices<a name="line.1877"></a>
-<span class="sourceLineNo">1878</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1878"></a>
-<span class="sourceLineNo">1879</span>    if (node != null) {<a name="line.1879"></a>
-<span class="sourceLineNo">1880</span>      node.offline();<a name="line.1880"></a>
-<span class="sourceLineNo">1881</span>    }<a name="line.1881"></a>
-<span class="sourceLineNo">1882</span>  }<a name="line.1882"></a>
-<span class="sourceLineNo">1883</span><a name="line.1883"></a>
-<span class="sourceLineNo">1884</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1884"></a>
-<span class="sourceLineNo">1885</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1885"></a>
-<span class="sourceLineNo">1886</span>  }<a name="line.1886"></a>
-<span class="sourceLineNo">1887</span><a name="line.1887"></a>
-<span class="sourceLineNo">1888</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1888"></a>
-<span class="sourceLineNo">1889</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1889"></a>
-<span class="sourceLineNo">1890</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1890"></a>
-<span class="sourceLineNo">1891</span>  }<a name="line.1891"></a>
-<span class="sourceLineNo">1892</span><a name="line.1892"></a>
+<span class="sourceLineNo">1804</span>  public int getNumRegionsOpened() {<a name="line.1804"></a>
+<span class="sourceLineNo">1805</span>    // TODO: Used by TestRegionPlacement.java and assume monotonically increasing value<a name="line.1805"></a>
+<span class="sourceLineNo">1806</span>    return 0;<a name="line.1806"></a>
+<span class="sourceLineNo">1807</span>  }<a name="line.1807"></a>
+<span class="sourceLineNo">1808</span><a name="line.1808"></a>
+<span class="sourceLineNo">1809</span>  /**<a name="line.1809"></a>
+<span class="sourceLineNo">1810</span>   * Usually run by the Master in reaction to server crash during normal processing. Can also be<a name="line.1810"></a>
+<span class="sourceLineNo">1811</span>   * invoked via external RPC to effect repair; in the latter case, the 'force' flag is set so we<a name="line.1811"></a>
+<span class="sourceLineNo">1812</span>   * push through the SCP though context may indicate already-running-SCP (An old SCP may have<a name="line.1812"></a>
+<span class="sourceLineNo">1813</span>   * exited abnormally, or damaged cluster may still have references in hbase:meta to 'Unknown<a name="line.1813"></a>
+<span class="sourceLineNo">1814</span>   * Servers' -- servers that are not online or in dead servers list, etc.)<a name="line.1814"></a>
+<span class="sourceLineNo">1815</span>   * @param force Set if the request came in externally over RPC (via hbck2). Force means run the<a name="line.1815"></a>
+<span class="sourceLineNo">1816</span>   *              SCP even if it seems as though there might be an outstanding SCP running.<a name="line.1816"></a>
+<span class="sourceLineNo">1817</span>   * @return pid of scheduled SCP or {@link Procedure#NO_PROC_ID} if none scheduled.<a name="line.1817"></a>
+<span class="sourceLineNo">1818</span>   */<a name="line.1818"></a>
+<span class="sourceLineNo">1819</span>  public long submitServerCrash(ServerName serverName, boolean shouldSplitWal, boolean force) {<a name="line.1819"></a>
+<span class="sourceLineNo">1820</span>    // May be an 'Unknown Server' so handle case where serverNode is null.<a name="line.1820"></a>
+<span class="sourceLineNo">1821</span>    ServerStateNode serverNode = regionStates.getServerNode(serverName);<a name="line.1821"></a>
+<span class="sourceLineNo">1822</span>    // Remove the in-memory rsReports result<a name="line.1822"></a>
+<span class="sourceLineNo">1823</span>    synchronized (rsReports) {<a name="line.1823"></a>
+<span class="sourceLineNo">1824</span>      rsReports.remove(serverName);<a name="line.1824"></a>
+<span class="sourceLineNo">1825</span>    }<a name="line.1825"></a>
+<span class="sourceLineNo">1826</span><a name="line.1826"></a>
+<span class="sourceLineNo">1827</span>    // We hold the write lock here for fencing on reportRegionStateTransition. Once we set the<a name="line.1827"></a>
+<span class="sourceLineNo">1828</span>    // server state to CRASHED, we will no longer accept the reportRegionStateTransition call from<a name="line.1828"></a>
+<span class="sourceLineNo">1829</span>    // this server. This is used to simplify the implementation for TRSP and SCP, where we can make<a name="line.1829"></a>
+<span class="sourceLineNo">1830</span>    // sure that, the region list fetched by SCP will not be changed any more.<a name="line.1830"></a>
+<span class="sourceLineNo">1831</span>    if (serverNode != null) {<a name="line.1831"></a>
+<span class="sourceLineNo">1832</span>      serverNode.writeLock().lock();<a name="line.1832"></a>
+<span class="sourceLineNo">1833</span>    }<a name="line.1833"></a>
+<span class="sourceLineNo">1834</span>    boolean carryingMeta;<a name="line.1834"></a>
+<span class="sourceLineNo">1835</span>    long pid;<a name="line.1835"></a>
+<span class="sourceLineNo">1836</span>    try {<a name="line.1836"></a>
+<span class="sourceLineNo">1837</span>      ProcedureExecutor&lt;MasterProcedureEnv&gt; procExec = this.master.getMasterProcedureExecutor();<a name="line.1837"></a>
+<span class="sourceLineNo">1838</span>      carryingMeta = isCarryingMeta(serverName);<a name="line.1838"></a>
+<span class="sourceLineNo">1839</span>      if (!force &amp;&amp; serverNode != null &amp;&amp; !serverNode.isInState(ServerState.ONLINE)) {<a name="line.1839"></a>
+<span class="sourceLineNo">1840</span>        LOG.info("Skip adding ServerCrashProcedure for {} (meta={}) -- running?", serverNode,<a name="line.1840"></a>
+<span class="sourceLineNo">1841</span>          carryingMeta);<a name="line.1841"></a>
+<span class="sourceLineNo">1842</span>        return Procedure.NO_PROC_ID;<a name="line.1842"></a>
+<span class="sourceLineNo">1843</span>      } else {<a name="line.1843"></a>
+<span class="sourceLineNo">1844</span>        MasterProcedureEnv mpe = procExec.getEnvironment();<a name="line.1844"></a>
+<span class="sourceLineNo">1845</span>        // If serverNode == null, then 'Unknown Server'. Schedule HBCKSCP instead.<a name="line.1845"></a>
+<span class="sourceLineNo">1846</span>        // HBCKSCP scours Master in-memory state AND hbase;meta for references to<a name="line.1846"></a>
+<span class="sourceLineNo">1847</span>        // serverName just-in-case. An SCP that is scheduled when the server is<a name="line.1847"></a>
+<span class="sourceLineNo">1848</span>        // 'Unknown' probably originated externally with HBCK2 fix-it tool.<a name="line.1848"></a>
+<span class="sourceLineNo">1849</span>        ServerState oldState = null;<a name="line.1849"></a>
+<span class="sourceLineNo">1850</span>        if (serverNode != null) {<a name="line.1850"></a>
+<span class="sourceLineNo">1851</span>          oldState = serverNode.getState();<a name="line.1851"></a>
+<span class="sourceLineNo">1852</span>          serverNode.setState(ServerState.CRASHED);<a name="line.1852"></a>
+<span class="sourceLineNo">1853</span>        }<a name="line.1853"></a>
+<span class="sourceLineNo">1854</span><a name="line.1854"></a>
+<span class="sourceLineNo">1855</span>        if (force) {<a name="line.1855"></a>
+<span class="sourceLineNo">1856</span>          pid = procExec.submitProcedure(<a name="line.1856"></a>
+<span class="sourceLineNo">1857</span>            new HBCKServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1857"></a>
+<span class="sourceLineNo">1858</span>        } else {<a name="line.1858"></a>
+<span class="sourceLineNo">1859</span>          pid = procExec.submitProcedure(<a name="line.1859"></a>
+<span class="sourceLineNo">1860</span>            new ServerCrashProcedure(mpe, serverName, shouldSplitWal, carryingMeta));<a name="line.1860"></a>
+<span class="sourceLineNo">1861</span>        }<a name="line.1861"></a>
+<span class="sourceLineNo">1862</span>        LOG.info("Scheduled ServerCrashProcedure pid={} for {} (carryingMeta={}){}.", pid,<a name="line.1862"></a>
+<span class="sourceLineNo">1863</span>          serverName, carryingMeta,<a name="line.1863"></a>
+<span class="sourceLineNo">1864</span>          serverNode == null ? "" : " " + serverNode.toString() + ", oldState=" + oldState);<a name="line.1864"></a>
+<span class="sourceLineNo">1865</span>      }<a name="line.1865"></a>
+<span class="sourceLineNo">1866</span>    } finally {<a name="line.1866"></a>
+<span class="sourceLineNo">1867</span>      if (serverNode != null) {<a name="line.1867"></a>
+<span class="sourceLineNo">1868</span>        serverNode.writeLock().unlock();<a name="line.1868"></a>
+<span class="sourceLineNo">1869</span>      }<a name="line.1869"></a>
+<span class="sourceLineNo">1870</span>    }<a name="line.1870"></a>
+<span class="sourceLineNo">1871</span>    return pid;<a name="line.1871"></a>
+<span class="sourceLineNo">1872</span>  }<a name="line.1872"></a>
+<span class="sourceLineNo">1873</span><a name="line.1873"></a>
+<span class="sourceLineNo">1874</span>  public void offlineRegion(final RegionInfo regionInfo) {<a name="line.1874"></a>
+<span class="sourceLineNo">1875</span>    // TODO used by MasterRpcServices<a name="line.1875"></a>
+<span class="sourceLineNo">1876</span>    RegionStateNode node = regionStates.getRegionStateNode(regionInfo);<a name="line.1876"></a>
+<span class="sourceLineNo">1877</span>    if (node != null) {<a name="line.1877"></a>
+<span class="sourceLineNo">1878</span>      node.offline();<a name="line.1878"></a>
+<span class="sourceLineNo">1879</span>    }<a name="line.1879"></a>
+<span class="sourceLineNo">1880</span>  }<a name="line.1880"></a>
+<span class="sourceLineNo">1881</span><a name="line.1881"></a>
+<span class="sourceLineNo">1882</span>  public void onlineRegion(final RegionInfo regionInfo, final ServerName serverName) {<a name="line.1882"></a>
+<span class="sourceLineNo">1883</span>    // TODO used by TestSplitTransactionOnCluster.java<a name="line.1883"></a>
+<span class="sourceLineNo">1884</span>  }<a name="line.1884"></a>
+<span class="sourceLineNo">1885</span><a name="line.1885"></a>
+<span class="sourceLineNo">1886</span>  public Map&lt;ServerName, List&lt;RegionInfo&gt;&gt;<a name="line.1886"></a>
+<span class="sourceLineNo">1887</span>    getSnapShotOfAssignment(final Collection&lt;RegionInfo&gt; regions) {<a name="line.1887"></a>
+<span class="sourceLineNo">1888</span>    return regionStates.getSnapShotOfAssignment(regions);<a name="line.1888"></a>
+<span class="sourceLineNo">1889</span>  }<a name="line.1889"></a>
+<span class="sourceLineNo">1890</span><a name="line.1890"></a>
+<span class="sourceLineNo">1891</span>  // ============================================================================================<a name="line.1891"></a>
+<span class="sourceLineNo">1892</span>  // TODO: UTILS/HELPERS?<a name="line.1892"></a>
 <span class="sourceLineNo">1893</span>  // ============================================================================================<a name="line.1893"></a>
-<span class="sourceLineNo">1894</span>  // TODO: UTILS/HELPERS?<a name="line.1894"></a>
-<span class="sourceLineNo">1895</span>  // ============================================================================================<a name="line.1895"></a>
-<span class="sourceLineNo">1896</span>  /**<a name="line.1896"></a>
-<span class="sourceLineNo">1897</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1897"></a>
-<span class="sourceLineNo">1898</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1898"></a>
-<span class="sourceLineNo">1899</span>   */<a name="line.1899"></a>
-<span class="sourceLineNo">1900</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1900"></a>
-<span class="sourceLineNo">1901</span>    if (isTableDisabled(tableName)) {<a name="line.1901"></a>
-<span class="sourceLineNo">1902</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1902"></a>
-<span class="sourceLineNo">1903</span>    }<a name="line.1903"></a>
-<span class="sourceLineNo">1904</span><a name="line.1904"></a>
-<span class="sourceLineNo">1905</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1905"></a>
-<span class="sourceLineNo">1906</span>    int ritCount = 0;<a name="line.1906"></a>
-<span class="sourceLineNo">1907</span>    for (RegionState regionState : states) {<a name="line.1907"></a>
-<span class="sourceLineNo">1908</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1908"></a>
-<span class="sourceLineNo">1909</span>        ritCount++;<a name="line.1909"></a>
-<span class="sourceLineNo">1910</span>      }<a name="line.1910"></a>
-<span class="sourceLineNo">1911</span>    }<a name="line.1911"></a>
-<span class="sourceLineNo">1912</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1912"></a>
-<span class="sourceLineNo">1913</span>  }<a name="line.1913"></a>
-<span class="sourceLineNo">1914</span><a name="line.1914"></a>
+<span class="sourceLineNo">1894</span>  /**<a name="line.1894"></a>
+<span class="sourceLineNo">1895</span>   * Used by the client (via master) to identify if all regions have the schema updates<a name="line.1895"></a>
+<span class="sourceLineNo">1896</span>   * @return Pair indicating the status of the alter command (pending/total)<a name="line.1896"></a>
+<span class="sourceLineNo">1897</span>   */<a name="line.1897"></a>
+<span class="sourceLineNo">1898</span>  public Pair&lt;Integer, Integer&gt; getReopenStatus(TableName tableName) {<a name="line.1898"></a>
+<span class="sourceLineNo">1899</span>    if (isTableDisabled(tableName)) {<a name="line.1899"></a>
+<span class="sourceLineNo">1900</span>      return new Pair&lt;Integer, Integer&gt;(0, 0);<a name="line.1900"></a>
+<span class="sourceLineNo">1901</span>    }<a name="line.1901"></a>
+<span class="sourceLineNo">1902</span><a name="line.1902"></a>
+<span class="sourceLineNo">1903</span>    final List&lt;RegionState&gt; states = regionStates.getTableRegionStates(tableName);<a name="line.1903"></a>
+<span class="sourceLineNo">1904</span>    int ritCount = 0;<a name="line.1904"></a>
+<span class="sourceLineNo">1905</span>    for (RegionState regionState : states) {<a name="line.1905"></a>
+<span class="sourceLineNo">1906</span>      if (!regionState.isOpened() &amp;&amp; !regionState.isSplit()) {<a name="line.1906"></a>
+<span class="sourceLineNo">1907</span>        ritCount++;<a name="line.1907"></a>
+<span class="sourceLineNo">1908</span>      }<a name="line.1908"></a>
+<span class="sourceLineNo">1909</span>    }<a name="line.1909"></a>
+<span class="sourceLineNo">1910</span>    return new Pair&lt;Integer, Integer&gt;(ritCount, states.size());<a name="line.1910"></a>
+<span class="sourceLineNo">1911</span>  }<a name="line.1911"></a>
+<span class="sourceLineNo">1912</span><a name="line.1912"></a>
+<span class="sourceLineNo">1913</span>  // ============================================================================================<a name="line.1913"></a>
+<span class="sourceLineNo">1914</span>  // TODO: Region State In Transition<a name="line.1914"></a>
 <span class="sourceLineNo">1915</span>  // ============================================================================================<a name="line.1915"></a>
-<span class="sourceLineNo">1916</span>  // TODO: Region State In Transition<a name="line.1916"></a>
-<span class="sourceLineNo">1917</span>  // ============================================================================================<a name="line.1917"></a>
-<span class="sourceLineNo">1918</span>  public boolean hasRegionsInTransition() {<a name="line.1918"></a>
-<span class="sourceLineNo">1919</span>    return regionStates.hasRegionsInTransition();<a name="line.1919"></a>
-<span class="sourceLineNo">1920</span>  }<a name="line.1920"></a>
-<span class="sourceLineNo">1921</span><a name="line.1921"></a>
-<span class="sourceLineNo">1922</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1922"></a>
-<span class="sourceLineNo">1923</span>    return regionStates.getRegionsInTransition();<a name="line.1923"></a>
-<span class="sourceLineNo">1924</span>  }<a name="line.1924"></a>
-<span class="sourceLineNo">1925</span><a name="line.1925"></a>
-<span class="sourceLineNo">1926</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1926"></a>
-<span class="sourceLineNo">1927</span>    return regionStates.getAssignedRegions();<a name="line.1927"></a>
-<span class="sourceLineNo">1928</span>  }<a name="line.1928"></a>
-<span class="sourceLineNo">1929</span><a name="line.1929"></a>
-<span class="sourceLineNo">1930</span>  /**<a name="line.1930"></a>
-<span class="sourceLineNo">1931</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1931"></a>
-<span class="sourceLineNo">1932</span>   */<a name="line.1932"></a>
-<span class="sourceLineNo">1933</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1933"></a>
-<span class="sourceLineNo">1934</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1934"></a>
-<span class="sourceLineNo">1935</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1935"></a>
-<span class="sourceLineNo">1936</span>  }<a name="line.1936"></a>
-<span class="sourceLineNo">1937</span><a name="line.1937"></a>
-<span class="sourceLineNo">1938</span>  /**<a name="line.1938"></a>
-<span class="sourceLineNo">1939</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1939"></a>
-<span class="sourceLineNo">1940</span>   */<a name="line.1940"></a>
-<span class="sourceLineNo">1941</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1941"></a>
-<span class="sourceLineNo">1942</span>    final RegionStateNode regionState =<a name="line.1942"></a>
-<span class="sourceLineNo">1943</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1943"></a>
-<span class="sourceLineNo">1944</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1944"></a>
-<span class="sourceLineNo">1945</span>  }<a name="line.1945"></a>
-<span class="sourceLineNo">1946</span><a name="line.1946"></a>
-<span class="sourceLineNo">1947</span>  // ============================================================================================<a name="line.1947"></a>
-<span class="sourceLineNo">1948</span>  // Expected states on region state transition.<a name="line.1948"></a>
-<span class="sourceLineNo">1949</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1949"></a>
-<span class="sourceLineNo">1950</span>  // See the comments in regionOpening method for more details.<a name="line.1950"></a>
-<span class="sourceLineNo">1951</span>  // ============================================================================================<a name="line.1951"></a>
-<span class="sourceLineNo">1952</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1952"></a>
-<span class="sourceLineNo">1953</span>    State.OPEN // Retrying<a name="line.1953"></a>
-<span class="sourceLineNo">1954</span>  };<a name="line.1954"></a>
-<span class="sourceLineNo">1955</span><a name="line.1955"></a>
-<span class="sourceLineNo">1956</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1956"></a>
-<span class="sourceLineNo">1957</span>    State.CLOSING, // Retrying<a name="line.1957"></a>
-<span class="sourceLineNo">1958</span>    State.SPLITTING, // Offline the split parent<a name="line.1958"></a>
-<span class="sourceLineNo">1959</span>    State.MERGING // Offline the merge parents<a name="line.1959"></a>
-<span class="sourceLineNo">1960</span>  };<a name="line.1960"></a>
-<span class="sourceLineNo">1961</span><a name="line.1961"></a>
-<span class="sourceLineNo">1962</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1962"></a>
-<span class="sourceLineNo">1963</span>    State.CLOSED // Retrying<a name="line.1963"></a>
-<span class="sourceLineNo">1964</span>  };<a name="line.1964"></a>
-<span class="sourceLineNo">1965</span><a name="line.1965"></a>
-<span class="sourceLineNo">1966</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1966"></a>
-<span class="sourceLineNo">1967</span>  // usages<a name="line.1967"></a>
-<span class="sourceLineNo">1968</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1968"></a>
-<span class="sourceLineNo">1969</span><a name="line.1969"></a>
-<span class="sourceLineNo">1970</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1970"></a>
-<span class="sourceLineNo">1971</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1971"></a>
-<span class="sourceLineNo">1972</span><a name="line.1972"></a>
-<span class="sourceLineNo">1973</span>  // ============================================================================================<a name="line.1973"></a>
-<span class="sourceLineNo">1974</span>  // Region Status update<a name="line.1974"></a>
-<span class="sourceLineNo">1975</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1975"></a>
-<span class="sourceLineNo">1976</span>  // and pre-assumptions are very tricky.<a name="line.1976"></a>
-<span class="sourceLineNo">1977</span>  // ============================================================================================<a name="line.1977"></a>
-<span class="sourceLineNo">1978</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1978"></a>
-<span class="sourceLineNo">1979</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1979"></a>
-<span class="sourceLineNo">1980</span>    RegionState.State state = regionNode.getState();<a name="line.1980"></a>
-<span class="sourceLineNo">1981</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1981"></a>
-<span class="sourceLineNo">1982</span>    boolean succ = false;<a name="line.1982"></a>
-<span class="sourceLineNo">1983</span>    try {<a name="line.1983"></a>
-<span class="sourceLineNo">1984</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1984"></a>
-<span class="sourceLineNo">1985</span>      succ = true;<a name="line.1985"></a>
-<span class="sourceLineNo">1986</span>    } finally {<a name="line.1986"></a>
-<span class="sourceLineNo">1987</span>      if (!succ) {<a name="line.1987"></a>
-<span class="sourceLineNo">1988</span>        // revert<a name="line.1988"></a>
-<span class="sourceLineNo">1989</span>        regionNode.setState(state);<a name="line.1989"></a>
-<span class="sourceLineNo">1990</span>      }<a name="line.1990"></a>
-<span class="sourceLineNo">1991</span>    }<a name="line.1991"></a>
-<span class="sourceLineNo">1992</span>  }<a name="line.1992"></a>
-<span class="sourceLineNo">1993</span><a name="line.1993"></a>
-<span class="sourceLineNo">1994</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1994"></a>
-<span class="sourceLineNo">1995</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1995"></a>
-<span class="sourceLineNo">1996</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1996"></a>
-<span class="sourceLineNo">1997</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1997"></a>
-<span class="sourceLineNo">1998</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1998"></a>
-<span class="sourceLineNo">1999</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1999"></a>
-<span class="sourceLineNo">2000</span>    regionStates.addRegionToServer(regionNode);<a name="line.2000"></a>
-<span class="sourceLineNo">2001</span>    // update the operation count metrics<a name="line.2001"></a>
-<span class="sourceLineNo">2002</span>    metrics.incrementOperationCounter();<a name="line.2002"></a>
-<span class="sourceLineNo">2003</span>  }<a name="line.2003"></a>
-<span class="sourceLineNo">2004</span><a name="line.2004"></a>
-<span class="sourceLineNo">2005</span>  // should be called under the RegionStateNode lock<a name="line.2005"></a>
-<span class="sourceLineNo">2006</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2006"></a>
-<span class="sourceLineNo">2007</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2007"></a>
-<span class="sourceLineNo">2008</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2008"></a>
-<span class="sourceLineNo">2009</span>    RegionState.State state = regionNode.getState();<a name="line.2009"></a>
-<span class="sourceLineNo">2010</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2010"></a>
-<span class="sourceLineNo">2011</span>    if (giveUp) {<a name="line.2011"></a>
-<span class="sourceLineNo">2012</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2012"></a>
-<span class="sourceLineNo">2013</span>      regionNode.setRegionLocation(null);<a name="line.2013"></a>
-<span class="sourceLineNo">2014</span>      boolean succ = false;<a name="line.2014"></a>
-<span class="sourceLineNo">2015</span>      try {<a name="line.2015"></a>
-<span class="sourceLineNo">2016</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2016"></a>
-<span class="sourceLineNo">2017</span>        succ = true;<a name="line.2017"></a>
-<span class="sourceLineNo">2018</span>      } finally {<a name="line.2018"></a>
-<span class="sourceLineNo">2019</span>        if (!succ) {<a name="line.2019"></a>
-<span class="sourceLineNo">2020</span>          // revert<a name="line.2020"></a>
-<span class="sourceLineNo">2021</span>          regionNode.setState(state);<a name="line.2021"></a>
-<span class="sourceLineNo">2022</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2022"></a>
-<span class="sourceLineNo">2023</span>        }<a name="line.2023"></a>
-<span class="sourceLineNo">2024</span>      }<a name="line.2024"></a>
-<span class="sourceLineNo">2025</span>    }<a name="line.2025"></a>
-<span class="sourceLineNo">2026</span>    if (regionLocation != null) {<a name="line.2026"></a>
-<span class="sourceLineNo">2027</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2027"></a>
-<span class="sourceLineNo">2028</span>    }<a name="line.2028"></a>
-<span class="sourceLineNo">2029</span>  }<a name="line.2029"></a>
-<span class="sourceLineNo">2030</span><a name="line.2030"></a>
-<span class="sourceLineNo">2031</span>  // should be called under the RegionStateNode lock<a name="line.2031"></a>
-<span class="sourceLineNo">2032</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2032"></a>
-<span class="sourceLineNo">2033</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2033"></a>
-<span class="sourceLineNo">2034</span><a name="line.2034"></a>
-<span class="sourceLineNo">2035</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2035"></a>
-<span class="sourceLineNo">2036</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2036"></a>
-<span class="sourceLineNo">2037</span>    if (isMetaRegion(hri)) {<a name="line.2037"></a>
-<span class="sourceLineNo">2038</span>      setMetaAssigned(hri, false);<a name="line.2038"></a>
-<span class="sourceLineNo">2039</span>    }<a name="line.2039"></a>
-<span class="sourceLineNo">2040</span>    regionStates.addRegionToServer(regionNode);<a name="line.2040"></a>
-<span class="sourceLineNo">2041</span>    // update the operation count metrics<a name="line.2041"></a>
-<span class="sourceLineNo">2042</span>    metrics.incrementOperationCounter();<a name="line.2042"></a>
-<span class="sourceLineNo">2043</span>  }<a name="line.2043"></a>
-<span class="sourceLineNo">2044</span><a name="line.2044"></a>
-<span class="sourceLineNo">2045</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2045"></a>
-<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2046"></a>
-<span class="sourceLineNo">2047</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2047"></a>
-<span class="sourceLineNo">2048</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2048"></a>
-<span class="sourceLineNo">2049</span><a name="line.2049"></a>
-<span class="sourceLineNo">2050</span>  // should be called under the RegionStateNode lock<a name="line.2050"></a>
-<span class="sourceLineNo">2051</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2051"></a>
-<span class="sourceLineNo">2052</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2052"></a>
-<span class="sourceLineNo">2053</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2053"></a>
-<span class="sourceLineNo">2054</span>    regionStates.addRegionToServer(regionNode);<a name="line.2054"></a>
-<span class="sourceLineNo">2055</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2055"></a>
-<span class="sourceLineNo">2056</span>  }<a name="line.2056"></a>
-<span class="sourceLineNo">2057</span><a name="line.2057"></a>
-<span class="sourceLineNo">2058</span>  // should be called under the RegionStateNode lock<a name="line.2058"></a>
-<span class="sourceLineNo">2059</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2059"></a>
-<span class="sourceLineNo">2060</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2060"></a>
-<span class="sourceLineNo">2061</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2061"></a>
-<span class="sourceLineNo">2062</span>    regionNode.setRegionLocation(null);<a name="line.2062"></a>
-<span class="sourceLineNo">2063</span>    if (regionLocation != null) {<a name="line.2063"></a>
-<span class="sourceLineNo">2064</span>      regionNode.setLastHost(regionLocation);<a name="line.2064"></a>
-<span class="sourceLineNo">2065</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2065"></a>
-<span class="sourceLineNo">2066</span>    }<a name="line.2066"></a>
-<span class="sourceLineNo">2067</span>  }<a name="line.2067"></a>
-<span class="sourceLineNo">2068</span><a name="line.2068"></a>
-<span class="sourceLineNo">2069</span>  // should be called under the RegionStateNode lock<a name="line.2069"></a>
-<span class="sourceLineNo">2070</span>  // for SCP<a name="line.2070"></a>
-<span class="sourceLineNo">2071</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2071"></a>
-<span class="sourceLineNo">2072</span>    RegionState.State state = regionNode.getState();<a name="line.2072"></a>
-<span class="sourceLineNo">2073</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2073"></a>
-<span class="sourceLineNo">2074</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2074"></a>
-<span class="sourceLineNo">2075</span>    regionNode.setRegionLocation(null);<a name="line.2075"></a>
-<span class="sourceLineNo">2076</span>    boolean succ = false;<a name="line.2076"></a>
-<span class="sourceLineNo">2077</span>    try {<a name="line.2077"></a>
-<span class="sourceLineNo">2078</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2078"></a>
-<span class="sourceLineNo">2079</span>      succ = true;<a name="line.2079"></a>
-<span class="sourceLineNo">2080</span>    } finally {<a name="line.2080"></a>
-<span class="sourceLineNo">2081</span>      if (!succ) {<a name="line.2081"></a>
-<span class="sourceLineNo">2082</span>        // revert<a name="line.2082"></a>
-<span class="sourceLineNo">2083</span>        regionNode.setState(state);<a name="line.2083"></a>
-<span class="sourceLineNo">2084</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2084"></a>
-<span class="sourceLineNo">2085</span>      }<a name="line.2085"></a>
-<span class="sourceLineNo">2086</span>    }<a name="line.2086"></a>
-<span class="sourceLineNo">2087</span>    if (regionLocation != null) {<a name="line.2087"></a>
-<span class="sourceLineNo">2088</span>      regionNode.setLastHost(regionLocation);<a name="line.2088"></a>
-<span class="sourceLineNo">2089</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2089"></a>
-<span class="sourceLineNo">2090</span>    }<a name="line.2090"></a>
-<span class="sourceLineNo">2091</span>  }<a name="line.2091"></a>
-<span class="sourceLineNo">2092</span><a name="line.2092"></a>
-<span class="sourceLineNo">2093</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2093"></a>
-<span class="sourceLineNo">2094</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2094"></a>
-<span class="sourceLineNo">2095</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2095"></a>
-<span class="sourceLineNo">2096</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2096"></a>
-<span class="sourceLineNo">2097</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2097"></a>
-<span class="sourceLineNo">2098</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2098"></a>
-<span class="sourceLineNo">2099</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2099"></a>
-<span class="sourceLineNo">2100</span>      // on table that contains state.<a name="line.2100"></a>
-<span class="sourceLineNo">2101</span>      setMetaAssigned(regionInfo, true);<a name="line.2101"></a>
-<span class="sourceLineNo">2102</span>    }<a name="line.2102"></a>
-<span class="sourceLineNo">2103</span>  }<a name="line.2103"></a>
-<span class="sourceLineNo">2104</span><a name="line.2104"></a>
+<span class="sourceLineNo">1916</span>  public boolean hasRegionsInTransition() {<a name="line.1916"></a>
+<span class="sourceLineNo">1917</span>    return regionStates.hasRegionsInTransition();<a name="line.1917"></a>
+<span class="sourceLineNo">1918</span>  }<a name="line.1918"></a>
+<span class="sourceLineNo">1919</span><a name="line.1919"></a>
+<span class="sourceLineNo">1920</span>  public List&lt;RegionStateNode&gt; getRegionsInTransition() {<a name="line.1920"></a>
+<span class="sourceLineNo">1921</span>    return regionStates.getRegionsInTransition();<a name="line.1921"></a>
+<span class="sourceLineNo">1922</span>  }<a name="line.1922"></a>
+<span class="sourceLineNo">1923</span><a name="line.1923"></a>
+<span class="sourceLineNo">1924</span>  public List&lt;RegionInfo&gt; getAssignedRegions() {<a name="line.1924"></a>
+<span class="sourceLineNo">1925</span>    return regionStates.getAssignedRegions();<a name="line.1925"></a>
+<span class="sourceLineNo">1926</span>  }<a name="line.1926"></a>
+<span class="sourceLineNo">1927</span><a name="line.1927"></a>
+<span class="sourceLineNo">1928</span>  /**<a name="line.1928"></a>
+<span class="sourceLineNo">1929</span>   * Resolve a cached {@link RegionInfo} from the region name as a {@code byte[]}.<a name="line.1929"></a>
+<span class="sourceLineNo">1930</span>   */<a name="line.1930"></a>
+<span class="sourceLineNo">1931</span>  public RegionInfo getRegionInfo(final byte[] regionName) {<a name="line.1931"></a>
+<span class="sourceLineNo">1932</span>    final RegionStateNode regionState = regionStates.getRegionStateNodeFromName(regionName);<a name="line.1932"></a>
+<span class="sourceLineNo">1933</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1933"></a>
+<span class="sourceLineNo">1934</span>  }<a name="line.1934"></a>
+<span class="sourceLineNo">1935</span><a name="line.1935"></a>
+<span class="sourceLineNo">1936</span>  /**<a name="line.1936"></a>
+<span class="sourceLineNo">1937</span>   * Resolve a cached {@link RegionInfo} from the encoded region name as a {@code String}.<a name="line.1937"></a>
+<span class="sourceLineNo">1938</span>   */<a name="line.1938"></a>
+<span class="sourceLineNo">1939</span>  public RegionInfo getRegionInfo(final String encodedRegionName) {<a name="line.1939"></a>
+<span class="sourceLineNo">1940</span>    final RegionStateNode regionState =<a name="line.1940"></a>
+<span class="sourceLineNo">1941</span>      regionStates.getRegionStateNodeFromEncodedRegionName(encodedRegionName);<a name="line.1941"></a>
+<span class="sourceLineNo">1942</span>    return regionState != null ? regionState.getRegionInfo() : null;<a name="line.1942"></a>
+<span class="sourceLineNo">1943</span>  }<a name="line.1943"></a>
+<span class="sourceLineNo">1944</span><a name="line.1944"></a>
+<span class="sourceLineNo">1945</span>  // ============================================================================================<a name="line.1945"></a>
+<span class="sourceLineNo">1946</span>  // Expected states on region state transition.<a name="line.1946"></a>
+<span class="sourceLineNo">1947</span>  // Notice that there is expected states for transiting to OPENING state, this is because SCP.<a name="line.1947"></a>
+<span class="sourceLineNo">1948</span>  // See the comments in regionOpening method for more details.<a name="line.1948"></a>
+<span class="sourceLineNo">1949</span>  // ============================================================================================<a name="line.1949"></a>
+<span class="sourceLineNo">1950</span>  private static final State[] STATES_EXPECTED_ON_OPEN = { State.OPENING, // Normal case<a name="line.1950"></a>
+<span class="sourceLineNo">1951</span>    State.OPEN // Retrying<a name="line.1951"></a>
+<span class="sourceLineNo">1952</span>  };<a name="line.1952"></a>
+<span class="sourceLineNo">1953</span><a name="line.1953"></a>
+<span class="sourceLineNo">1954</span>  private static final State[] STATES_EXPECTED_ON_CLOSING = { State.OPEN, // Normal case<a name="line.1954"></a>
+<span class="sourceLineNo">1955</span>    State.CLOSING, // Retrying<a name="line.1955"></a>
+<span class="sourceLineNo">1956</span>    State.SPLITTING, // Offline the split parent<a name="line.1956"></a>
+<span class="sourceLineNo">1957</span>    State.MERGING // Offline the merge parents<a name="line.1957"></a>
+<span class="sourceLineNo">1958</span>  };<a name="line.1958"></a>
+<span class="sourceLineNo">1959</span><a name="line.1959"></a>
+<span class="sourceLineNo">1960</span>  private static final State[] STATES_EXPECTED_ON_CLOSED = { State.CLOSING, // Normal case<a name="line.1960"></a>
+<span class="sourceLineNo">1961</span>    State.CLOSED // Retrying<a name="line.1961"></a>
+<span class="sourceLineNo">1962</span>  };<a name="line.1962"></a>
+<span class="sourceLineNo">1963</span><a name="line.1963"></a>
+<span class="sourceLineNo">1964</span>  // This is for manually scheduled region assign, can add other states later if we find out other<a name="line.1964"></a>
+<span class="sourceLineNo">1965</span>  // usages<a name="line.1965"></a>
+<span class="sourceLineNo">1966</span>  private static final State[] STATES_EXPECTED_ON_ASSIGN = { State.CLOSED, State.OFFLINE };<a name="line.1966"></a>
+<span class="sourceLineNo">1967</span><a name="line.1967"></a>
+<span class="sourceLineNo">1968</span>  // We only allow unassign or move a region which is in OPEN state.<a name="line.1968"></a>
+<span class="sourceLineNo">1969</span>  private static final State[] STATES_EXPECTED_ON_UNASSIGN_OR_MOVE = { State.OPEN };<a name="line.1969"></a>
+<span class="sourceLineNo">1970</span><a name="line.1970"></a>
+<span class="sourceLineNo">1971</span>  // ============================================================================================<a name="line.1971"></a>
+<span class="sourceLineNo">1972</span>  // Region Status update<a name="line.1972"></a>
+<span class="sourceLineNo">1973</span>  // Should only be called in TransitRegionStateProcedure(and related procedures), as the locking<a name="line.1973"></a>
+<span class="sourceLineNo">1974</span>  // and pre-assumptions are very tricky.<a name="line.1974"></a>
+<span class="sourceLineNo">1975</span>  // ============================================================================================<a name="line.1975"></a>
+<span class="sourceLineNo">1976</span>  private void transitStateAndUpdate(RegionStateNode regionNode, RegionState.State newState,<a name="line.1976"></a>
+<span class="sourceLineNo">1977</span>    RegionState.State... expectedStates) throws IOException {<a name="line.1977"></a>
+<span class="sourceLineNo">1978</span>    RegionState.State state = regionNode.getState();<a name="line.1978"></a>
+<span class="sourceLineNo">1979</span>    regionNode.transitionState(newState, expectedStates);<a name="line.1979"></a>
+<span class="sourceLineNo">1980</span>    boolean succ = false;<a name="line.1980"></a>
+<span class="sourceLineNo">1981</span>    try {<a name="line.1981"></a>
+<span class="sourceLineNo">1982</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.1982"></a>
+<span class="sourceLineNo">1983</span>      succ = true;<a name="line.1983"></a>
+<span class="sourceLineNo">1984</span>    } finally {<a name="line.1984"></a>
+<span class="sourceLineNo">1985</span>      if (!succ) {<a name="line.1985"></a>
+<span class="sourceLineNo">1986</span>        // revert<a name="line.1986"></a>
+<span class="sourceLineNo">1987</span>        regionNode.setState(state);<a name="line.1987"></a>
+<span class="sourceLineNo">1988</span>      }<a name="line.1988"></a>
+<span class="sourceLineNo">1989</span>    }<a name="line.1989"></a>
+<span class="sourceLineNo">1990</span>  }<a name="line.1990"></a>
+<span class="sourceLineNo">1991</span><a name="line.1991"></a>
+<span class="sourceLineNo">1992</span>  // should be called within the synchronized block of RegionStateNode<a name="line.1992"></a>
+<span class="sourceLineNo">1993</span>  void regionOpening(RegionStateNode regionNode) throws IOException {<a name="line.1993"></a>
+<span class="sourceLineNo">1994</span>    // As in SCP, for performance reason, there is no TRSP attached with this region, we will not<a name="line.1994"></a>
+<span class="sourceLineNo">1995</span>    // update the region state, which means that the region could be in any state when we want to<a name="line.1995"></a>
+<span class="sourceLineNo">1996</span>    // assign it after a RS crash. So here we do not pass the expectedStates parameter.<a name="line.1996"></a>
+<span class="sourceLineNo">1997</span>    transitStateAndUpdate(regionNode, State.OPENING);<a name="line.1997"></a>
+<span class="sourceLineNo">1998</span>    regionStates.addRegionToServer(regionNode);<a name="line.1998"></a>
+<span class="sourceLineNo">1999</span>    // update the operation count metrics<a name="line.1999"></a>
+<span class="sourceLineNo">2000</span>    metrics.incrementOperationCounter();<a name="line.2000"></a>
+<span class="sourceLineNo">2001</span>  }<a name="line.2001"></a>
+<span class="sourceLineNo">2002</span><a name="line.2002"></a>
+<span class="sourceLineNo">2003</span>  // should be called under the RegionStateNode lock<a name="line.2003"></a>
+<span class="sourceLineNo">2004</span>  // The parameter 'giveUp' means whether we will try to open the region again, if it is true, then<a name="line.2004"></a>
+<span class="sourceLineNo">2005</span>  // we will persist the FAILED_OPEN state into hbase:meta.<a name="line.2005"></a>
+<span class="sourceLineNo">2006</span>  void regionFailedOpen(RegionStateNode regionNode, boolean giveUp) throws IOException {<a name="line.2006"></a>
+<span class="sourceLineNo">2007</span>    RegionState.State state = regionNode.getState();<a name="line.2007"></a>
+<span class="sourceLineNo">2008</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2008"></a>
+<span class="sourceLineNo">2009</span>    if (giveUp) {<a name="line.2009"></a>
+<span class="sourceLineNo">2010</span>      regionNode.setState(State.FAILED_OPEN);<a name="line.2010"></a>
+<span class="sourceLineNo">2011</span>      regionNode.setRegionLocation(null);<a name="line.2011"></a>
+<span class="sourceLineNo">2012</span>      boolean succ = false;<a name="line.2012"></a>
+<span class="sourceLineNo">2013</span>      try {<a name="line.2013"></a>
+<span class="sourceLineNo">2014</span>        regionStateStore.updateRegionLocation(regionNode);<a name="line.2014"></a>
+<span class="sourceLineNo">2015</span>        succ = true;<a name="line.2015"></a>
+<span class="sourceLineNo">2016</span>      } finally {<a name="line.2016"></a>
+<span class="sourceLineNo">2017</span>        if (!succ) {<a name="line.2017"></a>
+<span class="sourceLineNo">2018</span>          // revert<a name="line.2018"></a>
+<span class="sourceLineNo">2019</span>          regionNode.setState(state);<a name="line.2019"></a>
+<span class="sourceLineNo">2020</span>          regionNode.setRegionLocation(regionLocation);<a name="line.2020"></a>
+<span class="sourceLineNo">2021</span>        }<a name="line.2021"></a>
+<span class="sourceLineNo">2022</span>      }<a name="line.2022"></a>
+<span class="sourceLineNo">2023</span>    }<a name="line.2023"></a>
+<span class="sourceLineNo">2024</span>    if (regionLocation != null) {<a name="line.2024"></a>
+<span class="sourceLineNo">2025</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2025"></a>
+<span class="sourceLineNo">2026</span>    }<a name="line.2026"></a>
+<span class="sourceLineNo">2027</span>  }<a name="line.2027"></a>
+<span class="sourceLineNo">2028</span><a name="line.2028"></a>
+<span class="sourceLineNo">2029</span>  // should be called under the RegionStateNode lock<a name="line.2029"></a>
+<span class="sourceLineNo">2030</span>  void regionClosing(RegionStateNode regionNode) throws IOException {<a name="line.2030"></a>
+<span class="sourceLineNo">2031</span>    transitStateAndUpdate(regionNode, State.CLOSING, STATES_EXPECTED_ON_CLOSING);<a name="line.2031"></a>
+<span class="sourceLineNo">2032</span><a name="line.2032"></a>
+<span class="sourceLineNo">2033</span>    RegionInfo hri = regionNode.getRegionInfo();<a name="line.2033"></a>
+<span class="sourceLineNo">2034</span>    // Set meta has not initialized early. so people trying to create/edit tables will wait<a name="line.2034"></a>
+<span class="sourceLineNo">2035</span>    if (isMetaRegion(hri)) {<a name="line.2035"></a>
+<span class="sourceLineNo">2036</span>      setMetaAssigned(hri, false);<a name="line.2036"></a>
+<span class="sourceLineNo">2037</span>    }<a name="line.2037"></a>
+<span class="sourceLineNo">2038</span>    regionStates.addRegionToServer(regionNode);<a name="line.2038"></a>
+<span class="sourceLineNo">2039</span>    // update the operation count metrics<a name="line.2039"></a>
+<span class="sourceLineNo">2040</span>    metrics.incrementOperationCounter();<a name="line.2040"></a>
+<span class="sourceLineNo">2041</span>  }<a name="line.2041"></a>
+<span class="sourceLineNo">2042</span><a name="line.2042"></a>
+<span class="sourceLineNo">2043</span>  // for open and close, they will first be persist to the procedure store in<a name="line.2043"></a>
+<span class="sourceLineNo">2044</span>  // RegionRemoteProcedureBase. So here we will first change the in memory state as it is considered<a name="line.2044"></a>
+<span class="sourceLineNo">2045</span>  // as succeeded if the persistence to procedure store is succeeded, and then when the<a name="line.2045"></a>
+<span class="sourceLineNo">2046</span>  // RegionRemoteProcedureBase is woken up, we will persist the RegionStateNode to hbase:meta.<a name="line.2046"></a>
+<span class="sourceLineNo">2047</span><a name="line.2047"></a>
+<span class="sourceLineNo">2048</span>  // should be called under the RegionStateNode lock<a name="line.2048"></a>
+<span class="sourceLineNo">2049</span>  void regionOpenedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2049"></a>
+<span class="sourceLineNo">2050</span>    regionNode.transitionState(State.OPEN, STATES_EXPECTED_ON_OPEN);<a name="line.2050"></a>
+<span class="sourceLineNo">2051</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2051"></a>
+<span class="sourceLineNo">2052</span>    regionStates.addRegionToServer(regionNode);<a name="line.2052"></a>
+<span class="sourceLineNo">2053</span>    regionStates.removeFromFailedOpen(regionInfo);<a name="line.2053"></a>
+<span class="sourceLineNo">2054</span>  }<a name="line.2054"></a>
+<span class="sourceLineNo">2055</span><a name="line.2055"></a>
+<span class="sourceLineNo">2056</span>  // should be called under the RegionStateNode lock<a name="line.2056"></a>
+<span class="sourceLineNo">2057</span>  void regionClosedWithoutPersistingToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2057"></a>
+<span class="sourceLineNo">2058</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2058"></a>
+<span class="sourceLineNo">2059</span>    regionNode.transitionState(State.CLOSED, STATES_EXPECTED_ON_CLOSED);<a name="line.2059"></a>
+<span class="sourceLineNo">2060</span>    regionNode.setRegionLocation(null);<a name="line.2060"></a>
+<span class="sourceLineNo">2061</span>    if (regionLocation != null) {<a name="line.2061"></a>
+<span class="sourceLineNo">2062</span>      regionNode.setLastHost(regionLocation);<a name="line.2062"></a>
+<span class="sourceLineNo">2063</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2063"></a>
+<span class="sourceLineNo">2064</span>    }<a name="line.2064"></a>
+<span class="sourceLineNo">2065</span>  }<a name="line.2065"></a>
+<span class="sourceLineNo">2066</span><a name="line.2066"></a>
+<span class="sourceLineNo">2067</span>  // should be called under the RegionStateNode lock<a name="line.2067"></a>
+<span class="sourceLineNo">2068</span>  // for SCP<a name="line.2068"></a>
+<span class="sourceLineNo">2069</span>  public void regionClosedAbnormally(RegionStateNode regionNode) throws IOException {<a name="line.2069"></a>
+<span class="sourceLineNo">2070</span>    RegionState.State state = regionNode.getState();<a name="line.2070"></a>
+<span class="sourceLineNo">2071</span>    ServerName regionLocation = regionNode.getRegionLocation();<a name="line.2071"></a>
+<span class="sourceLineNo">2072</span>    regionNode.transitionState(State.ABNORMALLY_CLOSED);<a name="line.2072"></a>
+<span class="sourceLineNo">2073</span>    regionNode.setRegionLocation(null);<a name="line.2073"></a>
+<span class="sourceLineNo">2074</span>    boolean succ = false;<a name="line.2074"></a>
+<span class="sourceLineNo">2075</span>    try {<a name="line.2075"></a>
+<span class="sourceLineNo">2076</span>      regionStateStore.updateRegionLocation(regionNode);<a name="line.2076"></a>
+<span class="sourceLineNo">2077</span>      succ = true;<a name="line.2077"></a>
+<span class="sourceLineNo">2078</span>    } finally {<a name="line.2078"></a>
+<span class="sourceLineNo">2079</span>      if (!succ) {<a name="line.2079"></a>
+<span class="sourceLineNo">2080</span>        // revert<a name="line.2080"></a>
+<span class="sourceLineNo">2081</span>        regionNode.setState(state);<a name="line.2081"></a>
+<span class="sourceLineNo">2082</span>        regionNode.setRegionLocation(regionLocation);<a name="line.2082"></a>
+<span class="sourceLineNo">2083</span>      }<a name="line.2083"></a>
+<span class="sourceLineNo">2084</span>    }<a name="line.2084"></a>
+<span class="sourceLineNo">2085</span>    if (regionLocation != null) {<a name="line.2085"></a>
+<span class="sourceLineNo">2086</span>      regionNode.setLastHost(regionLocation);<a name="line.2086"></a>
+<span class="sourceLineNo">2087</span>      regionStates.removeRegionFromServer(regionLocation, regionNode);<a name="line.2087"></a>
+<span class="sourceLineNo">2088</span>    }<a name="line.2088"></a>
+<span class="sourceLineNo">2089</span>  }<a name="line.2089"></a>
+<span class="sourceLineNo">2090</span><a name="line.2090"></a>
+<span class="sourceLineNo">2091</span>  void persistToMeta(RegionStateNode regionNode) throws IOException {<a name="line.2091"></a>
+<span class="sourceLineNo">2092</span>    regionStateStore.updateRegionLocation(regionNode);<a name="line.2092"></a>
+<span class="sourceLineNo">2093</span>    RegionInfo regionInfo = regionNode.getRegionInfo();<a name="line.2093"></a>
+<span class="sourceLineNo">2094</span>    if (isMetaRegion(regionInfo) &amp;&amp; regionNode.getState() == State.OPEN) {<a name="line.2094"></a>
+<span class="sourceLineNo">2095</span>      // Usually we'd set a table ENABLED at this stage but hbase:meta is ALWAYs enabled, it<a name="line.2095"></a>
+<span class="sourceLineNo">2096</span>      // can't be disabled -- so skip the RPC (besides... enabled is managed by TableStateManager<a name="line.2096"></a>
+<span class="sourceLineNo">2097</span>      // which is backed by hbase:meta... Avoid setting ENABLED to avoid having to update state<a name="line.2097"></a>
+<span class="sourceLineNo">2098</span>      // on table that contains state.<a name="line.2098"></a>
+<span class="sourceLineNo">2099</span>      setMetaAssigned(regionInfo, true);<a name="line.2099"></a>
+<span class="sourceLineNo">2100</span>    }<a name="line.2100"></a>
+<span class="sourceLineNo">2101</span>  }<a name="line.2101"></a>
+<span class="sourceLineNo">2102</span><a name="line.2102"></a>
+<span class="sourceLineNo">2103</span>  // ============================================================================================<a name="line.2103"></a>
+<span class="sourceLineNo">2104</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2104"></a>
 <span class="sourceLineNo">2105</span>  // ============================================================================================<a name="line.2105"></a>
-<span class="sourceLineNo">2106</span>  // The above methods can only be called in TransitRegionStateProcedure(and related procedures)<a name="line.2106"></a>
-<span class="sourceLineNo">2107</span>  // ============================================================================================<a name="line.2107"></a>
-<span class="sourceLineNo">2108</span><a name="line.2108"></a>
-<span class="sourceLineNo">2109</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2109"></a>
-<span class="sourceLineNo">2110</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2110"></a>
-<span class="sourceLineNo">2111</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2111"></a>
-<span class="sourceLineNo">2112</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2112"></a>
-<span class="sourceLineNo">2113</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2113"></a>
-<span class="sourceLineNo">2114</span>    // later figuring what regions are in a table and what are not: see<a name="line.2114"></a>
-<span class="sourceLineNo">2115</span>    // regionStates#getRegionsOfTable<a name="line.2115"></a>
-<span class="sourceLineNo">2116</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2116"></a>
-<span class="sourceLineNo">2117</span>    node.setState(State.SPLIT);<a name="line.2117"></a>
-<span class="sourceLineNo">2118</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2118"></a>
-<span class="sourceLineNo">2119</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
-<span class="sourceLineNo">2120</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2120"></a>
-<span class="sourceLineNo">2121</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2121"></a>
-<span class="sourceLineNo">2122</span><a name="line.2122"></a>
-<span class="sourceLineNo">2123</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2123"></a>
-<span class="sourceLineNo">2124</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2124"></a>
-<span class="sourceLineNo">2125</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2125"></a>
-<span class="sourceLineNo">2126</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2126"></a>
-<span class="sourceLineNo">2127</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2127"></a>
-<span class="sourceLineNo">2128</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2128"></a>
-<span class="sourceLineNo">2129</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2129"></a>
-<span class="sourceLineNo">2130</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2130"></a>
-<span class="sourceLineNo">2131</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2131"></a>
-<span class="sourceLineNo">2132</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2132"></a>
-<span class="sourceLineNo">2133</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2133"></a>
-<span class="sourceLineNo">2134</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2134"></a>
-<span class="sourceLineNo">2135</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2135"></a>
-<span class="sourceLineNo">2136</span>        daughterB);<a name="line.2136"></a>
-<span class="sourceLineNo">2137</span>    }<a name="line.2137"></a>
-<span class="sourceLineNo">2138</span>  }<a name="line.2138"></a>
-<span class="sourceLineNo">2139</span><a name="line.2139"></a>
-<span class="sourceLineNo">2140</span>  /**<a name="line.2140"></a>
-<span class="sourceLineNo">2141</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2141"></a>
-<span class="sourceLineNo">2142</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2142"></a>
-<span class="sourceLineNo">2143</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2143"></a>
-<span class="sourceLineNo">2144</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2144"></a>
-<span class="sourceLineNo">2145</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2145"></a>
-<span class="sourceLineNo">2146</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2146"></a>
-<span class="sourceLineNo">2147</span>   * the archiver chore runs, are the References removed).<a name="line.2147"></a>
-<span class="sourceLineNo">2148</span>   */<a name="line.2148"></a>
-<span class="sourceLineNo">2149</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2149"></a>
-<span class="sourceLineNo">2150</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2150"></a>
-<span class="sourceLineNo">2151</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2151"></a>
-<span class="sourceLineNo">2152</span>    node.setState(State.MERGED);<a name="line.2152"></a>
-<span class="sourceLineNo">2153</span>    for (RegionInfo ri : mergeParents) {<a name="line.2153"></a>
-<span class="sourceLineNo">2154</span>      regionStates.deleteRegion(ri);<a name="line.2154"></a>
-<span class="sourceLineNo">2155</span>    }<a name="line.2155"></a>
-<span class="sourceLineNo">2156</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2156"></a>
-<span class="sourceLineNo">2157</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2157"></a>
-<span class="sourceLineNo">2158</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2158"></a>
-<span class="sourceLineNo">2159</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2159"></a>
-<span class="sourceLineNo">2160</span>    }<a name="line.2160"></a>
-<span class="sourceLineNo">2161</span>  }<a name="line.2161"></a>
-<span class="sourceLineNo">2162</span><a name="line.2162"></a>
-<span class="sourceLineNo">2163</span>  /*<a name="line.2163"></a>
-<span class="sourceLineNo">2164</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2164"></a>
-<span class="sourceLineNo">2165</span>   * belongs to a non-system table.<a name="line.2165"></a>
-<span class="sourceLineNo">2166</span>   */<a name="line.2166"></a>
-<span class="sourceLineNo">2167</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2167"></a>
-<span class="sourceLineNo">2168</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2168"></a>
-<span class="sourceLineNo">2169</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2169"></a>
-<span class="sourceLineNo">2170</span>  }<a name="line.2170"></a>
-<span class="sourceLineNo">2171</span><a name="line.2171"></a>
+<span class="sourceLineNo">2106</span><a name="line.2106"></a>
+<span class="sourceLineNo">2107</span>  public void markRegionAsSplit(final RegionInfo parent, final ServerName serverName,<a name="line.2107"></a>
+<span class="sourceLineNo">2108</span>    final RegionInfo daughterA, final RegionInfo daughterB) throws IOException {<a name="line.2108"></a>
+<span class="sourceLineNo">2109</span>    // Update hbase:meta. Parent will be marked offline and split up in hbase:meta.<a name="line.2109"></a>
+<span class="sourceLineNo">2110</span>    // The parent stays in regionStates until cleared when removed by CatalogJanitor.<a name="line.2110"></a>
+<span class="sourceLineNo">2111</span>    // Update its state in regionStates to it shows as offline and split when read<a name="line.2111"></a>
+<span class="sourceLineNo">2112</span>    // later figuring what regions are in a table and what are not: see<a name="line.2112"></a>
+<span class="sourceLineNo">2113</span>    // regionStates#getRegionsOfTable<a name="line.2113"></a>
+<span class="sourceLineNo">2114</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(parent);<a name="line.2114"></a>
+<span class="sourceLineNo">2115</span>    node.setState(State.SPLIT);<a name="line.2115"></a>
+<span class="sourceLineNo">2116</span>    final RegionStateNode nodeA = regionStates.getOrCreateRegionStateNode(daughterA);<a name="line.2116"></a>
+<span class="sourceLineNo">2117</span>    nodeA.setState(State.SPLITTING_NEW);<a name="line.2117"></a>
+<span class="sourceLineNo">2118</span>    final RegionStateNode nodeB = regionStates.getOrCreateRegionStateNode(daughterB);<a name="line.2118"></a>
+<span class="sourceLineNo">2119</span>    nodeB.setState(State.SPLITTING_NEW);<a name="line.2119"></a>
+<span class="sourceLineNo">2120</span><a name="line.2120"></a>
+<span class="sourceLineNo">2121</span>    TableDescriptor td = master.getTableDescriptors().get(parent.getTable());<a name="line.2121"></a>
+<span class="sourceLineNo">2122</span>    // TODO: here we just update the parent region info in meta, to set split and offline to true,<a name="line.2122"></a>
+<span class="sourceLineNo">2123</span>    // without changing the one in the region node. This is a bit confusing but the region info<a name="line.2123"></a>
+<span class="sourceLineNo">2124</span>    // field in RegionStateNode is not expected to be changed in the current design. Need to find a<a name="line.2124"></a>
+<span class="sourceLineNo">2125</span>    // possible way to address this problem, or at least adding more comments about the trick to<a name="line.2125"></a>
+<span class="sourceLineNo">2126</span>    // deal with this problem, that when you want to filter out split parent, you need to check both<a name="line.2126"></a>
+<span class="sourceLineNo">2127</span>    // the RegionState on whether it is split, and also the region info. If one of them matches then<a name="line.2127"></a>
+<span class="sourceLineNo">2128</span>    // it is a split parent. And usually only one of them can match, as after restart, the region<a name="line.2128"></a>
+<span class="sourceLineNo">2129</span>    // state will be changed from SPLIT to CLOSED.<a name="line.2129"></a>
+<span class="sourceLineNo">2130</span>    regionStateStore.splitRegion(parent, daughterA, daughterB, serverName, td);<a name="line.2130"></a>
+<span class="sourceLineNo">2131</span>    if (shouldAssignFavoredNodes(parent)) {<a name="line.2131"></a>
+<span class="sourceLineNo">2132</span>      List&lt;ServerName&gt; onlineServers = this.master.getServerManager().getOnlineServersList();<a name="line.2132"></a>
+<span class="sourceLineNo">2133</span>      getFavoredNodePromoter().generateFavoredNodesForDaughter(onlineServers, parent, daughterA,<a name="line.2133"></a>
+<span class="sourceLineNo">2134</span>        daughterB);<a name="line.2134"></a>
+<span class="sourceLineNo">2135</span>    }<a name="line.2135"></a>
+<span class="sourceLineNo">2136</span>  }<a name="line.2136"></a>
+<span class="sourceLineNo">2137</span><a name="line.2137"></a>
+<span class="sourceLineNo">2138</span>  /**<a name="line.2138"></a>
+<span class="sourceLineNo">2139</span>   * When called here, the merge has happened. The merged regions have been unassigned and the above<a name="line.2139"></a>
+<span class="sourceLineNo">2140</span>   * markRegionClosed has been called on each so they have been disassociated from a hosting Server.<a name="line.2140"></a>
+<span class="sourceLineNo">2141</span>   * The merged region will be open after this call. The merged regions are removed from hbase:meta<a name="line.2141"></a>
+<span class="sourceLineNo">2142</span>   * below. Later they are deleted from the filesystem by the catalog janitor running against<a name="line.2142"></a>
+<span class="sourceLineNo">2143</span>   * hbase:meta. It notices when the merged region no longer holds references to the old regions<a name="line.2143"></a>
+<span class="sourceLineNo">2144</span>   * (References are deleted after a compaction rewrites what the Reference points at but not until<a name="line.2144"></a>
+<span class="sourceLineNo">2145</span>   * the archiver chore runs, are the References removed).<a name="line.2145"></a>
+<span class="sourceLineNo">2146</span>   */<a name="line.2146"></a>
+<span class="sourceLineNo">2147</span>  public void markRegionAsMerged(final RegionInfo child, final ServerName serverName,<a name="line.2147"></a>
+<span class="sourceLineNo">2148</span>    RegionInfo[] mergeParents) throws IOException {<a name="line.2148"></a>
+<span class="sourceLineNo">2149</span>    final RegionStateNode node = regionStates.getOrCreateRegionStateNode(child);<a name="line.2149"></a>
+<span class="sourceLineNo">2150</span>    node.setState(State.MERGED);<a name="line.2150"></a>
+<span class="sourceLineNo">2151</span>    for (RegionInfo ri : mergeParents) {<a name="line.2151"></a>
+<span class="sourceLineNo">2152</span>      regionStates.deleteRegion(ri);<a name="line.2152"></a>
+<span class="sourceLineNo">2153</span>    }<a name="line.2153"></a>
+<span class="sourceLineNo">2154</span>    TableDescriptor td = master.getTableDescriptors().get(child.getTable());<a name="line.2154"></a>
+<span class="sourceLineNo">2155</span>    regionStateStore.mergeRegions(child, mergeParents, serverName, td);<a name="line.2155"></a>
+<span class="sourceLineNo">2156</span>    if (shouldAssignFavoredNodes(child)) {<a name="line.2156"></a>
+<span class="sourceLineNo">2157</span>      getFavoredNodePromoter().generateFavoredNodesForMergedRegion(child, mergeParents);<a name="line.2157"></a>
+<span class="sourceLineNo">2158</span>    }<a name="line.2158"></a>
+<span class="sourceLineNo">2159</span>  }<a name="line.2159"></a>
+<span class="sourceLineNo">2160</span><a name="line.2160"></a>
+<span class="sourceLineNo">2161</span>  /*<a name="line.2161"></a>
+<span class="sourceLineNo">2162</span>   * Favored nodes should be applied only when FavoredNodes balancer is configured and the region<a name="line.2162"></a>
+<span class="sourceLineNo">2163</span>   * belongs to a non-system table.<a name="line.2163"></a>
+<span class="sourceLineNo">2164</span>   */<a name="line.2164"></a>
+<span class="sourceLineNo">2165</span>  private boolean shouldAssignFavoredNodes(RegionInfo region) {<a name="line.2165"></a>
+<span class="sourceLineNo">2166</span>    return this.shouldAssignRegionsWithFavoredNodes<a name="line.2166"></a>
+<span class="sourceLineNo">2167</span>      &amp;&amp; FavoredNodesManager.isFavoredNodeApplicable(region);<a name="line.2167"></a>
+<span class="sourceLineNo">2168</span>  }<a name="line.2168"></a>
+<span class="sourceLineNo">2169</span><a name="line.2169"></a>
+<span class="sourceLineNo">2170</span>  // ============================================================================================<a name="line.2170"></a>
+<span class="sourceLineNo">2171</span>  // Assign Queue (Assign/Balance)<a name="line.2171"></a>
 <span class="sourceLineNo">2172</span>  // ============================================================================================<a name="line.2172"></a>
-<span class="sourceLineNo">2173</span>  // Assign Queue (Assign/Balance)<a name="line.2173"></a>
-<span class="sourceLineNo">2174</span>  // ============================================================================================<a name="line.2174"></a>
-<span class="sourceLineNo">2175</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2175"></a>
-<span class="sourceLineNo">2176</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2176"></a>
-<span class="sourceLineNo">2177</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2177"></a>
-<span class="sourceLineNo">2178</span><a name="line.2178"></a>
-<span class="sourceLineNo">2179</span>  /**<a name="line.2179"></a>
-<span class="sourceLineNo">2180</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2180"></a>
-<span class="sourceLineNo">2181</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2181"></a>
-<span class="sourceLineNo">2182</span>   */<a name="line.2182"></a>
-<span class="sourceLineNo">2183</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2183"></a>
-<span class="sourceLineNo">2184</span>    regionNode.getProcedureEvent().suspend();<a name="line.2184"></a>
-<span class="sourceLineNo">2185</span><a name="line.2185"></a>
-<span class="sourceLineNo">2186</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2186"></a>
-<span class="sourceLineNo">2187</span>    assignQueueLock.lock();<a name="line.2187"></a>
-<span class="sourceLineNo">2188</span>    try {<a name="line.2188"></a>
-<span class="sourceLineNo">2189</span>      pendingAssignQueue.add(regionNode);<a name="line.2189"></a>
-<span class="sourceLineNo">2190</span>      if (<a name="line.2190"></a>
-<span class="sourceLineNo">2191</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2191"></a>
-<span class="sourceLineNo">2192</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2192"></a>
-<span class="sourceLineNo">2193</span>      ) {<a name="line.2193"></a>
-<span class="sourceLineNo">2194</span>        assignQueueFullCond.signal();<a name="line.2194"></a>
-<span class="sourceLineNo">2195</span>      }<a name="line.2195"></a>
-<span class="sourceLineNo">2196</span>    } finally {<a name="line.2196"></a>
-<span class="sourceLineNo">2197</span>      assignQueueLock.unlock();<a name="line.2197"></a>
-<span class="sourceLineNo">2198</span>    }<a name="line.2198"></a>
-<span class="sourceLineNo">2199</span>  }<a name="line.2199"></a>
-<span class="sourceLineNo">2200</span><a name="line.2200"></a>
-<span class="sourceLineNo">2201</span>  private void startAssignmentThread() {<a name="line.2201"></a>
-<span class="sourceLineNo">2202</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2202"></a>
-<span class="sourceLineNo">2203</span>      @Override<a name="line.2203"></a>
-<span class="sourceLineNo">2204</span>      public void run() {<a name="line.2204"></a>
-<span class="sourceLineNo">2205</span>        while (isRunning()) {<a name="line.2205"></a>
-<span class="sourceLineNo">2206</span>          processAssignQueue();<a name="line.2206"></a>
-<span class="sourceLineNo">2207</span>        }<a name="line.2207"></a>
-<span class="sourceLineNo">2208</span>        pendingAssignQueue.clear();<a name="line.2208"></a>
-<span class="sourceLineNo">2209</span>      }<a name="line.2209"></a>
-<span class="sourceLineNo">2210</span>    };<a name="line.2210"></a>
-<span class="sourceLineNo">2211</span>    assignThread.setDaemon(true);<a name="line.2211"></a>
-<span class="sourceLineNo">2212</span>    assignThread.start();<a name="line.2212"></a>
-<span class="sourceLineNo">2213</span>  }<a name="line.2213"></a>
-<span class="sourceLineNo">2214</span><a name="line.2214"></a>
-<span class="sourceLineNo">2215</span>  private void stopAssignmentThread() {<a name="line.2215"></a>
-<span class="sourceLineNo">2216</span>    assignQueueSignal();<a name="line.2216"></a>
-<span class="sourceLineNo">2217</span>    try {<a name="line.2217"></a>
-<span class="sourceLineNo">2218</span>      while (assignThread.isAlive()) {<a name="line.2218"></a>
-<span class="sourceLineNo">2219</span>        assignQueueSignal();<a name="line.2219"></a>
-<span class="sourceLineNo">2220</span>        assignThread.join(250);<a name="line.2220"></a>
-<span class="sourceLineNo">2221</span>      }<a name="line.2221"></a>
-<span class="sourceLineNo">2222</span>    } catch (InterruptedException e) {<a name="line.2222"></a>
-<span class="sourceLineNo">2223</span>      LOG.warn("join interrupted", e);<a name="line.2223"></a>
-<span class="sourceLineNo">2224</span>      Thread.currentThread().interrupt();<a name="line.2224"></a>
-<span class="sourceLineNo">2225</span>    }<a name="line.2225"></a>
-<span class="sourceLineNo">2226</span>  }<a name="line.2226"></a>
-<span class="sourceLineNo">2227</span><a name="line.2227"></a>
-<span class="sourceLineNo">2228</span>  private void assignQueueSignal() {<a name="line.2228"></a>
-<span class="sourceLineNo">2229</span>    assignQueueLock.lock();<a name="line.2229"></a>
-<span class="sourceLineNo">2230</span>    try {<a name="line.2230"></a>
-<span class="sourceLineNo">2231</span>      assignQueueFullCond.signal();<a name="line.2231"></a>
-<span class="sourceLineNo">2232</span>    } finally {<a name="line.2232"></a>
-<span class="sourceLineNo">2233</span>      assignQueueLock.unlock();<a name="line.2233"></a>
-<span class="sourceLineNo">2234</span>    }<a name="line.2234"></a>
-<span class="sourceLineNo">2235</span>  }<a name="line.2235"></a>
-<span class="sourceLineNo">2236</span><a name="line.2236"></a>
-<span class="sourceLineNo">2237</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2237"></a>
-<span class="sourceLineNo">2238</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2238"></a>
-<span class="sourceLineNo">2239</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2239"></a>
-<span class="sourceLineNo">2240</span><a name="line.2240"></a>
-<span class="sourceLineNo">2241</span>    assignQueueLock.lock();<a name="line.2241"></a>
-<span class="sourceLineNo">2242</span>    try {<a name="line.2242"></a>
-<span class="sourceLineNo">2243</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2243"></a>
-<span class="sourceLineNo">2244</span>        assignQueueFullCond.await();<a name="line.2244"></a>
-<span class="sourceLineNo">2245</span>      }<a name="line.2245"></a>
-<span class="sourceLineNo">2246</span><a name="line.2246"></a>
-<span class="sourceLineNo">2247</span>      if (!isRunning()) {<a name="line.2247"></a>
-<span class="sourceLineNo">2248</span>        return null;<a name="line.2248"></a>
-<span class="sourceLineNo">2249</span>      }<a name="line.2249"></a>
-<span class="sourceLineNo">2250</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2250"></a>
-<span class="sourceLineNo">2251</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2251"></a>
-<span class="sourceLineNo">2252</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2252"></a>
-<span class="sourceLineNo">2253</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2253"></a>
-<span class="sourceLineNo">2254</span>      }<a name="line.2254"></a>
-<span class="sourceLineNo">2255</span>      pendingAssignQueue.clear();<a name="line.2255"></a>
-<span class="sourceLineNo">2256</span>    } catch (InterruptedException e) {<a name="line.2256"></a>
-<span class="sourceLineNo">2257</span>      LOG.warn("got interrupted ", e);<a name="line.2257"></a>
-<span class="sourceLineNo">2258</span>      Thread.currentThread().interrupt();<a name="line.2258"></a>
-<span class="sourceLineNo">2259</span>    } finally {<a name="line.2259"></a>
-<span class="sourceLineNo">2260</span>      assignQueueLock.unlock();<a name="line.2260"></a>
-<span class="sourceLineNo">2261</span>    }<a name="line.2261"></a>
-<span class="sourceLineNo">2262</span>    return regions;<a name="line.2262"></a>
-<span class="sourceLineNo">2263</span>  }<a name="line.2263"></a>
-<span class="sourceLineNo">2264</span><a name="line.2264"></a>
-<span class="sourceLineNo">2265</span>  private void processAssignQueue() {<a name="line.2265"></a>
-<span class="sourceLineNo">2266</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2266"></a>
-<span class="sourceLineNo">2267</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2267"></a>
-<span class="sourceLineNo">2268</span>      return;<a name="line.2268"></a>
-<span class="sourceLineNo">2269</span>    }<a name="line.2269"></a>
-<span class="sourceLineNo">2270</span><a name="line.2270"></a>
-<span class="sourceLineNo">2271</span>    if (LOG.isTraceEnabled()) {<a name="line.2271"></a>
-<span class="sourceLineNo">2272</span>      LOG.trace("PROCESS ASSIGN QUEUE regionCount=" + regions.size());<a name="line.2272"></a>
-<span class="sourceLineNo">2273</span>    }<a name="line.2273"></a>
-<span class="sourceLineNo">2274</span><a name="line.2274"></a>
-<span class="sourceLineNo">2275</span>    // TODO: Optimize balancer. pass a RegionPlan?<a name="line.2275"></a>
-<span class="sourceLineNo">2276</span>    final HashMap&lt;RegionInfo, ServerName&gt; retainMap = new HashMap&lt;&gt;();<a name="line.2276"></a>
-<span class="sourceLineNo">2277</span>    final List&lt;RegionInfo&gt; userHRIs = new ArrayList&lt;&gt;(regions.size());<a name="line.2277"></a>
-<span class="sourceLineNo">2278</span>    // Regions for system tables requiring reassignment<a name="line.2278"></a>
-<span class="sourceLineNo">2279</span>    final List&lt;RegionInfo&gt; systemHRIs = new ArrayList&lt;&gt;();<a name="line.2279"></a>
-<span class="sourceLineNo">2280</span>    for (RegionStateNode regionStateNode : regions.values()) {<a name="line.2280"></a>
-<span class="sourceLineNo">2281</span>      boolean sysTable = regionStateNode.isSystemTable();<a name="line.2281"></a>
-<span class="sourceLineNo">2282</span>      final List&lt;RegionInfo&gt; hris = sysTable ? systemHRIs : userHRIs;<a name="line.2282"></a>
-<span class="sourceLineNo">2283</span>      if (regionStateNode.getRegionLocation() != null) {<a name="line.2283"></a>
-<span class="sourceLineNo">2284</span>        retainMap.put(regionStateNode.getRegionInfo(), regionStateNode.getRegionLocation());<a name="line.2284"></a>
-<span class="sourceLineNo">2285</span>      } else {<a name="line.2285"></a>
-<span class="sourceLineNo">2286</span>        hris.add(regionStateNode.getRegionInfo());<a name="line.2286"></a>
-<span class="sourceLineNo">2287</span>      }<a name="line.2287"></a>
-<span class="sourceLineNo">2288</span>    }<a name="line.2288"></a>
+<span class="sourceLineNo">2173</span>  private final ArrayList&lt;RegionStateNode&gt; pendingAssignQueue = new ArrayList&lt;RegionStateNode&gt;();<a name="line.2173"></a>
+<span class="sourceLineNo">2174</span>  private final ReentrantLock assignQueueLock = new ReentrantLock();<a name="line.2174"></a>
+<span class="sourceLineNo">2175</span>  private final Condition assignQueueFullCond = assignQueueLock.newCondition();<a name="line.2175"></a>
+<span class="sourceLineNo">2176</span><a name="line.2176"></a>
+<span class="sourceLineNo">2177</span>  /**<a name="line.2177"></a>
+<span class="sourceLineNo">2178</span>   * Add the assign operation to the assignment queue. The pending assignment operation will be<a name="line.2178"></a>
+<span class="sourceLineNo">2179</span>   * processed, and each region will be assigned by a server using the balancer.<a name="line.2179"></a>
+<span class="sourceLineNo">2180</span>   */<a name="line.2180"></a>
+<span class="sourceLineNo">2181</span>  protected void queueAssign(final RegionStateNode regionNode) {<a name="line.2181"></a>
+<span class="sourceLineNo">2182</span>    regionNode.getProcedureEvent().suspend();<a name="line.2182"></a>
+<span class="sourceLineNo">2183</span><a name="line.2183"></a>
+<span class="sourceLineNo">2184</span>    // TODO: quick-start for meta and the other sys-tables?<a name="line.2184"></a>
+<span class="sourceLineNo">2185</span>    assignQueueLock.lock();<a name="line.2185"></a>
+<span class="sourceLineNo">2186</span>    try {<a name="line.2186"></a>
+<span class="sourceLineNo">2187</span>      pendingAssignQueue.add(regionNode);<a name="line.2187"></a>
+<span class="sourceLineNo">2188</span>      if (<a name="line.2188"></a>
+<span class="sourceLineNo">2189</span>        regionNode.isSystemTable() || pendingAssignQueue.size() == 1<a name="line.2189"></a>
+<span class="sourceLineNo">2190</span>          || pendingAssignQueue.size() &gt;= assignDispatchWaitQueueMaxSize<a name="line.2190"></a>
+<span class="sourceLineNo">2191</span>      ) {<a name="line.2191"></a>
+<span class="sourceLineNo">2192</span>        assignQueueFullCond.signal();<a name="line.2192"></a>
+<span class="sourceLineNo">2193</span>      }<a name="line.2193"></a>
+<span class="sourceLineNo">2194</span>    } finally {<a name="line.2194"></a>
+<span class="sourceLineNo">2195</span>      assignQueueLock.unlock();<a name="line.2195"></a>
+<span class="sourceLineNo">2196</span>    }<a name="line.2196"></a>
+<span class="sourceLineNo">2197</span>  }<a name="line.2197"></a>
+<span class="sourceLineNo">2198</span><a name="line.2198"></a>
+<span class="sourceLineNo">2199</span>  private void startAssignmentThread() {<a name="line.2199"></a>
+<span class="sourceLineNo">2200</span>    assignThread = new Thread(master.getServerName().toShortString()) {<a name="line.2200"></a>
+<span class="sourceLineNo">2201</span>      @Override<a name="line.2201"></a>
+<span class="sourceLineNo">2202</span>      public void run() {<a name="line.2202"></a>
+<span class="sourceLineNo">2203</span>        while (isRunning()) {<a name="line.2203"></a>
+<span class="sourceLineNo">2204</span>          processAssignQueue();<a name="line.2204"></a>
+<span class="sourceLineNo">2205</span>        }<a name="line.2205"></a>
+<span class="sourceLineNo">2206</span>        pendingAssignQueue.clear();<a name="line.2206"></a>
+<span class="sourceLineNo">2207</span>      }<a name="line.2207"></a>
+<span class="sourceLineNo">2208</span>    };<a name="line.2208"></a>
+<span class="sourceLineNo">2209</span>    assignThread.setDaemon(true);<a name="line.2209"></a>
+<span class="sourceLineNo">2210</span>    assignThread.start();<a name="line.2210"></a>
+<span class="sourceLineNo">2211</span>  }<a name="line.2211"></a>
+<span class="sourceLineNo">2212</span><a name="line.2212"></a>
+<span class="sourceLineNo">2213</span>  private void stopAssignmentThread() {<a name="line.2213"></a>
+<span class="sourceLineNo">2214</span>    assignQueueSignal();<a name="line.2214"></a>
+<span class="sourceLineNo">2215</span>    try {<a name="line.2215"></a>
+<span class="sourceLineNo">2216</span>      while (assignThread.isAlive()) {<a name="line.2216"></a>
+<span class="sourceLineNo">2217</span>        assignQueueSignal();<a name="line.2217"></a>
+<span class="sourceLineNo">2218</span>        assignThread.join(250);<a name="line.2218"></a>
+<span class="sourceLineNo">2219</span>      }<a name="line.2219"></a>
+<span class="sourceLineNo">2220</span>    } catch (InterruptedException e) {<a name="line.2220"></a>
+<span class="sourceLineNo">2221</span>      LOG.warn("join interrupted", e);<a name="line.2221"></a>
+<span class="sourceLineNo">2222</span>      Thread.currentThread().interrupt();<a name="line.2222"></a>
+<span class="sourceLineNo">2223</span>    }<a name="line.2223"></a>
+<span class="sourceLineNo">2224</span>  }<a name="line.2224"></a>
+<span class="sourceLineNo">2225</span><a name="line.2225"></a>
+<span class="sourceLineNo">2226</span>  private void assignQueueSignal() {<a name="line.2226"></a>
+<span class="sourceLineNo">2227</span>    assignQueueLock.lock();<a name="line.2227"></a>
+<span class="sourceLineNo">2228</span>    try {<a name="line.2228"></a>
+<span class="sourceLineNo">2229</span>      assignQueueFullCond.signal();<a name="line.2229"></a>
+<span class="sourceLineNo">2230</span>    } finally {<a name="line.2230"></a>
+<span class="sourceLineNo">2231</span>      assignQueueLock.unlock();<a name="line.2231"></a>
+<span class="sourceLineNo">2232</span>    }<a name="line.2232"></a>
+<span class="sourceLineNo">2233</span>  }<a name="line.2233"></a>
+<span class="sourceLineNo">2234</span><a name="line.2234"></a>
+<span class="sourceLineNo">2235</span>  @edu.umd.cs.findbugs.annotations.SuppressWarnings("WA_AWAIT_NOT_IN_LOOP")<a name="line.2235"></a>
+<span class="sourceLineNo">2236</span>  private HashMap&lt;RegionInfo, RegionStateNode&gt; waitOnAssignQueue() {<a name="line.2236"></a>
+<span class="sourceLineNo">2237</span>    HashMap&lt;RegionInfo, RegionStateNode&gt; regions = null;<a name="line.2237"></a>
+<span class="sourceLineNo">2238</span><a name="line.2238"></a>
+<span class="sourceLineNo">2239</span>    assignQueueLock.lock();<a name="line.2239"></a>
+<span class="sourceLineNo">2240</span>    try {<a name="line.2240"></a>
+<span class="sourceLineNo">2241</span>      if (pendingAssignQueue.isEmpty() &amp;&amp; isRunning()) {<a name="line.2241"></a>
+<span class="sourceLineNo">2242</span>        assignQueueFullCond.await();<a name="line.2242"></a>
+<span class="sourceLineNo">2243</span>      }<a name="line.2243"></a>
+<span class="sourceLineNo">2244</span><a name="line.2244"></a>
+<span class="sourceLineNo">2245</span>      if (!isRunning()) {<a name="line.2245"></a>
+<span class="sourceLineNo">2246</span>        return null;<a name="line.2246"></a>
+<span class="sourceLineNo">2247</span>      }<a name="line.2247"></a>
+<span class="sourceLineNo">2248</span>      assignQueueFullCond.await(assignDispatchWaitMillis, TimeUnit.MILLISECONDS);<a name="line.2248"></a>
+<span class="sourceLineNo">2249</span>      regions = new HashMap&lt;RegionInfo, RegionStateNode&gt;(pendingAssignQueue.size());<a name="line.2249"></a>
+<span class="sourceLineNo">2250</span>      for (RegionStateNode regionNode : pendingAssignQueue) {<a name="line.2250"></a>
+<span class="sourceLineNo">2251</span>        regions.put(regionNode.getRegionInfo(), regionNode);<a name="line.2251"></a>
+<span class="sourceLineNo">2252</span>      }<a name="line.2252"></a>
+<span class="sourceLineNo">2253</span>      pendingAssignQueue.clear();<a name="line.2253"></a>
+<span class="sourceLineNo">2254</span>    } catch (InterruptedException e) {<a name="line.2254"></a>
+<span class="sourceLineNo">2255</span>      LOG.warn("got interrupted ", e);<a name="line.2255"></a>
+<span class="sourceLineNo">2256</span>      Thread.currentThread().interrupt();<a name="line.2256"></a>
+<span class="sourceLineNo">2257</span>    } finally {<a name="line.2257"></a>
+<span class="sourceLineNo">2258</span>      assignQueueLock.unlock();<a name="line.2258"></a>
+<span class="sourceLineNo">2259</span>    }<a name="line.2259"></a>
+<span class="sourceLineNo">2260</span>    return regions;<a name="line.2260"></a>
+<span class="sourceLineNo">2261</span>  }<a name="line.2261"></a>
+<span class="sourceLineNo">2262</span><a name="line.2262"></a>
+<span class="sourceLineNo">2263</span>  private void processAssignQueue() {<a name="line.2263"></a>
+<span class="sourceLineNo">2264</span>    final HashMap&lt;RegionInfo, RegionStateNode&gt; regions = waitOnAssignQueue();<a name="line.2264"></a>
+<span class="sourceLineNo">2265</span>    if (regions == null || regions.size() == 0 || !isRunning()) {<a name="line.2265"></a>
... 7161 lines suppressed ...