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 2022/03/30 14:55:44 UTC

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

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 abc395f  Published site at 7adccd2a19afdb5e3e5e6f679fa288f6d9c9046c.
abc395f is described below

commit abc395f37655e634f881fb5706db5a7dca3fbcbf
Author: jenkins <bu...@apache.org>
AuthorDate: Wed Mar 30 14:55:14 2022 +0000

    Published site at 7adccd2a19afdb5e3e5e6f679fa288f6d9c9046c.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          |   28 +-
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    4 +-
 .../hadoop/hbase/backup/HFileArchiver.File.html    |   24 +-
 .../hbase/backup/HFileArchiver.FileConverter.html  |    6 +-
 .../backup/HFileArchiver.FileStatusConverter.html  |    6 +-
 .../hbase/backup/HFileArchiver.FileablePath.html   |   20 +-
 .../backup/HFileArchiver.FileableStoreFile.html    |   18 +-
 .../hbase/backup/HFileArchiver.StoreToFile.html    |    6 +-
 .../apache/hadoop/hbase/backup/HFileArchiver.html  |    4 +-
 ...TransitRegionStateProcedure.TransitionType.html |   14 +-
 .../assignment/TransitRegionStateProcedure.html    |   88 +-
 .../hadoop/hbase/backup/HFileArchiver.File.html    |  629 +++++----
 .../hbase/backup/HFileArchiver.FileConverter.html  |  629 +++++----
 .../backup/HFileArchiver.FileStatusConverter.html  |  629 +++++----
 .../hbase/backup/HFileArchiver.FileablePath.html   |  629 +++++----
 .../backup/HFileArchiver.FileableStoreFile.html    |  629 +++++----
 .../hbase/backup/HFileArchiver.StoreToFile.html    |  629 +++++----
 .../apache/hadoop/hbase/backup/HFileArchiver.html  |  629 +++++----
 ...TransitRegionStateProcedure.TransitionType.html | 1130 ++++++++--------
 .../assignment/TransitRegionStateProcedure.html    | 1130 ++++++++--------
 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 +-
 testdevapidocs/index-all.html                      |    8 +
 .../TestHFileArchiving.ArchivingFunction.html      |    4 +-
 .../hadoop/hbase/backup/TestHFileArchiving.html    |  170 ++-
 .../TestHFileArchiving.ArchivingFunction.html      |    9 +
 .../org/apache/hadoop/hbase/package-tree.html      |   10 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    4 +-
 .../hadoop/hbase/regionserver/package-tree.html    |    4 +-
 .../org/apache/hadoop/hbase/test/package-tree.html |    6 +-
 .../org/apache/hadoop/hbase/wal/package-tree.html  |    2 +-
 .../TestHFileArchiving.ArchivingFunction.html      | 1431 ++++++++++----------
 .../hadoop/hbase/backup/TestHFileArchiving.html    | 1431 ++++++++++----------
 60 files changed, 5229 insertions(+), 4791 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index 7a9655b..21dc087 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -455,7 +455,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 ed64c2b..072c5bd 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 1.5.3, based on Prawn 2.2.2)
 /Producer (Apache HBase Team)
-/ModDate (D:20220328165934+00'00')
-/CreationDate (D:20220328171258+00'00')
+/ModDate (D:20220330143941+00'00')
+/CreationDate (D:20220330145318+00'00')
 >>
 endobj
 2 0 obj
diff --git a/book.html b/book.html
index dc5e410..259dce5 100644
--- a/book.html
+++ b/book.html
@@ -46555,7 +46555,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 3.0.0-alpha-3-SNAPSHOT<br>
-Last updated 2022-03-28 16:59:34 UTC
+Last updated 2022-03-30 14:39:41 UTC
 </div>
 </div>
 <link rel="stylesheet" href="./coderay-asciidoctor.css">
diff --git a/bulk-loads.html b/bulk-loads.html
index 38e34c9..28cae8a 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -160,7 +160,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 cf7351f..99c1185 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -7307,7 +7307,7 @@
 <tr class="a">
 <td>annotation</td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_annotation.html#MissingDeprecated">MissingDeprecated</a></td>
-<td>9</td>
+<td>6</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="b">
 <td>blocks</td>
@@ -7411,7 +7411,7 @@
 <tr class="b">
 <td></td>
 <td><a class="externalLink" href="http://checkstyle.sourceforge.net/config_javadoc.html#NonEmptyAtclauseDescription">NonEmptyAtclauseDescription</a></td>
-<td>2046</td>
+<td>2049</td>
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td></tr>
 <tr class="a">
 <td>misc</td>
@@ -12606,31 +12606,31 @@
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>666</td></tr>
+<td>697</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>672</td></tr>
+<td>703</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>689</td></tr>
+<td>720</td></tr>
 <tr class="a">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>javadoc</td>
 <td>NonEmptyAtclauseDescription</td>
 <td>At-clause should have a non-empty description.</td>
-<td>691</td></tr>
+<td>722</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>727</td></tr></table></div>
+<td>758</td></tr></table></div>
 <div class="section">
 <h3 id="org.apache.hadoop.hbase.backup.regionserver.LogRollBackupSubprocedurePool.java">org/apache/hadoop/hbase/backup/regionserver/LogRollBackupSubprocedurePool.java</h3>
 <table border="0" class="table table-striped">
@@ -34875,8 +34875,8 @@
 <th>Line</th></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>annotation</td>
-<td>MissingDeprecated</td>
+<td>javadoc</td>
+<td>NonEmptyAtclauseDescription</td>
 <td>Javadoc comment at column 14 has parse error. Details: mismatched input ':' expecting &lt;EOF&gt; while parsing JAVADOC</td>
 <td>46</td></tr></table></div>
 <div class="section">
@@ -49392,8 +49392,8 @@
 <th>Line</th></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>annotation</td>
-<td>MissingDeprecated</td>
+<td>javadoc</td>
+<td>NonEmptyAtclauseDescription</td>
 <td>Javadoc comment at column 54 has parse error. Details: no viable alternative at input '(' while parsing JAVADOC_INLINE_TAG</td>
 <td>59</td></tr>
 <tr class="a">
@@ -68973,8 +68973,8 @@
 <td>598</td></tr>
 <tr class="b">
 <td><img src="images/icon_error_sml.gif" alt="" />&#160;Error</td>
-<td>annotation</td>
-<td>MissingDeprecated</td>
+<td>javadoc</td>
+<td>NonEmptyAtclauseDescription</td>
 <td>Javadoc comment at column 0 has parse error. Details: mismatched input '   *' expecting JAVADOC_INLINE_TAG_END while parsing JAVADOC_INLINE_TAG</td>
 <td>747</td></tr>
 <tr class="a">
@@ -71799,7 +71799,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 4e15cfb..04eb3bf 100644
--- a/coc.html
+++ b/coc.html
@@ -229,7 +229,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 6ed678c..8f5b8b5 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -301,7 +301,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 396b035..7b4239e 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -961,7 +961,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 76dcad2..65cf187 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -182,7 +182,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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 ed1e292..58ea8f2 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1254,7 +1254,7 @@
 <tr class="a">
 <td>org.bouncycastle</td>
 <td><a class="externalLink" href="http://www.bouncycastle.org/java.html">bcprov-jdk15on</a></td>
-<td>1.60</td>
+<td>1.67</td>
 <td>-</td>
 <td>jar</td>
 <td><a class="externalLink" href="http://www.bouncycastle.org/licence.html">Bouncy Castle Licence</a></td></tr>
@@ -1273,7 +1273,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/org/apache/hadoop/hbase/backup/HFileArchiver.File.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
index 666b764..dce43c9 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
@@ -117,7 +117,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private abstract static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.643">HFileArchiver.File</a>
+<pre>private abstract static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.674">HFileArchiver.File</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>
 <div class="block">Wrapper to handle file operations uniformly</div>
 </li>
@@ -246,7 +246,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>fs</h4>
-<pre>protected final&nbsp;org.apache.hadoop.fs.FileSystem <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.644">fs</a></pre>
+<pre>protected final&nbsp;org.apache.hadoop.fs.FileSystem <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.675">fs</a></pre>
 </li>
 </ul>
 </li>
@@ -263,7 +263,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>File</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.646">File</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.677">File</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
 </li>
 </ul>
 </li>
@@ -280,7 +280,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>delete</h4>
-<pre>abstract&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.654">delete</a>()
+<pre>abstract&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.685">delete</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>
 <div class="block">Delete the file</div>
 <dl>
@@ -295,7 +295,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isFile</h4>
-<pre>abstract&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.661">isFile</a>()
+<pre>abstract&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.692">isFile</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>
 <div class="block">Check to see if this is a file or a directory</div>
 <dl>
@@ -312,7 +312,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getChildren</h4>
-<pre>abstract&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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.668">getChildren</a>()
+<pre>abstract&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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.699">getChildren</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="returnLabel">Returns:</span></dt>
@@ -329,7 +329,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>close</h4>
-<pre>abstract&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.674">close</a>()
+<pre>abstract&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.705">close</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>
 <div class="block">close any outside readers of the file</div>
 <dl>
@@ -344,7 +344,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getName</h4>
-<pre>abstract&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/backup/HFileArchiver.File.html#line.680">getName</a>()</pre>
+<pre>abstract&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/backup/HFileArchiver.File.html#line.711">getName</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the name of the file (not the full fs path, just the individual
@@ -358,7 +358,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getPath</h4>
-<pre>abstract&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.685">getPath</a>()</pre>
+<pre>abstract&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.716">getPath</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the path to this file</dd>
@@ -371,7 +371,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>moveAndClose</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.693">moveAndClose</a>(org.apache.hadoop.fs.Path&nbsp;dest)
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.724">moveAndClose</a>(org.apache.hadoop.fs.Path&nbsp;dest)
                      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">Move the file to the given destination</div>
 <dl>
@@ -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>getFileSystem</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.702">getFileSystem</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html#line.733">getFileSystem</a>()</pre>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
 <dd>the <code>FileSystem</code> on which this file resides</dd>
@@ -403,7 +403,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>toString</h4>
-<pre>public&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/backup/HFileArchiver.File.html#line.707">toString</a>()</pre>
+<pre>public&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/backup/HFileArchiver.File.html#line.738">toString</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true#toString--" title="class or interface in java.lang">toString</a></code>&nbsp;in class&nbsp;<code><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></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
index d9294e1..2fe01fa 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
@@ -119,7 +119,7 @@
 </dl>
 <hr>
 <br>
-<pre>private abstract static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.603">HFileArchiver.FileConverter</a>&lt;T&gt;
+<pre>private abstract static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.634">HFileArchiver.FileConverter</a>&lt;T&gt;
 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="https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html?is-external=true" title="class or interface in java.util.function">Function</a>&lt;T,<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;</pre>
 <div class="block">Adapt a type to match the <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup"><code>HFileArchiver.File</code></a> interface, which is used internally for handling
@@ -206,7 +206,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function
 <ul class="blockListLast">
 <li class="blockList">
 <h4>fs</h4>
-<pre>protected final&nbsp;org.apache.hadoop.fs.FileSystem <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html#line.604">fs</a></pre>
+<pre>protected final&nbsp;org.apache.hadoop.fs.FileSystem <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html#line.635">fs</a></pre>
 </li>
 </ul>
 </li>
@@ -223,7 +223,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FileConverter</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html#line.606">FileConverter</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html#line.637">FileConverter</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
index 9e03b4f..8c85c64 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.614">HFileArchiver.FileStatusConverter</a>
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.645">HFileArchiver.FileStatusConverter</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.FileConverter</a>&lt;org.apache.hadoop.fs.FileStatus&gt;</pre>
 <div class="block">Convert a FileStatus to something we can manage in the archiving</div>
 </li>
@@ -214,7 +214,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FileStatusConverter</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html#line.615">FileStatusConverter</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html#line.646">FileStatusConverter</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
 </li>
 </ul>
 </li>
@@ -231,7 +231,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>apply</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html#line.620">apply</a>(org.apache.hadoop.fs.FileStatus&nbsp;input)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html#line.651">apply</a>(org.apache.hadoop.fs.FileStatus&nbsp;input)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
index c033314..0b4ca27 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.715">HFileArchiver.FileablePath</a>
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.746">HFileArchiver.FileablePath</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></pre>
 <div class="block">A <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup"><code>HFileArchiver.File</code></a> that wraps a simple <code>Path</code> on a <code>FileSystem</code>.</div>
 </li>
@@ -252,7 +252,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>file</h4>
-<pre>private final&nbsp;org.apache.hadoop.fs.Path <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.716">file</a></pre>
+<pre>private final&nbsp;org.apache.hadoop.fs.Path <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.747">file</a></pre>
 </li>
 </ul>
 <a name="getAsFile">
@@ -261,7 +261,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getAsFile</h4>
-<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.FileStatusConverter</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.717">getAsFile</a></pre>
+<pre>private final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.FileStatusConverter</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.748">getAsFile</a></pre>
 </li>
 </ul>
 </li>
@@ -278,7 +278,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FileablePath</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.719">FileablePath</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.750">FileablePath</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                     org.apache.hadoop.fs.Path&nbsp;file)</pre>
 </li>
 </ul>
@@ -296,7 +296,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>delete</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.726">delete</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.757">delete</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#delete--">HFileArchiver.File</a></code></span></div>
 <div class="block">Delete the file</div>
@@ -314,7 +314,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>getName</h4>
-<pre>public&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/backup/HFileArchiver.FileablePath.html#line.731">getName</a>()</pre>
+<pre>public&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/backup/HFileArchiver.FileablePath.html#line.762">getName</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#getName--">getName</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></code></dd>
@@ -330,7 +330,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>getChildren</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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.736">getChildren</a>()
+<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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.767">getChildren</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="overrideSpecifyLabel">Specified by:</span></dt>
@@ -349,7 +349,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>isFile</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.744">isFile</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.775">isFile</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#isFile--">HFileArchiver.File</a></code></span></div>
 <div class="block">Check to see if this is a file or a directory</div>
@@ -369,7 +369,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>close</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.749">close</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.780">close</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#close--">HFileArchiver.File</a></code></span></div>
 <div class="block">close any outside readers of the file</div>
@@ -387,7 +387,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getPath</h4>
-<pre>org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.754">getPath</a>()</pre>
+<pre>org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html#line.785">getPath</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#getPath--">getPath</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
index 916a83a..5d42afc 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
@@ -118,7 +118,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.763">HFileArchiver.FileableStoreFile</a>
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.794">HFileArchiver.FileableStoreFile</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></pre>
 <div class="block"><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup"><code>HFileArchiver.File</code></a> adapter for a <a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver"><code>HStoreFile</code></a> living on a <code>FileSystem</code>
  .</div>
@@ -249,7 +249,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>file</h4>
-<pre><a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.764">file</a></pre>
+<pre><a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.795">file</a></pre>
 </li>
 </ul>
 </li>
@@ -266,7 +266,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FileableStoreFile</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.766">FileableStoreFile</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.797">FileableStoreFile</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                          <a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&nbsp;store)</pre>
 </li>
 </ul>
@@ -284,7 +284,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>delete</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.772">delete</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.803">delete</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#delete--">HFileArchiver.File</a></code></span></div>
 <div class="block">Delete the file</div>
@@ -302,7 +302,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>getName</h4>
-<pre>public&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/backup/HFileArchiver.FileableStoreFile.html#line.777">getName</a>()</pre>
+<pre>public&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/backup/HFileArchiver.FileableStoreFile.html#line.808">getName</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#getName--">getName</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></code></dd>
@@ -318,7 +318,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>isFile</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.782">isFile</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.813">isFile</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#isFile--">HFileArchiver.File</a></code></span></div>
 <div class="block">Check to see if this is a file or a directory</div>
 <dl>
@@ -335,7 +335,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>getChildren</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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.787">getChildren</a>()
+<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/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.818">getChildren</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="overrideSpecifyLabel">Specified by:</span></dt>
@@ -354,7 +354,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockList">
 <li class="blockList">
 <h4>close</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.793">close</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.824">close</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#close--">HFileArchiver.File</a></code></span></div>
 <div class="block">close any outside readers of the file</div>
@@ -372,7 +372,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>getPath</h4>
-<pre>org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.798">getPath</a>()</pre>
+<pre>org.apache.hadoop.fs.Path&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html#line.829">getPath</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html#getPath--">getPath</a></code>&nbsp;in class&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a></code></dd>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
index e5b5b40..955331a 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.629">HFileArchiver.StoreToFile</a>
+<pre>private static class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.660">HFileArchiver.StoreToFile</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.FileConverter</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&gt;</pre>
 <div class="block">Convert the <a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver"><code>HStoreFile</code></a> into something we can manage in the archive
  methods</div>
@@ -215,7 +215,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>StoreToFile</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html#line.630">StoreToFile</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html#line.661">StoreToFile</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs)</pre>
 </li>
 </ul>
 </li>
@@ -232,7 +232,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.Fil
 <ul class="blockListLast">
 <li class="blockList">
 <h4>apply</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html#line.635">apply</a>(<a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&nbsp;input)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/backup/HFileArchiver.File.html" title="class in org.apache.hadoop.hbase.backup">HFileArchiver.File</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html#line.666">apply</a>(<a href="../../../../../org/apache/hadoop/hbase/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&nbsp;input)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.html b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.html
index 33232a7..0679512 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/HFileArchiver.html
@@ -807,7 +807,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>deleteRegionWithoutArchiving</h4>
-<pre>private static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.562">deleteRegionWithoutArchiving</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>private static&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.593">deleteRegionWithoutArchiving</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                                                     org.apache.hadoop.fs.Path&nbsp;regionDir)
                                              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">Without regard for backup, delete a region. Should be used with caution.</div>
@@ -828,7 +828,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>deleteStoreFilesWithoutArchiving</h4>
-<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.581">deleteStoreFilesWithoutArchiving</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/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&gt;&nbsp;compactedFiles)
+<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html#line.612">deleteStoreFilesWithoutArchiving</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/regionserver/HStoreFile.html" title="class in org.apache.hadoop.hbase.regionserver">HStoreFile</a>&gt;&nbsp;compactedFiles)
                                               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">Just do a simple delete of the given store files
  <p>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
index 32af20f..5e66e87 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static enum <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.557">TransitRegionStateProcedure.TransitionType</a>
+<pre>public static enum <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.559">TransitRegionStateProcedure.TransitionType</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang">Enum</a>&lt;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&gt;</pre>
 </li>
 </ul>
@@ -216,7 +216,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>ASSIGN</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.558">ASSIGN</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.560">ASSIGN</a></pre>
 </li>
 </ul>
 <a name="UNASSIGN">
@@ -225,7 +225,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>UNASSIGN</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.558">UNASSIGN</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.560">UNASSIGN</a></pre>
 </li>
 </ul>
 <a name="MOVE">
@@ -234,7 +234,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.558">MOVE</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.560">MOVE</a></pre>
 </li>
 </ul>
 <a name="REOPEN">
@@ -243,7 +243,7 @@ the order they are declared.</div>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>REOPEN</h4>
-<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.558">REOPEN</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.560">REOPEN</a></pre>
 </li>
 </ul>
 </li>
@@ -260,7 +260,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>values</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.590">values</a>()</pre>
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.592">values</a>()</pre>
 <div class="block">Returns an array containing the constants of this enum type, in
 the order they are declared.  This method may be used to iterate
 over the constants as follows:
@@ -280,7 +280,7 @@ for (TransitRegionStateProcedure.TransitionType c : TransitRegionStateProcedure.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>valueOf</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.590">valueOf</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" t [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html#line.592">valueOf</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" t [...]
 <div class="block">Returns the enum constant of this type with the specified name.
 The string must match <i>exactly</i> an identifier used to declare an
 enum constant in this type.  (Extraneous whitespace characters are 
diff --git a/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html b/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
index 4a760c2..b90fc1f 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
@@ -134,7 +134,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Private
-public class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.101">TransitRegionStateProcedure</a>
+public class <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.103">TransitRegionStateProcedure</a>
 extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/AbstractStateMachineRegionProcedure.html" title="class in org.apache.hadoop.hbase.master.procedure">AbstractStateMachineRegionProcedure</a>&lt;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&gt;</pre>
 <div class="block">The procedure to deal with the state transition of a region. A region with a TRSP in place is
  called RIT, i.e, RegionInTransition.
@@ -582,7 +582,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.104">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.106">LOG</a></pre>
 </li>
 </ul>
 <a name="type">
@@ -591,7 +591,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>type</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.106">type</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.108">type</a></pre>
 </li>
 </ul>
 <a name="initialState">
@@ -600,7 +600,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>initialState</h4>
-<pre>private&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.108">initialState</a></pre>
+<pre>private&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.110">initialState</a></pre>
 </li>
 </ul>
 <a name="lastState">
@@ -609,7 +609,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>lastState</h4>
-<pre>private&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.110">lastState</a></pre>
+<pre>private&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.112">lastState</a></pre>
 </li>
 </ul>
 <a name="assignCandidate">
@@ -618,7 +618,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>assignCandidate</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.113">assignCandidate</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.115">assignCandidate</a></pre>
 </li>
 </ul>
 <a name="forceNewPlan">
@@ -627,7 +627,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>forceNewPlan</h4>
-<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.115">forceNewPlan</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.117">forceNewPlan</a></pre>
 </li>
 </ul>
 <a name="retryCounter">
@@ -636,7 +636,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>retryCounter</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/util/RetryCounter.html" title="class in org.apache.hadoop.hbase.util">RetryCounter</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.117">retryCounter</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/util/RetryCounter.html" title="class in org.apache.hadoop.hbase.util">RetryCounter</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.119">retryCounter</a></pre>
 </li>
 </ul>
 <a name="remoteProc">
@@ -645,7 +645,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockListLast">
 <li class="blockList">
 <h4>remoteProc</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.119">remoteProc</a></pre>
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a> <a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.121">remoteProc</a></pre>
 </li>
 </ul>
 </li>
@@ -662,7 +662,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>TransitRegionStateProcedure</h4>
-<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.121">TransitRegionStateProcedure</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.123">TransitRegionStateProcedure</a>()</pre>
 </li>
 </ul>
 <a name="TransitRegionStateProcedure-org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv-org.apache.hadoop.hbase.client.RegionInfo-org.apache.hadoop.hbase.ServerName-boolean-org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure.TransitionType-">
@@ -671,7 +671,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockListLast">
 <li class="blockList">
 <h4>TransitRegionStateProcedure</h4>
-<pre>protected&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.144">TransitRegionStateProcedure</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>protected&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.146">TransitRegionStateProcedure</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                                       <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri,
                                       <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;assignCandidate,
                                       boolean&nbsp;forceNewPlan,
@@ -692,7 +692,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>setInitialAndLastState</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.124">setInitialAndLastState</a>()</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.126">setInitialAndLastState</a>()</pre>
 </li>
 </ul>
 <a name="getTableOperationType--">
@@ -701,7 +701,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getTableOperationType</h4>
-<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure">TableProcedureInterface.TableOperationType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.159">getTableOperationType</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure">TableProcedureInterface.TableOperationType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.161">getTableOperationType</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.html#getTableOperationType--">TableProcedureInterface</a></code></span></div>
 <div class="block">Given an operation type we can take decisions about what to do with pending operations.
  e.g. if we get a delete and we have some table operation pending (e.g. add column)
@@ -722,7 +722,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>waitInitialized</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.165">waitInitialized</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;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.167">waitInitialized</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>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#waitInitialized-TEnvironment-">Procedure</a></code></span></div>
 <div class="block">The <a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#doAcquireLock-TEnvironment-org.apache.hadoop.hbase.procedure2.store.ProcedureStore-"><code>Procedure.doAcquireLock(Object, ProcedureStore)</code></a> will be split into two steps, first, it will
  call us to determine whether we need to wait for initialization, second, it will call
@@ -747,7 +747,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>queueAssign</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.175">queueAssign</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>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.177">queueAssign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                          <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="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a></pre>
 <dl>
@@ -762,7 +762,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>openRegion</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.200">openRegion</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>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.202">openRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                         <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>
@@ -777,7 +777,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>confirmOpened</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.213">confirmOpened</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Ma [...]
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.215">confirmOpened</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Ma [...]
                                                  <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>
@@ -792,7 +792,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>closeRegion</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.261">closeRegion</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>private&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.263">closeRegion</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                          <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>
@@ -807,7 +807,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>confirmClosed</h4>
-<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.275">confirmClosed</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Ma [...]
+<pre>private&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.277">confirmClosed</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Ma [...]
                                                  <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>
@@ -822,7 +822,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>execute</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.315">execute</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>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html" title="class in org.apache.hadoop.hbase.procedure2">Procedure</a>[]&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.317">execute</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env)
                        throws <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a>,
                               <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureYieldException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureYieldException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
@@ -853,7 +853,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionStateNode</h4>
-<pre>private&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/TransitRegionStateProcedure.html#line.327">getRegionStateNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Mast [...]
+<pre>private&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/TransitRegionStateProcedure.html#line.329">getRegionStateNode</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">Mast [...]
 </li>
 </ul>
 <a name="executeFromState-org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv-org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState-">
@@ -862,7 +862,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>executeFromState</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.332">executeFromState</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedur [...]
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2">StateMachineProcedure.Flow</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.334">executeFromState</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedur [...]
                                                       org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;state)
                                                throws <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureSuspendedException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureSuspendedException</a>,
                                                       <a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureYieldException.html" title="class in org.apache.hadoop.hbase.procedure2">ProcedureYieldException</a>,
@@ -889,7 +889,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>setTimeoutFailure</h4>
-<pre>protected&nbsp;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.387">setTimeoutFailure</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;boolean&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.389">setTimeoutFailure</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>
 <div class="block">At end of timeout, wake ourselves up so we run again.</div>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
@@ -906,7 +906,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>reportTransition</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.394">reportTransition</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>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.396">reportTransition</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                              <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/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                              org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode&nbsp;code,
@@ -925,7 +925,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>serverCrashed</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.416">serverCrashed</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>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.418">serverCrashed</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                           <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/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                           boolean&nbsp;forceNewPlan)
@@ -942,7 +942,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>attachRemoteProc</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.428">attachRemoteProc</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a>&nbsp;proc)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.430">attachRemoteProc</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a>&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="unattachRemoteProc-org.apache.hadoop.hbase.master.assignment.RegionRemoteProcedureBase-">
@@ -951,7 +951,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>unattachRemoteProc</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.432">unattachRemoteProc</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a>&nbsp;proc)</pre>
+<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.434">unattachRemoteProc</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.html" title="class in org.apache.hadoop.hbase.master.assignment">RegionRemoteProcedureBase</a>&nbsp;proc)</pre>
 </li>
 </ul>
 <a name="stateLoaded-org.apache.hadoop.hbase.master.assignment.AssignmentManager-org.apache.hadoop.hbase.master.assignment.RegionStateNode-">
@@ -960,7 +960,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>stateLoaded</h4>
-<pre>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.440">stateLoaded</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>void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.442">stateLoaded</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/AssignmentManager.html" title="class in org.apache.hadoop.hbase.master.assignment">AssignmentManager</a>&nbsp;am,
                  <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>
@@ -970,7 +970,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>rollbackState</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.447">rollbackState</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>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.449">rollbackState</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterProcedureEnv</a>&nbsp;env,
                              org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;state)
                       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>,
                              <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
@@ -992,7 +992,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getState</h4>
-<pre>protected&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.454">getState</a>(int&nbsp;stateId)</pre>
+<pre>protected&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.456">getState</a>(int&nbsp;stateId)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.html#getState-int-">StateMachineProcedure</a></code></span></div>
 <div class="block">Convert an ordinal (or state id) to an Enum (or more descriptive) state object.</div>
 <dl>
@@ -1011,7 +1011,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getStateId</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.459">getStateId</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;state)</pre>
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.461">getStateId</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;state)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.html#getStateId-TState-">StateMachineProcedure</a></code></span></div>
 <div class="block">Convert the Enum (or more descriptive) state object to an ordinal (or state id).</div>
 <dl>
@@ -1030,7 +1030,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getInitialState</h4>
-<pre>protected&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.464">getInitialState</a>()</pre>
+<pre>protected&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.466">getInitialState</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.html#getInitialState--">StateMachineProcedure</a></code></span></div>
 <div class="block">Return the initial state object that will be used for the first call to executeFromState().</div>
 <dl>
@@ -1047,7 +1047,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>convert</h4>
-<pre>private static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.468">convert</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType&nbsp;type)</pre>
+<pre>private static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.470">convert</a>(org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType&nbsp;type)</pre>
 </li>
 </ul>
 <a name="convert-org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure.TransitionType-">
@@ -1056,7 +1056,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>convert</h4>
-<pre>private static&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.483">convert</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;type)</pre>
+<pre>private static&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.485">convert</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html" title="enum in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure.TransitionType</a>&nbsp;type)</pre>
 </li>
 </ul>
 <a name="serializeStateData-org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer-">
@@ -1065,7 +1065,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>serializeStateData</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.499">serializeStateData</a>(<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.501">serializeStateData</a>(<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
                            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"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#serializeStateData-org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer-">Procedure</a></code></span></div>
 <div class="block">The user-level code of the procedure may have some state to
@@ -1087,7 +1087,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>deserializeStateData</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.510">deserializeStateData</a>(<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.512">deserializeStateData</a>(<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureStateSerializer.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureStateSerializer</a>&nbsp;serializer)
                              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"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#deserializeStateData-org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer-">Procedure</a></code></span></div>
 <div class="block">Called on store load to allow the user to decode the previously serialized
@@ -1108,7 +1108,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcedureMetrics</h4>
-<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureMetrics.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureMetrics</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.523">getProcedureMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterPro [...]
+<pre>protected&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/procedure2/ProcedureMetrics.html" title="interface in org.apache.hadoop.hbase.procedure2">ProcedureMetrics</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.525">getProcedureMetrics</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master.procedure">MasterPro [...]
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#getProcedureMetrics-TEnvironment-">Procedure</a></code></span></div>
 <div class="block">Override this method to provide procedure specific counters for submitted count, failed
  count and time histogram.</div>
@@ -1128,7 +1128,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>toStringClassDetails</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.540">toStringClassDetails</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html?is-external=true" title="class or interface in java.lang">StringBuilder</a>&nbsp;sb)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.542">toStringClassDetails</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html?is-external=true" title="class or interface in java.lang">StringBuilder</a>&nbsp;sb)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../../org/apache/hadoop/hbase/procedure2/Procedure.html#toStringClassDetails-java.lang.StringBuilder-">Procedure</a></code></span></div>
 <div class="block">Extend the toString() information with the procedure details
  e.g. className and parameters</div>
@@ -1146,7 +1146,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>setOwner</h4>
-<pre>private static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.551">setOwner</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.m [...]
+<pre>private static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.553">setOwner</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.m [...]
                                                     <a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;proc)</pre>
 </li>
 </ul>
@@ -1156,7 +1156,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>assign</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.564">assign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.566">assign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
                                                  <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                                                  @Nullable
                                                  <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;targetServer)</pre>
@@ -1168,7 +1168,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>assign</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.569">assign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.571">assign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
                                                  <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                                                  boolean&nbsp;forceNewPlan,
                                                  @Nullable
@@ -1181,7 +1181,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>unassign</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.575">unassign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.ma [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.577">unassign</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.ma [...]
                                                    <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</pre>
 </li>
 </ul>
@@ -1191,7 +1191,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockList">
 <li class="blockList">
 <h4>reopen</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.580">reopen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.582">reopen</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.mast [...]
                                                  <a href="../../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region)</pre>
 </li>
 </ul>
@@ -1201,7 +1201,7 @@ extends <a href="../../../../../../org/apache/hadoop/hbase/master/procedure/Abst
 <ul class="blockListLast">
 <li class="blockList">
 <h4>move</h4>
-<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.585">move</a>(<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MasterProcedureEnv.html" title="class in org.apache.hadoop.hbase.master [...]
+<pre>public static&nbsp;<a href="../../../../../../org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html" title="class in org.apache.hadoop.hbase.master.assignment">TransitRegionStateProcedure</a>&nbsp;<a href="../../../../../../src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html#line.587">move</a>(<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,
                                                @Nullable
                                                <a href="../../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;targetServer)</pre>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.File.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileConverter.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileStatusConverter.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileablePath.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.FileableStoreFile.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.StoreToFile.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html
index 22ea136..ee79f25 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/backup/HFileArchiver.html
@@ -496,318 +496,349 @@
 <span class="sourceLineNo">488</span>    Path archiveFile = new Path(archiveDir, filename);<a name="line.488"></a>
 <span class="sourceLineNo">489</span>    FileSystem fs = currentFile.getFileSystem();<a name="line.489"></a>
 <span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>    // if the file already exists in the archive, move that one to a timestamped backup. This is a<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    // really, really unlikely situtation, where we get the same name for the existing file, but<a name="line.492"></a>
-<span class="sourceLineNo">493</span>    // is included just for that 1 in trillion chance.<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    if (fs.exists(archiveFile)) {<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.debug("{} already exists in archive, moving to timestamped backup and " +<a name="line.495"></a>
-<span class="sourceLineNo">496</span>          "overwriting current.", archiveFile);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      // move the archive file to the stamped backup<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.499"></a>
-<span class="sourceLineNo">500</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.501"></a>
-<span class="sourceLineNo">502</span>            + ", deleting existing file in favor of newer.");<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        // try to delete the exisiting file, if we can't rename it<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        if (!fs.delete(archiveFile, false)) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.505"></a>
-<span class="sourceLineNo">506</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.506"></a>
-<span class="sourceLineNo">507</span>              + ") to make room for similarly named file.");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>        }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>      LOG.debug("Backed up archive file from " + archiveFile);<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    }<a name="line.511"></a>
-<span class="sourceLineNo">512</span><a name="line.512"></a>
-<span class="sourceLineNo">513</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.513"></a>
-<span class="sourceLineNo">514</span><a name="line.514"></a>
-<span class="sourceLineNo">515</span>    // at this point, we should have a free spot for the archive file<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    boolean success = false;<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      if (i &gt; 0) {<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        // Ensure that the archive directory exists.<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        // The previous "move to archive" operation has failed probably because<a name="line.520"></a>
-<span class="sourceLineNo">521</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        try {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>          if (!fs.exists(archiveDir)) {<a name="line.524"></a>
-<span class="sourceLineNo">525</span>            if (fs.mkdirs(archiveDir)) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.526"></a>
-<span class="sourceLineNo">527</span>            }<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          }<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        } catch (IOException e) {<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      }<a name="line.532"></a>
-<span class="sourceLineNo">533</span><a name="line.533"></a>
-<span class="sourceLineNo">534</span>      try {<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      } catch (FileNotFoundException fnfe) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.537"></a>
-<span class="sourceLineNo">538</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        success = true;<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      } catch (IOException e) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        success = false;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
+<span class="sourceLineNo">491</span>    // An existing destination file in the archive is unexpected, but we handle it here.<a name="line.491"></a>
+<span class="sourceLineNo">492</span>    if (fs.exists(archiveFile)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      if (!fs.exists(currentFile.getPath())) {<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        // If the file already exists in the archive, and there is no current file to archive, then<a name="line.494"></a>
+<span class="sourceLineNo">495</span>        // assume that the file in archive is correct. This is an unexpected situation, suggesting a<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        // race condition or split brain.<a name="line.496"></a>
+<span class="sourceLineNo">497</span>        // In HBASE-26718 this was found when compaction incorrectly happened during warmupRegion.<a name="line.497"></a>
+<span class="sourceLineNo">498</span>        LOG.warn("{} exists in archive. Attempted to archive nonexistent file {}.", archiveFile,<a name="line.498"></a>
+<span class="sourceLineNo">499</span>          currentFile);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>        // We return success to match existing behavior in this method, where FileNotFoundException<a name="line.500"></a>
+<span class="sourceLineNo">501</span>        // in moveAndClose is ignored.<a name="line.501"></a>
+<span class="sourceLineNo">502</span>        return true;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      }<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      // There is a conflict between the current file and the already existing archived file.<a name="line.504"></a>
+<span class="sourceLineNo">505</span>      // Move the archived file to a timestamped backup. This is a really, really unlikely<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      // situation, where we get the same name for the existing file, but is included just for that<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      // 1 in trillion chance. We are potentially incurring data loss in the archive directory if<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      // the files are not identical. The timestamped backup will be cleaned by HFileCleaner as it<a name="line.508"></a>
+<span class="sourceLineNo">509</span>      // has no references.<a name="line.509"></a>
+<span class="sourceLineNo">510</span>      FileStatus curStatus = fs.getFileStatus(currentFile.getPath());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>      FileStatus archiveStatus = fs.getFileStatus(archiveFile);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      long curLen = curStatus.getLen();<a name="line.512"></a>
+<span class="sourceLineNo">513</span>      long archiveLen = archiveStatus.getLen();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>      long curMtime = curStatus.getModificationTime();<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      long archiveMtime = archiveStatus.getModificationTime();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>      if (curLen != archiveLen) {<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        LOG.error("{} already exists in archive with different size than current {}."<a name="line.517"></a>
+<span class="sourceLineNo">518</span>            + " archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.518"></a>
+<span class="sourceLineNo">519</span>          archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.519"></a>
+<span class="sourceLineNo">520</span>        throw new IOException(archiveFile + " already exists in archive with different size" +<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          " than " + currentFile);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>      }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>      LOG.error("{} already exists in archive, moving to timestamped backup and overwriting"<a name="line.524"></a>
+<span class="sourceLineNo">525</span>          + " current {}. archiveLen: {} currentLen: {} archiveMtime: {} currentMtime: {}",<a name="line.525"></a>
+<span class="sourceLineNo">526</span>        archiveFile, currentFile, archiveLen, curLen, archiveMtime, curMtime);<a name="line.526"></a>
+<span class="sourceLineNo">527</span><a name="line.527"></a>
+<span class="sourceLineNo">528</span>      // move the archive file to the stamped backup<a name="line.528"></a>
+<span class="sourceLineNo">529</span>      Path backedupArchiveFile = new Path(archiveDir, filename + SEPARATOR + archiveStartTime);<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      if (!fs.rename(archiveFile, backedupArchiveFile)) {<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        LOG.error("Could not rename archive file to backup: " + backedupArchiveFile<a name="line.531"></a>
+<span class="sourceLineNo">532</span>            + ", deleting existing file in favor of newer.");<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        // try to delete the existing file, if we can't rename it<a name="line.533"></a>
+<span class="sourceLineNo">534</span>        if (!fs.delete(archiveFile, false)) {<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          throw new IOException("Couldn't delete existing archive file (" + archiveFile<a name="line.535"></a>
+<span class="sourceLineNo">536</span>              + ") or rename it to the backup file (" + backedupArchiveFile<a name="line.536"></a>
+<span class="sourceLineNo">537</span>              + ") to make room for similarly named file.");<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>      } else {<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        LOG.info("Backed up archive file from {} to {}.", archiveFile, backedupArchiveFile);<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    }<a name="line.542"></a>
+<span class="sourceLineNo">543</span><a name="line.543"></a>
+<span class="sourceLineNo">544</span>    LOG.trace("No existing file in archive for {}, free to archive original file.", archiveFile);<a name="line.544"></a>
 <span class="sourceLineNo">545</span><a name="line.545"></a>
-<span class="sourceLineNo">546</span>    if (!success) {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      LOG.error("Failed to archive " + currentFile);<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      return false;<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return true;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /**<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.557"></a>
-<span class="sourceLineNo">558</span>   * @param fs FileSystem from which to delete the region<a name="line.558"></a>
-<span class="sourceLineNo">559</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.559"></a>
-<span class="sourceLineNo">560</span>   * @throws IOException on filesystem operation failure<a name="line.560"></a>
-<span class="sourceLineNo">561</span>   */<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      throws IOException {<a name="line.563"></a>
-<span class="sourceLineNo">564</span>    if (fs.delete(regionDir, true)) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      LOG.debug("Deleted {}", regionDir);<a name="line.565"></a>
-<span class="sourceLineNo">566</span>      return true;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>    }<a name="line.567"></a>
-<span class="sourceLineNo">568</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.568"></a>
-<span class="sourceLineNo">569</span>    return false;<a name="line.569"></a>
-<span class="sourceLineNo">570</span>  }<a name="line.570"></a>
-<span class="sourceLineNo">571</span><a name="line.571"></a>
-<span class="sourceLineNo">572</span>  /**<a name="line.572"></a>
-<span class="sourceLineNo">573</span>   * Just do a simple delete of the given store files<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * &lt;p&gt;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.575"></a>
-<span class="sourceLineNo">576</span>   * &lt;p&gt;<a name="line.576"></a>
-<span class="sourceLineNo">577</span>   * @param compactedFiles store files to delete from the file system.<a name="line.577"></a>
-<span class="sourceLineNo">578</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.578"></a>
-<span class="sourceLineNo">579</span>   *           throwing the exception, rather than failing at the first file.<a name="line.579"></a>
-<span class="sourceLineNo">580</span>   */<a name="line.580"></a>
-<span class="sourceLineNo">581</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      throws IOException {<a name="line.582"></a>
-<span class="sourceLineNo">583</span>    LOG.debug("Deleting files without archiving.");<a name="line.583"></a>
-<span class="sourceLineNo">584</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      try {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        hsf.deleteStoreFile();<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      } catch (IOException e) {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.589"></a>
-<span class="sourceLineNo">590</span>        errors.add(e);<a name="line.590"></a>
-<span class="sourceLineNo">591</span>      }<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    }<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (errors.size() &gt; 0) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      throw MultipleIOException.createIOException(errors);<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    }<a name="line.595"></a>
-<span class="sourceLineNo">596</span>  }<a name="line.596"></a>
-<span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   * archival/removal of files<a name="line.600"></a>
-<span class="sourceLineNo">601</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.601"></a>
-<span class="sourceLineNo">602</span>   */<a name="line.602"></a>
-<span class="sourceLineNo">603</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    protected final FileSystem fs;<a name="line.604"></a>
-<span class="sourceLineNo">605</span><a name="line.605"></a>
-<span class="sourceLineNo">606</span>    public FileConverter(FileSystem fs) {<a name="line.606"></a>
-<span class="sourceLineNo">607</span>      this.fs = fs;<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    }<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  }<a name="line.609"></a>
-<span class="sourceLineNo">610</span><a name="line.610"></a>
-<span class="sourceLineNo">611</span>  /**<a name="line.611"></a>
-<span class="sourceLineNo">612</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.612"></a>
-<span class="sourceLineNo">613</span>   */<a name="line.613"></a>
-<span class="sourceLineNo">614</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>    public FileStatusConverter(FileSystem fs) {<a name="line.615"></a>
-<span class="sourceLineNo">616</span>      super(fs);<a name="line.616"></a>
-<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
-<span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>    @Override<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    public File apply(FileStatus input) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      return new FileablePath(fs, input.getPath());<a name="line.621"></a>
-<span class="sourceLineNo">622</span>    }<a name="line.622"></a>
-<span class="sourceLineNo">623</span>  }<a name="line.623"></a>
-<span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  /**<a name="line.625"></a>
-<span class="sourceLineNo">626</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.626"></a>
-<span class="sourceLineNo">627</span>   * methods<a name="line.627"></a>
-<span class="sourceLineNo">628</span>   */<a name="line.628"></a>
-<span class="sourceLineNo">629</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>    public StoreToFile(FileSystem fs) {<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      super(fs);<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span><a name="line.633"></a>
-<span class="sourceLineNo">634</span>    @Override<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    public File apply(HStoreFile input) {<a name="line.635"></a>
-<span class="sourceLineNo">636</span>      return new FileableStoreFile(fs, input);<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    }<a name="line.637"></a>
-<span class="sourceLineNo">638</span>  }<a name="line.638"></a>
-<span class="sourceLineNo">639</span><a name="line.639"></a>
-<span class="sourceLineNo">640</span>  /**<a name="line.640"></a>
-<span class="sourceLineNo">641</span>   * Wrapper to handle file operations uniformly<a name="line.641"></a>
-<span class="sourceLineNo">642</span>   */<a name="line.642"></a>
-<span class="sourceLineNo">643</span>  private static abstract class File {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>    protected final FileSystem fs;<a name="line.644"></a>
-<span class="sourceLineNo">645</span><a name="line.645"></a>
-<span class="sourceLineNo">646</span>    public File(FileSystem fs) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>      this.fs = fs;<a name="line.647"></a>
+<span class="sourceLineNo">546</span>    // at this point, we should have a free spot for the archive file<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    boolean success = false;<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    for (int i = 0; !success &amp;&amp; i &lt; DEFAULT_RETRIES_NUMBER; ++i) {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (i &gt; 0) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        // Ensure that the archive directory exists.<a name="line.550"></a>
+<span class="sourceLineNo">551</span>        // The previous "move to archive" operation has failed probably because<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        // the cleaner has removed our archive directory (HBASE-7643).<a name="line.552"></a>
+<span class="sourceLineNo">553</span>        // (we're in a retry loop, so don't worry too much about the exception)<a name="line.553"></a>
+<span class="sourceLineNo">554</span>        try {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>          if (!fs.exists(archiveDir)) {<a name="line.555"></a>
+<span class="sourceLineNo">556</span>            if (fs.mkdirs(archiveDir)) {<a name="line.556"></a>
+<span class="sourceLineNo">557</span>              LOG.debug("Created archive directory {}", archiveDir);<a name="line.557"></a>
+<span class="sourceLineNo">558</span>            }<a name="line.558"></a>
+<span class="sourceLineNo">559</span>          }<a name="line.559"></a>
+<span class="sourceLineNo">560</span>        } catch (IOException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>          LOG.warn("Failed to create directory {}", archiveDir, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>        }<a name="line.562"></a>
+<span class="sourceLineNo">563</span>      }<a name="line.563"></a>
+<span class="sourceLineNo">564</span><a name="line.564"></a>
+<span class="sourceLineNo">565</span>      try {<a name="line.565"></a>
+<span class="sourceLineNo">566</span>        success = currentFile.moveAndClose(archiveFile);<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      } catch (FileNotFoundException fnfe) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>        LOG.warn("Failed to archive " + currentFile +<a name="line.568"></a>
+<span class="sourceLineNo">569</span>            " because it does not exist! Skipping and continuing on.", fnfe);<a name="line.569"></a>
+<span class="sourceLineNo">570</span>        success = true;<a name="line.570"></a>
+<span class="sourceLineNo">571</span>      } catch (IOException e) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>        LOG.warn("Failed to archive " + currentFile + " on try #" + i, e);<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        success = false;<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (!success) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.error("Failed to archive " + currentFile);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return false;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>    LOG.debug("Archived from {} to {}", currentFile, archiveFile);<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return true;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  /**<a name="line.586"></a>
+<span class="sourceLineNo">587</span>   * Without regard for backup, delete a region. Should be used with caution.<a name="line.587"></a>
+<span class="sourceLineNo">588</span>   * @param regionDir {@link Path} to the region to be deleted.<a name="line.588"></a>
+<span class="sourceLineNo">589</span>   * @param fs FileSystem from which to delete the region<a name="line.589"></a>
+<span class="sourceLineNo">590</span>   * @return &lt;tt&gt;true&lt;/tt&gt; on successful deletion, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.590"></a>
+<span class="sourceLineNo">591</span>   * @throws IOException on filesystem operation failure<a name="line.591"></a>
+<span class="sourceLineNo">592</span>   */<a name="line.592"></a>
+<span class="sourceLineNo">593</span>  private static boolean deleteRegionWithoutArchiving(FileSystem fs, Path regionDir)<a name="line.593"></a>
+<span class="sourceLineNo">594</span>      throws IOException {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    if (fs.delete(regionDir, true)) {<a name="line.595"></a>
+<span class="sourceLineNo">596</span>      LOG.debug("Deleted {}", regionDir);<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      return true;<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    }<a name="line.598"></a>
+<span class="sourceLineNo">599</span>    LOG.debug("Failed to delete directory {}", regionDir);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>    return false;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>  }<a name="line.601"></a>
+<span class="sourceLineNo">602</span><a name="line.602"></a>
+<span class="sourceLineNo">603</span>  /**<a name="line.603"></a>
+<span class="sourceLineNo">604</span>   * Just do a simple delete of the given store files<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * &lt;p&gt;<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   * A best effort is made to delete each of the files, rather than bailing on the first failure.<a name="line.606"></a>
+<span class="sourceLineNo">607</span>   * &lt;p&gt;<a name="line.607"></a>
+<span class="sourceLineNo">608</span>   * @param compactedFiles store files to delete from the file system.<a name="line.608"></a>
+<span class="sourceLineNo">609</span>   * @throws IOException if a file cannot be deleted. All files will be attempted to deleted before<a name="line.609"></a>
+<span class="sourceLineNo">610</span>   *           throwing the exception, rather than failing at the first file.<a name="line.610"></a>
+<span class="sourceLineNo">611</span>   */<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  private static void deleteStoreFilesWithoutArchiving(Collection&lt;HStoreFile&gt; compactedFiles)<a name="line.612"></a>
+<span class="sourceLineNo">613</span>      throws IOException {<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    LOG.debug("Deleting files without archiving.");<a name="line.614"></a>
+<span class="sourceLineNo">615</span>    List&lt;IOException&gt; errors = new ArrayList&lt;&gt;(0);<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    for (HStoreFile hsf : compactedFiles) {<a name="line.616"></a>
+<span class="sourceLineNo">617</span>      try {<a name="line.617"></a>
+<span class="sourceLineNo">618</span>        hsf.deleteStoreFile();<a name="line.618"></a>
+<span class="sourceLineNo">619</span>      } catch (IOException e) {<a name="line.619"></a>
+<span class="sourceLineNo">620</span>        LOG.error("Failed to delete {}", hsf.getPath());<a name="line.620"></a>
+<span class="sourceLineNo">621</span>        errors.add(e);<a name="line.621"></a>
+<span class="sourceLineNo">622</span>      }<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    }<a name="line.623"></a>
+<span class="sourceLineNo">624</span>    if (errors.size() &gt; 0) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>      throw MultipleIOException.createIOException(errors);<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    }<a name="line.626"></a>
+<span class="sourceLineNo">627</span>  }<a name="line.627"></a>
+<span class="sourceLineNo">628</span><a name="line.628"></a>
+<span class="sourceLineNo">629</span>  /**<a name="line.629"></a>
+<span class="sourceLineNo">630</span>   * Adapt a type to match the {@link File} interface, which is used internally for handling<a name="line.630"></a>
+<span class="sourceLineNo">631</span>   * archival/removal of files<a name="line.631"></a>
+<span class="sourceLineNo">632</span>   * @param &lt;T&gt; type to adapt to the {@link File} interface<a name="line.632"></a>
+<span class="sourceLineNo">633</span>   */<a name="line.633"></a>
+<span class="sourceLineNo">634</span>  private static abstract class FileConverter&lt;T&gt; implements Function&lt;T, File&gt; {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>    protected final FileSystem fs;<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>    public FileConverter(FileSystem fs) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>      this.fs = fs;<a name="line.638"></a>
+<span class="sourceLineNo">639</span>    }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>  }<a name="line.640"></a>
+<span class="sourceLineNo">641</span><a name="line.641"></a>
+<span class="sourceLineNo">642</span>  /**<a name="line.642"></a>
+<span class="sourceLineNo">643</span>   * Convert a FileStatus to something we can manage in the archiving<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   */<a name="line.644"></a>
+<span class="sourceLineNo">645</span>  private static class FileStatusConverter extends FileConverter&lt;FileStatus&gt; {<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    public FileStatusConverter(FileSystem fs) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>      super(fs);<a name="line.647"></a>
 <span class="sourceLineNo">648</span>    }<a name="line.648"></a>
 <span class="sourceLineNo">649</span><a name="line.649"></a>
-<span class="sourceLineNo">650</span>    /**<a name="line.650"></a>
-<span class="sourceLineNo">651</span>     * Delete the file<a name="line.651"></a>
-<span class="sourceLineNo">652</span>     * @throws IOException on failure<a name="line.652"></a>
-<span class="sourceLineNo">653</span>     */<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    abstract void delete() throws IOException;<a name="line.654"></a>
+<span class="sourceLineNo">650</span>    @Override<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    public File apply(FileStatus input) {<a name="line.651"></a>
+<span class="sourceLineNo">652</span>      return new FileablePath(fs, input.getPath());<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>  }<a name="line.654"></a>
 <span class="sourceLineNo">655</span><a name="line.655"></a>
-<span class="sourceLineNo">656</span>    /**<a name="line.656"></a>
-<span class="sourceLineNo">657</span>     * Check to see if this is a file or a directory<a name="line.657"></a>
-<span class="sourceLineNo">658</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.658"></a>
-<span class="sourceLineNo">659</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.659"></a>
-<span class="sourceLineNo">660</span>     */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>    abstract boolean isFile() throws IOException;<a name="line.661"></a>
-<span class="sourceLineNo">662</span><a name="line.662"></a>
-<span class="sourceLineNo">663</span>    /**<a name="line.663"></a>
-<span class="sourceLineNo">664</span>     * @return if this is a directory, returns all the children in the<a name="line.664"></a>
-<span class="sourceLineNo">665</span>     *         directory, otherwise returns an empty list<a name="line.665"></a>
-<span class="sourceLineNo">666</span>     * @throws IOException<a name="line.666"></a>
-<span class="sourceLineNo">667</span>     */<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.668"></a>
-<span class="sourceLineNo">669</span><a name="line.669"></a>
-<span class="sourceLineNo">670</span>    /**<a name="line.670"></a>
-<span class="sourceLineNo">671</span>     * close any outside readers of the file<a name="line.671"></a>
-<span class="sourceLineNo">672</span>     * @throws IOException<a name="line.672"></a>
-<span class="sourceLineNo">673</span>     */<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    abstract void close() throws IOException;<a name="line.674"></a>
-<span class="sourceLineNo">675</span><a name="line.675"></a>
-<span class="sourceLineNo">676</span>    /**<a name="line.676"></a>
-<span class="sourceLineNo">677</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.677"></a>
-<span class="sourceLineNo">678</span>     *         file name)<a name="line.678"></a>
-<span class="sourceLineNo">679</span>     */<a name="line.679"></a>
-<span class="sourceLineNo">680</span>    abstract String getName();<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>    /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>     * @return the path to this file<a name="line.683"></a>
+<span class="sourceLineNo">656</span>  /**<a name="line.656"></a>
+<span class="sourceLineNo">657</span>   * Convert the {@link HStoreFile} into something we can manage in the archive<a name="line.657"></a>
+<span class="sourceLineNo">658</span>   * methods<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   */<a name="line.659"></a>
+<span class="sourceLineNo">660</span>  private static class StoreToFile extends FileConverter&lt;HStoreFile&gt; {<a name="line.660"></a>
+<span class="sourceLineNo">661</span>    public StoreToFile(FileSystem fs) {<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      super(fs);<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    }<a name="line.663"></a>
+<span class="sourceLineNo">664</span><a name="line.664"></a>
+<span class="sourceLineNo">665</span>    @Override<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    public File apply(HStoreFile input) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      return new FileableStoreFile(fs, input);<a name="line.667"></a>
+<span class="sourceLineNo">668</span>    }<a name="line.668"></a>
+<span class="sourceLineNo">669</span>  }<a name="line.669"></a>
+<span class="sourceLineNo">670</span><a name="line.670"></a>
+<span class="sourceLineNo">671</span>  /**<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * Wrapper to handle file operations uniformly<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private static abstract class File {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    protected final FileSystem fs;<a name="line.675"></a>
+<span class="sourceLineNo">676</span><a name="line.676"></a>
+<span class="sourceLineNo">677</span>    public File(FileSystem fs) {<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      this.fs = fs;<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
+<span class="sourceLineNo">680</span><a name="line.680"></a>
+<span class="sourceLineNo">681</span>    /**<a name="line.681"></a>
+<span class="sourceLineNo">682</span>     * Delete the file<a name="line.682"></a>
+<span class="sourceLineNo">683</span>     * @throws IOException on failure<a name="line.683"></a>
 <span class="sourceLineNo">684</span>     */<a name="line.684"></a>
-<span class="sourceLineNo">685</span>    abstract Path getPath();<a name="line.685"></a>
+<span class="sourceLineNo">685</span>    abstract void delete() throws IOException;<a name="line.685"></a>
 <span class="sourceLineNo">686</span><a name="line.686"></a>
 <span class="sourceLineNo">687</span>    /**<a name="line.687"></a>
-<span class="sourceLineNo">688</span>     * Move the file to the given destination<a name="line.688"></a>
-<span class="sourceLineNo">689</span>     * @param dest<a name="line.689"></a>
-<span class="sourceLineNo">690</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.690"></a>
-<span class="sourceLineNo">691</span>     * @throws IOException<a name="line.691"></a>
-<span class="sourceLineNo">692</span>     */<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>      this.close();<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      Path p = this.getPath();<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span><a name="line.698"></a>
-<span class="sourceLineNo">699</span>    /**<a name="line.699"></a>
-<span class="sourceLineNo">700</span>     * @return the {@link FileSystem} on which this file resides<a name="line.700"></a>
-<span class="sourceLineNo">701</span>     */<a name="line.701"></a>
-<span class="sourceLineNo">702</span>    public FileSystem getFileSystem() {<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      return this.fs;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>    }<a name="line.704"></a>
-<span class="sourceLineNo">705</span><a name="line.705"></a>
-<span class="sourceLineNo">706</span>    @Override<a name="line.706"></a>
-<span class="sourceLineNo">707</span>    public String toString() {<a name="line.707"></a>
-<span class="sourceLineNo">708</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.708"></a>
-<span class="sourceLineNo">709</span>    }<a name="line.709"></a>
-<span class="sourceLineNo">710</span>  }<a name="line.710"></a>
-<span class="sourceLineNo">711</span><a name="line.711"></a>
-<span class="sourceLineNo">712</span>  /**<a name="line.712"></a>
-<span class="sourceLineNo">713</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.713"></a>
-<span class="sourceLineNo">714</span>   */<a name="line.714"></a>
-<span class="sourceLineNo">715</span>  private static class FileablePath extends File {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    private final Path file;<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    private final FileStatusConverter getAsFile;<a name="line.717"></a>
-<span class="sourceLineNo">718</span><a name="line.718"></a>
-<span class="sourceLineNo">719</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      super(fs);<a name="line.720"></a>
-<span class="sourceLineNo">721</span>      this.file = file;<a name="line.721"></a>
-<span class="sourceLineNo">722</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.722"></a>
-<span class="sourceLineNo">723</span>    }<a name="line.723"></a>
-<span class="sourceLineNo">724</span><a name="line.724"></a>
-<span class="sourceLineNo">725</span>    @Override<a name="line.725"></a>
-<span class="sourceLineNo">726</span>    public void delete() throws IOException {<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.727"></a>
+<span class="sourceLineNo">688</span>     * Check to see if this is a file or a directory<a name="line.688"></a>
+<span class="sourceLineNo">689</span>     * @return &lt;tt&gt;true&lt;/tt&gt; if it is a file, &lt;tt&gt;false&lt;/tt&gt; otherwise<a name="line.689"></a>
+<span class="sourceLineNo">690</span>     * @throws IOException on {@link FileSystem} connection error<a name="line.690"></a>
+<span class="sourceLineNo">691</span>     */<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    abstract boolean isFile() throws IOException;<a name="line.692"></a>
+<span class="sourceLineNo">693</span><a name="line.693"></a>
+<span class="sourceLineNo">694</span>    /**<a name="line.694"></a>
+<span class="sourceLineNo">695</span>     * @return if this is a directory, returns all the children in the<a name="line.695"></a>
+<span class="sourceLineNo">696</span>     *         directory, otherwise returns an empty list<a name="line.696"></a>
+<span class="sourceLineNo">697</span>     * @throws IOException<a name="line.697"></a>
+<span class="sourceLineNo">698</span>     */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    abstract Collection&lt;File&gt; getChildren() throws IOException;<a name="line.699"></a>
+<span class="sourceLineNo">700</span><a name="line.700"></a>
+<span class="sourceLineNo">701</span>    /**<a name="line.701"></a>
+<span class="sourceLineNo">702</span>     * close any outside readers of the file<a name="line.702"></a>
+<span class="sourceLineNo">703</span>     * @throws IOException<a name="line.703"></a>
+<span class="sourceLineNo">704</span>     */<a name="line.704"></a>
+<span class="sourceLineNo">705</span>    abstract void close() throws IOException;<a name="line.705"></a>
+<span class="sourceLineNo">706</span><a name="line.706"></a>
+<span class="sourceLineNo">707</span>    /**<a name="line.707"></a>
+<span class="sourceLineNo">708</span>     * @return the name of the file (not the full fs path, just the individual<a name="line.708"></a>
+<span class="sourceLineNo">709</span>     *         file name)<a name="line.709"></a>
+<span class="sourceLineNo">710</span>     */<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    abstract String getName();<a name="line.711"></a>
+<span class="sourceLineNo">712</span><a name="line.712"></a>
+<span class="sourceLineNo">713</span>    /**<a name="line.713"></a>
+<span class="sourceLineNo">714</span>     * @return the path to this file<a name="line.714"></a>
+<span class="sourceLineNo">715</span>     */<a name="line.715"></a>
+<span class="sourceLineNo">716</span>    abstract Path getPath();<a name="line.716"></a>
+<span class="sourceLineNo">717</span><a name="line.717"></a>
+<span class="sourceLineNo">718</span>    /**<a name="line.718"></a>
+<span class="sourceLineNo">719</span>     * Move the file to the given destination<a name="line.719"></a>
+<span class="sourceLineNo">720</span>     * @param dest<a name="line.720"></a>
+<span class="sourceLineNo">721</span>     * @return &lt;tt&gt;true&lt;/tt&gt; on success<a name="line.721"></a>
+<span class="sourceLineNo">722</span>     * @throws IOException<a name="line.722"></a>
+<span class="sourceLineNo">723</span>     */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>    public boolean moveAndClose(Path dest) throws IOException {<a name="line.724"></a>
+<span class="sourceLineNo">725</span>      this.close();<a name="line.725"></a>
+<span class="sourceLineNo">726</span>      Path p = this.getPath();<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      return CommonFSUtils.renameAndSetModifyTime(fs, p, dest);<a name="line.727"></a>
 <span class="sourceLineNo">728</span>    }<a name="line.728"></a>
 <span class="sourceLineNo">729</span><a name="line.729"></a>
-<span class="sourceLineNo">730</span>    @Override<a name="line.730"></a>
-<span class="sourceLineNo">731</span>    public String getName() {<a name="line.731"></a>
-<span class="sourceLineNo">732</span>      return file.getName();<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    }<a name="line.733"></a>
-<span class="sourceLineNo">734</span><a name="line.734"></a>
-<span class="sourceLineNo">735</span>    @Override<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.736"></a>
-<span class="sourceLineNo">737</span>      if (fs.isFile(file)) {<a name="line.737"></a>
-<span class="sourceLineNo">738</span>        return Collections.emptyList();<a name="line.738"></a>
-<span class="sourceLineNo">739</span>      }<a name="line.739"></a>
-<span class="sourceLineNo">740</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.740"></a>
-<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">730</span>    /**<a name="line.730"></a>
+<span class="sourceLineNo">731</span>     * @return the {@link FileSystem} on which this file resides<a name="line.731"></a>
+<span class="sourceLineNo">732</span>     */<a name="line.732"></a>
+<span class="sourceLineNo">733</span>    public FileSystem getFileSystem() {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>      return this.fs;<a name="line.734"></a>
+<span class="sourceLineNo">735</span>    }<a name="line.735"></a>
+<span class="sourceLineNo">736</span><a name="line.736"></a>
+<span class="sourceLineNo">737</span>    @Override<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    public String toString() {<a name="line.738"></a>
+<span class="sourceLineNo">739</span>      return this.getClass().getSimpleName() + ", " + getPath().toString();<a name="line.739"></a>
+<span class="sourceLineNo">740</span>    }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>  }<a name="line.741"></a>
 <span class="sourceLineNo">742</span><a name="line.742"></a>
-<span class="sourceLineNo">743</span>    @Override<a name="line.743"></a>
-<span class="sourceLineNo">744</span>    public boolean isFile() throws IOException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>      return fs.isFile(file);<a name="line.745"></a>
-<span class="sourceLineNo">746</span>    }<a name="line.746"></a>
-<span class="sourceLineNo">747</span><a name="line.747"></a>
-<span class="sourceLineNo">748</span>    @Override<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    public void close() throws IOException {<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      // NOOP - files are implicitly closed on removal<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    }<a name="line.751"></a>
-<span class="sourceLineNo">752</span><a name="line.752"></a>
-<span class="sourceLineNo">753</span>    @Override<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    Path getPath() {<a name="line.754"></a>
-<span class="sourceLineNo">755</span>      return file;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>    }<a name="line.756"></a>
-<span class="sourceLineNo">757</span>  }<a name="line.757"></a>
-<span class="sourceLineNo">758</span><a name="line.758"></a>
-<span class="sourceLineNo">759</span>  /**<a name="line.759"></a>
-<span class="sourceLineNo">760</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.760"></a>
-<span class="sourceLineNo">761</span>   * .<a name="line.761"></a>
-<span class="sourceLineNo">762</span>   */<a name="line.762"></a>
-<span class="sourceLineNo">763</span>  private static class FileableStoreFile extends File {<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    HStoreFile file;<a name="line.764"></a>
+<span class="sourceLineNo">743</span>  /**<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * A {@link File} that wraps a simple {@link Path} on a {@link FileSystem}.<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   */<a name="line.745"></a>
+<span class="sourceLineNo">746</span>  private static class FileablePath extends File {<a name="line.746"></a>
+<span class="sourceLineNo">747</span>    private final Path file;<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    private final FileStatusConverter getAsFile;<a name="line.748"></a>
+<span class="sourceLineNo">749</span><a name="line.749"></a>
+<span class="sourceLineNo">750</span>    public FileablePath(FileSystem fs, Path file) {<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      super(fs);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>      this.file = file;<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.getAsFile = new FileStatusConverter(fs);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
+<span class="sourceLineNo">755</span><a name="line.755"></a>
+<span class="sourceLineNo">756</span>    @Override<a name="line.756"></a>
+<span class="sourceLineNo">757</span>    public void delete() throws IOException {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>      if (!fs.delete(file, true)) throw new IOException("Failed to delete:" + this.file);<a name="line.758"></a>
+<span class="sourceLineNo">759</span>    }<a name="line.759"></a>
+<span class="sourceLineNo">760</span><a name="line.760"></a>
+<span class="sourceLineNo">761</span>    @Override<a name="line.761"></a>
+<span class="sourceLineNo">762</span>    public String getName() {<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      return file.getName();<a name="line.763"></a>
+<span class="sourceLineNo">764</span>    }<a name="line.764"></a>
 <span class="sourceLineNo">765</span><a name="line.765"></a>
-<span class="sourceLineNo">766</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.766"></a>
-<span class="sourceLineNo">767</span>      super(fs);<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      this.file = store;<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    }<a name="line.769"></a>
-<span class="sourceLineNo">770</span><a name="line.770"></a>
-<span class="sourceLineNo">771</span>    @Override<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    public void delete() throws IOException {<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      file.deleteStoreFile();<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    }<a name="line.774"></a>
-<span class="sourceLineNo">775</span><a name="line.775"></a>
-<span class="sourceLineNo">776</span>    @Override<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    public String getName() {<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      return file.getPath().getName();<a name="line.778"></a>
-<span class="sourceLineNo">779</span>    }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>    @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>    public boolean isFile() {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      return true;<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    }<a name="line.784"></a>
-<span class="sourceLineNo">785</span><a name="line.785"></a>
-<span class="sourceLineNo">786</span>    @Override<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.787"></a>
-<span class="sourceLineNo">788</span>      // storefiles don't have children<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      return Collections.emptyList();<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span><a name="line.791"></a>
-<span class="sourceLineNo">792</span>    @Override<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    public void close() throws IOException {<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      file.closeStoreFile(true);<a name="line.794"></a>
-<span class="sourceLineNo">795</span>    }<a name="line.795"></a>
+<span class="sourceLineNo">766</span>    @Override<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.767"></a>
+<span class="sourceLineNo">768</span>      if (fs.isFile(file)) {<a name="line.768"></a>
+<span class="sourceLineNo">769</span>        return Collections.emptyList();<a name="line.769"></a>
+<span class="sourceLineNo">770</span>      }<a name="line.770"></a>
+<span class="sourceLineNo">771</span>      return Stream.of(fs.listStatus(file)).map(getAsFile).collect(Collectors.toList());<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    }<a name="line.772"></a>
+<span class="sourceLineNo">773</span><a name="line.773"></a>
+<span class="sourceLineNo">774</span>    @Override<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    public boolean isFile() throws IOException {<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      return fs.isFile(file);<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
+<span class="sourceLineNo">778</span><a name="line.778"></a>
+<span class="sourceLineNo">779</span>    @Override<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    public void close() throws IOException {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      // NOOP - files are implicitly closed on removal<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span><a name="line.783"></a>
+<span class="sourceLineNo">784</span>    @Override<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    Path getPath() {<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      return file;<a name="line.786"></a>
+<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
+<span class="sourceLineNo">788</span>  }<a name="line.788"></a>
+<span class="sourceLineNo">789</span><a name="line.789"></a>
+<span class="sourceLineNo">790</span>  /**<a name="line.790"></a>
+<span class="sourceLineNo">791</span>   * {@link File} adapter for a {@link HStoreFile} living on a {@link FileSystem}<a name="line.791"></a>
+<span class="sourceLineNo">792</span>   * .<a name="line.792"></a>
+<span class="sourceLineNo">793</span>   */<a name="line.793"></a>
+<span class="sourceLineNo">794</span>  private static class FileableStoreFile extends File {<a name="line.794"></a>
+<span class="sourceLineNo">795</span>    HStoreFile file;<a name="line.795"></a>
 <span class="sourceLineNo">796</span><a name="line.796"></a>
-<span class="sourceLineNo">797</span>    @Override<a name="line.797"></a>
-<span class="sourceLineNo">798</span>    Path getPath() {<a name="line.798"></a>
-<span class="sourceLineNo">799</span>      return file.getPath();<a name="line.799"></a>
+<span class="sourceLineNo">797</span>    public FileableStoreFile(FileSystem fs, HStoreFile store) {<a name="line.797"></a>
+<span class="sourceLineNo">798</span>      super(fs);<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      this.file = store;<a name="line.799"></a>
 <span class="sourceLineNo">800</span>    }<a name="line.800"></a>
-<span class="sourceLineNo">801</span>  }<a name="line.801"></a>
-<span class="sourceLineNo">802</span>}<a name="line.802"></a>
+<span class="sourceLineNo">801</span><a name="line.801"></a>
+<span class="sourceLineNo">802</span>    @Override<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    public void delete() throws IOException {<a name="line.803"></a>
+<span class="sourceLineNo">804</span>      file.deleteStoreFile();<a name="line.804"></a>
+<span class="sourceLineNo">805</span>    }<a name="line.805"></a>
+<span class="sourceLineNo">806</span><a name="line.806"></a>
+<span class="sourceLineNo">807</span>    @Override<a name="line.807"></a>
+<span class="sourceLineNo">808</span>    public String getName() {<a name="line.808"></a>
+<span class="sourceLineNo">809</span>      return file.getPath().getName();<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    }<a name="line.810"></a>
+<span class="sourceLineNo">811</span><a name="line.811"></a>
+<span class="sourceLineNo">812</span>    @Override<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    public boolean isFile() {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      return true;<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span><a name="line.816"></a>
+<span class="sourceLineNo">817</span>    @Override<a name="line.817"></a>
+<span class="sourceLineNo">818</span>    public Collection&lt;File&gt; getChildren() throws IOException {<a name="line.818"></a>
+<span class="sourceLineNo">819</span>      // storefiles don't have children<a name="line.819"></a>
+<span class="sourceLineNo">820</span>      return Collections.emptyList();<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>    @Override<a name="line.823"></a>
+<span class="sourceLineNo">824</span>    public void close() throws IOException {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      file.closeStoreFile(true);<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    }<a name="line.826"></a>
+<span class="sourceLineNo">827</span><a name="line.827"></a>
+<span class="sourceLineNo">828</span>    @Override<a name="line.828"></a>
+<span class="sourceLineNo">829</span>    Path getPath() {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>      return file.getPath();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>    }<a name="line.831"></a>
+<span class="sourceLineNo">832</span>  }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>}<a name="line.833"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
index 3392220..3a56a19 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.TransitionType.html
@@ -25,577 +25,579 @@
 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
 <span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.master.assignment;<a name="line.18"></a>
 <span class="sourceLineNo">019</span><a name="line.19"></a>
-<span class="sourceLineNo">020</span>import edu.umd.cs.findbugs.annotations.Nullable;<a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.IOException;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import org.apache.hadoop.hbase.HBaseIOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import org.apache.hadoop.hbase.ServerName;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import org.apache.hadoop.hbase.TableName;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.client.RetriesExhaustedException;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.master.MetricsAssignmentManager;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.master.RegionState.State;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineRegionProcedure;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.procedure2.Procedure;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.procedure2.ProcedureMetrics;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.procedure2.ProcedureUtil;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.util.RetryCounter;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.slf4j.Logger;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.slf4j.LoggerFactory;<a name="line.42"></a>
-<span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionStateData;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode;<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>/**<a name="line.51"></a>
-<span class="sourceLineNo">052</span> * The procedure to deal with the state transition of a region. A region with a TRSP in place is<a name="line.52"></a>
-<span class="sourceLineNo">053</span> * called RIT, i.e, RegionInTransition.<a name="line.53"></a>
-<span class="sourceLineNo">054</span> * &lt;p/&gt;<a name="line.54"></a>
-<span class="sourceLineNo">055</span> * It can be used to assign/unassign/reopen/move a region, and for<a name="line.55"></a>
-<span class="sourceLineNo">056</span> * {@link #unassign(MasterProcedureEnv, RegionInfo)} and<a name="line.56"></a>
-<span class="sourceLineNo">057</span> * {@link #reopen(MasterProcedureEnv, RegionInfo)}, you do not need to specify a target server, and<a name="line.57"></a>
-<span class="sourceLineNo">058</span> * for {@link #assign(MasterProcedureEnv, RegionInfo, ServerName)} and<a name="line.58"></a>
-<span class="sourceLineNo">059</span> * {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you want to you can provide a<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * target server. And for {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you do not<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * specify a targetServer, we will select one randomly.<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * &lt;p/&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;p/&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * The typical state transition for assigning a region is:<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;pre&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;/pre&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * Notice that, if there are failures we may go back to the {@code GET_ASSIGN_CANDIDATE} state to<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * try again.<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p/&gt;<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * The typical state transition for unassigning a region is:<a name="line.73"></a>
-<span class="sourceLineNo">074</span> *<a name="line.74"></a>
-<span class="sourceLineNo">075</span> * &lt;pre&gt;<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * CLOSE -----&gt; CONFIRM_CLOSED<a name="line.76"></a>
-<span class="sourceLineNo">077</span> * &lt;/pre&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *<a name="line.78"></a>
-<span class="sourceLineNo">079</span> * Here things go a bit different, if there are failures, especially that if there is a server<a name="line.79"></a>
-<span class="sourceLineNo">080</span> * crash, we will go to the {@code GET_ASSIGN_CANDIDATE} state to bring the region online first, and<a name="line.80"></a>
-<span class="sourceLineNo">081</span> * then go through the normal way to unassign it.<a name="line.81"></a>
-<span class="sourceLineNo">082</span> * &lt;p/&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * The typical state transition for reopening/moving a region is:<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;pre&gt;<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * CLOSE -----&gt; CONFIRM_CLOSED -----&gt; GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;/pre&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *<a name="line.88"></a>
-<span class="sourceLineNo">089</span> * The retry logic is the same with the above assign/unassign.<a name="line.89"></a>
-<span class="sourceLineNo">090</span> * &lt;p/&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> * Notice that, although we allow specify a target server, it just acts as a candidate, we do not<a name="line.91"></a>
-<span class="sourceLineNo">092</span> * guarantee that the region will finally be on the target server. If this is important for you, you<a name="line.92"></a>
-<span class="sourceLineNo">093</span> * should check whether the region is on the target server after the procedure is finished.<a name="line.93"></a>
-<span class="sourceLineNo">094</span> * &lt;p/&gt;<a name="line.94"></a>
-<span class="sourceLineNo">095</span> * When you want to schedule a TRSP, please check whether there is still one for this region, and<a name="line.95"></a>
-<span class="sourceLineNo">096</span> * the check should be under the RegionStateNode lock. We will remove the TRSP from a<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * RegionStateNode when we are done, see the code in {@code reportTransition} method below. There<a name="line.97"></a>
-<span class="sourceLineNo">098</span> * could be at most one TRSP for a give region.<a name="line.98"></a>
-<span class="sourceLineNo">099</span> */<a name="line.99"></a>
-<span class="sourceLineNo">100</span>@InterfaceAudience.Private<a name="line.100"></a>
-<span class="sourceLineNo">101</span>public class TransitRegionStateProcedure<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    extends AbstractStateMachineRegionProcedure&lt;RegionStateTransitionState&gt; {<a name="line.102"></a>
-<span class="sourceLineNo">103</span><a name="line.103"></a>
-<span class="sourceLineNo">104</span>  private static final Logger LOG = LoggerFactory.getLogger(TransitRegionStateProcedure.class);<a name="line.104"></a>
+<span class="sourceLineNo">020</span>import static org.apache.hadoop.hbase.master.LoadBalancer.BOGUS_SERVER_NAME;<a name="line.20"></a>
+<span class="sourceLineNo">021</span><a name="line.21"></a>
+<span class="sourceLineNo">022</span>import edu.umd.cs.findbugs.annotations.Nullable;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.io.IOException;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import org.apache.hadoop.hbase.HBaseIOException;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.hadoop.hbase.ServerName;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.TableName;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.client.RetriesExhaustedException;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.master.MetricsAssignmentManager;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.master.RegionState.State;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineRegionProcedure;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.procedure2.Procedure;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.procedure2.ProcedureMetrics;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.procedure2.ProcedureUtil;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.util.RetryCounter;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.slf4j.Logger;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.slf4j.LoggerFactory;<a name="line.44"></a>
+<span class="sourceLineNo">045</span><a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionStateData;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>/**<a name="line.53"></a>
+<span class="sourceLineNo">054</span> * The procedure to deal with the state transition of a region. A region with a TRSP in place is<a name="line.54"></a>
+<span class="sourceLineNo">055</span> * called RIT, i.e, RegionInTransition.<a name="line.55"></a>
+<span class="sourceLineNo">056</span> * &lt;p/&gt;<a name="line.56"></a>
+<span class="sourceLineNo">057</span> * It can be used to assign/unassign/reopen/move a region, and for<a name="line.57"></a>
+<span class="sourceLineNo">058</span> * {@link #unassign(MasterProcedureEnv, RegionInfo)} and<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * {@link #reopen(MasterProcedureEnv, RegionInfo)}, you do not need to specify a target server, and<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * for {@link #assign(MasterProcedureEnv, RegionInfo, ServerName)} and<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you want to you can provide a<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * target server. And for {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you do not<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * specify a targetServer, we will select one randomly.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;p/&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;p/&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * The typical state transition for assigning a region is:<a name="line.66"></a>
+<span class="sourceLineNo">067</span> *<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;pre&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.69"></a>
+<span class="sourceLineNo">070</span> * &lt;/pre&gt;<a name="line.70"></a>
+<span class="sourceLineNo">071</span> *<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * Notice that, if there are failures we may go back to the {@code GET_ASSIGN_CANDIDATE} state to<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * try again.<a name="line.73"></a>
+<span class="sourceLineNo">074</span> * &lt;p/&gt;<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * The typical state transition for unassigning a region is:<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *<a name="line.76"></a>
+<span class="sourceLineNo">077</span> * &lt;pre&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> * CLOSE -----&gt; CONFIRM_CLOSED<a name="line.78"></a>
+<span class="sourceLineNo">079</span> * &lt;/pre&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *<a name="line.80"></a>
+<span class="sourceLineNo">081</span> * Here things go a bit different, if there are failures, especially that if there is a server<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * crash, we will go to the {@code GET_ASSIGN_CANDIDATE} state to bring the region online first, and<a name="line.82"></a>
+<span class="sourceLineNo">083</span> * then go through the normal way to unassign it.<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p/&gt;<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * The typical state transition for reopening/moving a region is:<a name="line.85"></a>
+<span class="sourceLineNo">086</span> *<a name="line.86"></a>
+<span class="sourceLineNo">087</span> * &lt;pre&gt;<a name="line.87"></a>
+<span class="sourceLineNo">088</span> * CLOSE -----&gt; CONFIRM_CLOSED -----&gt; GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.88"></a>
+<span class="sourceLineNo">089</span> * &lt;/pre&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *<a name="line.90"></a>
+<span class="sourceLineNo">091</span> * The retry logic is the same with the above assign/unassign.<a name="line.91"></a>
+<span class="sourceLineNo">092</span> * &lt;p/&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> * Notice that, although we allow specify a target server, it just acts as a candidate, we do not<a name="line.93"></a>
+<span class="sourceLineNo">094</span> * guarantee that the region will finally be on the target server. If this is important for you, you<a name="line.94"></a>
+<span class="sourceLineNo">095</span> * should check whether the region is on the target server after the procedure is finished.<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;p/&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> * When you want to schedule a TRSP, please check whether there is still one for this region, and<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * the check should be under the RegionStateNode lock. We will remove the TRSP from a<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * RegionStateNode when we are done, see the code in {@code reportTransition} method below. There<a name="line.99"></a>
+<span class="sourceLineNo">100</span> * could be at most one TRSP for a give region.<a name="line.100"></a>
+<span class="sourceLineNo">101</span> */<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@InterfaceAudience.Private<a name="line.102"></a>
+<span class="sourceLineNo">103</span>public class TransitRegionStateProcedure<a name="line.103"></a>
+<span class="sourceLineNo">104</span>    extends AbstractStateMachineRegionProcedure&lt;RegionStateTransitionState&gt; {<a name="line.104"></a>
 <span class="sourceLineNo">105</span><a name="line.105"></a>
-<span class="sourceLineNo">106</span>  private TransitionType type;<a name="line.106"></a>
+<span class="sourceLineNo">106</span>  private static final Logger LOG = LoggerFactory.getLogger(TransitRegionStateProcedure.class);<a name="line.106"></a>
 <span class="sourceLineNo">107</span><a name="line.107"></a>
-<span class="sourceLineNo">108</span>  private RegionStateTransitionState initialState;<a name="line.108"></a>
+<span class="sourceLineNo">108</span>  private TransitionType type;<a name="line.108"></a>
 <span class="sourceLineNo">109</span><a name="line.109"></a>
-<span class="sourceLineNo">110</span>  private RegionStateTransitionState lastState;<a name="line.110"></a>
+<span class="sourceLineNo">110</span>  private RegionStateTransitionState initialState;<a name="line.110"></a>
 <span class="sourceLineNo">111</span><a name="line.111"></a>
-<span class="sourceLineNo">112</span>  // the candidate where we want to assign the region to.<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  private ServerName assignCandidate;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>  private boolean forceNewPlan;<a name="line.115"></a>
+<span class="sourceLineNo">112</span>  private RegionStateTransitionState lastState;<a name="line.112"></a>
+<span class="sourceLineNo">113</span><a name="line.113"></a>
+<span class="sourceLineNo">114</span>  // the candidate where we want to assign the region to.<a name="line.114"></a>
+<span class="sourceLineNo">115</span>  private ServerName assignCandidate;<a name="line.115"></a>
 <span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private RetryCounter retryCounter;<a name="line.117"></a>
+<span class="sourceLineNo">117</span>  private boolean forceNewPlan;<a name="line.117"></a>
 <span class="sourceLineNo">118</span><a name="line.118"></a>
-<span class="sourceLineNo">119</span>  private RegionRemoteProcedureBase remoteProc;<a name="line.119"></a>
+<span class="sourceLineNo">119</span>  private RetryCounter retryCounter;<a name="line.119"></a>
 <span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  public TransitRegionStateProcedure() {<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  private void setInitialAndLastState() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    switch (type) {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>      case ASSIGN:<a name="line.126"></a>
-<span class="sourceLineNo">127</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>        break;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>      case UNASSIGN:<a name="line.130"></a>
-<span class="sourceLineNo">131</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED;<a name="line.132"></a>
-<span class="sourceLineNo">133</span>        break;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      case MOVE:<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      case REOPEN:<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.136"></a>
-<span class="sourceLineNo">137</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        break;<a name="line.138"></a>
-<span class="sourceLineNo">139</span>      default:<a name="line.139"></a>
-<span class="sourceLineNo">140</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    }<a name="line.141"></a>
-<span class="sourceLineNo">142</span>  }<a name="line.142"></a>
-<span class="sourceLineNo">143</span><a name="line.143"></a>
-<span class="sourceLineNo">144</span>  protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,<a name="line.144"></a>
-<span class="sourceLineNo">145</span>      ServerName assignCandidate, boolean forceNewPlan, TransitionType type) {<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    super(env, hri);<a name="line.146"></a>
-<span class="sourceLineNo">147</span>    this.assignCandidate = assignCandidate;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>    this.forceNewPlan = forceNewPlan;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    this.type = type;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    setInitialAndLastState();<a name="line.150"></a>
-<span class="sourceLineNo">151</span><a name="line.151"></a>
-<span class="sourceLineNo">152</span>    // when do reopen TRSP, let the rs know the targetServer so it can keep some info on close<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    if (type == TransitionType.REOPEN) {<a name="line.153"></a>
-<span class="sourceLineNo">154</span>      this.assignCandidate = getRegionStateNode(env).getRegionLocation();<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    }<a name="line.155"></a>
-<span class="sourceLineNo">156</span>  }<a name="line.156"></a>
-<span class="sourceLineNo">157</span><a name="line.157"></a>
-<span class="sourceLineNo">158</span>  @Override<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  public TableOperationType getTableOperationType() {<a name="line.159"></a>
-<span class="sourceLineNo">160</span>    // TODO: maybe we should make another type here, REGION_TRANSITION?<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    return TableOperationType.REGION_EDIT;<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  }<a name="line.162"></a>
-<span class="sourceLineNo">163</span><a name="line.163"></a>
-<span class="sourceLineNo">164</span>  @Override<a name="line.164"></a>
-<span class="sourceLineNo">165</span>  protected boolean waitInitialized(MasterProcedureEnv env) {<a name="line.165"></a>
-<span class="sourceLineNo">166</span>    if (TableName.isMetaTableName(getTableName())) {<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      return false;<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    }<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    // First we need meta to be loaded, and second, if meta is not online then we will likely to<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    // fail when updating meta so we wait until it is assigned.<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    AssignmentManager am = env.getAssignmentManager();<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    return am.waitMetaLoaded(this) || am.waitMetaAssigned(this, getRegion());<a name="line.172"></a>
-<span class="sourceLineNo">173</span>  }<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>  private void queueAssign(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.175"></a>
-<span class="sourceLineNo">176</span>      throws ProcedureSuspendedException {<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    boolean retain = false;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    if (forceNewPlan) {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>      // set the region location to null if forceNewPlan is true<a name="line.179"></a>
-<span class="sourceLineNo">180</span>      regionNode.setRegionLocation(null);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    } else {<a name="line.181"></a>
-<span class="sourceLineNo">182</span>      if (assignCandidate != null) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>        retain = assignCandidate.equals(regionNode.getLastHost());<a name="line.183"></a>
-<span class="sourceLineNo">184</span>        regionNode.setRegionLocation(assignCandidate);<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      } else if (regionNode.getLastHost() != null) {<a name="line.185"></a>
-<span class="sourceLineNo">186</span>        retain = true;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>        LOG.info("Setting lastHost as the region location {}", regionNode.getLastHost());<a name="line.187"></a>
-<span class="sourceLineNo">188</span>        regionNode.setRegionLocation(regionNode.getLastHost());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>      }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
-<span class="sourceLineNo">191</span>    LOG.info("Starting {}; {}; forceNewPlan={}, retain={}", this, regionNode.toShortString(),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      forceNewPlan, retain);<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    env.getAssignmentManager().queueAssign(regionNode);<a name="line.193"></a>
-<span class="sourceLineNo">194</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_OPEN);<a name="line.194"></a>
-<span class="sourceLineNo">195</span>    if (regionNode.getProcedureEvent().suspendIfNotReady(this)) {<a name="line.195"></a>
-<span class="sourceLineNo">196</span>      throw new ProcedureSuspendedException();<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    }<a name="line.197"></a>
-<span class="sourceLineNo">198</span>  }<a name="line.198"></a>
-<span class="sourceLineNo">199</span><a name="line.199"></a>
-<span class="sourceLineNo">200</span>  private void openRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    ServerName loc = regionNode.getRegionLocation();<a name="line.201"></a>
-<span class="sourceLineNo">202</span>    if (loc == null) {<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      LOG.warn("No location specified for {}, jump back to state {} to get one", getRegion(),<a name="line.203"></a>
-<span class="sourceLineNo">204</span>        RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      return;<a name="line.206"></a>
-<span class="sourceLineNo">207</span>    }<a name="line.207"></a>
-<span class="sourceLineNo">208</span>    env.getAssignmentManager().regionOpening(regionNode);<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    addChildProcedure(new OpenRegionProcedure(this, getRegion(), loc));<a name="line.209"></a>
-<span class="sourceLineNo">210</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED);<a name="line.210"></a>
-<span class="sourceLineNo">211</span>  }<a name="line.211"></a>
-<span class="sourceLineNo">212</span><a name="line.212"></a>
-<span class="sourceLineNo">213</span>  private Flow confirmOpened(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.213"></a>
-<span class="sourceLineNo">214</span>      throws IOException {<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    if (regionNode.isInState(State.OPEN)) {<a name="line.215"></a>
-<span class="sourceLineNo">216</span>      retryCounter = null;<a name="line.216"></a>
-<span class="sourceLineNo">217</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED) {<a name="line.217"></a>
-<span class="sourceLineNo">218</span>        // we are the last state, finish<a name="line.218"></a>
-<span class="sourceLineNo">219</span>        regionNode.unsetProcedure(this);<a name="line.219"></a>
-<span class="sourceLineNo">220</span>        ServerCrashProcedure.updateProgress(env, getParentProcId());<a name="line.220"></a>
-<span class="sourceLineNo">221</span>        return Flow.NO_MORE_STATE;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>      }<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      // It is possible that we arrive here but confirm opened is not the last state, for example,<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      // when merging or splitting a region, we unassign the region from a RS and the RS is crashed,<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      // then there will be recovered edits for this region, we'd better make the region online<a name="line.225"></a>
-<span class="sourceLineNo">226</span>      // again and then unassign it, otherwise we have to fail the merge/split procedure as we may<a name="line.226"></a>
-<span class="sourceLineNo">227</span>      // loss data.<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.228"></a>
-<span class="sourceLineNo">229</span>      return Flow.HAS_MORE_STATE;<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    }<a name="line.230"></a>
-<span class="sourceLineNo">231</span><a name="line.231"></a>
-<span class="sourceLineNo">232</span>    int retries = env.getAssignmentManager().getRegionStates().addToFailedOpen(regionNode)<a name="line.232"></a>
-<span class="sourceLineNo">233</span>        .incrementAndGetRetries();<a name="line.233"></a>
-<span class="sourceLineNo">234</span>    int maxAttempts = env.getAssignmentManager().getAssignMaxAttempts();<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    LOG.info("Retry={} of max={}; {}; {}", retries, maxAttempts, this, regionNode.toShortString());<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    if (retries &gt;= maxAttempts) {<a name="line.237"></a>
-<span class="sourceLineNo">238</span>      env.getAssignmentManager().regionFailedOpen(regionNode, true);<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      setFailure(getClass().getSimpleName(), new RetriesExhaustedException(<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        "Max attempts " + env.getAssignmentManager().getAssignMaxAttempts() + " exceeded"));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      regionNode.unsetProcedure(this);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      return Flow.NO_MORE_STATE;<a name="line.242"></a>
-<span class="sourceLineNo">243</span>    }<a name="line.243"></a>
-<span class="sourceLineNo">244</span><a name="line.244"></a>
-<span class="sourceLineNo">245</span>    env.getAssignmentManager().regionFailedOpen(regionNode, false);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    // we failed to assign the region, force a new plan<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    forceNewPlan = true;<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    regionNode.setRegionLocation(null);<a name="line.248"></a>
-<span class="sourceLineNo">249</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.249"></a>
-<span class="sourceLineNo">250</span><a name="line.250"></a>
-<span class="sourceLineNo">251</span>    if (retries &gt; env.getAssignmentManager().getAssignRetryImmediatelyMaxAttempts()) {<a name="line.251"></a>
-<span class="sourceLineNo">252</span>      // Throw exception to backoff and retry when failed open too many times<a name="line.252"></a>
-<span class="sourceLineNo">253</span>      throw new HBaseIOException("Failed confirm OPEN of " + regionNode +<a name="line.253"></a>
-<span class="sourceLineNo">254</span>          " (remote log may yield more detail on why).");<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    } else {<a name="line.255"></a>
-<span class="sourceLineNo">256</span>      // Here we do not throw exception because we want to the region to be online ASAP<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      return Flow.HAS_MORE_STATE;<a name="line.257"></a>
-<span class="sourceLineNo">258</span>    }<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  }<a name="line.259"></a>
-<span class="sourceLineNo">260</span><a name="line.260"></a>
-<span class="sourceLineNo">261</span>  private void closeRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    if (regionNode.isInState(State.OPEN, State.CLOSING, State.MERGING, State.SPLITTING)) {<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      // this is the normal case<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      env.getAssignmentManager().regionClosing(regionNode);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      addChildProcedure(new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),<a name="line.265"></a>
-<span class="sourceLineNo">266</span>        assignCandidate));<a name="line.266"></a>
-<span class="sourceLineNo">267</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    } else {<a name="line.268"></a>
-<span class="sourceLineNo">269</span>      forceNewPlan = true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      regionNode.setRegionLocation(null);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  private Flow confirmClosed(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      throws IOException {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    if (regionNode.isInState(State.CLOSED)) {<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      retryCounter = null;<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        // we are the last state, finish<a name="line.280"></a>
-<span class="sourceLineNo">281</span>        regionNode.unsetProcedure(this);<a name="line.281"></a>
-<span class="sourceLineNo">282</span>        return Flow.NO_MORE_STATE;<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      }<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      // This means we need to open the region again, should be a move or reopen<a name="line.284"></a>
-<span class="sourceLineNo">285</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return Flow.HAS_MORE_STATE;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    if (regionNode.isInState(State.CLOSING)) {<a name="line.288"></a>
-<span class="sourceLineNo">289</span>      // This is possible, think the target RS crashes and restarts immediately, the close region<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      // operation will return a NotServingRegionException soon, we can only recover after SCP takes<a name="line.290"></a>
-<span class="sourceLineNo">291</span>      // care of this RS. So here we throw an IOException to let upper layer to retry with backoff.<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      throw new HBaseIOException("Failed to close region");<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    }<a name="line.294"></a>
-<span class="sourceLineNo">295</span>    // abnormally closed, need to reopen it, no matter what is the last state, see the comment in<a name="line.295"></a>
-<span class="sourceLineNo">296</span>    // confirmOpened for more details that why we need to reopen the region first even if we just<a name="line.296"></a>
-<span class="sourceLineNo">297</span>    // want to close it.<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    // The only exception is for non-default replica, where we do not need to deal with recovered<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    // edits. Notice that the region will remain in ABNORMALLY_CLOSED state, the upper layer need to<a name="line.299"></a>
-<span class="sourceLineNo">300</span>    // deal with this state. For non-default replica, this is usually the same with CLOSED.<a name="line.300"></a>
-<span class="sourceLineNo">301</span>    assert regionNode.isInState(State.ABNORMALLY_CLOSED);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    if (!RegionReplicaUtil.isDefaultReplica(getRegion()) &amp;&amp;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      regionNode.unsetProcedure(this);<a name="line.304"></a>
-<span class="sourceLineNo">305</span>      return Flow.NO_MORE_STATE;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>    }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    retryCounter = null;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    return Flow.HAS_MORE_STATE;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  }<a name="line.310"></a>
-<span class="sourceLineNo">311</span><a name="line.311"></a>
-<span class="sourceLineNo">312</span>  // Override to lock RegionStateNode<a name="line.312"></a>
-<span class="sourceLineNo">313</span>  @SuppressWarnings("rawtypes")<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  @Override<a name="line.314"></a>
-<span class="sourceLineNo">315</span>  protected Procedure[] execute(MasterProcedureEnv env)<a name="line.315"></a>
-<span class="sourceLineNo">316</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    RegionStateNode regionNode =<a name="line.317"></a>
-<span class="sourceLineNo">318</span>      env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    regionNode.lock();<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    try {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      return super.execute(env);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    } finally {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      regionNode.unlock();<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
-<span class="sourceLineNo">325</span>  }<a name="line.325"></a>
-<span class="sourceLineNo">326</span><a name="line.326"></a>
-<span class="sourceLineNo">327</span>  private RegionStateNode getRegionStateNode(MasterProcedureEnv env) {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    return env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.328"></a>
-<span class="sourceLineNo">329</span>  }<a name="line.329"></a>
-<span class="sourceLineNo">330</span><a name="line.330"></a>
-<span class="sourceLineNo">331</span>  @Override<a name="line.331"></a>
-<span class="sourceLineNo">332</span>  protected Flow executeFromState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    RegionStateNode regionNode = getRegionStateNode(env);<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    try {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      switch (state) {<a name="line.336"></a>
-<span class="sourceLineNo">337</span>        case REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE:<a name="line.337"></a>
-<span class="sourceLineNo">338</span>          // Need to do some sanity check for replica region, if the region does not exist at<a name="line.338"></a>
-<span class="sourceLineNo">339</span>          // master, do not try to assign the replica region, log error and return.<a name="line.339"></a>
-<span class="sourceLineNo">340</span>          if (!RegionReplicaUtil.isDefaultReplica(regionNode.getRegionInfo())) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>            RegionInfo defaultRI =<a name="line.341"></a>
-<span class="sourceLineNo">342</span>              RegionReplicaUtil.getRegionInfoForDefaultReplica(regionNode.getRegionInfo());<a name="line.342"></a>
-<span class="sourceLineNo">343</span>            if (env.getMasterServices().getAssignmentManager().getRegionStates().<a name="line.343"></a>
-<span class="sourceLineNo">344</span>              getRegionStateNode(defaultRI) == null) {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>              LOG.error(<a name="line.345"></a>
-<span class="sourceLineNo">346</span>                "Cannot assign replica region {} because its primary region {} does not exist.",<a name="line.346"></a>
-<span class="sourceLineNo">347</span>                regionNode.getRegionInfo(), defaultRI);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>              regionNode.unsetProcedure(this);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>              return Flow.NO_MORE_STATE;<a name="line.349"></a>
-<span class="sourceLineNo">350</span>            }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>          }<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          queueAssign(env, regionNode);<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          return Flow.HAS_MORE_STATE;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>        case REGION_STATE_TRANSITION_OPEN:<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          openRegion(env, regionNode);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          return Flow.HAS_MORE_STATE;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        case REGION_STATE_TRANSITION_CONFIRM_OPENED:<a name="line.357"></a>
-<span class="sourceLineNo">358</span>          return confirmOpened(env, regionNode);<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        case REGION_STATE_TRANSITION_CLOSE:<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          closeRegion(env, regionNode);<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          return Flow.HAS_MORE_STATE;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        case REGION_STATE_TRANSITION_CONFIRM_CLOSED:<a name="line.362"></a>
-<span class="sourceLineNo">363</span>          return confirmClosed(env, regionNode);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        default:<a name="line.364"></a>
-<span class="sourceLineNo">365</span>          throw new UnsupportedOperationException("unhandled state=" + state);<a name="line.365"></a>
-<span class="sourceLineNo">366</span>      }<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    } catch (IOException e) {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      if (retryCounter == null) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>        retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration());<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      }<a name="line.370"></a>
-<span class="sourceLineNo">371</span>      long backoff = retryCounter.getBackoffTimeAndIncrementAttempts();<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      LOG.warn(<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        "Failed transition, suspend {}secs {}; {}; waiting on rectified condition fixed " +<a name="line.373"></a>
-<span class="sourceLineNo">374</span>          "by other Procedure or operator intervention",<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        backoff / 1000, this, regionNode.toShortString(), e);<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      setTimeout(Math.toIntExact(backoff));<a name="line.376"></a>
-<span class="sourceLineNo">377</span>      setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT);<a name="line.377"></a>
-<span class="sourceLineNo">378</span>      skipPersistence();<a name="line.378"></a>
-<span class="sourceLineNo">379</span>      throw new ProcedureSuspendedException();<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    }<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  }<a name="line.381"></a>
-<span class="sourceLineNo">382</span><a name="line.382"></a>
-<span class="sourceLineNo">383</span>  /**<a name="line.383"></a>
-<span class="sourceLineNo">384</span>   * At end of timeout, wake ourselves up so we run again.<a name="line.384"></a>
-<span class="sourceLineNo">385</span>   */<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  @Override<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  protected synchronized boolean setTimeoutFailure(MasterProcedureEnv env) {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    setState(ProcedureProtos.ProcedureState.RUNNABLE);<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    env.getProcedureScheduler().addFront(this);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    return false; // 'false' means that this procedure handled the timeout<a name="line.390"></a>
-<span class="sourceLineNo">391</span>  }<a name="line.391"></a>
-<span class="sourceLineNo">392</span><a name="line.392"></a>
-<span class="sourceLineNo">393</span>  // Should be called with RegionStateNode locked<a name="line.393"></a>
-<span class="sourceLineNo">394</span>  public void reportTransition(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      ServerName serverName, TransitionCode code, long seqId, long procId) throws IOException {<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    if (remoteProc == null) {<a name="line.396"></a>
-<span class="sourceLineNo">397</span>      LOG.warn(<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        "There is no outstanding remote region procedure for {}, serverName={}, code={}," +<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          " seqId={}, proc={}, should be a retry, ignore",<a name="line.399"></a>
-<span class="sourceLineNo">400</span>        regionNode, serverName, code, seqId, this);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>      return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    // The procId could be -1 if it is from an old region server, we need to deal with it so that we<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    // can do rolling upgraing.<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    if (procId &gt;= 0 &amp;&amp; remoteProc.getProcId() != procId) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      LOG.warn(<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        "The pid of remote region procedure for {} is {}, the reported pid={}, serverName={}," +<a name="line.407"></a>
-<span class="sourceLineNo">408</span>          " code={}, seqId={}, proc={}, should be a retry, ignore",<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        regionNode, remoteProc.getProcId(), procId, serverName, code, seqId, this);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      return;<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    }<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    remoteProc.reportTransition(env, regionNode, serverName, code, seqId);<a name="line.412"></a>
-<span class="sourceLineNo">413</span>  }<a name="line.413"></a>
-<span class="sourceLineNo">414</span><a name="line.414"></a>
-<span class="sourceLineNo">415</span>  // Should be called with RegionStateNode locked<a name="line.415"></a>
-<span class="sourceLineNo">416</span>  public void serverCrashed(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      ServerName serverName, boolean forceNewPlan) throws IOException {<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    this.forceNewPlan = forceNewPlan;<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    if (remoteProc != null) {<a name="line.419"></a>
-<span class="sourceLineNo">420</span>      // this means we are waiting for the sub procedure, so wake it up<a name="line.420"></a>
-<span class="sourceLineNo">421</span>      remoteProc.serverCrashed(env, regionNode, serverName);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    } else {<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      // we are in RUNNING state, just update the region state, and we will process it later.<a name="line.423"></a>
-<span class="sourceLineNo">424</span>      env.getAssignmentManager().regionClosedAbnormally(regionNode);<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
-<span class="sourceLineNo">426</span>  }<a name="line.426"></a>
-<span class="sourceLineNo">427</span><a name="line.427"></a>
-<span class="sourceLineNo">428</span>  void attachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    this.remoteProc = proc;<a name="line.429"></a>
-<span class="sourceLineNo">430</span>  }<a name="line.430"></a>
-<span class="sourceLineNo">431</span><a name="line.431"></a>
-<span class="sourceLineNo">432</span>  void unattachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    assert this.remoteProc == proc;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    this.remoteProc = null;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
-<span class="sourceLineNo">436</span><a name="line.436"></a>
-<span class="sourceLineNo">437</span>  // will be called after we finish loading the meta entry for this region.<a name="line.437"></a>
-<span class="sourceLineNo">438</span>  // used to change the state of the region node if we have a sub procedure, as we may not persist<a name="line.438"></a>
-<span class="sourceLineNo">439</span>  // the state to meta yet. See the code in RegionRemoteProcedureBase.execute for more details.<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  void stateLoaded(AssignmentManager am, RegionStateNode regionNode) {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    if (remoteProc != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      remoteProc.stateLoaded(am, regionNode);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>  @Override<a name="line.446"></a>
-<span class="sourceLineNo">447</span>  protected void rollbackState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.447"></a>
-<span class="sourceLineNo">448</span>      throws IOException, InterruptedException {<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // no rollback<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    throw new UnsupportedOperationException();<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  @Override<a name="line.453"></a>
-<span class="sourceLineNo">454</span>  protected RegionStateTransitionState getState(int stateId) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return RegionStateTransitionState.forNumber(stateId);<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  @Override<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  protected int getStateId(RegionStateTransitionState state) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    return state.getNumber();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>  }<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>  @Override<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  protected RegionStateTransitionState getInitialState() {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    return initialState;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
-<span class="sourceLineNo">467</span><a name="line.467"></a>
-<span class="sourceLineNo">468</span>  private static TransitionType convert(RegionTransitionType type) {<a name="line.468"></a>
-<span class="sourceLineNo">469</span>    switch (type) {<a name="line.469"></a>
-<span class="sourceLineNo">470</span>      case ASSIGN:<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        return TransitionType.ASSIGN;<a name="line.471"></a>
-<span class="sourceLineNo">472</span>      case UNASSIGN:<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        return TransitionType.UNASSIGN;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>      case MOVE:<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        return TransitionType.MOVE;<a name="line.475"></a>
-<span class="sourceLineNo">476</span>      case REOPEN:<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        return TransitionType.REOPEN;<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      default:<a name="line.478"></a>
-<span class="sourceLineNo">479</span>        throw new IllegalArgumentException("Unknown RegionTransitionType: " + type);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
-<span class="sourceLineNo">482</span><a name="line.482"></a>
-<span class="sourceLineNo">483</span>  private static RegionTransitionType convert(TransitionType type) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    switch (type) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      case ASSIGN:<a name="line.485"></a>
-<span class="sourceLineNo">486</span>        return RegionTransitionType.ASSIGN;<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      case UNASSIGN:<a name="line.487"></a>
-<span class="sourceLineNo">488</span>        return RegionTransitionType.UNASSIGN;<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      case MOVE:<a name="line.489"></a>
-<span class="sourceLineNo">490</span>        return RegionTransitionType.MOVE;<a name="line.490"></a>
-<span class="sourceLineNo">491</span>      case REOPEN:<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        return RegionTransitionType.REOPEN;<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      default:<a name="line.493"></a>
-<span class="sourceLineNo">494</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    }<a name="line.495"></a>
-<span class="sourceLineNo">496</span>  }<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>  @Override<a name="line.498"></a>
-<span class="sourceLineNo">499</span>  protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>    super.serializeStateData(serializer);<a name="line.500"></a>
-<span class="sourceLineNo">501</span>    RegionStateTransitionStateData.Builder builder = RegionStateTransitionStateData.newBuilder()<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      .setType(convert(type)).setForceNewPlan(forceNewPlan);<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    if (assignCandidate != null) {<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    }<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    serializer.serialize(builder.build());<a name="line.506"></a>
-<span class="sourceLineNo">507</span>  }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>  @Override<a name="line.509"></a>
-<span class="sourceLineNo">510</span>  protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    super.deserializeStateData(serializer);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>    RegionStateTransitionStateData data =<a name="line.512"></a>
-<span class="sourceLineNo">513</span>      serializer.deserialize(RegionStateTransitionStateData.class);<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    type = convert(data.getType());<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    setInitialAndLastState();<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    forceNewPlan = data.getForceNewPlan();<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    if (data.hasAssignCandidate()) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span>  }<a name="line.520"></a>
-<span class="sourceLineNo">521</span><a name="line.521"></a>
-<span class="sourceLineNo">522</span>  @Override<a name="line.522"></a>
-<span class="sourceLineNo">523</span>  protected ProcedureMetrics getProcedureMetrics(MasterProcedureEnv env) {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    MetricsAssignmentManager metrics = env.getAssignmentManager().getAssignmentManagerMetrics();<a name="line.524"></a>
-<span class="sourceLineNo">525</span>    switch (type) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      case ASSIGN:<a name="line.526"></a>
-<span class="sourceLineNo">527</span>        return metrics.getAssignProcMetrics();<a name="line.527"></a>
-<span class="sourceLineNo">528</span>      case UNASSIGN:<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        return metrics.getUnassignProcMetrics();<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      case MOVE:<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        return metrics.getMoveProcMetrics();<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      case REOPEN:<a name="line.532"></a>
-<span class="sourceLineNo">533</span>        return metrics.getReopenProcMetrics();<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      default:<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        throw new IllegalArgumentException("Unknown transition type: " + type);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    }<a name="line.536"></a>
-<span class="sourceLineNo">537</span>  }<a name="line.537"></a>
-<span class="sourceLineNo">538</span><a name="line.538"></a>
-<span class="sourceLineNo">539</span>  @Override<a name="line.539"></a>
-<span class="sourceLineNo">540</span>  public void toStringClassDetails(StringBuilder sb) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    super.toStringClassDetails(sb);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    if (initialState == RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE) {<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      sb.append(", ASSIGN");<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    } else if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.544"></a>
-<span class="sourceLineNo">545</span>      sb.append(", UNASSIGN");<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    } else {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      sb.append(", REOPEN/MOVE");<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    }<a name="line.548"></a>
-<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>  private static TransitRegionStateProcedure setOwner(MasterProcedureEnv env,<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      TransitRegionStateProcedure proc) {<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    proc.setOwner(env.getRequestUser().getShortName());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    return proc;<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  public enum TransitionType {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    ASSIGN, UNASSIGN, MOVE, REOPEN<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  }<a name="line.559"></a>
-<span class="sourceLineNo">560</span><a name="line.560"></a>
-<span class="sourceLineNo">561</span>  // Be careful that, when you call these 4 methods below, you need to manually attach the returned<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  // procedure with the RegionStateNode, otherwise the procedure will quit immediately without doing<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  // anything. See the comment in executeFromState to find out why we need this assumption.<a name="line.563"></a>
-<span class="sourceLineNo">564</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      @Nullable ServerName targetServer) {<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return assign(env, region, false, targetServer);<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.569"></a>
-<span class="sourceLineNo">570</span>      boolean forceNewPlan, @Nullable ServerName targetServer) {<a name="line.570"></a>
-<span class="sourceLineNo">571</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer, forceNewPlan,<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        TransitionType.ASSIGN));<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public static TransitRegionStateProcedure unassign(MasterProcedureEnv env, RegionInfo region) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    return setOwner(env,<a name="line.576"></a>
-<span class="sourceLineNo">577</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN));<a name="line.577"></a>
-<span class="sourceLineNo">578</span>  }<a name="line.578"></a>
-<span class="sourceLineNo">579</span><a name="line.579"></a>
-<span class="sourceLineNo">580</span>  public static TransitRegionStateProcedure reopen(MasterProcedureEnv env, RegionInfo region) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>    return setOwner(env,<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.REOPEN));<a name="line.582"></a>
-<span class="sourceLineNo">583</span>  }<a name="line.583"></a>
-<span class="sourceLineNo">584</span><a name="line.584"></a>
-<span class="sourceLineNo">585</span>  public static TransitRegionStateProcedure move(MasterProcedureEnv env, RegionInfo region,<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      @Nullable ServerName targetServer) {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer,<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      targetServer == null, TransitionType.MOVE));<a name="line.588"></a>
-<span class="sourceLineNo">589</span>  }<a name="line.589"></a>
-<span class="sourceLineNo">590</span>}<a name="line.590"></a>
+<span class="sourceLineNo">121</span>  private RegionRemoteProcedureBase remoteProc;<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  public TransitRegionStateProcedure() {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>  }<a name="line.124"></a>
+<span class="sourceLineNo">125</span><a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private void setInitialAndLastState() {<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    switch (type) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>      case ASSIGN:<a name="line.128"></a>
+<span class="sourceLineNo">129</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE;<a name="line.129"></a>
+<span class="sourceLineNo">130</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>        break;<a name="line.131"></a>
+<span class="sourceLineNo">132</span>      case UNASSIGN:<a name="line.132"></a>
+<span class="sourceLineNo">133</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>        break;<a name="line.135"></a>
+<span class="sourceLineNo">136</span>      case MOVE:<a name="line.136"></a>
+<span class="sourceLineNo">137</span>      case REOPEN:<a name="line.137"></a>
+<span class="sourceLineNo">138</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>        break;<a name="line.140"></a>
+<span class="sourceLineNo">141</span>      default:<a name="line.141"></a>
+<span class="sourceLineNo">142</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    }<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  }<a name="line.144"></a>
+<span class="sourceLineNo">145</span><a name="line.145"></a>
+<span class="sourceLineNo">146</span>  protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,<a name="line.146"></a>
+<span class="sourceLineNo">147</span>      ServerName assignCandidate, boolean forceNewPlan, TransitionType type) {<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    super(env, hri);<a name="line.148"></a>
+<span class="sourceLineNo">149</span>    this.assignCandidate = assignCandidate;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>    this.forceNewPlan = forceNewPlan;<a name="line.150"></a>
+<span class="sourceLineNo">151</span>    this.type = type;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>    setInitialAndLastState();<a name="line.152"></a>
+<span class="sourceLineNo">153</span><a name="line.153"></a>
+<span class="sourceLineNo">154</span>    // when do reopen TRSP, let the rs know the targetServer so it can keep some info on close<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    if (type == TransitionType.REOPEN) {<a name="line.155"></a>
+<span class="sourceLineNo">156</span>      this.assignCandidate = getRegionStateNode(env).getRegionLocation();<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    }<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public TableOperationType getTableOperationType() {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    // TODO: maybe we should make another type here, REGION_TRANSITION?<a name="line.162"></a>
+<span class="sourceLineNo">163</span>    return TableOperationType.REGION_EDIT;<a name="line.163"></a>
+<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
+<span class="sourceLineNo">165</span><a name="line.165"></a>
+<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
+<span class="sourceLineNo">167</span>  protected boolean waitInitialized(MasterProcedureEnv env) {<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    if (TableName.isMetaTableName(getTableName())) {<a name="line.168"></a>
+<span class="sourceLineNo">169</span>      return false;<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    }<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    // First we need meta to be loaded, and second, if meta is not online then we will likely to<a name="line.171"></a>
+<span class="sourceLineNo">172</span>    // fail when updating meta so we wait until it is assigned.<a name="line.172"></a>
+<span class="sourceLineNo">173</span>    AssignmentManager am = env.getAssignmentManager();<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    return am.waitMetaLoaded(this) || am.waitMetaAssigned(this, getRegion());<a name="line.174"></a>
+<span class="sourceLineNo">175</span>  }<a name="line.175"></a>
+<span class="sourceLineNo">176</span><a name="line.176"></a>
+<span class="sourceLineNo">177</span>  private void queueAssign(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      throws ProcedureSuspendedException {<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    boolean retain = false;<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    if (forceNewPlan) {<a name="line.180"></a>
+<span class="sourceLineNo">181</span>      // set the region location to null if forceNewPlan is true<a name="line.181"></a>
+<span class="sourceLineNo">182</span>      regionNode.setRegionLocation(null);<a name="line.182"></a>
+<span class="sourceLineNo">183</span>    } else {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      if (assignCandidate != null) {<a name="line.184"></a>
+<span class="sourceLineNo">185</span>        retain = assignCandidate.equals(regionNode.getLastHost());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>        regionNode.setRegionLocation(assignCandidate);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      } else if (regionNode.getLastHost() != null) {<a name="line.187"></a>
+<span class="sourceLineNo">188</span>        retain = true;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>        LOG.info("Setting lastHost as the region location {}", regionNode.getLastHost());<a name="line.189"></a>
+<span class="sourceLineNo">190</span>        regionNode.setRegionLocation(regionNode.getLastHost());<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      }<a name="line.191"></a>
+<span class="sourceLineNo">192</span>    }<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    LOG.info("Starting {}; {}; forceNewPlan={}, retain={}", this, regionNode.toShortString(),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      forceNewPlan, retain);<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    env.getAssignmentManager().queueAssign(regionNode);<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_OPEN);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    if (regionNode.getProcedureEvent().suspendIfNotReady(this)) {<a name="line.197"></a>
+<span class="sourceLineNo">198</span>      throw new ProcedureSuspendedException();<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    }<a name="line.199"></a>
+<span class="sourceLineNo">200</span>  }<a name="line.200"></a>
+<span class="sourceLineNo">201</span><a name="line.201"></a>
+<span class="sourceLineNo">202</span>  private void openRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    ServerName loc = regionNode.getRegionLocation();<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    if (loc == null || BOGUS_SERVER_NAME.equals(loc)) {<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      LOG.warn("No location specified for {}, jump back to state {} to get one", getRegion(),<a name="line.205"></a>
+<span class="sourceLineNo">206</span>        RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      return;<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    }<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    env.getAssignmentManager().regionOpening(regionNode);<a name="line.210"></a>
+<span class="sourceLineNo">211</span>    addChildProcedure(new OpenRegionProcedure(this, getRegion(), loc));<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED);<a name="line.212"></a>
+<span class="sourceLineNo">213</span>  }<a name="line.213"></a>
+<span class="sourceLineNo">214</span><a name="line.214"></a>
+<span class="sourceLineNo">215</span>  private Flow confirmOpened(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.215"></a>
+<span class="sourceLineNo">216</span>      throws IOException {<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    if (regionNode.isInState(State.OPEN)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>      retryCounter = null;<a name="line.218"></a>
+<span class="sourceLineNo">219</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>        // we are the last state, finish<a name="line.220"></a>
+<span class="sourceLineNo">221</span>        regionNode.unsetProcedure(this);<a name="line.221"></a>
+<span class="sourceLineNo">222</span>        ServerCrashProcedure.updateProgress(env, getParentProcId());<a name="line.222"></a>
+<span class="sourceLineNo">223</span>        return Flow.NO_MORE_STATE;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>      }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      // It is possible that we arrive here but confirm opened is not the last state, for example,<a name="line.225"></a>
+<span class="sourceLineNo">226</span>      // when merging or splitting a region, we unassign the region from a RS and the RS is crashed,<a name="line.226"></a>
+<span class="sourceLineNo">227</span>      // then there will be recovered edits for this region, we'd better make the region online<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      // again and then unassign it, otherwise we have to fail the merge/split procedure as we may<a name="line.228"></a>
+<span class="sourceLineNo">229</span>      // loss data.<a name="line.229"></a>
+<span class="sourceLineNo">230</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>      return Flow.HAS_MORE_STATE;<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    }<a name="line.232"></a>
+<span class="sourceLineNo">233</span><a name="line.233"></a>
+<span class="sourceLineNo">234</span>    int retries = env.getAssignmentManager().getRegionStates().addToFailedOpen(regionNode)<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        .incrementAndGetRetries();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    int maxAttempts = env.getAssignmentManager().getAssignMaxAttempts();<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    LOG.info("Retry={} of max={}; {}; {}", retries, maxAttempts, this, regionNode.toShortString());<a name="line.237"></a>
+<span class="sourceLineNo">238</span><a name="line.238"></a>
+<span class="sourceLineNo">239</span>    if (retries &gt;= maxAttempts) {<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      env.getAssignmentManager().regionFailedOpen(regionNode, true);<a name="line.240"></a>
+<span class="sourceLineNo">241</span>      setFailure(getClass().getSimpleName(), new RetriesExhaustedException(<a name="line.241"></a>
+<span class="sourceLineNo">242</span>        "Max attempts " + env.getAssignmentManager().getAssignMaxAttempts() + " exceeded"));<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      regionNode.unsetProcedure(this);<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      return Flow.NO_MORE_STATE;<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span><a name="line.246"></a>
+<span class="sourceLineNo">247</span>    env.getAssignmentManager().regionFailedOpen(regionNode, false);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    // we failed to assign the region, force a new plan<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    forceNewPlan = true;<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    regionNode.setRegionLocation(null);<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.251"></a>
+<span class="sourceLineNo">252</span><a name="line.252"></a>
+<span class="sourceLineNo">253</span>    if (retries &gt; env.getAssignmentManager().getAssignRetryImmediatelyMaxAttempts()) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      // Throw exception to backoff and retry when failed open too many times<a name="line.254"></a>
+<span class="sourceLineNo">255</span>      throw new HBaseIOException("Failed confirm OPEN of " + regionNode +<a name="line.255"></a>
+<span class="sourceLineNo">256</span>          " (remote log may yield more detail on why).");<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    } else {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      // Here we do not throw exception because we want to the region to be online ASAP<a name="line.258"></a>
+<span class="sourceLineNo">259</span>      return Flow.HAS_MORE_STATE;<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    }<a name="line.260"></a>
+<span class="sourceLineNo">261</span>  }<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  private void closeRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>    if (regionNode.isInState(State.OPEN, State.CLOSING, State.MERGING, State.SPLITTING)) {<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      // this is the normal case<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      env.getAssignmentManager().regionClosing(regionNode);<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      addChildProcedure(new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),<a name="line.267"></a>
+<span class="sourceLineNo">268</span>        assignCandidate));<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    } else {<a name="line.270"></a>
+<span class="sourceLineNo">271</span>      forceNewPlan = true;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>      regionNode.setRegionLocation(null);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.273"></a>
+<span class="sourceLineNo">274</span>    }<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  }<a name="line.275"></a>
+<span class="sourceLineNo">276</span><a name="line.276"></a>
+<span class="sourceLineNo">277</span>  private Flow confirmClosed(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      throws IOException {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>    if (regionNode.isInState(State.CLOSED)) {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      retryCounter = null;<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.281"></a>
+<span class="sourceLineNo">282</span>        // we are the last state, finish<a name="line.282"></a>
+<span class="sourceLineNo">283</span>        regionNode.unsetProcedure(this);<a name="line.283"></a>
+<span class="sourceLineNo">284</span>        return Flow.NO_MORE_STATE;<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      }<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      // This means we need to open the region again, should be a move or reopen<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      return Flow.HAS_MORE_STATE;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    }<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    if (regionNode.isInState(State.CLOSING)) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      // This is possible, think the target RS crashes and restarts immediately, the close region<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      // operation will return a NotServingRegionException soon, we can only recover after SCP takes<a name="line.292"></a>
+<span class="sourceLineNo">293</span>      // care of this RS. So here we throw an IOException to let upper layer to retry with backoff.<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      throw new HBaseIOException("Failed to close region");<a name="line.295"></a>
+<span class="sourceLineNo">296</span>    }<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    // abnormally closed, need to reopen it, no matter what is the last state, see the comment in<a name="line.297"></a>
+<span class="sourceLineNo">298</span>    // confirmOpened for more details that why we need to reopen the region first even if we just<a name="line.298"></a>
+<span class="sourceLineNo">299</span>    // want to close it.<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    // The only exception is for non-default replica, where we do not need to deal with recovered<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    // edits. Notice that the region will remain in ABNORMALLY_CLOSED state, the upper layer need to<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    // deal with this state. For non-default replica, this is usually the same with CLOSED.<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    assert regionNode.isInState(State.ABNORMALLY_CLOSED);<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    if (!RegionReplicaUtil.isDefaultReplica(getRegion()) &amp;&amp;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      regionNode.unsetProcedure(this);<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return Flow.NO_MORE_STATE;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    retryCounter = null;<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    return Flow.HAS_MORE_STATE;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  }<a name="line.312"></a>
+<span class="sourceLineNo">313</span><a name="line.313"></a>
+<span class="sourceLineNo">314</span>  // Override to lock RegionStateNode<a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @SuppressWarnings("rawtypes")<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
+<span class="sourceLineNo">317</span>  protected Procedure[] execute(MasterProcedureEnv env)<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    RegionStateNode regionNode =<a name="line.319"></a>
+<span class="sourceLineNo">320</span>      env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    regionNode.lock();<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    try {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>      return super.execute(env);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    } finally {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      regionNode.unlock();<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    }<a name="line.326"></a>
+<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
+<span class="sourceLineNo">328</span><a name="line.328"></a>
+<span class="sourceLineNo">329</span>  private RegionStateNode getRegionStateNode(MasterProcedureEnv env) {<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    return env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.330"></a>
+<span class="sourceLineNo">331</span>  }<a name="line.331"></a>
+<span class="sourceLineNo">332</span><a name="line.332"></a>
+<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
+<span class="sourceLineNo">334</span>  protected Flow executeFromState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    RegionStateNode regionNode = getRegionStateNode(env);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    try {<a name="line.337"></a>
+<span class="sourceLineNo">338</span>      switch (state) {<a name="line.338"></a>
+<span class="sourceLineNo">339</span>        case REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE:<a name="line.339"></a>
+<span class="sourceLineNo">340</span>          // Need to do some sanity check for replica region, if the region does not exist at<a name="line.340"></a>
+<span class="sourceLineNo">341</span>          // master, do not try to assign the replica region, log error and return.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>          if (!RegionReplicaUtil.isDefaultReplica(regionNode.getRegionInfo())) {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>            RegionInfo defaultRI =<a name="line.343"></a>
+<span class="sourceLineNo">344</span>              RegionReplicaUtil.getRegionInfoForDefaultReplica(regionNode.getRegionInfo());<a name="line.344"></a>
+<span class="sourceLineNo">345</span>            if (env.getMasterServices().getAssignmentManager().getRegionStates().<a name="line.345"></a>
+<span class="sourceLineNo">346</span>              getRegionStateNode(defaultRI) == null) {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>              LOG.error(<a name="line.347"></a>
+<span class="sourceLineNo">348</span>                "Cannot assign replica region {} because its primary region {} does not exist.",<a name="line.348"></a>
+<span class="sourceLineNo">349</span>                regionNode.getRegionInfo(), defaultRI);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>              regionNode.unsetProcedure(this);<a name="line.350"></a>
+<span class="sourceLineNo">351</span>              return Flow.NO_MORE_STATE;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>            }<a name="line.352"></a>
+<span class="sourceLineNo">353</span>          }<a name="line.353"></a>
+<span class="sourceLineNo">354</span>          queueAssign(env, regionNode);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>          return Flow.HAS_MORE_STATE;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        case REGION_STATE_TRANSITION_OPEN:<a name="line.356"></a>
+<span class="sourceLineNo">357</span>          openRegion(env, regionNode);<a name="line.357"></a>
+<span class="sourceLineNo">358</span>          return Flow.HAS_MORE_STATE;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>        case REGION_STATE_TRANSITION_CONFIRM_OPENED:<a name="line.359"></a>
+<span class="sourceLineNo">360</span>          return confirmOpened(env, regionNode);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        case REGION_STATE_TRANSITION_CLOSE:<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          closeRegion(env, regionNode);<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          return Flow.HAS_MORE_STATE;<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        case REGION_STATE_TRANSITION_CONFIRM_CLOSED:<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          return confirmClosed(env, regionNode);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        default:<a name="line.366"></a>
+<span class="sourceLineNo">367</span>          throw new UnsupportedOperationException("unhandled state=" + state);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    } catch (IOException e) {<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      if (retryCounter == null) {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration());<a name="line.371"></a>
+<span class="sourceLineNo">372</span>      }<a name="line.372"></a>
+<span class="sourceLineNo">373</span>      long backoff = retryCounter.getBackoffTimeAndIncrementAttempts();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      LOG.warn(<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        "Failed transition, suspend {}secs {}; {}; waiting on rectified condition fixed " +<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          "by other Procedure or operator intervention",<a name="line.376"></a>
+<span class="sourceLineNo">377</span>        backoff / 1000, this, regionNode.toShortString(), e);<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      setTimeout(Math.toIntExact(backoff));<a name="line.378"></a>
+<span class="sourceLineNo">379</span>      setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT);<a name="line.379"></a>
+<span class="sourceLineNo">380</span>      skipPersistence();<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      throw new ProcedureSuspendedException();<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  /**<a name="line.385"></a>
+<span class="sourceLineNo">386</span>   * At end of timeout, wake ourselves up so we run again.<a name="line.386"></a>
+<span class="sourceLineNo">387</span>   */<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  @Override<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  protected synchronized boolean setTimeoutFailure(MasterProcedureEnv env) {<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    setState(ProcedureProtos.ProcedureState.RUNNABLE);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    env.getProcedureScheduler().addFront(this);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    return false; // 'false' means that this procedure handled the timeout<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  }<a name="line.393"></a>
+<span class="sourceLineNo">394</span><a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // Should be called with RegionStateNode locked<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  public void reportTransition(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      ServerName serverName, TransitionCode code, long seqId, long procId) throws IOException {<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    if (remoteProc == null) {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      LOG.warn(<a name="line.399"></a>
+<span class="sourceLineNo">400</span>        "There is no outstanding remote region procedure for {}, serverName={}, code={}," +<a name="line.400"></a>
+<span class="sourceLineNo">401</span>          " seqId={}, proc={}, should be a retry, ignore",<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        regionNode, serverName, code, seqId, this);<a name="line.402"></a>
+<span class="sourceLineNo">403</span>      return;<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    }<a name="line.404"></a>
+<span class="sourceLineNo">405</span>    // The procId could be -1 if it is from an old region server, we need to deal with it so that we<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    // can do rolling upgraing.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    if (procId &gt;= 0 &amp;&amp; remoteProc.getProcId() != procId) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      LOG.warn(<a name="line.408"></a>
+<span class="sourceLineNo">409</span>        "The pid of remote region procedure for {} is {}, the reported pid={}, serverName={}," +<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          " code={}, seqId={}, proc={}, should be a retry, ignore",<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        regionNode, remoteProc.getProcId(), procId, serverName, code, seqId, this);<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      return;<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    }<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    remoteProc.reportTransition(env, regionNode, serverName, code, seqId);<a name="line.414"></a>
+<span class="sourceLineNo">415</span>  }<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>  // Should be called with RegionStateNode locked<a name="line.417"></a>
+<span class="sourceLineNo">418</span>  public void serverCrashed(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      ServerName serverName, boolean forceNewPlan) throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    this.forceNewPlan = forceNewPlan;<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    if (remoteProc != null) {<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      // this means we are waiting for the sub procedure, so wake it up<a name="line.422"></a>
+<span class="sourceLineNo">423</span>      remoteProc.serverCrashed(env, regionNode, serverName);<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    } else {<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      // we are in RUNNING state, just update the region state, and we will process it later.<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      env.getAssignmentManager().regionClosedAbnormally(regionNode);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    }<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  void attachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    this.remoteProc = proc;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  void unattachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    assert this.remoteProc == proc;<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    this.remoteProc = null;<a name="line.436"></a>
+<span class="sourceLineNo">437</span>  }<a name="line.437"></a>
+<span class="sourceLineNo">438</span><a name="line.438"></a>
+<span class="sourceLineNo">439</span>  // will be called after we finish loading the meta entry for this region.<a name="line.439"></a>
+<span class="sourceLineNo">440</span>  // used to change the state of the region node if we have a sub procedure, as we may not persist<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  // the state to meta yet. See the code in RegionRemoteProcedureBase.execute for more details.<a name="line.441"></a>
+<span class="sourceLineNo">442</span>  void stateLoaded(AssignmentManager am, RegionStateNode regionNode) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    if (remoteProc != null) {<a name="line.443"></a>
+<span class="sourceLineNo">444</span>      remoteProc.stateLoaded(am, regionNode);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    }<a name="line.445"></a>
+<span class="sourceLineNo">446</span>  }<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>  @Override<a name="line.448"></a>
+<span class="sourceLineNo">449</span>  protected void rollbackState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      throws IOException, InterruptedException {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    // no rollback<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    throw new UnsupportedOperationException();<a name="line.452"></a>
+<span class="sourceLineNo">453</span>  }<a name="line.453"></a>
+<span class="sourceLineNo">454</span><a name="line.454"></a>
+<span class="sourceLineNo">455</span>  @Override<a name="line.455"></a>
+<span class="sourceLineNo">456</span>  protected RegionStateTransitionState getState(int stateId) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    return RegionStateTransitionState.forNumber(stateId);<a name="line.457"></a>
+<span class="sourceLineNo">458</span>  }<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>  @Override<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  protected int getStateId(RegionStateTransitionState state) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    return state.getNumber();<a name="line.462"></a>
+<span class="sourceLineNo">463</span>  }<a name="line.463"></a>
+<span class="sourceLineNo">464</span><a name="line.464"></a>
+<span class="sourceLineNo">465</span>  @Override<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  protected RegionStateTransitionState getInitialState() {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    return initialState;<a name="line.467"></a>
+<span class="sourceLineNo">468</span>  }<a name="line.468"></a>
+<span class="sourceLineNo">469</span><a name="line.469"></a>
+<span class="sourceLineNo">470</span>  private static TransitionType convert(RegionTransitionType type) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>    switch (type) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>      case ASSIGN:<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        return TransitionType.ASSIGN;<a name="line.473"></a>
+<span class="sourceLineNo">474</span>      case UNASSIGN:<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        return TransitionType.UNASSIGN;<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      case MOVE:<a name="line.476"></a>
+<span class="sourceLineNo">477</span>        return TransitionType.MOVE;<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      case REOPEN:<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        return TransitionType.REOPEN;<a name="line.479"></a>
+<span class="sourceLineNo">480</span>      default:<a name="line.480"></a>
+<span class="sourceLineNo">481</span>        throw new IllegalArgumentException("Unknown RegionTransitionType: " + type);<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    }<a name="line.482"></a>
+<span class="sourceLineNo">483</span>  }<a name="line.483"></a>
+<span class="sourceLineNo">484</span><a name="line.484"></a>
+<span class="sourceLineNo">485</span>  private static RegionTransitionType convert(TransitionType type) {<a name="line.485"></a>
+<span class="sourceLineNo">486</span>    switch (type) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>      case ASSIGN:<a name="line.487"></a>
+<span class="sourceLineNo">488</span>        return RegionTransitionType.ASSIGN;<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      case UNASSIGN:<a name="line.489"></a>
+<span class="sourceLineNo">490</span>        return RegionTransitionType.UNASSIGN;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>      case MOVE:<a name="line.491"></a>
+<span class="sourceLineNo">492</span>        return RegionTransitionType.MOVE;<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      case REOPEN:<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        return RegionTransitionType.REOPEN;<a name="line.494"></a>
+<span class="sourceLineNo">495</span>      default:<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    }<a name="line.497"></a>
+<span class="sourceLineNo">498</span>  }<a name="line.498"></a>
+<span class="sourceLineNo">499</span><a name="line.499"></a>
+<span class="sourceLineNo">500</span>  @Override<a name="line.500"></a>
+<span class="sourceLineNo">501</span>  protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.501"></a>
+<span class="sourceLineNo">502</span>    super.serializeStateData(serializer);<a name="line.502"></a>
+<span class="sourceLineNo">503</span>    RegionStateTransitionStateData.Builder builder = RegionStateTransitionStateData.newBuilder()<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      .setType(convert(type)).setForceNewPlan(forceNewPlan);<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    if (assignCandidate != null) {<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));<a name="line.506"></a>
+<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    serializer.serialize(builder.build());<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  }<a name="line.509"></a>
+<span class="sourceLineNo">510</span><a name="line.510"></a>
+<span class="sourceLineNo">511</span>  @Override<a name="line.511"></a>
+<span class="sourceLineNo">512</span>  protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.512"></a>
+<span class="sourceLineNo">513</span>    super.deserializeStateData(serializer);<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    RegionStateTransitionStateData data =<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      serializer.deserialize(RegionStateTransitionStateData.class);<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    type = convert(data.getType());<a name="line.516"></a>
+<span class="sourceLineNo">517</span>    setInitialAndLastState();<a name="line.517"></a>
+<span class="sourceLineNo">518</span>    forceNewPlan = data.getForceNewPlan();<a name="line.518"></a>
+<span class="sourceLineNo">519</span>    if (data.hasAssignCandidate()) {<a name="line.519"></a>
+<span class="sourceLineNo">520</span>      assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());<a name="line.520"></a>
+<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
+<span class="sourceLineNo">522</span>  }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>  @Override<a name="line.524"></a>
+<span class="sourceLineNo">525</span>  protected ProcedureMetrics getProcedureMetrics(MasterProcedureEnv env) {<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    MetricsAssignmentManager metrics = env.getAssignmentManager().getAssignmentManagerMetrics();<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    switch (type) {<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      case ASSIGN:<a name="line.528"></a>
+<span class="sourceLineNo">529</span>        return metrics.getAssignProcMetrics();<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      case UNASSIGN:<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        return metrics.getUnassignProcMetrics();<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      case MOVE:<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        return metrics.getMoveProcMetrics();<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      case REOPEN:<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        return metrics.getReopenProcMetrics();<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      default:<a name="line.536"></a>
+<span class="sourceLineNo">537</span>        throw new IllegalArgumentException("Unknown transition type: " + type);<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
+<span class="sourceLineNo">540</span><a name="line.540"></a>
+<span class="sourceLineNo">541</span>  @Override<a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public void toStringClassDetails(StringBuilder sb) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    super.toStringClassDetails(sb);<a name="line.543"></a>
+<span class="sourceLineNo">544</span>    if (initialState == RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE) {<a name="line.544"></a>
+<span class="sourceLineNo">545</span>      sb.append(", ASSIGN");<a name="line.545"></a>
+<span class="sourceLineNo">546</span>    } else if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>      sb.append(", UNASSIGN");<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    } else {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      sb.append(", REOPEN/MOVE");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    }<a name="line.550"></a>
+<span class="sourceLineNo">551</span>  }<a name="line.551"></a>
+<span class="sourceLineNo">552</span><a name="line.552"></a>
+<span class="sourceLineNo">553</span>  private static TransitRegionStateProcedure setOwner(MasterProcedureEnv env,<a name="line.553"></a>
+<span class="sourceLineNo">554</span>      TransitRegionStateProcedure proc) {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    proc.setOwner(env.getRequestUser().getShortName());<a name="line.555"></a>
+<span class="sourceLineNo">556</span>    return proc;<a name="line.556"></a>
+<span class="sourceLineNo">557</span>  }<a name="line.557"></a>
+<span class="sourceLineNo">558</span><a name="line.558"></a>
+<span class="sourceLineNo">559</span>  public enum TransitionType {<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    ASSIGN, UNASSIGN, MOVE, REOPEN<a name="line.560"></a>
+<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
+<span class="sourceLineNo">562</span><a name="line.562"></a>
+<span class="sourceLineNo">563</span>  // Be careful that, when you call these 4 methods below, you need to manually attach the returned<a name="line.563"></a>
+<span class="sourceLineNo">564</span>  // procedure with the RegionStateNode, otherwise the procedure will quit immediately without doing<a name="line.564"></a>
+<span class="sourceLineNo">565</span>  // anything. See the comment in executeFromState to find out why we need this assumption.<a name="line.565"></a>
+<span class="sourceLineNo">566</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      @Nullable ServerName targetServer) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return assign(env, region, false, targetServer);<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      boolean forceNewPlan, @Nullable ServerName targetServer) {<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer, forceNewPlan,<a name="line.573"></a>
+<span class="sourceLineNo">574</span>        TransitionType.ASSIGN));<a name="line.574"></a>
+<span class="sourceLineNo">575</span>  }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>  public static TransitRegionStateProcedure unassign(MasterProcedureEnv env, RegionInfo region) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    return setOwner(env,<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN));<a name="line.579"></a>
+<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>  public static TransitRegionStateProcedure reopen(MasterProcedureEnv env, RegionInfo region) {<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return setOwner(env,<a name="line.583"></a>
+<span class="sourceLineNo">584</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.REOPEN));<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  public static TransitRegionStateProcedure move(MasterProcedureEnv env, RegionInfo region,<a name="line.587"></a>
+<span class="sourceLineNo">588</span>      @Nullable ServerName targetServer) {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer,<a name="line.589"></a>
+<span class="sourceLineNo">590</span>      targetServer == null, TransitionType.MOVE));<a name="line.590"></a>
+<span class="sourceLineNo">591</span>  }<a name="line.591"></a>
+<span class="sourceLineNo">592</span>}<a name="line.592"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
index 3392220..3a56a19 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/assignment/TransitRegionStateProcedure.html
@@ -25,577 +25,579 @@
 <span class="sourceLineNo">017</span> */<a name="line.17"></a>
 <span class="sourceLineNo">018</span>package org.apache.hadoop.hbase.master.assignment;<a name="line.18"></a>
 <span class="sourceLineNo">019</span><a name="line.19"></a>
-<span class="sourceLineNo">020</span>import edu.umd.cs.findbugs.annotations.Nullable;<a name="line.20"></a>
-<span class="sourceLineNo">021</span>import java.io.IOException;<a name="line.21"></a>
-<span class="sourceLineNo">022</span>import org.apache.hadoop.hbase.HBaseIOException;<a name="line.22"></a>
-<span class="sourceLineNo">023</span>import org.apache.hadoop.hbase.ServerName;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import org.apache.hadoop.hbase.TableName;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.client.RetriesExhaustedException;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.master.MetricsAssignmentManager;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.master.RegionState.State;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineRegionProcedure;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.procedure2.Procedure;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.procedure2.ProcedureMetrics;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.procedure2.ProcedureUtil;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.util.RetryCounter;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.slf4j.Logger;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.slf4j.LoggerFactory;<a name="line.42"></a>
-<span class="sourceLineNo">043</span><a name="line.43"></a>
-<span class="sourceLineNo">044</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionStateData;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode;<a name="line.49"></a>
-<span class="sourceLineNo">050</span><a name="line.50"></a>
-<span class="sourceLineNo">051</span>/**<a name="line.51"></a>
-<span class="sourceLineNo">052</span> * The procedure to deal with the state transition of a region. A region with a TRSP in place is<a name="line.52"></a>
-<span class="sourceLineNo">053</span> * called RIT, i.e, RegionInTransition.<a name="line.53"></a>
-<span class="sourceLineNo">054</span> * &lt;p/&gt;<a name="line.54"></a>
-<span class="sourceLineNo">055</span> * It can be used to assign/unassign/reopen/move a region, and for<a name="line.55"></a>
-<span class="sourceLineNo">056</span> * {@link #unassign(MasterProcedureEnv, RegionInfo)} and<a name="line.56"></a>
-<span class="sourceLineNo">057</span> * {@link #reopen(MasterProcedureEnv, RegionInfo)}, you do not need to specify a target server, and<a name="line.57"></a>
-<span class="sourceLineNo">058</span> * for {@link #assign(MasterProcedureEnv, RegionInfo, ServerName)} and<a name="line.58"></a>
-<span class="sourceLineNo">059</span> * {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you want to you can provide a<a name="line.59"></a>
-<span class="sourceLineNo">060</span> * target server. And for {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you do not<a name="line.60"></a>
-<span class="sourceLineNo">061</span> * specify a targetServer, we will select one randomly.<a name="line.61"></a>
-<span class="sourceLineNo">062</span> * &lt;p/&gt;<a name="line.62"></a>
-<span class="sourceLineNo">063</span> * &lt;p/&gt;<a name="line.63"></a>
-<span class="sourceLineNo">064</span> * The typical state transition for assigning a region is:<a name="line.64"></a>
-<span class="sourceLineNo">065</span> *<a name="line.65"></a>
-<span class="sourceLineNo">066</span> * &lt;pre&gt;<a name="line.66"></a>
-<span class="sourceLineNo">067</span> * GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.67"></a>
-<span class="sourceLineNo">068</span> * &lt;/pre&gt;<a name="line.68"></a>
-<span class="sourceLineNo">069</span> *<a name="line.69"></a>
-<span class="sourceLineNo">070</span> * Notice that, if there are failures we may go back to the {@code GET_ASSIGN_CANDIDATE} state to<a name="line.70"></a>
-<span class="sourceLineNo">071</span> * try again.<a name="line.71"></a>
-<span class="sourceLineNo">072</span> * &lt;p/&gt;<a name="line.72"></a>
-<span class="sourceLineNo">073</span> * The typical state transition for unassigning a region is:<a name="line.73"></a>
-<span class="sourceLineNo">074</span> *<a name="line.74"></a>
-<span class="sourceLineNo">075</span> * &lt;pre&gt;<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * CLOSE -----&gt; CONFIRM_CLOSED<a name="line.76"></a>
-<span class="sourceLineNo">077</span> * &lt;/pre&gt;<a name="line.77"></a>
-<span class="sourceLineNo">078</span> *<a name="line.78"></a>
-<span class="sourceLineNo">079</span> * Here things go a bit different, if there are failures, especially that if there is a server<a name="line.79"></a>
-<span class="sourceLineNo">080</span> * crash, we will go to the {@code GET_ASSIGN_CANDIDATE} state to bring the region online first, and<a name="line.80"></a>
-<span class="sourceLineNo">081</span> * then go through the normal way to unassign it.<a name="line.81"></a>
-<span class="sourceLineNo">082</span> * &lt;p/&gt;<a name="line.82"></a>
-<span class="sourceLineNo">083</span> * The typical state transition for reopening/moving a region is:<a name="line.83"></a>
-<span class="sourceLineNo">084</span> *<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * &lt;pre&gt;<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * CLOSE -----&gt; CONFIRM_CLOSED -----&gt; GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.86"></a>
-<span class="sourceLineNo">087</span> * &lt;/pre&gt;<a name="line.87"></a>
-<span class="sourceLineNo">088</span> *<a name="line.88"></a>
-<span class="sourceLineNo">089</span> * The retry logic is the same with the above assign/unassign.<a name="line.89"></a>
-<span class="sourceLineNo">090</span> * &lt;p/&gt;<a name="line.90"></a>
-<span class="sourceLineNo">091</span> * Notice that, although we allow specify a target server, it just acts as a candidate, we do not<a name="line.91"></a>
-<span class="sourceLineNo">092</span> * guarantee that the region will finally be on the target server. If this is important for you, you<a name="line.92"></a>
-<span class="sourceLineNo">093</span> * should check whether the region is on the target server after the procedure is finished.<a name="line.93"></a>
-<span class="sourceLineNo">094</span> * &lt;p/&gt;<a name="line.94"></a>
-<span class="sourceLineNo">095</span> * When you want to schedule a TRSP, please check whether there is still one for this region, and<a name="line.95"></a>
-<span class="sourceLineNo">096</span> * the check should be under the RegionStateNode lock. We will remove the TRSP from a<a name="line.96"></a>
-<span class="sourceLineNo">097</span> * RegionStateNode when we are done, see the code in {@code reportTransition} method below. There<a name="line.97"></a>
-<span class="sourceLineNo">098</span> * could be at most one TRSP for a give region.<a name="line.98"></a>
-<span class="sourceLineNo">099</span> */<a name="line.99"></a>
-<span class="sourceLineNo">100</span>@InterfaceAudience.Private<a name="line.100"></a>
-<span class="sourceLineNo">101</span>public class TransitRegionStateProcedure<a name="line.101"></a>
-<span class="sourceLineNo">102</span>    extends AbstractStateMachineRegionProcedure&lt;RegionStateTransitionState&gt; {<a name="line.102"></a>
-<span class="sourceLineNo">103</span><a name="line.103"></a>
-<span class="sourceLineNo">104</span>  private static final Logger LOG = LoggerFactory.getLogger(TransitRegionStateProcedure.class);<a name="line.104"></a>
+<span class="sourceLineNo">020</span>import static org.apache.hadoop.hbase.master.LoadBalancer.BOGUS_SERVER_NAME;<a name="line.20"></a>
+<span class="sourceLineNo">021</span><a name="line.21"></a>
+<span class="sourceLineNo">022</span>import edu.umd.cs.findbugs.annotations.Nullable;<a name="line.22"></a>
+<span class="sourceLineNo">023</span>import java.io.IOException;<a name="line.23"></a>
+<span class="sourceLineNo">024</span>import org.apache.hadoop.hbase.HBaseIOException;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import org.apache.hadoop.hbase.ServerName;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.TableName;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.client.RegionReplicaUtil;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.client.RetriesExhaustedException;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.master.MetricsAssignmentManager;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.master.RegionState.State;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineRegionProcedure;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import org.apache.hadoop.hbase.procedure2.Procedure;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import org.apache.hadoop.hbase.procedure2.ProcedureMetrics;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import org.apache.hadoop.hbase.procedure2.ProcedureStateSerializer;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import org.apache.hadoop.hbase.procedure2.ProcedureUtil;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import org.apache.hadoop.hbase.util.RetryCounter;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.slf4j.Logger;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.slf4j.LoggerFactory;<a name="line.44"></a>
+<span class="sourceLineNo">045</span><a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionState;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionStateTransitionStateData;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.RegionTransitionType;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode;<a name="line.51"></a>
+<span class="sourceLineNo">052</span><a name="line.52"></a>
+<span class="sourceLineNo">053</span>/**<a name="line.53"></a>
+<span class="sourceLineNo">054</span> * The procedure to deal with the state transition of a region. A region with a TRSP in place is<a name="line.54"></a>
+<span class="sourceLineNo">055</span> * called RIT, i.e, RegionInTransition.<a name="line.55"></a>
+<span class="sourceLineNo">056</span> * &lt;p/&gt;<a name="line.56"></a>
+<span class="sourceLineNo">057</span> * It can be used to assign/unassign/reopen/move a region, and for<a name="line.57"></a>
+<span class="sourceLineNo">058</span> * {@link #unassign(MasterProcedureEnv, RegionInfo)} and<a name="line.58"></a>
+<span class="sourceLineNo">059</span> * {@link #reopen(MasterProcedureEnv, RegionInfo)}, you do not need to specify a target server, and<a name="line.59"></a>
+<span class="sourceLineNo">060</span> * for {@link #assign(MasterProcedureEnv, RegionInfo, ServerName)} and<a name="line.60"></a>
+<span class="sourceLineNo">061</span> * {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you want to you can provide a<a name="line.61"></a>
+<span class="sourceLineNo">062</span> * target server. And for {@link #move(MasterProcedureEnv, RegionInfo, ServerName)}, if you do not<a name="line.62"></a>
+<span class="sourceLineNo">063</span> * specify a targetServer, we will select one randomly.<a name="line.63"></a>
+<span class="sourceLineNo">064</span> * &lt;p/&gt;<a name="line.64"></a>
+<span class="sourceLineNo">065</span> * &lt;p/&gt;<a name="line.65"></a>
+<span class="sourceLineNo">066</span> * The typical state transition for assigning a region is:<a name="line.66"></a>
+<span class="sourceLineNo">067</span> *<a name="line.67"></a>
+<span class="sourceLineNo">068</span> * &lt;pre&gt;<a name="line.68"></a>
+<span class="sourceLineNo">069</span> * GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.69"></a>
+<span class="sourceLineNo">070</span> * &lt;/pre&gt;<a name="line.70"></a>
+<span class="sourceLineNo">071</span> *<a name="line.71"></a>
+<span class="sourceLineNo">072</span> * Notice that, if there are failures we may go back to the {@code GET_ASSIGN_CANDIDATE} state to<a name="line.72"></a>
+<span class="sourceLineNo">073</span> * try again.<a name="line.73"></a>
+<span class="sourceLineNo">074</span> * &lt;p/&gt;<a name="line.74"></a>
+<span class="sourceLineNo">075</span> * The typical state transition for unassigning a region is:<a name="line.75"></a>
+<span class="sourceLineNo">076</span> *<a name="line.76"></a>
+<span class="sourceLineNo">077</span> * &lt;pre&gt;<a name="line.77"></a>
+<span class="sourceLineNo">078</span> * CLOSE -----&gt; CONFIRM_CLOSED<a name="line.78"></a>
+<span class="sourceLineNo">079</span> * &lt;/pre&gt;<a name="line.79"></a>
+<span class="sourceLineNo">080</span> *<a name="line.80"></a>
+<span class="sourceLineNo">081</span> * Here things go a bit different, if there are failures, especially that if there is a server<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * crash, we will go to the {@code GET_ASSIGN_CANDIDATE} state to bring the region online first, and<a name="line.82"></a>
+<span class="sourceLineNo">083</span> * then go through the normal way to unassign it.<a name="line.83"></a>
+<span class="sourceLineNo">084</span> * &lt;p/&gt;<a name="line.84"></a>
+<span class="sourceLineNo">085</span> * The typical state transition for reopening/moving a region is:<a name="line.85"></a>
+<span class="sourceLineNo">086</span> *<a name="line.86"></a>
+<span class="sourceLineNo">087</span> * &lt;pre&gt;<a name="line.87"></a>
+<span class="sourceLineNo">088</span> * CLOSE -----&gt; CONFIRM_CLOSED -----&gt; GET_ASSIGN_CANDIDATE ------&gt; OPEN -----&gt; CONFIRM_OPENED<a name="line.88"></a>
+<span class="sourceLineNo">089</span> * &lt;/pre&gt;<a name="line.89"></a>
+<span class="sourceLineNo">090</span> *<a name="line.90"></a>
+<span class="sourceLineNo">091</span> * The retry logic is the same with the above assign/unassign.<a name="line.91"></a>
+<span class="sourceLineNo">092</span> * &lt;p/&gt;<a name="line.92"></a>
+<span class="sourceLineNo">093</span> * Notice that, although we allow specify a target server, it just acts as a candidate, we do not<a name="line.93"></a>
+<span class="sourceLineNo">094</span> * guarantee that the region will finally be on the target server. If this is important for you, you<a name="line.94"></a>
+<span class="sourceLineNo">095</span> * should check whether the region is on the target server after the procedure is finished.<a name="line.95"></a>
+<span class="sourceLineNo">096</span> * &lt;p/&gt;<a name="line.96"></a>
+<span class="sourceLineNo">097</span> * When you want to schedule a TRSP, please check whether there is still one for this region, and<a name="line.97"></a>
+<span class="sourceLineNo">098</span> * the check should be under the RegionStateNode lock. We will remove the TRSP from a<a name="line.98"></a>
+<span class="sourceLineNo">099</span> * RegionStateNode when we are done, see the code in {@code reportTransition} method below. There<a name="line.99"></a>
+<span class="sourceLineNo">100</span> * could be at most one TRSP for a give region.<a name="line.100"></a>
+<span class="sourceLineNo">101</span> */<a name="line.101"></a>
+<span class="sourceLineNo">102</span>@InterfaceAudience.Private<a name="line.102"></a>
+<span class="sourceLineNo">103</span>public class TransitRegionStateProcedure<a name="line.103"></a>
+<span class="sourceLineNo">104</span>    extends AbstractStateMachineRegionProcedure&lt;RegionStateTransitionState&gt; {<a name="line.104"></a>
 <span class="sourceLineNo">105</span><a name="line.105"></a>
-<span class="sourceLineNo">106</span>  private TransitionType type;<a name="line.106"></a>
+<span class="sourceLineNo">106</span>  private static final Logger LOG = LoggerFactory.getLogger(TransitRegionStateProcedure.class);<a name="line.106"></a>
 <span class="sourceLineNo">107</span><a name="line.107"></a>
-<span class="sourceLineNo">108</span>  private RegionStateTransitionState initialState;<a name="line.108"></a>
+<span class="sourceLineNo">108</span>  private TransitionType type;<a name="line.108"></a>
 <span class="sourceLineNo">109</span><a name="line.109"></a>
-<span class="sourceLineNo">110</span>  private RegionStateTransitionState lastState;<a name="line.110"></a>
+<span class="sourceLineNo">110</span>  private RegionStateTransitionState initialState;<a name="line.110"></a>
 <span class="sourceLineNo">111</span><a name="line.111"></a>
-<span class="sourceLineNo">112</span>  // the candidate where we want to assign the region to.<a name="line.112"></a>
-<span class="sourceLineNo">113</span>  private ServerName assignCandidate;<a name="line.113"></a>
-<span class="sourceLineNo">114</span><a name="line.114"></a>
-<span class="sourceLineNo">115</span>  private boolean forceNewPlan;<a name="line.115"></a>
+<span class="sourceLineNo">112</span>  private RegionStateTransitionState lastState;<a name="line.112"></a>
+<span class="sourceLineNo">113</span><a name="line.113"></a>
+<span class="sourceLineNo">114</span>  // the candidate where we want to assign the region to.<a name="line.114"></a>
+<span class="sourceLineNo">115</span>  private ServerName assignCandidate;<a name="line.115"></a>
 <span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private RetryCounter retryCounter;<a name="line.117"></a>
+<span class="sourceLineNo">117</span>  private boolean forceNewPlan;<a name="line.117"></a>
 <span class="sourceLineNo">118</span><a name="line.118"></a>
-<span class="sourceLineNo">119</span>  private RegionRemoteProcedureBase remoteProc;<a name="line.119"></a>
+<span class="sourceLineNo">119</span>  private RetryCounter retryCounter;<a name="line.119"></a>
 <span class="sourceLineNo">120</span><a name="line.120"></a>
-<span class="sourceLineNo">121</span>  public TransitRegionStateProcedure() {<a name="line.121"></a>
-<span class="sourceLineNo">122</span>  }<a name="line.122"></a>
-<span class="sourceLineNo">123</span><a name="line.123"></a>
-<span class="sourceLineNo">124</span>  private void setInitialAndLastState() {<a name="line.124"></a>
-<span class="sourceLineNo">125</span>    switch (type) {<a name="line.125"></a>
-<span class="sourceLineNo">126</span>      case ASSIGN:<a name="line.126"></a>
-<span class="sourceLineNo">127</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE;<a name="line.127"></a>
-<span class="sourceLineNo">128</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.128"></a>
-<span class="sourceLineNo">129</span>        break;<a name="line.129"></a>
-<span class="sourceLineNo">130</span>      case UNASSIGN:<a name="line.130"></a>
-<span class="sourceLineNo">131</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.131"></a>
-<span class="sourceLineNo">132</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED;<a name="line.132"></a>
-<span class="sourceLineNo">133</span>        break;<a name="line.133"></a>
-<span class="sourceLineNo">134</span>      case MOVE:<a name="line.134"></a>
-<span class="sourceLineNo">135</span>      case REOPEN:<a name="line.135"></a>
-<span class="sourceLineNo">136</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.136"></a>
-<span class="sourceLineNo">137</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.137"></a>
-<span class="sourceLineNo">138</span>        break;<a name="line.138"></a>
-<span class="sourceLineNo">139</span>      default:<a name="line.139"></a>
-<span class="sourceLineNo">140</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.140"></a>
-<span class="sourceLineNo">141</span>    }<a name="line.141"></a>
-<span class="sourceLineNo">142</span>  }<a name="line.142"></a>
-<span class="sourceLineNo">143</span><a name="line.143"></a>
-<span class="sourceLineNo">144</span>  protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,<a name="line.144"></a>
-<span class="sourceLineNo">145</span>      ServerName assignCandidate, boolean forceNewPlan, TransitionType type) {<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    super(env, hri);<a name="line.146"></a>
-<span class="sourceLineNo">147</span>    this.assignCandidate = assignCandidate;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>    this.forceNewPlan = forceNewPlan;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    this.type = type;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    setInitialAndLastState();<a name="line.150"></a>
-<span class="sourceLineNo">151</span><a name="line.151"></a>
-<span class="sourceLineNo">152</span>    // when do reopen TRSP, let the rs know the targetServer so it can keep some info on close<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    if (type == TransitionType.REOPEN) {<a name="line.153"></a>
-<span class="sourceLineNo">154</span>      this.assignCandidate = getRegionStateNode(env).getRegionLocation();<a name="line.154"></a>
-<span class="sourceLineNo">155</span>    }<a name="line.155"></a>
-<span class="sourceLineNo">156</span>  }<a name="line.156"></a>
-<span class="sourceLineNo">157</span><a name="line.157"></a>
-<span class="sourceLineNo">158</span>  @Override<a name="line.158"></a>
-<span class="sourceLineNo">159</span>  public TableOperationType getTableOperationType() {<a name="line.159"></a>
-<span class="sourceLineNo">160</span>    // TODO: maybe we should make another type here, REGION_TRANSITION?<a name="line.160"></a>
-<span class="sourceLineNo">161</span>    return TableOperationType.REGION_EDIT;<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  }<a name="line.162"></a>
-<span class="sourceLineNo">163</span><a name="line.163"></a>
-<span class="sourceLineNo">164</span>  @Override<a name="line.164"></a>
-<span class="sourceLineNo">165</span>  protected boolean waitInitialized(MasterProcedureEnv env) {<a name="line.165"></a>
-<span class="sourceLineNo">166</span>    if (TableName.isMetaTableName(getTableName())) {<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      return false;<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    }<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    // First we need meta to be loaded, and second, if meta is not online then we will likely to<a name="line.169"></a>
-<span class="sourceLineNo">170</span>    // fail when updating meta so we wait until it is assigned.<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    AssignmentManager am = env.getAssignmentManager();<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    return am.waitMetaLoaded(this) || am.waitMetaAssigned(this, getRegion());<a name="line.172"></a>
-<span class="sourceLineNo">173</span>  }<a name="line.173"></a>
-<span class="sourceLineNo">174</span><a name="line.174"></a>
-<span class="sourceLineNo">175</span>  private void queueAssign(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.175"></a>
-<span class="sourceLineNo">176</span>      throws ProcedureSuspendedException {<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    boolean retain = false;<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    if (forceNewPlan) {<a name="line.178"></a>
-<span class="sourceLineNo">179</span>      // set the region location to null if forceNewPlan is true<a name="line.179"></a>
-<span class="sourceLineNo">180</span>      regionNode.setRegionLocation(null);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    } else {<a name="line.181"></a>
-<span class="sourceLineNo">182</span>      if (assignCandidate != null) {<a name="line.182"></a>
-<span class="sourceLineNo">183</span>        retain = assignCandidate.equals(regionNode.getLastHost());<a name="line.183"></a>
-<span class="sourceLineNo">184</span>        regionNode.setRegionLocation(assignCandidate);<a name="line.184"></a>
-<span class="sourceLineNo">185</span>      } else if (regionNode.getLastHost() != null) {<a name="line.185"></a>
-<span class="sourceLineNo">186</span>        retain = true;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>        LOG.info("Setting lastHost as the region location {}", regionNode.getLastHost());<a name="line.187"></a>
-<span class="sourceLineNo">188</span>        regionNode.setRegionLocation(regionNode.getLastHost());<a name="line.188"></a>
-<span class="sourceLineNo">189</span>      }<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    }<a name="line.190"></a>
-<span class="sourceLineNo">191</span>    LOG.info("Starting {}; {}; forceNewPlan={}, retain={}", this, regionNode.toShortString(),<a name="line.191"></a>
-<span class="sourceLineNo">192</span>      forceNewPlan, retain);<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    env.getAssignmentManager().queueAssign(regionNode);<a name="line.193"></a>
-<span class="sourceLineNo">194</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_OPEN);<a name="line.194"></a>
-<span class="sourceLineNo">195</span>    if (regionNode.getProcedureEvent().suspendIfNotReady(this)) {<a name="line.195"></a>
-<span class="sourceLineNo">196</span>      throw new ProcedureSuspendedException();<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    }<a name="line.197"></a>
-<span class="sourceLineNo">198</span>  }<a name="line.198"></a>
-<span class="sourceLineNo">199</span><a name="line.199"></a>
-<span class="sourceLineNo">200</span>  private void openRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    ServerName loc = regionNode.getRegionLocation();<a name="line.201"></a>
-<span class="sourceLineNo">202</span>    if (loc == null) {<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      LOG.warn("No location specified for {}, jump back to state {} to get one", getRegion(),<a name="line.203"></a>
-<span class="sourceLineNo">204</span>        RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.204"></a>
-<span class="sourceLineNo">205</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.205"></a>
-<span class="sourceLineNo">206</span>      return;<a name="line.206"></a>
-<span class="sourceLineNo">207</span>    }<a name="line.207"></a>
-<span class="sourceLineNo">208</span>    env.getAssignmentManager().regionOpening(regionNode);<a name="line.208"></a>
-<span class="sourceLineNo">209</span>    addChildProcedure(new OpenRegionProcedure(this, getRegion(), loc));<a name="line.209"></a>
-<span class="sourceLineNo">210</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED);<a name="line.210"></a>
-<span class="sourceLineNo">211</span>  }<a name="line.211"></a>
-<span class="sourceLineNo">212</span><a name="line.212"></a>
-<span class="sourceLineNo">213</span>  private Flow confirmOpened(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.213"></a>
-<span class="sourceLineNo">214</span>      throws IOException {<a name="line.214"></a>
-<span class="sourceLineNo">215</span>    if (regionNode.isInState(State.OPEN)) {<a name="line.215"></a>
-<span class="sourceLineNo">216</span>      retryCounter = null;<a name="line.216"></a>
-<span class="sourceLineNo">217</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED) {<a name="line.217"></a>
-<span class="sourceLineNo">218</span>        // we are the last state, finish<a name="line.218"></a>
-<span class="sourceLineNo">219</span>        regionNode.unsetProcedure(this);<a name="line.219"></a>
-<span class="sourceLineNo">220</span>        ServerCrashProcedure.updateProgress(env, getParentProcId());<a name="line.220"></a>
-<span class="sourceLineNo">221</span>        return Flow.NO_MORE_STATE;<a name="line.221"></a>
-<span class="sourceLineNo">222</span>      }<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      // It is possible that we arrive here but confirm opened is not the last state, for example,<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      // when merging or splitting a region, we unassign the region from a RS and the RS is crashed,<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      // then there will be recovered edits for this region, we'd better make the region online<a name="line.225"></a>
-<span class="sourceLineNo">226</span>      // again and then unassign it, otherwise we have to fail the merge/split procedure as we may<a name="line.226"></a>
-<span class="sourceLineNo">227</span>      // loss data.<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.228"></a>
-<span class="sourceLineNo">229</span>      return Flow.HAS_MORE_STATE;<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    }<a name="line.230"></a>
-<span class="sourceLineNo">231</span><a name="line.231"></a>
-<span class="sourceLineNo">232</span>    int retries = env.getAssignmentManager().getRegionStates().addToFailedOpen(regionNode)<a name="line.232"></a>
-<span class="sourceLineNo">233</span>        .incrementAndGetRetries();<a name="line.233"></a>
-<span class="sourceLineNo">234</span>    int maxAttempts = env.getAssignmentManager().getAssignMaxAttempts();<a name="line.234"></a>
-<span class="sourceLineNo">235</span>    LOG.info("Retry={} of max={}; {}; {}", retries, maxAttempts, this, regionNode.toShortString());<a name="line.235"></a>
-<span class="sourceLineNo">236</span><a name="line.236"></a>
-<span class="sourceLineNo">237</span>    if (retries &gt;= maxAttempts) {<a name="line.237"></a>
-<span class="sourceLineNo">238</span>      env.getAssignmentManager().regionFailedOpen(regionNode, true);<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      setFailure(getClass().getSimpleName(), new RetriesExhaustedException(<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        "Max attempts " + env.getAssignmentManager().getAssignMaxAttempts() + " exceeded"));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      regionNode.unsetProcedure(this);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      return Flow.NO_MORE_STATE;<a name="line.242"></a>
-<span class="sourceLineNo">243</span>    }<a name="line.243"></a>
-<span class="sourceLineNo">244</span><a name="line.244"></a>
-<span class="sourceLineNo">245</span>    env.getAssignmentManager().regionFailedOpen(regionNode, false);<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    // we failed to assign the region, force a new plan<a name="line.246"></a>
-<span class="sourceLineNo">247</span>    forceNewPlan = true;<a name="line.247"></a>
-<span class="sourceLineNo">248</span>    regionNode.setRegionLocation(null);<a name="line.248"></a>
-<span class="sourceLineNo">249</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.249"></a>
-<span class="sourceLineNo">250</span><a name="line.250"></a>
-<span class="sourceLineNo">251</span>    if (retries &gt; env.getAssignmentManager().getAssignRetryImmediatelyMaxAttempts()) {<a name="line.251"></a>
-<span class="sourceLineNo">252</span>      // Throw exception to backoff and retry when failed open too many times<a name="line.252"></a>
-<span class="sourceLineNo">253</span>      throw new HBaseIOException("Failed confirm OPEN of " + regionNode +<a name="line.253"></a>
-<span class="sourceLineNo">254</span>          " (remote log may yield more detail on why).");<a name="line.254"></a>
-<span class="sourceLineNo">255</span>    } else {<a name="line.255"></a>
-<span class="sourceLineNo">256</span>      // Here we do not throw exception because we want to the region to be online ASAP<a name="line.256"></a>
-<span class="sourceLineNo">257</span>      return Flow.HAS_MORE_STATE;<a name="line.257"></a>
-<span class="sourceLineNo">258</span>    }<a name="line.258"></a>
-<span class="sourceLineNo">259</span>  }<a name="line.259"></a>
-<span class="sourceLineNo">260</span><a name="line.260"></a>
-<span class="sourceLineNo">261</span>  private void closeRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.261"></a>
-<span class="sourceLineNo">262</span>    if (regionNode.isInState(State.OPEN, State.CLOSING, State.MERGING, State.SPLITTING)) {<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      // this is the normal case<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      env.getAssignmentManager().regionClosing(regionNode);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      addChildProcedure(new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),<a name="line.265"></a>
-<span class="sourceLineNo">266</span>        assignCandidate));<a name="line.266"></a>
-<span class="sourceLineNo">267</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED);<a name="line.267"></a>
-<span class="sourceLineNo">268</span>    } else {<a name="line.268"></a>
-<span class="sourceLineNo">269</span>      forceNewPlan = true;<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      regionNode.setRegionLocation(null);<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    }<a name="line.272"></a>
-<span class="sourceLineNo">273</span>  }<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>  private Flow confirmClosed(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      throws IOException {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>    if (regionNode.isInState(State.CLOSED)) {<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      retryCounter = null;<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        // we are the last state, finish<a name="line.280"></a>
-<span class="sourceLineNo">281</span>        regionNode.unsetProcedure(this);<a name="line.281"></a>
-<span class="sourceLineNo">282</span>        return Flow.NO_MORE_STATE;<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      }<a name="line.283"></a>
-<span class="sourceLineNo">284</span>      // This means we need to open the region again, should be a move or reopen<a name="line.284"></a>
-<span class="sourceLineNo">285</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return Flow.HAS_MORE_STATE;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    if (regionNode.isInState(State.CLOSING)) {<a name="line.288"></a>
-<span class="sourceLineNo">289</span>      // This is possible, think the target RS crashes and restarts immediately, the close region<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      // operation will return a NotServingRegionException soon, we can only recover after SCP takes<a name="line.290"></a>
-<span class="sourceLineNo">291</span>      // care of this RS. So here we throw an IOException to let upper layer to retry with backoff.<a name="line.291"></a>
-<span class="sourceLineNo">292</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      throw new HBaseIOException("Failed to close region");<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    }<a name="line.294"></a>
-<span class="sourceLineNo">295</span>    // abnormally closed, need to reopen it, no matter what is the last state, see the comment in<a name="line.295"></a>
-<span class="sourceLineNo">296</span>    // confirmOpened for more details that why we need to reopen the region first even if we just<a name="line.296"></a>
-<span class="sourceLineNo">297</span>    // want to close it.<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    // The only exception is for non-default replica, where we do not need to deal with recovered<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    // edits. Notice that the region will remain in ABNORMALLY_CLOSED state, the upper layer need to<a name="line.299"></a>
-<span class="sourceLineNo">300</span>    // deal with this state. For non-default replica, this is usually the same with CLOSED.<a name="line.300"></a>
-<span class="sourceLineNo">301</span>    assert regionNode.isInState(State.ABNORMALLY_CLOSED);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    if (!RegionReplicaUtil.isDefaultReplica(getRegion()) &amp;&amp;<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>      regionNode.unsetProcedure(this);<a name="line.304"></a>
-<span class="sourceLineNo">305</span>      return Flow.NO_MORE_STATE;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>    }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>    retryCounter = null;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    return Flow.HAS_MORE_STATE;<a name="line.309"></a>
-<span class="sourceLineNo">310</span>  }<a name="line.310"></a>
-<span class="sourceLineNo">311</span><a name="line.311"></a>
-<span class="sourceLineNo">312</span>  // Override to lock RegionStateNode<a name="line.312"></a>
-<span class="sourceLineNo">313</span>  @SuppressWarnings("rawtypes")<a name="line.313"></a>
-<span class="sourceLineNo">314</span>  @Override<a name="line.314"></a>
-<span class="sourceLineNo">315</span>  protected Procedure[] execute(MasterProcedureEnv env)<a name="line.315"></a>
-<span class="sourceLineNo">316</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    RegionStateNode regionNode =<a name="line.317"></a>
-<span class="sourceLineNo">318</span>      env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    regionNode.lock();<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    try {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      return super.execute(env);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>    } finally {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>      regionNode.unlock();<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    }<a name="line.324"></a>
-<span class="sourceLineNo">325</span>  }<a name="line.325"></a>
-<span class="sourceLineNo">326</span><a name="line.326"></a>
-<span class="sourceLineNo">327</span>  private RegionStateNode getRegionStateNode(MasterProcedureEnv env) {<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    return env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.328"></a>
-<span class="sourceLineNo">329</span>  }<a name="line.329"></a>
-<span class="sourceLineNo">330</span><a name="line.330"></a>
-<span class="sourceLineNo">331</span>  @Override<a name="line.331"></a>
-<span class="sourceLineNo">332</span>  protected Flow executeFromState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    RegionStateNode regionNode = getRegionStateNode(env);<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    try {<a name="line.335"></a>
-<span class="sourceLineNo">336</span>      switch (state) {<a name="line.336"></a>
-<span class="sourceLineNo">337</span>        case REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE:<a name="line.337"></a>
-<span class="sourceLineNo">338</span>          // Need to do some sanity check for replica region, if the region does not exist at<a name="line.338"></a>
-<span class="sourceLineNo">339</span>          // master, do not try to assign the replica region, log error and return.<a name="line.339"></a>
-<span class="sourceLineNo">340</span>          if (!RegionReplicaUtil.isDefaultReplica(regionNode.getRegionInfo())) {<a name="line.340"></a>
-<span class="sourceLineNo">341</span>            RegionInfo defaultRI =<a name="line.341"></a>
-<span class="sourceLineNo">342</span>              RegionReplicaUtil.getRegionInfoForDefaultReplica(regionNode.getRegionInfo());<a name="line.342"></a>
-<span class="sourceLineNo">343</span>            if (env.getMasterServices().getAssignmentManager().getRegionStates().<a name="line.343"></a>
-<span class="sourceLineNo">344</span>              getRegionStateNode(defaultRI) == null) {<a name="line.344"></a>
-<span class="sourceLineNo">345</span>              LOG.error(<a name="line.345"></a>
-<span class="sourceLineNo">346</span>                "Cannot assign replica region {} because its primary region {} does not exist.",<a name="line.346"></a>
-<span class="sourceLineNo">347</span>                regionNode.getRegionInfo(), defaultRI);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>              regionNode.unsetProcedure(this);<a name="line.348"></a>
-<span class="sourceLineNo">349</span>              return Flow.NO_MORE_STATE;<a name="line.349"></a>
-<span class="sourceLineNo">350</span>            }<a name="line.350"></a>
-<span class="sourceLineNo">351</span>          }<a name="line.351"></a>
-<span class="sourceLineNo">352</span>          queueAssign(env, regionNode);<a name="line.352"></a>
-<span class="sourceLineNo">353</span>          return Flow.HAS_MORE_STATE;<a name="line.353"></a>
-<span class="sourceLineNo">354</span>        case REGION_STATE_TRANSITION_OPEN:<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          openRegion(env, regionNode);<a name="line.355"></a>
-<span class="sourceLineNo">356</span>          return Flow.HAS_MORE_STATE;<a name="line.356"></a>
-<span class="sourceLineNo">357</span>        case REGION_STATE_TRANSITION_CONFIRM_OPENED:<a name="line.357"></a>
-<span class="sourceLineNo">358</span>          return confirmOpened(env, regionNode);<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        case REGION_STATE_TRANSITION_CLOSE:<a name="line.359"></a>
-<span class="sourceLineNo">360</span>          closeRegion(env, regionNode);<a name="line.360"></a>
-<span class="sourceLineNo">361</span>          return Flow.HAS_MORE_STATE;<a name="line.361"></a>
-<span class="sourceLineNo">362</span>        case REGION_STATE_TRANSITION_CONFIRM_CLOSED:<a name="line.362"></a>
-<span class="sourceLineNo">363</span>          return confirmClosed(env, regionNode);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>        default:<a name="line.364"></a>
-<span class="sourceLineNo">365</span>          throw new UnsupportedOperationException("unhandled state=" + state);<a name="line.365"></a>
-<span class="sourceLineNo">366</span>      }<a name="line.366"></a>
-<span class="sourceLineNo">367</span>    } catch (IOException e) {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>      if (retryCounter == null) {<a name="line.368"></a>
-<span class="sourceLineNo">369</span>        retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration());<a name="line.369"></a>
-<span class="sourceLineNo">370</span>      }<a name="line.370"></a>
-<span class="sourceLineNo">371</span>      long backoff = retryCounter.getBackoffTimeAndIncrementAttempts();<a name="line.371"></a>
-<span class="sourceLineNo">372</span>      LOG.warn(<a name="line.372"></a>
-<span class="sourceLineNo">373</span>        "Failed transition, suspend {}secs {}; {}; waiting on rectified condition fixed " +<a name="line.373"></a>
-<span class="sourceLineNo">374</span>          "by other Procedure or operator intervention",<a name="line.374"></a>
-<span class="sourceLineNo">375</span>        backoff / 1000, this, regionNode.toShortString(), e);<a name="line.375"></a>
-<span class="sourceLineNo">376</span>      setTimeout(Math.toIntExact(backoff));<a name="line.376"></a>
-<span class="sourceLineNo">377</span>      setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT);<a name="line.377"></a>
-<span class="sourceLineNo">378</span>      skipPersistence();<a name="line.378"></a>
-<span class="sourceLineNo">379</span>      throw new ProcedureSuspendedException();<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    }<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  }<a name="line.381"></a>
-<span class="sourceLineNo">382</span><a name="line.382"></a>
-<span class="sourceLineNo">383</span>  /**<a name="line.383"></a>
-<span class="sourceLineNo">384</span>   * At end of timeout, wake ourselves up so we run again.<a name="line.384"></a>
-<span class="sourceLineNo">385</span>   */<a name="line.385"></a>
-<span class="sourceLineNo">386</span>  @Override<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  protected synchronized boolean setTimeoutFailure(MasterProcedureEnv env) {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    setState(ProcedureProtos.ProcedureState.RUNNABLE);<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    env.getProcedureScheduler().addFront(this);<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    return false; // 'false' means that this procedure handled the timeout<a name="line.390"></a>
-<span class="sourceLineNo">391</span>  }<a name="line.391"></a>
-<span class="sourceLineNo">392</span><a name="line.392"></a>
-<span class="sourceLineNo">393</span>  // Should be called with RegionStateNode locked<a name="line.393"></a>
-<span class="sourceLineNo">394</span>  public void reportTransition(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      ServerName serverName, TransitionCode code, long seqId, long procId) throws IOException {<a name="line.395"></a>
-<span class="sourceLineNo">396</span>    if (remoteProc == null) {<a name="line.396"></a>
-<span class="sourceLineNo">397</span>      LOG.warn(<a name="line.397"></a>
-<span class="sourceLineNo">398</span>        "There is no outstanding remote region procedure for {}, serverName={}, code={}," +<a name="line.398"></a>
-<span class="sourceLineNo">399</span>          " seqId={}, proc={}, should be a retry, ignore",<a name="line.399"></a>
-<span class="sourceLineNo">400</span>        regionNode, serverName, code, seqId, this);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>      return;<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    // The procId could be -1 if it is from an old region server, we need to deal with it so that we<a name="line.403"></a>
-<span class="sourceLineNo">404</span>    // can do rolling upgraing.<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    if (procId &gt;= 0 &amp;&amp; remoteProc.getProcId() != procId) {<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      LOG.warn(<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        "The pid of remote region procedure for {} is {}, the reported pid={}, serverName={}," +<a name="line.407"></a>
-<span class="sourceLineNo">408</span>          " code={}, seqId={}, proc={}, should be a retry, ignore",<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        regionNode, remoteProc.getProcId(), procId, serverName, code, seqId, this);<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      return;<a name="line.410"></a>
-<span class="sourceLineNo">411</span>    }<a name="line.411"></a>
-<span class="sourceLineNo">412</span>    remoteProc.reportTransition(env, regionNode, serverName, code, seqId);<a name="line.412"></a>
-<span class="sourceLineNo">413</span>  }<a name="line.413"></a>
-<span class="sourceLineNo">414</span><a name="line.414"></a>
-<span class="sourceLineNo">415</span>  // Should be called with RegionStateNode locked<a name="line.415"></a>
-<span class="sourceLineNo">416</span>  public void serverCrashed(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.416"></a>
-<span class="sourceLineNo">417</span>      ServerName serverName, boolean forceNewPlan) throws IOException {<a name="line.417"></a>
-<span class="sourceLineNo">418</span>    this.forceNewPlan = forceNewPlan;<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    if (remoteProc != null) {<a name="line.419"></a>
-<span class="sourceLineNo">420</span>      // this means we are waiting for the sub procedure, so wake it up<a name="line.420"></a>
-<span class="sourceLineNo">421</span>      remoteProc.serverCrashed(env, regionNode, serverName);<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    } else {<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      // we are in RUNNING state, just update the region state, and we will process it later.<a name="line.423"></a>
-<span class="sourceLineNo">424</span>      env.getAssignmentManager().regionClosedAbnormally(regionNode);<a name="line.424"></a>
-<span class="sourceLineNo">425</span>    }<a name="line.425"></a>
-<span class="sourceLineNo">426</span>  }<a name="line.426"></a>
-<span class="sourceLineNo">427</span><a name="line.427"></a>
-<span class="sourceLineNo">428</span>  void attachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.428"></a>
-<span class="sourceLineNo">429</span>    this.remoteProc = proc;<a name="line.429"></a>
-<span class="sourceLineNo">430</span>  }<a name="line.430"></a>
-<span class="sourceLineNo">431</span><a name="line.431"></a>
-<span class="sourceLineNo">432</span>  void unattachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    assert this.remoteProc == proc;<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    this.remoteProc = null;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>  }<a name="line.435"></a>
-<span class="sourceLineNo">436</span><a name="line.436"></a>
-<span class="sourceLineNo">437</span>  // will be called after we finish loading the meta entry for this region.<a name="line.437"></a>
-<span class="sourceLineNo">438</span>  // used to change the state of the region node if we have a sub procedure, as we may not persist<a name="line.438"></a>
-<span class="sourceLineNo">439</span>  // the state to meta yet. See the code in RegionRemoteProcedureBase.execute for more details.<a name="line.439"></a>
-<span class="sourceLineNo">440</span>  void stateLoaded(AssignmentManager am, RegionStateNode regionNode) {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    if (remoteProc != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      remoteProc.stateLoaded(am, regionNode);<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
-<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>  @Override<a name="line.446"></a>
-<span class="sourceLineNo">447</span>  protected void rollbackState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.447"></a>
-<span class="sourceLineNo">448</span>      throws IOException, InterruptedException {<a name="line.448"></a>
-<span class="sourceLineNo">449</span>    // no rollback<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    throw new UnsupportedOperationException();<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  @Override<a name="line.453"></a>
-<span class="sourceLineNo">454</span>  protected RegionStateTransitionState getState(int stateId) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    return RegionStateTransitionState.forNumber(stateId);<a name="line.455"></a>
-<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>  @Override<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  protected int getStateId(RegionStateTransitionState state) {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    return state.getNumber();<a name="line.460"></a>
-<span class="sourceLineNo">461</span>  }<a name="line.461"></a>
-<span class="sourceLineNo">462</span><a name="line.462"></a>
-<span class="sourceLineNo">463</span>  @Override<a name="line.463"></a>
-<span class="sourceLineNo">464</span>  protected RegionStateTransitionState getInitialState() {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    return initialState;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>  }<a name="line.466"></a>
-<span class="sourceLineNo">467</span><a name="line.467"></a>
-<span class="sourceLineNo">468</span>  private static TransitionType convert(RegionTransitionType type) {<a name="line.468"></a>
-<span class="sourceLineNo">469</span>    switch (type) {<a name="line.469"></a>
-<span class="sourceLineNo">470</span>      case ASSIGN:<a name="line.470"></a>
-<span class="sourceLineNo">471</span>        return TransitionType.ASSIGN;<a name="line.471"></a>
-<span class="sourceLineNo">472</span>      case UNASSIGN:<a name="line.472"></a>
-<span class="sourceLineNo">473</span>        return TransitionType.UNASSIGN;<a name="line.473"></a>
-<span class="sourceLineNo">474</span>      case MOVE:<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        return TransitionType.MOVE;<a name="line.475"></a>
-<span class="sourceLineNo">476</span>      case REOPEN:<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        return TransitionType.REOPEN;<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      default:<a name="line.478"></a>
-<span class="sourceLineNo">479</span>        throw new IllegalArgumentException("Unknown RegionTransitionType: " + type);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
-<span class="sourceLineNo">482</span><a name="line.482"></a>
-<span class="sourceLineNo">483</span>  private static RegionTransitionType convert(TransitionType type) {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    switch (type) {<a name="line.484"></a>
-<span class="sourceLineNo">485</span>      case ASSIGN:<a name="line.485"></a>
-<span class="sourceLineNo">486</span>        return RegionTransitionType.ASSIGN;<a name="line.486"></a>
-<span class="sourceLineNo">487</span>      case UNASSIGN:<a name="line.487"></a>
-<span class="sourceLineNo">488</span>        return RegionTransitionType.UNASSIGN;<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      case MOVE:<a name="line.489"></a>
-<span class="sourceLineNo">490</span>        return RegionTransitionType.MOVE;<a name="line.490"></a>
-<span class="sourceLineNo">491</span>      case REOPEN:<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        return RegionTransitionType.REOPEN;<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      default:<a name="line.493"></a>
-<span class="sourceLineNo">494</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    }<a name="line.495"></a>
-<span class="sourceLineNo">496</span>  }<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>  @Override<a name="line.498"></a>
-<span class="sourceLineNo">499</span>  protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>    super.serializeStateData(serializer);<a name="line.500"></a>
-<span class="sourceLineNo">501</span>    RegionStateTransitionStateData.Builder builder = RegionStateTransitionStateData.newBuilder()<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      .setType(convert(type)).setForceNewPlan(forceNewPlan);<a name="line.502"></a>
-<span class="sourceLineNo">503</span>    if (assignCandidate != null) {<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    }<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    serializer.serialize(builder.build());<a name="line.506"></a>
-<span class="sourceLineNo">507</span>  }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>  @Override<a name="line.509"></a>
-<span class="sourceLineNo">510</span>  protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    super.deserializeStateData(serializer);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>    RegionStateTransitionStateData data =<a name="line.512"></a>
-<span class="sourceLineNo">513</span>      serializer.deserialize(RegionStateTransitionStateData.class);<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    type = convert(data.getType());<a name="line.514"></a>
-<span class="sourceLineNo">515</span>    setInitialAndLastState();<a name="line.515"></a>
-<span class="sourceLineNo">516</span>    forceNewPlan = data.getForceNewPlan();<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    if (data.hasAssignCandidate()) {<a name="line.517"></a>
-<span class="sourceLineNo">518</span>      assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());<a name="line.518"></a>
-<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
-<span class="sourceLineNo">520</span>  }<a name="line.520"></a>
-<span class="sourceLineNo">521</span><a name="line.521"></a>
-<span class="sourceLineNo">522</span>  @Override<a name="line.522"></a>
-<span class="sourceLineNo">523</span>  protected ProcedureMetrics getProcedureMetrics(MasterProcedureEnv env) {<a name="line.523"></a>
-<span class="sourceLineNo">524</span>    MetricsAssignmentManager metrics = env.getAssignmentManager().getAssignmentManagerMetrics();<a name="line.524"></a>
-<span class="sourceLineNo">525</span>    switch (type) {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>      case ASSIGN:<a name="line.526"></a>
-<span class="sourceLineNo">527</span>        return metrics.getAssignProcMetrics();<a name="line.527"></a>
-<span class="sourceLineNo">528</span>      case UNASSIGN:<a name="line.528"></a>
-<span class="sourceLineNo">529</span>        return metrics.getUnassignProcMetrics();<a name="line.529"></a>
-<span class="sourceLineNo">530</span>      case MOVE:<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        return metrics.getMoveProcMetrics();<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      case REOPEN:<a name="line.532"></a>
-<span class="sourceLineNo">533</span>        return metrics.getReopenProcMetrics();<a name="line.533"></a>
-<span class="sourceLineNo">534</span>      default:<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        throw new IllegalArgumentException("Unknown transition type: " + type);<a name="line.535"></a>
-<span class="sourceLineNo">536</span>    }<a name="line.536"></a>
-<span class="sourceLineNo">537</span>  }<a name="line.537"></a>
-<span class="sourceLineNo">538</span><a name="line.538"></a>
-<span class="sourceLineNo">539</span>  @Override<a name="line.539"></a>
-<span class="sourceLineNo">540</span>  public void toStringClassDetails(StringBuilder sb) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    super.toStringClassDetails(sb);<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    if (initialState == RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE) {<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      sb.append(", ASSIGN");<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    } else if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.544"></a>
-<span class="sourceLineNo">545</span>      sb.append(", UNASSIGN");<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    } else {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>      sb.append(", REOPEN/MOVE");<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    }<a name="line.548"></a>
-<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>  private static TransitRegionStateProcedure setOwner(MasterProcedureEnv env,<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      TransitRegionStateProcedure proc) {<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    proc.setOwner(env.getRequestUser().getShortName());<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    return proc;<a name="line.554"></a>
-<span class="sourceLineNo">555</span>  }<a name="line.555"></a>
-<span class="sourceLineNo">556</span><a name="line.556"></a>
-<span class="sourceLineNo">557</span>  public enum TransitionType {<a name="line.557"></a>
-<span class="sourceLineNo">558</span>    ASSIGN, UNASSIGN, MOVE, REOPEN<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  }<a name="line.559"></a>
-<span class="sourceLineNo">560</span><a name="line.560"></a>
-<span class="sourceLineNo">561</span>  // Be careful that, when you call these 4 methods below, you need to manually attach the returned<a name="line.561"></a>
-<span class="sourceLineNo">562</span>  // procedure with the RegionStateNode, otherwise the procedure will quit immediately without doing<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  // anything. See the comment in executeFromState to find out why we need this assumption.<a name="line.563"></a>
-<span class="sourceLineNo">564</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.564"></a>
-<span class="sourceLineNo">565</span>      @Nullable ServerName targetServer) {<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return assign(env, region, false, targetServer);<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.569"></a>
-<span class="sourceLineNo">570</span>      boolean forceNewPlan, @Nullable ServerName targetServer) {<a name="line.570"></a>
-<span class="sourceLineNo">571</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer, forceNewPlan,<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        TransitionType.ASSIGN));<a name="line.572"></a>
-<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
-<span class="sourceLineNo">574</span><a name="line.574"></a>
-<span class="sourceLineNo">575</span>  public static TransitRegionStateProcedure unassign(MasterProcedureEnv env, RegionInfo region) {<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    return setOwner(env,<a name="line.576"></a>
-<span class="sourceLineNo">577</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN));<a name="line.577"></a>
-<span class="sourceLineNo">578</span>  }<a name="line.578"></a>
-<span class="sourceLineNo">579</span><a name="line.579"></a>
-<span class="sourceLineNo">580</span>  public static TransitRegionStateProcedure reopen(MasterProcedureEnv env, RegionInfo region) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>    return setOwner(env,<a name="line.581"></a>
-<span class="sourceLineNo">582</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.REOPEN));<a name="line.582"></a>
-<span class="sourceLineNo">583</span>  }<a name="line.583"></a>
-<span class="sourceLineNo">584</span><a name="line.584"></a>
-<span class="sourceLineNo">585</span>  public static TransitRegionStateProcedure move(MasterProcedureEnv env, RegionInfo region,<a name="line.585"></a>
-<span class="sourceLineNo">586</span>      @Nullable ServerName targetServer) {<a name="line.586"></a>
-<span class="sourceLineNo">587</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer,<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      targetServer == null, TransitionType.MOVE));<a name="line.588"></a>
-<span class="sourceLineNo">589</span>  }<a name="line.589"></a>
-<span class="sourceLineNo">590</span>}<a name="line.590"></a>
+<span class="sourceLineNo">121</span>  private RegionRemoteProcedureBase remoteProc;<a name="line.121"></a>
+<span class="sourceLineNo">122</span><a name="line.122"></a>
+<span class="sourceLineNo">123</span>  public TransitRegionStateProcedure() {<a name="line.123"></a>
+<span class="sourceLineNo">124</span>  }<a name="line.124"></a>
+<span class="sourceLineNo">125</span><a name="line.125"></a>
+<span class="sourceLineNo">126</span>  private void setInitialAndLastState() {<a name="line.126"></a>
+<span class="sourceLineNo">127</span>    switch (type) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>      case ASSIGN:<a name="line.128"></a>
+<span class="sourceLineNo">129</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE;<a name="line.129"></a>
+<span class="sourceLineNo">130</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.130"></a>
+<span class="sourceLineNo">131</span>        break;<a name="line.131"></a>
+<span class="sourceLineNo">132</span>      case UNASSIGN:<a name="line.132"></a>
+<span class="sourceLineNo">133</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.133"></a>
+<span class="sourceLineNo">134</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED;<a name="line.134"></a>
+<span class="sourceLineNo">135</span>        break;<a name="line.135"></a>
+<span class="sourceLineNo">136</span>      case MOVE:<a name="line.136"></a>
+<span class="sourceLineNo">137</span>      case REOPEN:<a name="line.137"></a>
+<span class="sourceLineNo">138</span>        initialState = RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE;<a name="line.138"></a>
+<span class="sourceLineNo">139</span>        lastState = RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED;<a name="line.139"></a>
+<span class="sourceLineNo">140</span>        break;<a name="line.140"></a>
+<span class="sourceLineNo">141</span>      default:<a name="line.141"></a>
+<span class="sourceLineNo">142</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.142"></a>
+<span class="sourceLineNo">143</span>    }<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  }<a name="line.144"></a>
+<span class="sourceLineNo">145</span><a name="line.145"></a>
+<span class="sourceLineNo">146</span>  protected TransitRegionStateProcedure(MasterProcedureEnv env, RegionInfo hri,<a name="line.146"></a>
+<span class="sourceLineNo">147</span>      ServerName assignCandidate, boolean forceNewPlan, TransitionType type) {<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    super(env, hri);<a name="line.148"></a>
+<span class="sourceLineNo">149</span>    this.assignCandidate = assignCandidate;<a name="line.149"></a>
+<span class="sourceLineNo">150</span>    this.forceNewPlan = forceNewPlan;<a name="line.150"></a>
+<span class="sourceLineNo">151</span>    this.type = type;<a name="line.151"></a>
+<span class="sourceLineNo">152</span>    setInitialAndLastState();<a name="line.152"></a>
+<span class="sourceLineNo">153</span><a name="line.153"></a>
+<span class="sourceLineNo">154</span>    // when do reopen TRSP, let the rs know the targetServer so it can keep some info on close<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    if (type == TransitionType.REOPEN) {<a name="line.155"></a>
+<span class="sourceLineNo">156</span>      this.assignCandidate = getRegionStateNode(env).getRegionLocation();<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    }<a name="line.157"></a>
+<span class="sourceLineNo">158</span>  }<a name="line.158"></a>
+<span class="sourceLineNo">159</span><a name="line.159"></a>
+<span class="sourceLineNo">160</span>  @Override<a name="line.160"></a>
+<span class="sourceLineNo">161</span>  public TableOperationType getTableOperationType() {<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    // TODO: maybe we should make another type here, REGION_TRANSITION?<a name="line.162"></a>
+<span class="sourceLineNo">163</span>    return TableOperationType.REGION_EDIT;<a name="line.163"></a>
+<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
+<span class="sourceLineNo">165</span><a name="line.165"></a>
+<span class="sourceLineNo">166</span>  @Override<a name="line.166"></a>
+<span class="sourceLineNo">167</span>  protected boolean waitInitialized(MasterProcedureEnv env) {<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    if (TableName.isMetaTableName(getTableName())) {<a name="line.168"></a>
+<span class="sourceLineNo">169</span>      return false;<a name="line.169"></a>
+<span class="sourceLineNo">170</span>    }<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    // First we need meta to be loaded, and second, if meta is not online then we will likely to<a name="line.171"></a>
+<span class="sourceLineNo">172</span>    // fail when updating meta so we wait until it is assigned.<a name="line.172"></a>
+<span class="sourceLineNo">173</span>    AssignmentManager am = env.getAssignmentManager();<a name="line.173"></a>
+<span class="sourceLineNo">174</span>    return am.waitMetaLoaded(this) || am.waitMetaAssigned(this, getRegion());<a name="line.174"></a>
+<span class="sourceLineNo">175</span>  }<a name="line.175"></a>
+<span class="sourceLineNo">176</span><a name="line.176"></a>
+<span class="sourceLineNo">177</span>  private void queueAssign(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      throws ProcedureSuspendedException {<a name="line.178"></a>
+<span class="sourceLineNo">179</span>    boolean retain = false;<a name="line.179"></a>
+<span class="sourceLineNo">180</span>    if (forceNewPlan) {<a name="line.180"></a>
+<span class="sourceLineNo">181</span>      // set the region location to null if forceNewPlan is true<a name="line.181"></a>
+<span class="sourceLineNo">182</span>      regionNode.setRegionLocation(null);<a name="line.182"></a>
+<span class="sourceLineNo">183</span>    } else {<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      if (assignCandidate != null) {<a name="line.184"></a>
+<span class="sourceLineNo">185</span>        retain = assignCandidate.equals(regionNode.getLastHost());<a name="line.185"></a>
+<span class="sourceLineNo">186</span>        regionNode.setRegionLocation(assignCandidate);<a name="line.186"></a>
+<span class="sourceLineNo">187</span>      } else if (regionNode.getLastHost() != null) {<a name="line.187"></a>
+<span class="sourceLineNo">188</span>        retain = true;<a name="line.188"></a>
+<span class="sourceLineNo">189</span>        LOG.info("Setting lastHost as the region location {}", regionNode.getLastHost());<a name="line.189"></a>
+<span class="sourceLineNo">190</span>        regionNode.setRegionLocation(regionNode.getLastHost());<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      }<a name="line.191"></a>
+<span class="sourceLineNo">192</span>    }<a name="line.192"></a>
+<span class="sourceLineNo">193</span>    LOG.info("Starting {}; {}; forceNewPlan={}, retain={}", this, regionNode.toShortString(),<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      forceNewPlan, retain);<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    env.getAssignmentManager().queueAssign(regionNode);<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_OPEN);<a name="line.196"></a>
+<span class="sourceLineNo">197</span>    if (regionNode.getProcedureEvent().suspendIfNotReady(this)) {<a name="line.197"></a>
+<span class="sourceLineNo">198</span>      throw new ProcedureSuspendedException();<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    }<a name="line.199"></a>
+<span class="sourceLineNo">200</span>  }<a name="line.200"></a>
+<span class="sourceLineNo">201</span><a name="line.201"></a>
+<span class="sourceLineNo">202</span>  private void openRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    ServerName loc = regionNode.getRegionLocation();<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    if (loc == null || BOGUS_SERVER_NAME.equals(loc)) {<a name="line.204"></a>
+<span class="sourceLineNo">205</span>      LOG.warn("No location specified for {}, jump back to state {} to get one", getRegion(),<a name="line.205"></a>
+<span class="sourceLineNo">206</span>        RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      return;<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    }<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    env.getAssignmentManager().regionOpening(regionNode);<a name="line.210"></a>
+<span class="sourceLineNo">211</span>    addChildProcedure(new OpenRegionProcedure(this, getRegion(), loc));<a name="line.211"></a>
+<span class="sourceLineNo">212</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED);<a name="line.212"></a>
+<span class="sourceLineNo">213</span>  }<a name="line.213"></a>
+<span class="sourceLineNo">214</span><a name="line.214"></a>
+<span class="sourceLineNo">215</span>  private Flow confirmOpened(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.215"></a>
+<span class="sourceLineNo">216</span>      throws IOException {<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    if (regionNode.isInState(State.OPEN)) {<a name="line.217"></a>
+<span class="sourceLineNo">218</span>      retryCounter = null;<a name="line.218"></a>
+<span class="sourceLineNo">219</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_OPENED) {<a name="line.219"></a>
+<span class="sourceLineNo">220</span>        // we are the last state, finish<a name="line.220"></a>
+<span class="sourceLineNo">221</span>        regionNode.unsetProcedure(this);<a name="line.221"></a>
+<span class="sourceLineNo">222</span>        ServerCrashProcedure.updateProgress(env, getParentProcId());<a name="line.222"></a>
+<span class="sourceLineNo">223</span>        return Flow.NO_MORE_STATE;<a name="line.223"></a>
+<span class="sourceLineNo">224</span>      }<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      // It is possible that we arrive here but confirm opened is not the last state, for example,<a name="line.225"></a>
+<span class="sourceLineNo">226</span>      // when merging or splitting a region, we unassign the region from a RS and the RS is crashed,<a name="line.226"></a>
+<span class="sourceLineNo">227</span>      // then there will be recovered edits for this region, we'd better make the region online<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      // again and then unassign it, otherwise we have to fail the merge/split procedure as we may<a name="line.228"></a>
+<span class="sourceLineNo">229</span>      // loss data.<a name="line.229"></a>
+<span class="sourceLineNo">230</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>      return Flow.HAS_MORE_STATE;<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    }<a name="line.232"></a>
+<span class="sourceLineNo">233</span><a name="line.233"></a>
+<span class="sourceLineNo">234</span>    int retries = env.getAssignmentManager().getRegionStates().addToFailedOpen(regionNode)<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        .incrementAndGetRetries();<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    int maxAttempts = env.getAssignmentManager().getAssignMaxAttempts();<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    LOG.info("Retry={} of max={}; {}; {}", retries, maxAttempts, this, regionNode.toShortString());<a name="line.237"></a>
+<span class="sourceLineNo">238</span><a name="line.238"></a>
+<span class="sourceLineNo">239</span>    if (retries &gt;= maxAttempts) {<a name="line.239"></a>
+<span class="sourceLineNo">240</span>      env.getAssignmentManager().regionFailedOpen(regionNode, true);<a name="line.240"></a>
+<span class="sourceLineNo">241</span>      setFailure(getClass().getSimpleName(), new RetriesExhaustedException(<a name="line.241"></a>
+<span class="sourceLineNo">242</span>        "Max attempts " + env.getAssignmentManager().getAssignMaxAttempts() + " exceeded"));<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      regionNode.unsetProcedure(this);<a name="line.243"></a>
+<span class="sourceLineNo">244</span>      return Flow.NO_MORE_STATE;<a name="line.244"></a>
+<span class="sourceLineNo">245</span>    }<a name="line.245"></a>
+<span class="sourceLineNo">246</span><a name="line.246"></a>
+<span class="sourceLineNo">247</span>    env.getAssignmentManager().regionFailedOpen(regionNode, false);<a name="line.247"></a>
+<span class="sourceLineNo">248</span>    // we failed to assign the region, force a new plan<a name="line.248"></a>
+<span class="sourceLineNo">249</span>    forceNewPlan = true;<a name="line.249"></a>
+<span class="sourceLineNo">250</span>    regionNode.setRegionLocation(null);<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.251"></a>
+<span class="sourceLineNo">252</span><a name="line.252"></a>
+<span class="sourceLineNo">253</span>    if (retries &gt; env.getAssignmentManager().getAssignRetryImmediatelyMaxAttempts()) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>      // Throw exception to backoff and retry when failed open too many times<a name="line.254"></a>
+<span class="sourceLineNo">255</span>      throw new HBaseIOException("Failed confirm OPEN of " + regionNode +<a name="line.255"></a>
+<span class="sourceLineNo">256</span>          " (remote log may yield more detail on why).");<a name="line.256"></a>
+<span class="sourceLineNo">257</span>    } else {<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      // Here we do not throw exception because we want to the region to be online ASAP<a name="line.258"></a>
+<span class="sourceLineNo">259</span>      return Flow.HAS_MORE_STATE;<a name="line.259"></a>
+<span class="sourceLineNo">260</span>    }<a name="line.260"></a>
+<span class="sourceLineNo">261</span>  }<a name="line.261"></a>
+<span class="sourceLineNo">262</span><a name="line.262"></a>
+<span class="sourceLineNo">263</span>  private void closeRegion(MasterProcedureEnv env, RegionStateNode regionNode) throws IOException {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>    if (regionNode.isInState(State.OPEN, State.CLOSING, State.MERGING, State.SPLITTING)) {<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      // this is the normal case<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      env.getAssignmentManager().regionClosing(regionNode);<a name="line.266"></a>
+<span class="sourceLineNo">267</span>      addChildProcedure(new CloseRegionProcedure(this, getRegion(), regionNode.getRegionLocation(),<a name="line.267"></a>
+<span class="sourceLineNo">268</span>        assignCandidate));<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>    } else {<a name="line.270"></a>
+<span class="sourceLineNo">271</span>      forceNewPlan = true;<a name="line.271"></a>
+<span class="sourceLineNo">272</span>      regionNode.setRegionLocation(null);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.273"></a>
+<span class="sourceLineNo">274</span>    }<a name="line.274"></a>
+<span class="sourceLineNo">275</span>  }<a name="line.275"></a>
+<span class="sourceLineNo">276</span><a name="line.276"></a>
+<span class="sourceLineNo">277</span>  private Flow confirmClosed(MasterProcedureEnv env, RegionStateNode regionNode)<a name="line.277"></a>
+<span class="sourceLineNo">278</span>      throws IOException {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>    if (regionNode.isInState(State.CLOSED)) {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>      retryCounter = null;<a name="line.280"></a>
+<span class="sourceLineNo">281</span>      if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.281"></a>
+<span class="sourceLineNo">282</span>        // we are the last state, finish<a name="line.282"></a>
+<span class="sourceLineNo">283</span>        regionNode.unsetProcedure(this);<a name="line.283"></a>
+<span class="sourceLineNo">284</span>        return Flow.NO_MORE_STATE;<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      }<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      // This means we need to open the region again, should be a move or reopen<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      return Flow.HAS_MORE_STATE;<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    }<a name="line.289"></a>
+<span class="sourceLineNo">290</span>    if (regionNode.isInState(State.CLOSING)) {<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      // This is possible, think the target RS crashes and restarts immediately, the close region<a name="line.291"></a>
+<span class="sourceLineNo">292</span>      // operation will return a NotServingRegionException soon, we can only recover after SCP takes<a name="line.292"></a>
+<span class="sourceLineNo">293</span>      // care of this RS. So here we throw an IOException to let upper layer to retry with backoff.<a name="line.293"></a>
+<span class="sourceLineNo">294</span>      setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_CLOSE);<a name="line.294"></a>
+<span class="sourceLineNo">295</span>      throw new HBaseIOException("Failed to close region");<a name="line.295"></a>
+<span class="sourceLineNo">296</span>    }<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    // abnormally closed, need to reopen it, no matter what is the last state, see the comment in<a name="line.297"></a>
+<span class="sourceLineNo">298</span>    // confirmOpened for more details that why we need to reopen the region first even if we just<a name="line.298"></a>
+<span class="sourceLineNo">299</span>    // want to close it.<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    // The only exception is for non-default replica, where we do not need to deal with recovered<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    // edits. Notice that the region will remain in ABNORMALLY_CLOSED state, the upper layer need to<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    // deal with this state. For non-default replica, this is usually the same with CLOSED.<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    assert regionNode.isInState(State.ABNORMALLY_CLOSED);<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    if (!RegionReplicaUtil.isDefaultReplica(getRegion()) &amp;&amp;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>      lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      regionNode.unsetProcedure(this);<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      return Flow.NO_MORE_STATE;<a name="line.307"></a>
+<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
+<span class="sourceLineNo">309</span>    retryCounter = null;<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    setNextState(RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    return Flow.HAS_MORE_STATE;<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  }<a name="line.312"></a>
+<span class="sourceLineNo">313</span><a name="line.313"></a>
+<span class="sourceLineNo">314</span>  // Override to lock RegionStateNode<a name="line.314"></a>
+<span class="sourceLineNo">315</span>  @SuppressWarnings("rawtypes")<a name="line.315"></a>
+<span class="sourceLineNo">316</span>  @Override<a name="line.316"></a>
+<span class="sourceLineNo">317</span>  protected Procedure[] execute(MasterProcedureEnv env)<a name="line.317"></a>
+<span class="sourceLineNo">318</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    RegionStateNode regionNode =<a name="line.319"></a>
+<span class="sourceLineNo">320</span>      env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    regionNode.lock();<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    try {<a name="line.322"></a>
+<span class="sourceLineNo">323</span>      return super.execute(env);<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    } finally {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      regionNode.unlock();<a name="line.325"></a>
+<span class="sourceLineNo">326</span>    }<a name="line.326"></a>
+<span class="sourceLineNo">327</span>  }<a name="line.327"></a>
+<span class="sourceLineNo">328</span><a name="line.328"></a>
+<span class="sourceLineNo">329</span>  private RegionStateNode getRegionStateNode(MasterProcedureEnv env) {<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    return env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(getRegion());<a name="line.330"></a>
+<span class="sourceLineNo">331</span>  }<a name="line.331"></a>
+<span class="sourceLineNo">332</span><a name="line.332"></a>
+<span class="sourceLineNo">333</span>  @Override<a name="line.333"></a>
+<span class="sourceLineNo">334</span>  protected Flow executeFromState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    RegionStateNode regionNode = getRegionStateNode(env);<a name="line.336"></a>
+<span class="sourceLineNo">337</span>    try {<a name="line.337"></a>
+<span class="sourceLineNo">338</span>      switch (state) {<a name="line.338"></a>
+<span class="sourceLineNo">339</span>        case REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE:<a name="line.339"></a>
+<span class="sourceLineNo">340</span>          // Need to do some sanity check for replica region, if the region does not exist at<a name="line.340"></a>
+<span class="sourceLineNo">341</span>          // master, do not try to assign the replica region, log error and return.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>          if (!RegionReplicaUtil.isDefaultReplica(regionNode.getRegionInfo())) {<a name="line.342"></a>
+<span class="sourceLineNo">343</span>            RegionInfo defaultRI =<a name="line.343"></a>
+<span class="sourceLineNo">344</span>              RegionReplicaUtil.getRegionInfoForDefaultReplica(regionNode.getRegionInfo());<a name="line.344"></a>
+<span class="sourceLineNo">345</span>            if (env.getMasterServices().getAssignmentManager().getRegionStates().<a name="line.345"></a>
+<span class="sourceLineNo">346</span>              getRegionStateNode(defaultRI) == null) {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>              LOG.error(<a name="line.347"></a>
+<span class="sourceLineNo">348</span>                "Cannot assign replica region {} because its primary region {} does not exist.",<a name="line.348"></a>
+<span class="sourceLineNo">349</span>                regionNode.getRegionInfo(), defaultRI);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>              regionNode.unsetProcedure(this);<a name="line.350"></a>
+<span class="sourceLineNo">351</span>              return Flow.NO_MORE_STATE;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>            }<a name="line.352"></a>
+<span class="sourceLineNo">353</span>          }<a name="line.353"></a>
+<span class="sourceLineNo">354</span>          queueAssign(env, regionNode);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>          return Flow.HAS_MORE_STATE;<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        case REGION_STATE_TRANSITION_OPEN:<a name="line.356"></a>
+<span class="sourceLineNo">357</span>          openRegion(env, regionNode);<a name="line.357"></a>
+<span class="sourceLineNo">358</span>          return Flow.HAS_MORE_STATE;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>        case REGION_STATE_TRANSITION_CONFIRM_OPENED:<a name="line.359"></a>
+<span class="sourceLineNo">360</span>          return confirmOpened(env, regionNode);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        case REGION_STATE_TRANSITION_CLOSE:<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          closeRegion(env, regionNode);<a name="line.362"></a>
+<span class="sourceLineNo">363</span>          return Flow.HAS_MORE_STATE;<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        case REGION_STATE_TRANSITION_CONFIRM_CLOSED:<a name="line.364"></a>
+<span class="sourceLineNo">365</span>          return confirmClosed(env, regionNode);<a name="line.365"></a>
+<span class="sourceLineNo">366</span>        default:<a name="line.366"></a>
+<span class="sourceLineNo">367</span>          throw new UnsupportedOperationException("unhandled state=" + state);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>      }<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    } catch (IOException e) {<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      if (retryCounter == null) {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        retryCounter = ProcedureUtil.createRetryCounter(env.getMasterConfiguration());<a name="line.371"></a>
+<span class="sourceLineNo">372</span>      }<a name="line.372"></a>
+<span class="sourceLineNo">373</span>      long backoff = retryCounter.getBackoffTimeAndIncrementAttempts();<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      LOG.warn(<a name="line.374"></a>
+<span class="sourceLineNo">375</span>        "Failed transition, suspend {}secs {}; {}; waiting on rectified condition fixed " +<a name="line.375"></a>
+<span class="sourceLineNo">376</span>          "by other Procedure or operator intervention",<a name="line.376"></a>
+<span class="sourceLineNo">377</span>        backoff / 1000, this, regionNode.toShortString(), e);<a name="line.377"></a>
+<span class="sourceLineNo">378</span>      setTimeout(Math.toIntExact(backoff));<a name="line.378"></a>
+<span class="sourceLineNo">379</span>      setState(ProcedureProtos.ProcedureState.WAITING_TIMEOUT);<a name="line.379"></a>
+<span class="sourceLineNo">380</span>      skipPersistence();<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      throw new ProcedureSuspendedException();<a name="line.381"></a>
+<span class="sourceLineNo">382</span>    }<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  }<a name="line.383"></a>
+<span class="sourceLineNo">384</span><a name="line.384"></a>
+<span class="sourceLineNo">385</span>  /**<a name="line.385"></a>
+<span class="sourceLineNo">386</span>   * At end of timeout, wake ourselves up so we run again.<a name="line.386"></a>
+<span class="sourceLineNo">387</span>   */<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  @Override<a name="line.388"></a>
+<span class="sourceLineNo">389</span>  protected synchronized boolean setTimeoutFailure(MasterProcedureEnv env) {<a name="line.389"></a>
+<span class="sourceLineNo">390</span>    setState(ProcedureProtos.ProcedureState.RUNNABLE);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>    env.getProcedureScheduler().addFront(this);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    return false; // 'false' means that this procedure handled the timeout<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  }<a name="line.393"></a>
+<span class="sourceLineNo">394</span><a name="line.394"></a>
+<span class="sourceLineNo">395</span>  // Should be called with RegionStateNode locked<a name="line.395"></a>
+<span class="sourceLineNo">396</span>  public void reportTransition(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      ServerName serverName, TransitionCode code, long seqId, long procId) throws IOException {<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    if (remoteProc == null) {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      LOG.warn(<a name="line.399"></a>
+<span class="sourceLineNo">400</span>        "There is no outstanding remote region procedure for {}, serverName={}, code={}," +<a name="line.400"></a>
+<span class="sourceLineNo">401</span>          " seqId={}, proc={}, should be a retry, ignore",<a name="line.401"></a>
+<span class="sourceLineNo">402</span>        regionNode, serverName, code, seqId, this);<a name="line.402"></a>
+<span class="sourceLineNo">403</span>      return;<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    }<a name="line.404"></a>
+<span class="sourceLineNo">405</span>    // The procId could be -1 if it is from an old region server, we need to deal with it so that we<a name="line.405"></a>
+<span class="sourceLineNo">406</span>    // can do rolling upgraing.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    if (procId &gt;= 0 &amp;&amp; remoteProc.getProcId() != procId) {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      LOG.warn(<a name="line.408"></a>
+<span class="sourceLineNo">409</span>        "The pid of remote region procedure for {} is {}, the reported pid={}, serverName={}," +<a name="line.409"></a>
+<span class="sourceLineNo">410</span>          " code={}, seqId={}, proc={}, should be a retry, ignore",<a name="line.410"></a>
+<span class="sourceLineNo">411</span>        regionNode, remoteProc.getProcId(), procId, serverName, code, seqId, this);<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      return;<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    }<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    remoteProc.reportTransition(env, regionNode, serverName, code, seqId);<a name="line.414"></a>
+<span class="sourceLineNo">415</span>  }<a name="line.415"></a>
+<span class="sourceLineNo">416</span><a name="line.416"></a>
+<span class="sourceLineNo">417</span>  // Should be called with RegionStateNode locked<a name="line.417"></a>
+<span class="sourceLineNo">418</span>  public void serverCrashed(MasterProcedureEnv env, RegionStateNode regionNode,<a name="line.418"></a>
+<span class="sourceLineNo">419</span>      ServerName serverName, boolean forceNewPlan) throws IOException {<a name="line.419"></a>
+<span class="sourceLineNo">420</span>    this.forceNewPlan = forceNewPlan;<a name="line.420"></a>
+<span class="sourceLineNo">421</span>    if (remoteProc != null) {<a name="line.421"></a>
+<span class="sourceLineNo">422</span>      // this means we are waiting for the sub procedure, so wake it up<a name="line.422"></a>
+<span class="sourceLineNo">423</span>      remoteProc.serverCrashed(env, regionNode, serverName);<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    } else {<a name="line.424"></a>
+<span class="sourceLineNo">425</span>      // we are in RUNNING state, just update the region state, and we will process it later.<a name="line.425"></a>
+<span class="sourceLineNo">426</span>      env.getAssignmentManager().regionClosedAbnormally(regionNode);<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    }<a name="line.427"></a>
+<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
+<span class="sourceLineNo">429</span><a name="line.429"></a>
+<span class="sourceLineNo">430</span>  void attachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>    this.remoteProc = proc;<a name="line.431"></a>
+<span class="sourceLineNo">432</span>  }<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>  void unattachRemoteProc(RegionRemoteProcedureBase proc) {<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    assert this.remoteProc == proc;<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    this.remoteProc = null;<a name="line.436"></a>
+<span class="sourceLineNo">437</span>  }<a name="line.437"></a>
+<span class="sourceLineNo">438</span><a name="line.438"></a>
+<span class="sourceLineNo">439</span>  // will be called after we finish loading the meta entry for this region.<a name="line.439"></a>
+<span class="sourceLineNo">440</span>  // used to change the state of the region node if we have a sub procedure, as we may not persist<a name="line.440"></a>
+<span class="sourceLineNo">441</span>  // the state to meta yet. See the code in RegionRemoteProcedureBase.execute for more details.<a name="line.441"></a>
+<span class="sourceLineNo">442</span>  void stateLoaded(AssignmentManager am, RegionStateNode regionNode) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    if (remoteProc != null) {<a name="line.443"></a>
+<span class="sourceLineNo">444</span>      remoteProc.stateLoaded(am, regionNode);<a name="line.444"></a>
+<span class="sourceLineNo">445</span>    }<a name="line.445"></a>
+<span class="sourceLineNo">446</span>  }<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>  @Override<a name="line.448"></a>
+<span class="sourceLineNo">449</span>  protected void rollbackState(MasterProcedureEnv env, RegionStateTransitionState state)<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      throws IOException, InterruptedException {<a name="line.450"></a>
+<span class="sourceLineNo">451</span>    // no rollback<a name="line.451"></a>
+<span class="sourceLineNo">452</span>    throw new UnsupportedOperationException();<a name="line.452"></a>
+<span class="sourceLineNo">453</span>  }<a name="line.453"></a>
+<span class="sourceLineNo">454</span><a name="line.454"></a>
+<span class="sourceLineNo">455</span>  @Override<a name="line.455"></a>
+<span class="sourceLineNo">456</span>  protected RegionStateTransitionState getState(int stateId) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>    return RegionStateTransitionState.forNumber(stateId);<a name="line.457"></a>
+<span class="sourceLineNo">458</span>  }<a name="line.458"></a>
+<span class="sourceLineNo">459</span><a name="line.459"></a>
+<span class="sourceLineNo">460</span>  @Override<a name="line.460"></a>
+<span class="sourceLineNo">461</span>  protected int getStateId(RegionStateTransitionState state) {<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    return state.getNumber();<a name="line.462"></a>
+<span class="sourceLineNo">463</span>  }<a name="line.463"></a>
+<span class="sourceLineNo">464</span><a name="line.464"></a>
+<span class="sourceLineNo">465</span>  @Override<a name="line.465"></a>
+<span class="sourceLineNo">466</span>  protected RegionStateTransitionState getInitialState() {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    return initialState;<a name="line.467"></a>
+<span class="sourceLineNo">468</span>  }<a name="line.468"></a>
+<span class="sourceLineNo">469</span><a name="line.469"></a>
+<span class="sourceLineNo">470</span>  private static TransitionType convert(RegionTransitionType type) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>    switch (type) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>      case ASSIGN:<a name="line.472"></a>
+<span class="sourceLineNo">473</span>        return TransitionType.ASSIGN;<a name="line.473"></a>
+<span class="sourceLineNo">474</span>      case UNASSIGN:<a name="line.474"></a>
+<span class="sourceLineNo">475</span>        return TransitionType.UNASSIGN;<a name="line.475"></a>
+<span class="sourceLineNo">476</span>      case MOVE:<a name="line.476"></a>
+<span class="sourceLineNo">477</span>        return TransitionType.MOVE;<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      case REOPEN:<a name="line.478"></a>
+<span class="sourceLineNo">479</span>        return TransitionType.REOPEN;<a name="line.479"></a>
+<span class="sourceLineNo">480</span>      default:<a name="line.480"></a>
+<span class="sourceLineNo">481</span>        throw new IllegalArgumentException("Unknown RegionTransitionType: " + type);<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    }<a name="line.482"></a>
+<span class="sourceLineNo">483</span>  }<a name="line.483"></a>
+<span class="sourceLineNo">484</span><a name="line.484"></a>
+<span class="sourceLineNo">485</span>  private static RegionTransitionType convert(TransitionType type) {<a name="line.485"></a>
+<span class="sourceLineNo">486</span>    switch (type) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>      case ASSIGN:<a name="line.487"></a>
+<span class="sourceLineNo">488</span>        return RegionTransitionType.ASSIGN;<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      case UNASSIGN:<a name="line.489"></a>
+<span class="sourceLineNo">490</span>        return RegionTransitionType.UNASSIGN;<a name="line.490"></a>
+<span class="sourceLineNo">491</span>      case MOVE:<a name="line.491"></a>
+<span class="sourceLineNo">492</span>        return RegionTransitionType.MOVE;<a name="line.492"></a>
+<span class="sourceLineNo">493</span>      case REOPEN:<a name="line.493"></a>
+<span class="sourceLineNo">494</span>        return RegionTransitionType.REOPEN;<a name="line.494"></a>
+<span class="sourceLineNo">495</span>      default:<a name="line.495"></a>
+<span class="sourceLineNo">496</span>        throw new IllegalArgumentException("Unknown TransitionType: " + type);<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    }<a name="line.497"></a>
+<span class="sourceLineNo">498</span>  }<a name="line.498"></a>
+<span class="sourceLineNo">499</span><a name="line.499"></a>
+<span class="sourceLineNo">500</span>  @Override<a name="line.500"></a>
+<span class="sourceLineNo">501</span>  protected void serializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.501"></a>
+<span class="sourceLineNo">502</span>    super.serializeStateData(serializer);<a name="line.502"></a>
+<span class="sourceLineNo">503</span>    RegionStateTransitionStateData.Builder builder = RegionStateTransitionStateData.newBuilder()<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      .setType(convert(type)).setForceNewPlan(forceNewPlan);<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    if (assignCandidate != null) {<a name="line.505"></a>
+<span class="sourceLineNo">506</span>      builder.setAssignCandidate(ProtobufUtil.toServerName(assignCandidate));<a name="line.506"></a>
+<span class="sourceLineNo">507</span>    }<a name="line.507"></a>
+<span class="sourceLineNo">508</span>    serializer.serialize(builder.build());<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  }<a name="line.509"></a>
+<span class="sourceLineNo">510</span><a name="line.510"></a>
+<span class="sourceLineNo">511</span>  @Override<a name="line.511"></a>
+<span class="sourceLineNo">512</span>  protected void deserializeStateData(ProcedureStateSerializer serializer) throws IOException {<a name="line.512"></a>
+<span class="sourceLineNo">513</span>    super.deserializeStateData(serializer);<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    RegionStateTransitionStateData data =<a name="line.514"></a>
+<span class="sourceLineNo">515</span>      serializer.deserialize(RegionStateTransitionStateData.class);<a name="line.515"></a>
+<span class="sourceLineNo">516</span>    type = convert(data.getType());<a name="line.516"></a>
+<span class="sourceLineNo">517</span>    setInitialAndLastState();<a name="line.517"></a>
+<span class="sourceLineNo">518</span>    forceNewPlan = data.getForceNewPlan();<a name="line.518"></a>
+<span class="sourceLineNo">519</span>    if (data.hasAssignCandidate()) {<a name="line.519"></a>
+<span class="sourceLineNo">520</span>      assignCandidate = ProtobufUtil.toServerName(data.getAssignCandidate());<a name="line.520"></a>
+<span class="sourceLineNo">521</span>    }<a name="line.521"></a>
+<span class="sourceLineNo">522</span>  }<a name="line.522"></a>
+<span class="sourceLineNo">523</span><a name="line.523"></a>
+<span class="sourceLineNo">524</span>  @Override<a name="line.524"></a>
+<span class="sourceLineNo">525</span>  protected ProcedureMetrics getProcedureMetrics(MasterProcedureEnv env) {<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    MetricsAssignmentManager metrics = env.getAssignmentManager().getAssignmentManagerMetrics();<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    switch (type) {<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      case ASSIGN:<a name="line.528"></a>
+<span class="sourceLineNo">529</span>        return metrics.getAssignProcMetrics();<a name="line.529"></a>
+<span class="sourceLineNo">530</span>      case UNASSIGN:<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        return metrics.getUnassignProcMetrics();<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      case MOVE:<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        return metrics.getMoveProcMetrics();<a name="line.533"></a>
+<span class="sourceLineNo">534</span>      case REOPEN:<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        return metrics.getReopenProcMetrics();<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      default:<a name="line.536"></a>
+<span class="sourceLineNo">537</span>        throw new IllegalArgumentException("Unknown transition type: " + type);<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
+<span class="sourceLineNo">540</span><a name="line.540"></a>
+<span class="sourceLineNo">541</span>  @Override<a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public void toStringClassDetails(StringBuilder sb) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    super.toStringClassDetails(sb);<a name="line.543"></a>
+<span class="sourceLineNo">544</span>    if (initialState == RegionStateTransitionState.REGION_STATE_TRANSITION_GET_ASSIGN_CANDIDATE) {<a name="line.544"></a>
+<span class="sourceLineNo">545</span>      sb.append(", ASSIGN");<a name="line.545"></a>
+<span class="sourceLineNo">546</span>    } else if (lastState == RegionStateTransitionState.REGION_STATE_TRANSITION_CONFIRM_CLOSED) {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>      sb.append(", UNASSIGN");<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    } else {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      sb.append(", REOPEN/MOVE");<a name="line.549"></a>
+<span class="sourceLineNo">550</span>    }<a name="line.550"></a>
+<span class="sourceLineNo">551</span>  }<a name="line.551"></a>
+<span class="sourceLineNo">552</span><a name="line.552"></a>
+<span class="sourceLineNo">553</span>  private static TransitRegionStateProcedure setOwner(MasterProcedureEnv env,<a name="line.553"></a>
+<span class="sourceLineNo">554</span>      TransitRegionStateProcedure proc) {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>    proc.setOwner(env.getRequestUser().getShortName());<a name="line.555"></a>
+<span class="sourceLineNo">556</span>    return proc;<a name="line.556"></a>
+<span class="sourceLineNo">557</span>  }<a name="line.557"></a>
+<span class="sourceLineNo">558</span><a name="line.558"></a>
+<span class="sourceLineNo">559</span>  public enum TransitionType {<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    ASSIGN, UNASSIGN, MOVE, REOPEN<a name="line.560"></a>
+<span class="sourceLineNo">561</span>  }<a name="line.561"></a>
+<span class="sourceLineNo">562</span><a name="line.562"></a>
+<span class="sourceLineNo">563</span>  // Be careful that, when you call these 4 methods below, you need to manually attach the returned<a name="line.563"></a>
+<span class="sourceLineNo">564</span>  // procedure with the RegionStateNode, otherwise the procedure will quit immediately without doing<a name="line.564"></a>
+<span class="sourceLineNo">565</span>  // anything. See the comment in executeFromState to find out why we need this assumption.<a name="line.565"></a>
+<span class="sourceLineNo">566</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.566"></a>
+<span class="sourceLineNo">567</span>      @Nullable ServerName targetServer) {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return assign(env, region, false, targetServer);<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  public static TransitRegionStateProcedure assign(MasterProcedureEnv env, RegionInfo region,<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      boolean forceNewPlan, @Nullable ServerName targetServer) {<a name="line.572"></a>
+<span class="sourceLineNo">573</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer, forceNewPlan,<a name="line.573"></a>
+<span class="sourceLineNo">574</span>        TransitionType.ASSIGN));<a name="line.574"></a>
+<span class="sourceLineNo">575</span>  }<a name="line.575"></a>
+<span class="sourceLineNo">576</span><a name="line.576"></a>
+<span class="sourceLineNo">577</span>  public static TransitRegionStateProcedure unassign(MasterProcedureEnv env, RegionInfo region) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    return setOwner(env,<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.UNASSIGN));<a name="line.579"></a>
+<span class="sourceLineNo">580</span>  }<a name="line.580"></a>
+<span class="sourceLineNo">581</span><a name="line.581"></a>
+<span class="sourceLineNo">582</span>  public static TransitRegionStateProcedure reopen(MasterProcedureEnv env, RegionInfo region) {<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return setOwner(env,<a name="line.583"></a>
+<span class="sourceLineNo">584</span>      new TransitRegionStateProcedure(env, region, null, false, TransitionType.REOPEN));<a name="line.584"></a>
+<span class="sourceLineNo">585</span>  }<a name="line.585"></a>
+<span class="sourceLineNo">586</span><a name="line.586"></a>
+<span class="sourceLineNo">587</span>  public static TransitRegionStateProcedure move(MasterProcedureEnv env, RegionInfo region,<a name="line.587"></a>
+<span class="sourceLineNo">588</span>      @Nullable ServerName targetServer) {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>    return setOwner(env, new TransitRegionStateProcedure(env, region, targetServer,<a name="line.589"></a>
+<span class="sourceLineNo">590</span>      targetServer == null, TransitionType.MOVE));<a name="line.590"></a>
+<span class="sourceLineNo">591</span>  }<a name="line.591"></a>
+<span class="sourceLineNo">592</span>}<a name="line.592"></a>
 
 
 
diff --git a/downloads.html b/downloads.html
index 9226f11..443ed97 100644
--- a/downloads.html
+++ b/downloads.html
@@ -395,7 +395,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/export_control.html b/export_control.html
index 1b5abaa..d02fb67 100644
--- a/export_control.html
+++ b/export_control.html
@@ -185,7 +185,7 @@ for more details.</p>
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/index.html b/index.html
index defc722..4a94ffc 100644
--- a/index.html
+++ b/index.html
@@ -263,7 +263,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/issue-management.html b/issue-management.html
index 3e871d6..e31d564 100644
--- a/issue-management.html
+++ b/issue-management.html
@@ -157,7 +157,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/licenses.html b/licenses.html
index 0d3d9d0..726f34e 100644
--- a/licenses.html
+++ b/licenses.html
@@ -360,7 +360,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/mailing-lists.html b/mailing-lists.html
index bcd271a..fd57a3e 100644
--- a/mailing-lists.html
+++ b/mailing-lists.html
@@ -203,7 +203,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/metrics.html b/metrics.html
index a12521d..4fa2f9d 100644
--- a/metrics.html
+++ b/metrics.html
@@ -313,7 +313,7 @@ export HBASE_REGIONSERVER_OPTS=&quot;$HBASE_JMX_OPTS -Dcom.sun.management.jmxrem
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/old_news.html b/old_news.html
index af13844..4026080 100644
--- a/old_news.html
+++ b/old_news.html
@@ -304,7 +304,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/plugin-management.html b/plugin-management.html
index 0122976..0e154c7 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -309,7 +309,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/plugins.html b/plugins.html
index 9ae466b..1f2680d 100644
--- a/plugins.html
+++ b/plugins.html
@@ -240,7 +240,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/poweredbyhbase.html b/poweredbyhbase.html
index cdf242c..6a03cd6 100644
--- a/poweredbyhbase.html
+++ b/poweredbyhbase.html
@@ -638,7 +638,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/project-info.html b/project-info.html
index 57c464e..642561b 100644
--- a/project-info.html
+++ b/project-info.html
@@ -201,7 +201,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/project-reports.html b/project-reports.html
index e7dc879..322abd5 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -174,7 +174,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/pseudo-distributed.html b/pseudo-distributed.html
index 6498003..bcc6646 100644
--- a/pseudo-distributed.html
+++ b/pseudo-distributed.html
@@ -162,7 +162,7 @@ Running Apache HBase (TM) in pseudo-distributed mode
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/replication.html b/replication.html
index cb37b3a..4d131cb 100644
--- a/replication.html
+++ b/replication.html
@@ -157,7 +157,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/resources.html b/resources.html
index 2dd02d3..22a06c8 100644
--- a/resources.html
+++ b/resources.html
@@ -185,7 +185,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/scm.html b/scm.html
index 0e7245b..d2f8bba 100644
--- a/scm.html
+++ b/scm.html
@@ -168,7 +168,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/sponsors.html b/sponsors.html
index 5e44b11..eae6ec7 100644
--- a/sponsors.html
+++ b/sponsors.html
@@ -187,7 +187,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/summary.html b/summary.html
index f43d3ba..b082d96 100644
--- a/summary.html
+++ b/summary.html
@@ -200,7 +200,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/supportingprojects.html b/supportingprojects.html
index 0d8225d..c16f9a5 100644
--- a/supportingprojects.html
+++ b/supportingprojects.html
@@ -378,7 +378,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/team.html b/team.html
index 1398f7e..c5af60d 100644
--- a/team.html
+++ b/team.html
@@ -749,7 +749,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-28</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-03-30</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/testdevapidocs/index-all.html b/testdevapidocs/index-all.html
index 94c2b62..7833911 100644
--- a/testdevapidocs/index-all.html
+++ b/testdevapidocs/index-all.html
@@ -55345,6 +55345,14 @@
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems(String, String, TestHFileArchiving.ArchivingFunction&lt;Configuration, FileSystem, RegionInfo, Path, byte[], Collection&lt;HStoreFile&gt;&gt;)</a></span> - Method in class org.apache.hadoop.hbase.backup.<a h [...]
 <dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-boolean-boolean-boolean-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems(String, String, boolean, boolean, boolean, TestHFileArchiving.ArchivingFunction&lt;Configuration, FileSystem, RegionInfo, Path, byte[], Collection&lt;HStoreFile&gt;&gt;)</a></span> -  [...]
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent--">testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent()</a></span> - Method in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html" title="class in org.apache.hadoop.hbase.backup">TestHFileArchiving</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch--">testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch()</a></span> - Method in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html" title="class in org.apache.hadoop.hbase.backup">TestHFileArchiving</a></dt>
+<dd>&nbsp;</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived--">testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived()</a></span> - Method in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html" title="class in org.apache.hadoop.hbase.backup">TestHFileArchiving</a></dt>
+<dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsWallAndRootSame--">testArchiveStoreFilesDifferentFileSystemsWallAndRootSame()</a></span> - Method in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html" title="class in org.apache.hadoop.hbase.backup">TestHFileArchiving</a></dt>
 <dd>&nbsp;</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot--">testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot()</a></span> - Method in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestHFileArchiving.html" title="class in org.apache.hadoop.hbase.backup">TestHFileArchiving</a></dt>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html b/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
index a81998e..36213fc 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
@@ -110,7 +110,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html?is-external=true" title="class or interface in java.lang">@FunctionalInterface</a>
-private static interface <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.196">TestHFileArchiving.ArchivingFunction</a>&lt;Configuration,FS,Region,Dir,Family,Files&gt;</pre>
+private static interface <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.255">TestHFileArchiving.ArchivingFunction</a>&lt;Configuration,FS,Region,Dir,Family,Files&gt;</pre>
 </li>
 </ul>
 </div>
@@ -161,7 +161,7 @@ private static interface <a href="../../../../../src-html/org/apache/hadoop/hbas
 <ul class="blockListLast">
 <li class="blockList">
 <h4>apply</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html#line.197">apply</a>(<a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="type parameter in TestHFileArchiving.ArchivingFunction">Configuration</a>&nbsp;config,
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html#line.256">apply</a>(<a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="type parameter in TestHFileArchiving.ArchivingFunction">Configuration</a>&nbsp;config,
            <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="type parameter in TestHFileArchiving.ArchivingFunction">FS</a>&nbsp;fs,
            <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="type parameter in TestHFileArchiving.ArchivingFunction">Region</a>&nbsp;region,
            <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="type parameter in TestHFileArchiving.ArchivingFunction">Dir</a>&nbsp;dir,
diff --git a/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.html b/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.html
index b482df9..b778afa 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/backup/TestHFileArchiving.html
@@ -18,7 +18,7 @@
     catch(err) {
     }
 //-->
-var methods = {"i0":10,"i1":9,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":9,"i8":9,"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};
+var methods = {"i0":10,"i1":9,"i2":10,"i3":10,"i4":10,"i5":10,"i6":10,"i7":9,"i8":9,"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};
 var tabs = {65535:["t0","All Methods"],1:["t1","Static Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
 var altColor = "altColor";
 var rowColor = "rowColor";
@@ -109,7 +109,7 @@ var activeTableTab = "activeTableTab";
 <li class="blockList">
 <hr>
 <br>
-<pre>public class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.89">TestHFileArchiving</a>
+<pre>public class <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.91">TestHFileArchiving</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>
 <div class="block">Test that the <code>HFileArchiver</code> correctly removes all the parts of a region when cleaning up
  a region</div>
@@ -312,36 +312,57 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </tr>
 <tr id="i22" class="altColor">
 <td class="colFirst"><code>private void</code></td>
-<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems</a></span>(<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;walDir,
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-boolean-boolean-boolean-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems</a></span>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">Stri [...]
                                          <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;expectedBase,
+                                         boolean&nbsp;archiveFileExists,
+                                         boolean&nbsp;sourceFileExists,
+                                         boolean&nbsp;archiveFileDifferentLength,
                                          <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or in [...]
 </tr>
 <tr id="i23" class="rowColor">
+<td class="colFirst"><code>private void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems</a></span>(<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;walDir,
+                                         <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;expectedBase,
+                                         <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or in [...]
+</tr>
+<tr id="i24" class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent--">testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i25" class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch--">testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i26" class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived--">testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived</a></span>()</code>&nbsp;</td>
+</tr>
+<tr id="i27" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsWallAndRootSame--">testArchiveStoreFilesDifferentFileSystemsWallAndRootSame</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i24" class="altColor">
+<tr id="i28" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot--">testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i25" class="rowColor">
+<tr id="i29" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot--">testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot</a></span>()</code>&nbsp;</td>
 </tr>
-<tr id="i26" class="altColor">
+<tr id="i30" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testCleaningRace--">testCleaningRace</a></span>()</code>
 <div class="block">Test HFileArchiver.resolveAndArchive() race condition HBASE-7643</div>
 </td>
 </tr>
-<tr id="i27" class="rowColor">
+<tr id="i31" class="rowColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testDeleteRegionWithNoStoreFiles--">testDeleteRegionWithNoStoreFiles</a></span>()</code>
 <div class="block">Test that the region directory is removed when we archive a region without store files, but
  still has hidden files.</div>
 </td>
 </tr>
-<tr id="i28" class="altColor">
+<tr id="i32" class="altColor">
 <td class="colFirst"><code>void</code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testRemoveRegionDirOnArchive--">testRemoveRegionDirOnArchive</a></span>()</code>&nbsp;</td>
 </tr>
@@ -373,7 +394,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>CLASS_RULE</h4>
-<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.92">CLASS_RULE</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/HBaseClassTestRule.html" title="class in org.apache.hadoop.hbase">HBaseClassTestRule</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.94">CLASS_RULE</a></pre>
 </li>
 </ul>
 <a name="LOG">
@@ -382,7 +403,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.95">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.97">LOG</a></pre>
 </li>
 </ul>
 <a name="UTIL">
@@ -391,7 +412,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>UTIL</h4>
-<pre>private static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtil.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtil</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.96">UTIL</a></pre>
+<pre>private static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/HBaseTestingUtil.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtil</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.98">UTIL</a></pre>
 </li>
 </ul>
 <a name="TEST_FAM">
@@ -400,7 +421,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>TEST_FAM</h4>
-<pre>private static final&nbsp;byte[] <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.97">TEST_FAM</a></pre>
+<pre>private static final&nbsp;byte[] <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.99">TEST_FAM</a></pre>
 </li>
 </ul>
 <a name="POOL">
@@ -409,7 +430,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>POOL</h4>
-<pre>private static&nbsp;org.apache.hadoop.hbase.master.cleaner.DirScanPool <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.99">POOL</a></pre>
+<pre>private static&nbsp;org.apache.hadoop.hbase.master.cleaner.DirScanPool <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.101">POOL</a></pre>
 </li>
 </ul>
 <a name="name">
@@ -418,7 +439,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>name</h4>
-<pre>public&nbsp;org.junit.rules.TestName <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.101">name</a></pre>
+<pre>public&nbsp;org.junit.rules.TestName <a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.103">name</a></pre>
 </li>
 </ul>
 </li>
@@ -435,7 +456,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>TestHFileArchiving</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.89">TestHFileArchiving</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.91">TestHFileArchiving</a>()</pre>
 </li>
 </ul>
 </li>
@@ -452,7 +473,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setupCluster</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.107">setupCluster</a>()
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.109">setupCluster</a>()
                          throws <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></pre>
 <div class="block">Setup the config for the cluster</div>
 <dl>
@@ -467,7 +488,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>setupConf</h4>
-<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.117">setupConf</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
+<pre>private static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.119">setupConf</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 </li>
 </ul>
 <a name="tearDown--">
@@ -476,7 +497,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>tearDown</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.131">tearDown</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.133">tearDown</a>()
               throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -490,7 +511,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>cleanupTest</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.137">cleanupTest</a>()
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.139">cleanupTest</a>()
                         throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -504,7 +525,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.143">testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.145">testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot</a>()
                                                                       throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -518,7 +539,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.151">testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.153">testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot</a>()
                                                                 throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -532,7 +553,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveStoreFilesDifferentFileSystemsWallAndRootSame</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.158">testArchiveStoreFilesDifferentFileSystemsWallAndRootSame</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.160">testArchiveStoreFilesDifferentFileSystemsWallAndRootSame</a>()
                                                               throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -540,14 +561,75 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </dl>
 </li>
 </ul>
+<a name="testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.167">testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived</a>()
+                                                                  throws <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></pre>
+<dl>
+<dt><span class="throwsLabel">Throws:</span></dt>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+<a name="testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.174">testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent</a>()
+                                                                      throws <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></pre>
+<dl>
+<dt><span class="throwsLabel">Throws:</span></dt>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+<a name="testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch--">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch</h4>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.181">testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch</a>()
+                                                                  throws <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></pre>
+<dl>
+<dt><span class="throwsLabel">Throws:</span></dt>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
 <a name="testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">
 <!--   -->
 </a>
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveStoreFilesDifferentFileSystems</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.164">testArchiveStoreFilesDifferentFileSystems</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;walDir,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.187">testArchiveStoreFilesDifferentFileSystems</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;walDir,
+                                                       <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;expectedBase,
+                                                       <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" titl [...]
+                                                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>
+<dd><code><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></code></dd>
+</dl>
+</li>
+</ul>
+<a name="testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-boolean-boolean-boolean-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>testArchiveStoreFilesDifferentFileSystems</h4>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.194">testArchiveStoreFilesDifferentFileSystems</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;walDir,
                                                        <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;expectedBase,
+                                                       boolean&nbsp;archiveFileExists,
+                                                       boolean&nbsp;sourceFileExists,
+                                                       boolean&nbsp;archiveFileDifferentLength,
                                                        <a href="../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" titl [...]
                                                 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>
@@ -562,7 +644,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRecoveredEditsWalDirNull</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.202">testArchiveRecoveredEditsWalDirNull</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.261">testArchiveRecoveredEditsWalDirNull</a>()
                                          throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -576,7 +658,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRecoveredEditsWalDirSameFsStoreFiles</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.207">testArchiveRecoveredEditsWalDirSameFsStoreFiles</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.266">testArchiveRecoveredEditsWalDirSameFsStoreFiles</a>()
                                                      throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -590,7 +672,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRecoveredEditsWalDirNullOrSame</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.211">testArchiveRecoveredEditsWalDirNullOrSame</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;walDir)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.270">testArchiveRecoveredEditsWalDirNullOrSame</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;walDir)
                                                 throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -604,7 +686,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRecoveredEditsWrongFS</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.225">testArchiveRecoveredEditsWrongFS</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.284">testArchiveRecoveredEditsWrongFS</a>()
                                       throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -618,7 +700,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRecoveredEditsWalDirDifferentFS</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.236">testArchiveRecoveredEditsWalDirDifferentFS</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.295">testArchiveRecoveredEditsWalDirDifferentFS</a>()
                                                 throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -632,7 +714,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testRemoveRegionDirOnArchive</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.244">testRemoveRegionDirOnArchive</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.303">testRemoveRegionDirOnArchive</a>()
                                   throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -646,7 +728,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testDeleteRegionWithNoStoreFiles</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.303">testDeleteRegionWithNoStoreFiles</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.362">testDeleteRegionWithNoStoreFiles</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>
 <div class="block">Test that the region directory is removed when we archive a region without store files, but
  still has hidden files.</div>
@@ -663,7 +745,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>initTableForArchivingRegions</h4>
-<pre>private&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;org.apache.hadoop.hbase.regionserver.HRegion&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.350">initTableForArchivingRegions</a>(org.apache.hadoop.hbase.TableName&nbsp;tableName)
+<pre>private&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;org.apache.hadoop.hbase.regionserver.HRegion&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.409">initTableForArchivingRegions</a>(org.apache.hadoop.hbase.TableName&nbsp;tableName)
                                                                                  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>
@@ -677,7 +759,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.374">testArchiveRegions</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.433">testArchiveRegions</a>()
                         throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -691,7 +773,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRegionsWhenPermissionDenied</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.414">testArchiveRegionsWhenPermissionDenied</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.473">testArchiveRegionsWhenPermissionDenied</a>()
                                             throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -705,7 +787,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveOnTableDelete</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.445">testArchiveOnTableDelete</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.504">testArchiveOnTableDelete</a>()
                               throws <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></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -719,7 +801,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>assertArchiveFiles</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.488">assertArchiveFiles</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.547">assertArchiveFiles</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                                 <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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;storeFiles,
                                 long&nbsp;timeout)
                          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>
@@ -735,7 +817,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveOnTableFamilyDelete</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.527">testArchiveOnTableFamilyDelete</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.586">testArchiveOnTableFamilyDelete</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>,
                                            <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
 <div class="block">Test that the store files are archived when a column family is removed.</div>
@@ -752,7 +834,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testCleaningRace</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.575">testCleaningRace</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.634">testCleaningRace</a>()
                       throws <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></pre>
 <div class="block">Test HFileArchiver.resolveAndArchive() race condition HBASE-7643</div>
 <dl>
@@ -767,7 +849,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRegionTableAndRegionDirsNull</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.638">testArchiveRegionTableAndRegionDirsNull</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.697">testArchiveRegionTableAndRegionDirsNull</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>
@@ -781,7 +863,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRegionWithTableDirNull</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.646">testArchiveRegionWithTableDirNull</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.705">testArchiveRegionWithTableDirNull</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>
@@ -795,7 +877,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>testArchiveRegionWithRegionDirNull</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.663">testArchiveRegionWithRegionDirNull</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.722">testArchiveRegionWithRegionDirNull</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>
@@ -809,7 +891,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getHFileCleaner</h4>
-<pre>private&nbsp;org.apache.hadoop.hbase.master.cleaner.HFileCleaner&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.682">getHFileCleaner</a>(org.apache.hadoop.hbase.Stoppable&nbsp;stoppable,
+<pre>private&nbsp;org.apache.hadoop.hbase.master.cleaner.HFileCleaner&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.741">getHFileCleaner</a>(org.apache.hadoop.hbase.Stoppable&nbsp;stoppable,
                                                                             org.apache.hadoop.conf.Configuration&nbsp;conf,
                                                                             org.apache.hadoop.fs.FileSystem&nbsp;fs,
                                                                             org.apache.hadoop.fs.Path&nbsp;archiveDir)
@@ -826,7 +908,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>clearArchiveDirectory</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.690">clearArchiveDirectory</a>()
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.749">clearArchiveDirectory</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>
@@ -840,7 +922,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAllFileNames</h4>
-<pre>private&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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.702">getAllFileNames</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>private&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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.761">getAllFileNames</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                                      org.apache.hadoop.fs.Path&nbsp;archiveDir)
                               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">Get the names of all the files below the given directory</div>
@@ -861,7 +943,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>recurseOnFiles</h4>
-<pre>private&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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.716">recurseOnFiles</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
+<pre>private&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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.html#line.775">recurseOnFiles</a>(org.apache.hadoop.fs.FileSystem&nbsp;fs,
                                     org.apache.hadoop.fs.FileStatus[]&nbsp;files,
                                     <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="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;fileNames)
                              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>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/backup/class-use/TestHFileArchiving.ArchivingFunction.html b/testdevapidocs/org/apache/hadoop/hbase/backup/class-use/TestHFileArchiving.ArchivingFunction.html
index e8eae53..8a532e3 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/backup/class-use/TestHFileArchiving.ArchivingFunction.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/backup/class-use/TestHFileArchiving.ArchivingFunction.html
@@ -104,6 +104,15 @@
 <tbody>
 <tr class="altColor">
 <td class="colFirst"><code>private void</code></td>
+<td class="colLast"><span class="typeNameLabel">TestHFileArchiving.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-boolean-boolean-boolean-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems</a></span>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-ex [...]
+                                         <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;expectedBase,
+                                         boolean&nbsp;archiveFileExists,
+                                         boolean&nbsp;sourceFileExists,
+                                         boolean&nbsp;archiveFileDifferentLength,
+                                         <a href="../../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or [...]
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>private void</code></td>
 <td class="colLast"><span class="typeNameLabel">TestHFileArchiving.</span><code><span class="memberNameLink"><a href="../../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.html#testArchiveStoreFilesDifferentFileSystems-java.lang.String-java.lang.String-org.apache.hadoop.hbase.backup.TestHFileArchiving.ArchivingFunction-">testArchiveStoreFilesDifferentFileSystems</a></span>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="clas [...]
                                          <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;expectedBase,
                                          <a href="../../../../../../org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html" title="interface in org.apache.hadoop.hbase.backup">TestHFileArchiving.ArchivingFunction</a>&lt;org.apache.hadoop.conf.Configuration,org.apache.hadoop.fs.FileSystem,org.apache.hadoop.hbase.client.RegionInfo,org.apache.hadoop.fs.Path,byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or [...]
diff --git a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
index 07229ba..dd89d66 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -668,18 +668,18 @@
 <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/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestRegionReplicaPerf.Stat.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestRegionReplicaPerf.Stat</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.Signal.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.Signal</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleState.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ResourceChecker.Phase.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ResourceChecker.Phase</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.Service.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.Service</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/PerformanceEvaluation.Counter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">PerformanceEvaluation.Counter</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleCommand.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleCommand</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/IntegrationTestDDLMasterFailover.ACTION.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">IntegrationTestDDLMasterFailover.ACTION</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.RoleState.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.RoleState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/RESTApiClusterManager.HealthSummary.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">RESTApiClusterManager.HealthSummary</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.CommandProvider.Operation.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.CommandProvider.Operation</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ZNodeClusterManager.CmdType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ZNodeClusterManager.CmdType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterManager.ServiceType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterManager.ServiceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HBaseClusterManager.Signal.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HBaseClusterManager.Signal</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ScanPerformanceEvaluation.ScanCounter.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ScanPerformanceEvaluation.ScanCounter</span></a></li>
 </ul>
 </li>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index 1d5e3ee..36ba9e7 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -241,10 +241,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.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestYieldProcedures.TestStateMachineProcedure.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.TestSMProcedureState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestStateMachineProcedure.TestSMProcedureState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureBypass.StuckStateMachineState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureBypass.StuckStateMachineState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.TestSMProcedureState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestStateMachineProcedure.TestSMProcedureState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestProcedureRecovery.TestStateMachineProcedure.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.TestStateMachineProcedure.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">TestYieldProcedures.TestStateMachineProcedure.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 9c06d5b..a6a165d 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -763,12 +763,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.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCompactionState.StateSource.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCompactionState.StateSource</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DataBlockEncodingTool.Manipulation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DataBlockEncodingTool.Manipulation</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCacheOnWriteInSchema.CacheOnWriteType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCacheOnWriteInSchema.CacheOnWriteType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestCompactionState.StateSource.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestCompactionState.StateSource</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestRegionServerReadRequestMetrics.Metric.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestRegionServerReadRequestMetrics.Metric</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestAtomicOperation.TestStep.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestAtomicOperation.TestStep</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TestMultiLogThreshold.ActionType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TestMultiLogThreshold.ActionType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
index c8c6e84..92fb3a2 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/test/package-tree.html
@@ -260,11 +260,11 @@
 <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.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadCommonCrawl.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadCommonCrawl.Counts</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Generator.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Generator.Counts</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadAndVerify.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Verify.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Verify.Counts</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestBigLinkedList.Generator.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestBigLinkedList.Generator.Counts</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.Counters.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestWithCellVisibilityLoadAndVerify.Counters</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.test.<a href="../../../../../org/apache/hadoop/hbase/test/IntegrationTestLoadCommonCrawl.Counts.html" title="enum in org.apache.hadoop.hbase.test"><span class="typeNameLink">IntegrationTestLoadCommonCrawl.Counts</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
index ef1e9d6..464c534 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/wal/package-tree.html
@@ -206,9 +206,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/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/TestWALSplit.Corruptions.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">TestWALSplit.Corruptions</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/IOTestProvider.AllowedOperations.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">IOTestProvider.AllowedOperations</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.wal.<a href="../../../../../org/apache/hadoop/hbase/wal/FaultyFSLog.FailureType.html" title="enum in org.apache.hadoop.hbase.wal"><span class="typeNameLink">FaultyFSLog.FailureType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
index 2fe5299..5620b33 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/backup/TestHFileArchiving.ArchivingFunction.html
@@ -29,714 +29,773 @@
 <span class="sourceLineNo">021</span>import static org.junit.Assert.assertFalse;<a name="line.21"></a>
 <span class="sourceLineNo">022</span>import static org.junit.Assert.assertNotNull;<a name="line.22"></a>
 <span class="sourceLineNo">023</span>import static org.junit.Assert.assertTrue;<a name="line.23"></a>
-<span class="sourceLineNo">024</span>import static org.mockito.ArgumentMatchers.any;<a name="line.24"></a>
-<span class="sourceLineNo">025</span>import static org.mockito.Mockito.mock;<a name="line.25"></a>
-<span class="sourceLineNo">026</span>import static org.mockito.Mockito.times;<a name="line.26"></a>
-<span class="sourceLineNo">027</span>import static org.mockito.Mockito.verify;<a name="line.27"></a>
-<span class="sourceLineNo">028</span>import static org.mockito.Mockito.when;<a name="line.28"></a>
-<span class="sourceLineNo">029</span><a name="line.29"></a>
-<span class="sourceLineNo">030</span>import java.io.IOException;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import java.security.PrivilegedExceptionAction;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import java.util.ArrayList;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import java.util.Collection;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import java.util.Collections;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import java.util.HashMap;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import java.util.List;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import java.util.Map;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import java.util.Objects;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import java.util.stream.Collectors;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import org.apache.hadoop.conf.Configuration;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import org.apache.hadoop.fs.FileStatus;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import org.apache.hadoop.fs.FileSystem;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import org.apache.hadoop.fs.Path;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import org.apache.hadoop.fs.PathFilter;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import org.apache.hadoop.hbase.ChoreService;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import org.apache.hadoop.hbase.HBaseClassTestRule;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.HBaseTestingUtil;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.HConstants;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.Stoppable;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.TableName;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.client.Admin;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.client.Table;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.master.HMaster;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.master.cleaner.DirScanPool;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.master.cleaner.HFileCleaner;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.regionserver.HRegion;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.regionserver.HRegionServer;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.regionserver.HStoreFile;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.testclassification.LargeTests;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.testclassification.MiscTests;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.63"></a>
-<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.util.CommonFSUtils;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.util.FSUtils;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>import org.apache.hadoop.hbase.util.HFileArchiveTestingUtil;<a name="line.67"></a>
-<span class="sourceLineNo">068</span>import org.apache.hadoop.hbase.util.HFileArchiveUtil;<a name="line.68"></a>
-<span class="sourceLineNo">069</span>import org.apache.hadoop.hbase.util.StoppableImplementation;<a name="line.69"></a>
-<span class="sourceLineNo">070</span>import org.apache.hadoop.security.UserGroupInformation;<a name="line.70"></a>
-<span class="sourceLineNo">071</span>import org.junit.After;<a name="line.71"></a>
-<span class="sourceLineNo">072</span>import org.junit.AfterClass;<a name="line.72"></a>
-<span class="sourceLineNo">073</span>import org.junit.Assert;<a name="line.73"></a>
-<span class="sourceLineNo">074</span>import org.junit.BeforeClass;<a name="line.74"></a>
-<span class="sourceLineNo">075</span>import org.junit.ClassRule;<a name="line.75"></a>
-<span class="sourceLineNo">076</span>import org.junit.Rule;<a name="line.76"></a>
-<span class="sourceLineNo">077</span>import org.junit.Test;<a name="line.77"></a>
-<span class="sourceLineNo">078</span>import org.junit.experimental.categories.Category;<a name="line.78"></a>
-<span class="sourceLineNo">079</span>import org.junit.rules.TestName;<a name="line.79"></a>
-<span class="sourceLineNo">080</span>import org.mockito.ArgumentCaptor;<a name="line.80"></a>
-<span class="sourceLineNo">081</span>import org.slf4j.Logger;<a name="line.81"></a>
-<span class="sourceLineNo">082</span>import org.slf4j.LoggerFactory;<a name="line.82"></a>
-<span class="sourceLineNo">083</span><a name="line.83"></a>
-<span class="sourceLineNo">084</span>/**<a name="line.84"></a>
-<span class="sourceLineNo">085</span> * Test that the {@link HFileArchiver} correctly removes all the parts of a region when cleaning up<a name="line.85"></a>
-<span class="sourceLineNo">086</span> * a region<a name="line.86"></a>
-<span class="sourceLineNo">087</span> */<a name="line.87"></a>
-<span class="sourceLineNo">088</span>@Category({LargeTests.class, MiscTests.class})<a name="line.88"></a>
-<span class="sourceLineNo">089</span>public class TestHFileArchiving {<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>  @ClassRule<a name="line.91"></a>
-<span class="sourceLineNo">092</span>  public static final HBaseClassTestRule CLASS_RULE =<a name="line.92"></a>
-<span class="sourceLineNo">093</span>      HBaseClassTestRule.forClass(TestHFileArchiving.class);<a name="line.93"></a>
-<span class="sourceLineNo">094</span><a name="line.94"></a>
-<span class="sourceLineNo">095</span>  private static final Logger LOG = LoggerFactory.getLogger(TestHFileArchiving.class);<a name="line.95"></a>
-<span class="sourceLineNo">096</span>  private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();<a name="line.96"></a>
-<span class="sourceLineNo">097</span>  private static final byte[] TEST_FAM = Bytes.toBytes("fam");<a name="line.97"></a>
-<span class="sourceLineNo">098</span><a name="line.98"></a>
-<span class="sourceLineNo">099</span>  private static DirScanPool POOL;<a name="line.99"></a>
-<span class="sourceLineNo">100</span>  @Rule<a name="line.100"></a>
-<span class="sourceLineNo">101</span>  public TestName name = new TestName();<a name="line.101"></a>
-<span class="sourceLineNo">102</span><a name="line.102"></a>
-<span class="sourceLineNo">103</span>  /**<a name="line.103"></a>
-<span class="sourceLineNo">104</span>   * Setup the config for the cluster<a name="line.104"></a>
-<span class="sourceLineNo">105</span>   */<a name="line.105"></a>
-<span class="sourceLineNo">106</span>  @BeforeClass<a name="line.106"></a>
-<span class="sourceLineNo">107</span>  public static void setupCluster() throws Exception {<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    setupConf(UTIL.getConfiguration());<a name="line.108"></a>
-<span class="sourceLineNo">109</span>    UTIL.startMiniCluster();<a name="line.109"></a>
-<span class="sourceLineNo">110</span><a name="line.110"></a>
-<span class="sourceLineNo">111</span>    // We don't want the cleaner to remove files. The tests do that.<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    UTIL.getMiniHBaseCluster().getMaster().getHFileCleaner().cancel(true);<a name="line.112"></a>
-<span class="sourceLineNo">113</span><a name="line.113"></a>
-<span class="sourceLineNo">114</span>    POOL = DirScanPool.getHFileCleanerScanPool(UTIL.getConfiguration());<a name="line.114"></a>
-<span class="sourceLineNo">115</span>  }<a name="line.115"></a>
-<span class="sourceLineNo">116</span><a name="line.116"></a>
-<span class="sourceLineNo">117</span>  private static void setupConf(Configuration conf) {<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    // disable the ui<a name="line.118"></a>
-<span class="sourceLineNo">119</span>    conf.setInt("hbase.regionsever.info.port", -1);<a name="line.119"></a>
-<span class="sourceLineNo">120</span>    // drop the memstore size so we get flushes<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    conf.setInt("hbase.hregion.memstore.flush.size", 25000);<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    // disable major compactions<a name="line.122"></a>
-<span class="sourceLineNo">123</span>    conf.setInt(HConstants.MAJOR_COMPACTION_PERIOD, 0);<a name="line.123"></a>
-<span class="sourceLineNo">124</span><a name="line.124"></a>
-<span class="sourceLineNo">125</span>    // prevent aggressive region split<a name="line.125"></a>
-<span class="sourceLineNo">126</span>    conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,<a name="line.126"></a>
-<span class="sourceLineNo">127</span>      ConstantSizeRegionSplitPolicy.class.getName());<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  }<a name="line.128"></a>
-<span class="sourceLineNo">129</span><a name="line.129"></a>
-<span class="sourceLineNo">130</span>  @After<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  public void tearDown() throws Exception {<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    // cleanup the archive directory<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    clearArchiveDirectory();<a name="line.133"></a>
-<span class="sourceLineNo">134</span>  }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>  @AfterClass<a name="line.136"></a>
-<span class="sourceLineNo">137</span>  public static void cleanupTest() throws Exception {<a name="line.137"></a>
-<span class="sourceLineNo">138</span>    UTIL.shutdownMiniCluster();<a name="line.138"></a>
-<span class="sourceLineNo">139</span>    POOL.shutdownNow();<a name="line.139"></a>
-<span class="sourceLineNo">140</span>  }<a name="line.140"></a>
-<span class="sourceLineNo">141</span><a name="line.141"></a>
-<span class="sourceLineNo">142</span>  @Test<a name="line.142"></a>
-<span class="sourceLineNo">143</span>  public void testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot() throws Exception {<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    String walDir = "mockFS://mockFSAuthority:9876/mockDir/wals/";<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    testArchiveStoreFilesDifferentFileSystems(walDir, baseDir,<a name="line.146"></a>
-<span class="sourceLineNo">147</span>      HFileArchiver::archiveStoreFiles);<a name="line.147"></a>
-<span class="sourceLineNo">148</span>  }<a name="line.148"></a>
-<span class="sourceLineNo">149</span><a name="line.149"></a>
-<span class="sourceLineNo">150</span>  @Test<a name="line.150"></a>
-<span class="sourceLineNo">151</span>  public void testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot() throws Exception {<a name="line.151"></a>
-<span class="sourceLineNo">152</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    testArchiveStoreFilesDifferentFileSystems(null, baseDir,<a name="line.153"></a>
-<span class="sourceLineNo">154</span>      HFileArchiver::archiveStoreFiles);<a name="line.154"></a>
-<span class="sourceLineNo">155</span>  }<a name="line.155"></a>
-<span class="sourceLineNo">156</span><a name="line.156"></a>
-<span class="sourceLineNo">157</span>  @Test<a name="line.157"></a>
-<span class="sourceLineNo">158</span>  public void testArchiveStoreFilesDifferentFileSystemsWallAndRootSame() throws Exception {<a name="line.158"></a>
-<span class="sourceLineNo">159</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.159"></a>
-<span class="sourceLineNo">160</span>    testArchiveStoreFilesDifferentFileSystems("/hbase/wals/", baseDir,<a name="line.160"></a>
-<span class="sourceLineNo">161</span>      HFileArchiver::archiveStoreFiles);<a name="line.161"></a>
-<span class="sourceLineNo">162</span>  }<a name="line.162"></a>
-<span class="sourceLineNo">163</span><a name="line.163"></a>
-<span class="sourceLineNo">164</span>  private void testArchiveStoreFilesDifferentFileSystems(String walDir, String expectedBase,<a name="line.164"></a>
-<span class="sourceLineNo">165</span>    ArchivingFunction&lt;Configuration, FileSystem, RegionInfo, Path, byte[],<a name="line.165"></a>
-<span class="sourceLineNo">166</span>      Collection&lt;HStoreFile&gt;&gt; archivingFunction) throws IOException {<a name="line.166"></a>
-<span class="sourceLineNo">167</span>    FileSystem mockedFileSystem = mock(FileSystem.class);<a name="line.167"></a>
-<span class="sourceLineNo">168</span>    Configuration conf = new Configuration(UTIL.getConfiguration());<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    if(walDir != null) {<a name="line.169"></a>
-<span class="sourceLineNo">170</span>      conf.set(CommonFSUtils.HBASE_WAL_DIR, walDir);<a name="line.170"></a>
-<span class="sourceLineNo">171</span>    }<a name="line.171"></a>
-<span class="sourceLineNo">172</span>    Path filePath = new Path("/mockDir/wals/mockFile");<a name="line.172"></a>
-<span class="sourceLineNo">173</span>    when(mockedFileSystem.getScheme()).thenReturn("mockFS");<a name="line.173"></a>
-<span class="sourceLineNo">174</span>    when(mockedFileSystem.mkdirs(any())).thenReturn(true);<a name="line.174"></a>
-<span class="sourceLineNo">175</span>    when(mockedFileSystem.exists(any())).thenReturn(true);<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    RegionInfo mockedRegion = mock(RegionInfo.class);<a name="line.176"></a>
-<span class="sourceLineNo">177</span>    TableName tableName = TableName.valueOf("mockTable");<a name="line.177"></a>
-<span class="sourceLineNo">178</span>    when(mockedRegion.getTable()).thenReturn(tableName);<a name="line.178"></a>
-<span class="sourceLineNo">179</span>    when(mockedRegion.getEncodedName()).thenReturn("mocked-region-encoded-name");<a name="line.179"></a>
-<span class="sourceLineNo">180</span>    Path tableDir = new Path("mockFS://mockDir/tabledir");<a name="line.180"></a>
-<span class="sourceLineNo">181</span>    byte[] family = Bytes.toBytes("testfamily");<a name="line.181"></a>
-<span class="sourceLineNo">182</span>    HStoreFile mockedFile = mock(HStoreFile.class);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>    List&lt;HStoreFile&gt; list = new ArrayList&lt;&gt;();<a name="line.183"></a>
-<span class="sourceLineNo">184</span>    list.add(mockedFile);<a name="line.184"></a>
-<span class="sourceLineNo">185</span>    when(mockedFile.getPath()).thenReturn(filePath);<a name="line.185"></a>
-<span class="sourceLineNo">186</span>    when(mockedFileSystem.rename(any(),any())).thenReturn(true);<a name="line.186"></a>
-<span class="sourceLineNo">187</span>    archivingFunction.apply(conf, mockedFileSystem, mockedRegion, tableDir, family, list);<a name="line.187"></a>
-<span class="sourceLineNo">188</span>    ArgumentCaptor&lt;Path&gt; pathCaptor = ArgumentCaptor.forClass(Path.class);<a name="line.188"></a>
-<span class="sourceLineNo">189</span>    verify(mockedFileSystem, times(2)).rename(pathCaptor.capture(), any());<a name="line.189"></a>
-<span class="sourceLineNo">190</span>    String expectedDir = expectedBase +<a name="line.190"></a>
-<span class="sourceLineNo">191</span>      "archive/data/default/mockTable/mocked-region-encoded-name/testfamily/mockFile";<a name="line.191"></a>
-<span class="sourceLineNo">192</span>    assertTrue(pathCaptor.getAllValues().get(0).toString().equals(expectedDir));<a name="line.192"></a>
-<span class="sourceLineNo">193</span>  }<a name="line.193"></a>
-<span class="sourceLineNo">194</span><a name="line.194"></a>
-<span class="sourceLineNo">195</span>  @FunctionalInterface<a name="line.195"></a>
-<span class="sourceLineNo">196</span>  private interface ArchivingFunction&lt;Configuration, FS, Region, Dir, Family, Files&gt; {<a name="line.196"></a>
-<span class="sourceLineNo">197</span>    void apply(Configuration config, FS fs, Region region, Dir dir, Family family, Files files)<a name="line.197"></a>
-<span class="sourceLineNo">198</span>      throws IOException;<a name="line.198"></a>
-<span class="sourceLineNo">199</span>  }<a name="line.199"></a>
-<span class="sourceLineNo">200</span><a name="line.200"></a>
-<span class="sourceLineNo">201</span>  @Test<a name="line.201"></a>
-<span class="sourceLineNo">202</span>  public void testArchiveRecoveredEditsWalDirNull() throws Exception {<a name="line.202"></a>
-<span class="sourceLineNo">203</span>    testArchiveRecoveredEditsWalDirNullOrSame(null);<a name="line.203"></a>
-<span class="sourceLineNo">204</span>  }<a name="line.204"></a>
-<span class="sourceLineNo">205</span><a name="line.205"></a>
-<span class="sourceLineNo">206</span>  @Test<a name="line.206"></a>
-<span class="sourceLineNo">207</span>  public void testArchiveRecoveredEditsWalDirSameFsStoreFiles() throws Exception {<a name="line.207"></a>
-<span class="sourceLineNo">208</span>    testArchiveRecoveredEditsWalDirNullOrSame("/wal-dir");<a name="line.208"></a>
-<span class="sourceLineNo">209</span>  }<a name="line.209"></a>
-<span class="sourceLineNo">210</span><a name="line.210"></a>
-<span class="sourceLineNo">211</span>  private void testArchiveRecoveredEditsWalDirNullOrSame(String walDir) throws Exception {<a name="line.211"></a>
-<span class="sourceLineNo">212</span>    String originalRootDir = UTIL.getConfiguration().get(HConstants.HBASE_DIR);<a name="line.212"></a>
-<span class="sourceLineNo">213</span>    try {<a name="line.213"></a>
-<span class="sourceLineNo">214</span>      String baseDir = "mockFS://mockFSAuthority:9876/hbase/";<a name="line.214"></a>
-<span class="sourceLineNo">215</span>      UTIL.getConfiguration().set(HConstants.HBASE_DIR, baseDir);<a name="line.215"></a>
-<span class="sourceLineNo">216</span>      testArchiveStoreFilesDifferentFileSystems(walDir, baseDir,<a name="line.216"></a>
-<span class="sourceLineNo">217</span>        (conf, fs, region, dir, family, list) -&gt; HFileArchiver<a name="line.217"></a>
-<span class="sourceLineNo">218</span>          .archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.218"></a>
-<span class="sourceLineNo">219</span>    } finally {<a name="line.219"></a>
-<span class="sourceLineNo">220</span>      UTIL.getConfiguration().set(HConstants.HBASE_DIR, originalRootDir);<a name="line.220"></a>
-<span class="sourceLineNo">221</span>    }<a name="line.221"></a>
-<span class="sourceLineNo">222</span>  }<a name="line.222"></a>
-<span class="sourceLineNo">223</span><a name="line.223"></a>
-<span class="sourceLineNo">224</span>  @Test(expected = IOException.class)<a name="line.224"></a>
-<span class="sourceLineNo">225</span>  public void testArchiveRecoveredEditsWrongFS() throws Exception {<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.226"></a>
-<span class="sourceLineNo">227</span>    //Internally, testArchiveStoreFilesDifferentFileSystems will pass a "mockedFS"<a name="line.227"></a>
-<span class="sourceLineNo">228</span>    // to HFileArchiver.archiveRecoveredEdits, but since wal-dir is supposedly on same FS<a name="line.228"></a>
-<span class="sourceLineNo">229</span>    // as root dir it would lead to conflicting FSes and an IOException is expected.<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    testArchiveStoreFilesDifferentFileSystems("/wal-dir", baseDir,<a name="line.230"></a>
-<span class="sourceLineNo">231</span>      (conf, fs, region, dir, family, list) -&gt; HFileArchiver<a name="line.231"></a>
-<span class="sourceLineNo">232</span>        .archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.232"></a>
-<span class="sourceLineNo">233</span>  }<a name="line.233"></a>
-<span class="sourceLineNo">234</span><a name="line.234"></a>
-<span class="sourceLineNo">235</span>  @Test<a name="line.235"></a>
-<span class="sourceLineNo">236</span>  public void testArchiveRecoveredEditsWalDirDifferentFS() throws Exception {<a name="line.236"></a>
-<span class="sourceLineNo">237</span>    String walDir = "mockFS://mockFSAuthority:9876/mockDir/wals/";<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    testArchiveStoreFilesDifferentFileSystems(walDir, walDir,<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      (conf, fs, region, dir, family, list) -&gt;<a name="line.239"></a>
-<span class="sourceLineNo">240</span>        HFileArchiver.archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>  }<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>  @Test<a name="line.243"></a>
-<span class="sourceLineNo">244</span>  public void testRemoveRegionDirOnArchive() throws Exception {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.245"></a>
-<span class="sourceLineNo">246</span>    UTIL.createTable(tableName, TEST_FAM);<a name="line.246"></a>
-<span class="sourceLineNo">247</span><a name="line.247"></a>
-<span class="sourceLineNo">248</span>    final Admin admin = UTIL.getAdmin();<a name="line.248"></a>
-<span class="sourceLineNo">249</span><a name="line.249"></a>
-<span class="sourceLineNo">250</span>    // get the current store files for the region<a name="line.250"></a>
-<span class="sourceLineNo">251</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.251"></a>
-<span class="sourceLineNo">252</span>    // make sure we only have 1 region serving this table<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    assertEquals(1, servingRegions.size());<a name="line.253"></a>
-<span class="sourceLineNo">254</span>    HRegion region = servingRegions.get(0);<a name="line.254"></a>
-<span class="sourceLineNo">255</span><a name="line.255"></a>
-<span class="sourceLineNo">256</span>    // and load the table<a name="line.256"></a>
-<span class="sourceLineNo">257</span>    UTIL.loadRegion(region, TEST_FAM);<a name="line.257"></a>
-<span class="sourceLineNo">258</span><a name="line.258"></a>
-<span class="sourceLineNo">259</span>    // shutdown the table so we can manipulate the files<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    admin.disableTable(tableName);<a name="line.260"></a>
-<span class="sourceLineNo">261</span><a name="line.261"></a>
-<span class="sourceLineNo">262</span>    FileSystem fs = UTIL.getTestFileSystem();<a name="line.262"></a>
-<span class="sourceLineNo">263</span><a name="line.263"></a>
-<span class="sourceLineNo">264</span>    // now attempt to depose the region<a name="line.264"></a>
-<span class="sourceLineNo">265</span>    Path rootDir = region.getRegionFileSystem().getTableDir().getParent();<a name="line.265"></a>
-<span class="sourceLineNo">266</span>    Path regionDir = FSUtils.getRegionDirFromRootDir(rootDir, region.getRegionInfo());<a name="line.266"></a>
-<span class="sourceLineNo">267</span><a name="line.267"></a>
-<span class="sourceLineNo">268</span>    HFileArchiver.archiveRegion(UTIL.getConfiguration(), fs, region.getRegionInfo());<a name="line.268"></a>
+<span class="sourceLineNo">024</span>import static org.junit.Assert.fail;<a name="line.24"></a>
+<span class="sourceLineNo">025</span>import static org.mockito.ArgumentMatchers.any;<a name="line.25"></a>
+<span class="sourceLineNo">026</span>import static org.mockito.Mockito.mock;<a name="line.26"></a>
+<span class="sourceLineNo">027</span>import static org.mockito.Mockito.never;<a name="line.27"></a>
+<span class="sourceLineNo">028</span>import static org.mockito.Mockito.times;<a name="line.28"></a>
+<span class="sourceLineNo">029</span>import static org.mockito.Mockito.verify;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import static org.mockito.Mockito.when;<a name="line.30"></a>
+<span class="sourceLineNo">031</span><a name="line.31"></a>
+<span class="sourceLineNo">032</span>import java.io.IOException;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import java.security.PrivilegedExceptionAction;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import java.util.ArrayList;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import java.util.Collection;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import java.util.Collections;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import java.util.HashMap;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import java.util.List;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import java.util.Map;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import java.util.Objects;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import java.util.stream.Collectors;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import org.apache.hadoop.conf.Configuration;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import org.apache.hadoop.fs.FileStatus;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import org.apache.hadoop.fs.FileSystem;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import org.apache.hadoop.fs.Path;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import org.apache.hadoop.fs.PathFilter;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import org.apache.hadoop.hbase.ChoreService;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import org.apache.hadoop.hbase.HBaseClassTestRule;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import org.apache.hadoop.hbase.HBaseTestingUtil;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import org.apache.hadoop.hbase.HConstants;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.hadoop.hbase.Stoppable;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.TableName;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.client.Admin;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.client.Table;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.master.HMaster;<a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.master.cleaner.DirScanPool;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.master.cleaner.HFileCleaner;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy;<a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.regionserver.HRegion;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.regionserver.HRegionServer;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.regionserver.HStoreFile;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.testclassification.LargeTests;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.testclassification.MiscTests;<a name="line.64"></a>
+<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.util.Bytes;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.util.CommonFSUtils;<a name="line.66"></a>
+<span class="sourceLineNo">067</span>import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>import org.apache.hadoop.hbase.util.FSUtils;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>import org.apache.hadoop.hbase.util.HFileArchiveTestingUtil;<a name="line.69"></a>
+<span class="sourceLineNo">070</span>import org.apache.hadoop.hbase.util.HFileArchiveUtil;<a name="line.70"></a>
+<span class="sourceLineNo">071</span>import org.apache.hadoop.hbase.util.StoppableImplementation;<a name="line.71"></a>
+<span class="sourceLineNo">072</span>import org.apache.hadoop.security.UserGroupInformation;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>import org.junit.After;<a name="line.73"></a>
+<span class="sourceLineNo">074</span>import org.junit.AfterClass;<a name="line.74"></a>
+<span class="sourceLineNo">075</span>import org.junit.Assert;<a name="line.75"></a>
+<span class="sourceLineNo">076</span>import org.junit.BeforeClass;<a name="line.76"></a>
+<span class="sourceLineNo">077</span>import org.junit.ClassRule;<a name="line.77"></a>
+<span class="sourceLineNo">078</span>import org.junit.Rule;<a name="line.78"></a>
+<span class="sourceLineNo">079</span>import org.junit.Test;<a name="line.79"></a>
+<span class="sourceLineNo">080</span>import org.junit.experimental.categories.Category;<a name="line.80"></a>
+<span class="sourceLineNo">081</span>import org.junit.rules.TestName;<a name="line.81"></a>
+<span class="sourceLineNo">082</span>import org.mockito.ArgumentCaptor;<a name="line.82"></a>
+<span class="sourceLineNo">083</span>import org.slf4j.Logger;<a name="line.83"></a>
+<span class="sourceLineNo">084</span>import org.slf4j.LoggerFactory;<a name="line.84"></a>
+<span class="sourceLineNo">085</span><a name="line.85"></a>
+<span class="sourceLineNo">086</span>/**<a name="line.86"></a>
+<span class="sourceLineNo">087</span> * Test that the {@link HFileArchiver} correctly removes all the parts of a region when cleaning up<a name="line.87"></a>
+<span class="sourceLineNo">088</span> * a region<a name="line.88"></a>
+<span class="sourceLineNo">089</span> */<a name="line.89"></a>
+<span class="sourceLineNo">090</span>@Category({LargeTests.class, MiscTests.class})<a name="line.90"></a>
+<span class="sourceLineNo">091</span>public class TestHFileArchiving {<a name="line.91"></a>
+<span class="sourceLineNo">092</span><a name="line.92"></a>
+<span class="sourceLineNo">093</span>  @ClassRule<a name="line.93"></a>
+<span class="sourceLineNo">094</span>  public static final HBaseClassTestRule CLASS_RULE =<a name="line.94"></a>
+<span class="sourceLineNo">095</span>      HBaseClassTestRule.forClass(TestHFileArchiving.class);<a name="line.95"></a>
+<span class="sourceLineNo">096</span><a name="line.96"></a>
+<span class="sourceLineNo">097</span>  private static final Logger LOG = LoggerFactory.getLogger(TestHFileArchiving.class);<a name="line.97"></a>
+<span class="sourceLineNo">098</span>  private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();<a name="line.98"></a>
+<span class="sourceLineNo">099</span>  private static final byte[] TEST_FAM = Bytes.toBytes("fam");<a name="line.99"></a>
+<span class="sourceLineNo">100</span><a name="line.100"></a>
+<span class="sourceLineNo">101</span>  private static DirScanPool POOL;<a name="line.101"></a>
+<span class="sourceLineNo">102</span>  @Rule<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  public TestName name = new TestName();<a name="line.103"></a>
+<span class="sourceLineNo">104</span><a name="line.104"></a>
+<span class="sourceLineNo">105</span>  /**<a name="line.105"></a>
+<span class="sourceLineNo">106</span>   * Setup the config for the cluster<a name="line.106"></a>
+<span class="sourceLineNo">107</span>   */<a name="line.107"></a>
+<span class="sourceLineNo">108</span>  @BeforeClass<a name="line.108"></a>
+<span class="sourceLineNo">109</span>  public static void setupCluster() throws Exception {<a name="line.109"></a>
+<span class="sourceLineNo">110</span>    setupConf(UTIL.getConfiguration());<a name="line.110"></a>
+<span class="sourceLineNo">111</span>    UTIL.startMiniCluster();<a name="line.111"></a>
+<span class="sourceLineNo">112</span><a name="line.112"></a>
+<span class="sourceLineNo">113</span>    // We don't want the cleaner to remove files. The tests do that.<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    UTIL.getMiniHBaseCluster().getMaster().getHFileCleaner().cancel(true);<a name="line.114"></a>
+<span class="sourceLineNo">115</span><a name="line.115"></a>
+<span class="sourceLineNo">116</span>    POOL = DirScanPool.getHFileCleanerScanPool(UTIL.getConfiguration());<a name="line.116"></a>
+<span class="sourceLineNo">117</span>  }<a name="line.117"></a>
+<span class="sourceLineNo">118</span><a name="line.118"></a>
+<span class="sourceLineNo">119</span>  private static void setupConf(Configuration conf) {<a name="line.119"></a>
+<span class="sourceLineNo">120</span>    // disable the ui<a name="line.120"></a>
+<span class="sourceLineNo">121</span>    conf.setInt("hbase.regionsever.info.port", -1);<a name="line.121"></a>
+<span class="sourceLineNo">122</span>    // drop the memstore size so we get flushes<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    conf.setInt("hbase.hregion.memstore.flush.size", 25000);<a name="line.123"></a>
+<span class="sourceLineNo">124</span>    // disable major compactions<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    conf.setInt(HConstants.MAJOR_COMPACTION_PERIOD, 0);<a name="line.125"></a>
+<span class="sourceLineNo">126</span><a name="line.126"></a>
+<span class="sourceLineNo">127</span>    // prevent aggressive region split<a name="line.127"></a>
+<span class="sourceLineNo">128</span>    conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,<a name="line.128"></a>
+<span class="sourceLineNo">129</span>      ConstantSizeRegionSplitPolicy.class.getName());<a name="line.129"></a>
+<span class="sourceLineNo">130</span>  }<a name="line.130"></a>
+<span class="sourceLineNo">131</span><a name="line.131"></a>
+<span class="sourceLineNo">132</span>  @After<a name="line.132"></a>
+<span class="sourceLineNo">133</span>  public void tearDown() throws Exception {<a name="line.133"></a>
+<span class="sourceLineNo">134</span>    // cleanup the archive directory<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    clearArchiveDirectory();<a name="line.135"></a>
+<span class="sourceLineNo">136</span>  }<a name="line.136"></a>
+<span class="sourceLineNo">137</span><a name="line.137"></a>
+<span class="sourceLineNo">138</span>  @AfterClass<a name="line.138"></a>
+<span class="sourceLineNo">139</span>  public static void cleanupTest() throws Exception {<a name="line.139"></a>
+<span class="sourceLineNo">140</span>    UTIL.shutdownMiniCluster();<a name="line.140"></a>
+<span class="sourceLineNo">141</span>    POOL.shutdownNow();<a name="line.141"></a>
+<span class="sourceLineNo">142</span>  }<a name="line.142"></a>
+<span class="sourceLineNo">143</span><a name="line.143"></a>
+<span class="sourceLineNo">144</span>  @Test<a name="line.144"></a>
+<span class="sourceLineNo">145</span>  public void testArchiveStoreFilesDifferentFileSystemsWallWithSchemaPlainRoot() throws Exception {<a name="line.145"></a>
+<span class="sourceLineNo">146</span>    String walDir = "mockFS://mockFSAuthority:9876/mockDir/wals/";<a name="line.146"></a>
+<span class="sourceLineNo">147</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.147"></a>
+<span class="sourceLineNo">148</span>    testArchiveStoreFilesDifferentFileSystems(walDir, baseDir,<a name="line.148"></a>
+<span class="sourceLineNo">149</span>      HFileArchiver::archiveStoreFiles);<a name="line.149"></a>
+<span class="sourceLineNo">150</span>  }<a name="line.150"></a>
+<span class="sourceLineNo">151</span><a name="line.151"></a>
+<span class="sourceLineNo">152</span>  @Test<a name="line.152"></a>
+<span class="sourceLineNo">153</span>  public void testArchiveStoreFilesDifferentFileSystemsWallNullPlainRoot() throws Exception {<a name="line.153"></a>
+<span class="sourceLineNo">154</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.154"></a>
+<span class="sourceLineNo">155</span>    testArchiveStoreFilesDifferentFileSystems(null, baseDir,<a name="line.155"></a>
+<span class="sourceLineNo">156</span>      HFileArchiver::archiveStoreFiles);<a name="line.156"></a>
+<span class="sourceLineNo">157</span>  }<a name="line.157"></a>
+<span class="sourceLineNo">158</span><a name="line.158"></a>
+<span class="sourceLineNo">159</span>  @Test<a name="line.159"></a>
+<span class="sourceLineNo">160</span>  public void testArchiveStoreFilesDifferentFileSystemsWallAndRootSame() throws Exception {<a name="line.160"></a>
+<span class="sourceLineNo">161</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    testArchiveStoreFilesDifferentFileSystems("/hbase/wals/", baseDir,<a name="line.162"></a>
+<span class="sourceLineNo">163</span>      HFileArchiver::archiveStoreFiles);<a name="line.163"></a>
+<span class="sourceLineNo">164</span>  }<a name="line.164"></a>
+<span class="sourceLineNo">165</span><a name="line.165"></a>
+<span class="sourceLineNo">166</span>  @Test<a name="line.166"></a>
+<span class="sourceLineNo">167</span>  public void testArchiveStoreFilesDifferentFileSystemsFileAlreadyArchived() throws Exception {<a name="line.167"></a>
+<span class="sourceLineNo">168</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.168"></a>
+<span class="sourceLineNo">169</span>    testArchiveStoreFilesDifferentFileSystems("/hbase/wals/", baseDir, true, false, false,<a name="line.169"></a>
+<span class="sourceLineNo">170</span>      HFileArchiver::archiveStoreFiles);<a name="line.170"></a>
+<span class="sourceLineNo">171</span>  }<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>  @Test<a name="line.173"></a>
+<span class="sourceLineNo">174</span>  public void testArchiveStoreFilesDifferentFileSystemsArchiveFileMatchCurrent() throws Exception {<a name="line.174"></a>
+<span class="sourceLineNo">175</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.175"></a>
+<span class="sourceLineNo">176</span>    testArchiveStoreFilesDifferentFileSystems("/hbase/wals/", baseDir, true, true, false,<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      HFileArchiver::archiveStoreFiles);<a name="line.177"></a>
+<span class="sourceLineNo">178</span>  }<a name="line.178"></a>
+<span class="sourceLineNo">179</span><a name="line.179"></a>
+<span class="sourceLineNo">180</span>  @Test(expected = IOException.class)<a name="line.180"></a>
+<span class="sourceLineNo">181</span>  public void testArchiveStoreFilesDifferentFileSystemsArchiveFileMismatch() throws Exception {<a name="line.181"></a>
+<span class="sourceLineNo">182</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.182"></a>
+<span class="sourceLineNo">183</span>    testArchiveStoreFilesDifferentFileSystems("/hbase/wals/", baseDir, true, true, true,<a name="line.183"></a>
+<span class="sourceLineNo">184</span>      HFileArchiver::archiveStoreFiles);<a name="line.184"></a>
+<span class="sourceLineNo">185</span>  }<a name="line.185"></a>
+<span class="sourceLineNo">186</span><a name="line.186"></a>
+<span class="sourceLineNo">187</span>  private void testArchiveStoreFilesDifferentFileSystems(String walDir, String expectedBase,<a name="line.187"></a>
+<span class="sourceLineNo">188</span>    ArchivingFunction&lt;Configuration, FileSystem, RegionInfo, Path, byte[],<a name="line.188"></a>
+<span class="sourceLineNo">189</span>      Collection&lt;HStoreFile&gt;&gt; archivingFunction) throws IOException {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>    testArchiveStoreFilesDifferentFileSystems(walDir, expectedBase, false, true, false,<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      archivingFunction);<a name="line.191"></a>
+<span class="sourceLineNo">192</span>  }<a name="line.192"></a>
+<span class="sourceLineNo">193</span><a name="line.193"></a>
+<span class="sourceLineNo">194</span>  private void testArchiveStoreFilesDifferentFileSystems(String walDir, String expectedBase,<a name="line.194"></a>
+<span class="sourceLineNo">195</span>    boolean archiveFileExists, boolean sourceFileExists, boolean archiveFileDifferentLength,<a name="line.195"></a>
+<span class="sourceLineNo">196</span>    ArchivingFunction&lt;Configuration, FileSystem, RegionInfo, Path, byte[],<a name="line.196"></a>
+<span class="sourceLineNo">197</span>      Collection&lt;HStoreFile&gt;&gt; archivingFunction) throws IOException {<a name="line.197"></a>
+<span class="sourceLineNo">198</span>    FileSystem mockedFileSystem = mock(FileSystem.class);<a name="line.198"></a>
+<span class="sourceLineNo">199</span>    Configuration conf = new Configuration(UTIL.getConfiguration());<a name="line.199"></a>
+<span class="sourceLineNo">200</span>    if(walDir != null) {<a name="line.200"></a>
+<span class="sourceLineNo">201</span>      conf.set(CommonFSUtils.HBASE_WAL_DIR, walDir);<a name="line.201"></a>
+<span class="sourceLineNo">202</span>    }<a name="line.202"></a>
+<span class="sourceLineNo">203</span>    when(mockedFileSystem.getScheme()).thenReturn("mockFS");<a name="line.203"></a>
+<span class="sourceLineNo">204</span>    when(mockedFileSystem.mkdirs(any())).thenReturn(true);<a name="line.204"></a>
+<span class="sourceLineNo">205</span>    HashMap&lt;Path,Boolean&gt; existsTracker = new HashMap&lt;&gt;();<a name="line.205"></a>
+<span class="sourceLineNo">206</span>    Path filePath = new Path("/mockDir/wals/mockFile");<a name="line.206"></a>
+<span class="sourceLineNo">207</span>    String expectedDir = expectedBase +<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      "archive/data/default/mockTable/mocked-region-encoded-name/testfamily/mockFile";<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    existsTracker.put(new Path(expectedDir), archiveFileExists);<a name="line.209"></a>
+<span class="sourceLineNo">210</span>    existsTracker.put(filePath, sourceFileExists);<a name="line.210"></a>
+<span class="sourceLineNo">211</span>    when(mockedFileSystem.exists(any())).thenAnswer(invocation -&gt;<a name="line.211"></a>
+<span class="sourceLineNo">212</span>      existsTracker.getOrDefault((Path)invocation.getArgument(0), true));<a name="line.212"></a>
+<span class="sourceLineNo">213</span>    FileStatus mockedStatus = mock(FileStatus.class);<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    when(mockedStatus.getLen()).thenReturn(12L).thenReturn(archiveFileDifferentLength ? 34L : 12L);<a name="line.214"></a>
+<span class="sourceLineNo">215</span>    when(mockedFileSystem.getFileStatus(any())).thenReturn(mockedStatus);<a name="line.215"></a>
+<span class="sourceLineNo">216</span>    RegionInfo mockedRegion = mock(RegionInfo.class);<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    TableName tableName = TableName.valueOf("mockTable");<a name="line.217"></a>
+<span class="sourceLineNo">218</span>    when(mockedRegion.getTable()).thenReturn(tableName);<a name="line.218"></a>
+<span class="sourceLineNo">219</span>    when(mockedRegion.getEncodedName()).thenReturn("mocked-region-encoded-name");<a name="line.219"></a>
+<span class="sourceLineNo">220</span>    Path tableDir = new Path("mockFS://mockDir/tabledir");<a name="line.220"></a>
+<span class="sourceLineNo">221</span>    byte[] family = Bytes.toBytes("testfamily");<a name="line.221"></a>
+<span class="sourceLineNo">222</span>    HStoreFile mockedFile = mock(HStoreFile.class);<a name="line.222"></a>
+<span class="sourceLineNo">223</span>    List&lt;HStoreFile&gt; list = new ArrayList&lt;&gt;();<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    list.add(mockedFile);<a name="line.224"></a>
+<span class="sourceLineNo">225</span>    when(mockedFile.getPath()).thenReturn(filePath);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>    when(mockedFileSystem.rename(any(),any())).thenReturn(true);<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    archivingFunction.apply(conf, mockedFileSystem, mockedRegion, tableDir, family, list);<a name="line.227"></a>
+<span class="sourceLineNo">228</span><a name="line.228"></a>
+<span class="sourceLineNo">229</span>    if (sourceFileExists) {<a name="line.229"></a>
+<span class="sourceLineNo">230</span>      ArgumentCaptor&lt;Path&gt; srcPath = ArgumentCaptor.forClass(Path.class);<a name="line.230"></a>
+<span class="sourceLineNo">231</span>      ArgumentCaptor&lt;Path&gt; destPath = ArgumentCaptor.forClass(Path.class);<a name="line.231"></a>
+<span class="sourceLineNo">232</span>      if (archiveFileExists) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>        // Verify we renamed the archived file to sideline, and then renamed the source file.<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        verify(mockedFileSystem, times(2)).rename(srcPath.capture(), destPath.capture());<a name="line.234"></a>
+<span class="sourceLineNo">235</span>        assertEquals(expectedDir, srcPath.getAllValues().get(0).toString());<a name="line.235"></a>
+<span class="sourceLineNo">236</span>        assertEquals(filePath, srcPath.getAllValues().get(1));<a name="line.236"></a>
+<span class="sourceLineNo">237</span>        assertEquals(expectedDir, destPath.getAllValues().get(1).toString());<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      } else {<a name="line.238"></a>
+<span class="sourceLineNo">239</span>        // Verify we renamed the source file to the archived file.<a name="line.239"></a>
+<span class="sourceLineNo">240</span>        verify(mockedFileSystem, times(1)).rename(srcPath.capture(), destPath.capture());<a name="line.240"></a>
+<span class="sourceLineNo">241</span>        assertEquals(filePath, srcPath.getAllValues().get(0));<a name="line.241"></a>
+<span class="sourceLineNo">242</span>        assertEquals(expectedDir, destPath.getAllValues().get(0).toString());<a name="line.242"></a>
+<span class="sourceLineNo">243</span>      }<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    } else {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      if (archiveFileExists) {<a name="line.245"></a>
+<span class="sourceLineNo">246</span>        // Verify we did not rename. No source file with a present archive file should be a no-op.<a name="line.246"></a>
+<span class="sourceLineNo">247</span>        verify(mockedFileSystem, never()).rename(any(), any());<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      } else {<a name="line.248"></a>
+<span class="sourceLineNo">249</span>        fail("Unsupported test conditions: sourceFileExists and archiveFileExists both false.");<a name="line.249"></a>
+<span class="sourceLineNo">250</span>      }<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    }<a name="line.251"></a>
+<span class="sourceLineNo">252</span>  }<a name="line.252"></a>
+<span class="sourceLineNo">253</span><a name="line.253"></a>
+<span class="sourceLineNo">254</span>  @FunctionalInterface<a name="line.254"></a>
+<span class="sourceLineNo">255</span>  private interface ArchivingFunction&lt;Configuration, FS, Region, Dir, Family, Files&gt; {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>    void apply(Configuration config, FS fs, Region region, Dir dir, Family family, Files files)<a name="line.256"></a>
+<span class="sourceLineNo">257</span>      throws IOException;<a name="line.257"></a>
+<span class="sourceLineNo">258</span>  }<a name="line.258"></a>
+<span class="sourceLineNo">259</span><a name="line.259"></a>
+<span class="sourceLineNo">260</span>  @Test<a name="line.260"></a>
+<span class="sourceLineNo">261</span>  public void testArchiveRecoveredEditsWalDirNull() throws Exception {<a name="line.261"></a>
+<span class="sourceLineNo">262</span>    testArchiveRecoveredEditsWalDirNullOrSame(null);<a name="line.262"></a>
+<span class="sourceLineNo">263</span>  }<a name="line.263"></a>
+<span class="sourceLineNo">264</span><a name="line.264"></a>
+<span class="sourceLineNo">265</span>  @Test<a name="line.265"></a>
+<span class="sourceLineNo">266</span>  public void testArchiveRecoveredEditsWalDirSameFsStoreFiles() throws Exception {<a name="line.266"></a>
+<span class="sourceLineNo">267</span>    testArchiveRecoveredEditsWalDirNullOrSame("/wal-dir");<a name="line.267"></a>
+<span class="sourceLineNo">268</span>  }<a name="line.268"></a>
 <span class="sourceLineNo">269</span><a name="line.269"></a>
-<span class="sourceLineNo">270</span>    // check for the existence of the archive directory and some files in it<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    Path archiveDir = HFileArchiveTestingUtil.getRegionArchiveDir(UTIL.getConfiguration(), region);<a name="line.271"></a>
-<span class="sourceLineNo">272</span>    assertTrue(fs.exists(archiveDir));<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>    // check to make sure the store directory was copied<a name="line.274"></a>
-<span class="sourceLineNo">275</span>    FileStatus[] stores = fs.listStatus(archiveDir, new PathFilter() {<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      @Override<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      public boolean accept(Path p) {<a name="line.277"></a>
-<span class="sourceLineNo">278</span>        if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) {<a name="line.278"></a>
-<span class="sourceLineNo">279</span>          return false;<a name="line.279"></a>
-<span class="sourceLineNo">280</span>        }<a name="line.280"></a>
-<span class="sourceLineNo">281</span>        return true;<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      }<a name="line.282"></a>
-<span class="sourceLineNo">283</span>    });<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    assertTrue(stores.length == 1);<a name="line.284"></a>
-<span class="sourceLineNo">285</span><a name="line.285"></a>
-<span class="sourceLineNo">286</span>    // make sure we archived the store files<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    FileStatus[] storeFiles = fs.listStatus(stores[0].getPath());<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    assertTrue(storeFiles.length &gt; 0);<a name="line.288"></a>
-<span class="sourceLineNo">289</span><a name="line.289"></a>
-<span class="sourceLineNo">290</span>    // then ensure the region's directory isn't present<a name="line.290"></a>
-<span class="sourceLineNo">291</span>    assertFalse(fs.exists(regionDir));<a name="line.291"></a>
-<span class="sourceLineNo">292</span><a name="line.292"></a>
-<span class="sourceLineNo">293</span>    UTIL.deleteTable(tableName);<a name="line.293"></a>
-<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
-<span class="sourceLineNo">295</span><a name="line.295"></a>
-<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   * Test that the region directory is removed when we archive a region without store files, but<a name="line.297"></a>
-<span class="sourceLineNo">298</span>   * still has hidden files.<a name="line.298"></a>
-<span class="sourceLineNo">299</span>   * @throws IOException throws an IOException if there's problem creating a table<a name="line.299"></a>
-<span class="sourceLineNo">300</span>   *   or if there's an issue with accessing FileSystem.<a name="line.300"></a>
-<span class="sourceLineNo">301</span>   */<a name="line.301"></a>
+<span class="sourceLineNo">270</span>  private void testArchiveRecoveredEditsWalDirNullOrSame(String walDir) throws Exception {<a name="line.270"></a>
+<span class="sourceLineNo">271</span>    String originalRootDir = UTIL.getConfiguration().get(HConstants.HBASE_DIR);<a name="line.271"></a>
+<span class="sourceLineNo">272</span>    try {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      String baseDir = "mockFS://mockFSAuthority:9876/hbase/";<a name="line.273"></a>
+<span class="sourceLineNo">274</span>      UTIL.getConfiguration().set(HConstants.HBASE_DIR, baseDir);<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      testArchiveStoreFilesDifferentFileSystems(walDir, baseDir,<a name="line.275"></a>
+<span class="sourceLineNo">276</span>        (conf, fs, region, dir, family, list) -&gt; HFileArchiver<a name="line.276"></a>
+<span class="sourceLineNo">277</span>          .archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.277"></a>
+<span class="sourceLineNo">278</span>    } finally {<a name="line.278"></a>
+<span class="sourceLineNo">279</span>      UTIL.getConfiguration().set(HConstants.HBASE_DIR, originalRootDir);<a name="line.279"></a>
+<span class="sourceLineNo">280</span>    }<a name="line.280"></a>
+<span class="sourceLineNo">281</span>  }<a name="line.281"></a>
+<span class="sourceLineNo">282</span><a name="line.282"></a>
+<span class="sourceLineNo">283</span>  @Test(expected = IOException.class)<a name="line.283"></a>
+<span class="sourceLineNo">284</span>  public void testArchiveRecoveredEditsWrongFS() throws Exception {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>    String baseDir = CommonFSUtils.getRootDir(UTIL.getConfiguration()).toString() + "/";<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    //Internally, testArchiveStoreFilesDifferentFileSystems will pass a "mockedFS"<a name="line.286"></a>
+<span class="sourceLineNo">287</span>    // to HFileArchiver.archiveRecoveredEdits, but since wal-dir is supposedly on same FS<a name="line.287"></a>
+<span class="sourceLineNo">288</span>    // as root dir it would lead to conflicting FSes and an IOException is expected.<a name="line.288"></a>
+<span class="sourceLineNo">289</span>    testArchiveStoreFilesDifferentFileSystems("/wal-dir", baseDir,<a name="line.289"></a>
+<span class="sourceLineNo">290</span>      (conf, fs, region, dir, family, list) -&gt; HFileArchiver<a name="line.290"></a>
+<span class="sourceLineNo">291</span>        .archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.291"></a>
+<span class="sourceLineNo">292</span>  }<a name="line.292"></a>
+<span class="sourceLineNo">293</span><a name="line.293"></a>
+<span class="sourceLineNo">294</span>  @Test<a name="line.294"></a>
+<span class="sourceLineNo">295</span>  public void testArchiveRecoveredEditsWalDirDifferentFS() throws Exception {<a name="line.295"></a>
+<span class="sourceLineNo">296</span>    String walDir = "mockFS://mockFSAuthority:9876/mockDir/wals/";<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    testArchiveStoreFilesDifferentFileSystems(walDir, walDir,<a name="line.297"></a>
+<span class="sourceLineNo">298</span>      (conf, fs, region, dir, family, list) -&gt;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>        HFileArchiver.archiveRecoveredEdits(conf, fs, region, family, list));<a name="line.299"></a>
+<span class="sourceLineNo">300</span>  }<a name="line.300"></a>
+<span class="sourceLineNo">301</span><a name="line.301"></a>
 <span class="sourceLineNo">302</span>  @Test<a name="line.302"></a>
-<span class="sourceLineNo">303</span>  public void testDeleteRegionWithNoStoreFiles() throws IOException {<a name="line.303"></a>
+<span class="sourceLineNo">303</span>  public void testRemoveRegionDirOnArchive() throws Exception {<a name="line.303"></a>
 <span class="sourceLineNo">304</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.304"></a>
 <span class="sourceLineNo">305</span>    UTIL.createTable(tableName, TEST_FAM);<a name="line.305"></a>
 <span class="sourceLineNo">306</span><a name="line.306"></a>
-<span class="sourceLineNo">307</span>    // get the current store files for the region<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.308"></a>
-<span class="sourceLineNo">309</span>    // make sure we only have 1 region serving this table<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    assertEquals(1, servingRegions.size());<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    HRegion region = servingRegions.get(0);<a name="line.311"></a>
-<span class="sourceLineNo">312</span><a name="line.312"></a>
-<span class="sourceLineNo">313</span>    FileSystem fs = region.getRegionFileSystem().getFileSystem();<a name="line.313"></a>
+<span class="sourceLineNo">307</span>    final Admin admin = UTIL.getAdmin();<a name="line.307"></a>
+<span class="sourceLineNo">308</span><a name="line.308"></a>
+<span class="sourceLineNo">309</span>    // get the current store files for the region<a name="line.309"></a>
+<span class="sourceLineNo">310</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    // make sure we only have 1 region serving this table<a name="line.311"></a>
+<span class="sourceLineNo">312</span>    assertEquals(1, servingRegions.size());<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    HRegion region = servingRegions.get(0);<a name="line.313"></a>
 <span class="sourceLineNo">314</span><a name="line.314"></a>
-<span class="sourceLineNo">315</span>    // make sure there are some files in the regiondir<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    Path rootDir = CommonFSUtils.getRootDir(fs.getConf());<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    Path regionDir = FSUtils.getRegionDirFromRootDir(rootDir, region.getRegionInfo());<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    FileStatus[] regionFiles = CommonFSUtils.listStatus(fs, regionDir, null);<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    Assert.assertNotNull("No files in the region directory", regionFiles);<a name="line.319"></a>
-<span class="sourceLineNo">320</span>    if (LOG.isDebugEnabled()) {<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      List&lt;Path&gt; files = new ArrayList&lt;&gt;();<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      for (FileStatus file : regionFiles) {<a name="line.322"></a>
-<span class="sourceLineNo">323</span>        files.add(file.getPath());<a name="line.323"></a>
-<span class="sourceLineNo">324</span>      }<a name="line.324"></a>
-<span class="sourceLineNo">325</span>      LOG.debug("Current files:" + files);<a name="line.325"></a>
-<span class="sourceLineNo">326</span>    }<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    // delete the visible folders so we just have hidden files/folders<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    final PathFilter dirFilter = new FSUtils.DirFilter(fs);<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    PathFilter nonHidden = new PathFilter() {<a name="line.329"></a>
-<span class="sourceLineNo">330</span>      @Override<a name="line.330"></a>
-<span class="sourceLineNo">331</span>      public boolean accept(Path file) {<a name="line.331"></a>
-<span class="sourceLineNo">332</span>        return dirFilter.accept(file) &amp;&amp; !file.getName().startsWith(".");<a name="line.332"></a>
-<span class="sourceLineNo">333</span>      }<a name="line.333"></a>
-<span class="sourceLineNo">334</span>    };<a name="line.334"></a>
-<span class="sourceLineNo">335</span>    FileStatus[] storeDirs = CommonFSUtils.listStatus(fs, regionDir, nonHidden);<a name="line.335"></a>
-<span class="sourceLineNo">336</span>    for (FileStatus store : storeDirs) {<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      LOG.debug("Deleting store for test");<a name="line.337"></a>
-<span class="sourceLineNo">338</span>      fs.delete(store.getPath(), true);<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    }<a name="line.339"></a>
-<span class="sourceLineNo">340</span><a name="line.340"></a>
-<span class="sourceLineNo">341</span>    // then archive the region<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    HFileArchiver.archiveRegion(UTIL.getConfiguration(), fs, region.getRegionInfo());<a name="line.342"></a>
-<span class="sourceLineNo">343</span><a name="line.343"></a>
-<span class="sourceLineNo">344</span>    // and check to make sure the region directoy got deleted<a name="line.344"></a>
-<span class="sourceLineNo">345</span>    assertFalse("Region directory (" + regionDir + "), still exists.", fs.exists(regionDir));<a name="line.345"></a>
-<span class="sourceLineNo">346</span><a name="line.346"></a>
-<span class="sourceLineNo">347</span>    UTIL.deleteTable(tableName);<a name="line.347"></a>
-<span class="sourceLineNo">348</span>  }<a name="line.348"></a>
-<span class="sourceLineNo">349</span><a name="line.349"></a>
-<span class="sourceLineNo">350</span>  private List&lt;HRegion&gt; initTableForArchivingRegions(TableName tableName) throws IOException {<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    final byte[][] splitKeys = new byte[][] {<a name="line.351"></a>
-<span class="sourceLineNo">352</span>      Bytes.toBytes("b"), Bytes.toBytes("c"), Bytes.toBytes("d")<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    };<a name="line.353"></a>
+<span class="sourceLineNo">315</span>    // and load the table<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    UTIL.loadRegion(region, TEST_FAM);<a name="line.316"></a>
+<span class="sourceLineNo">317</span><a name="line.317"></a>
+<span class="sourceLineNo">318</span>    // shutdown the table so we can manipulate the files<a name="line.318"></a>
+<span class="sourceLineNo">319</span>    admin.disableTable(tableName);<a name="line.319"></a>
+<span class="sourceLineNo">320</span><a name="line.320"></a>
+<span class="sourceLineNo">321</span>    FileSystem fs = UTIL.getTestFileSystem();<a name="line.321"></a>
+<span class="sourceLineNo">322</span><a name="line.322"></a>
+<span class="sourceLineNo">323</span>    // now attempt to depose the region<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    Path rootDir = region.getRegionFileSystem().getTableDir().getParent();<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    Path regionDir = FSUtils.getRegionDirFromRootDir(rootDir, region.getRegionInfo());<a name="line.325"></a>
+<span class="sourceLineNo">326</span><a name="line.326"></a>
+<span class="sourceLineNo">327</span>    HFileArchiver.archiveRegion(UTIL.getConfiguration(), fs, region.getRegionInfo());<a name="line.327"></a>
+<span class="sourceLineNo">328</span><a name="line.328"></a>
+<span class="sourceLineNo">329</span>    // check for the existence of the archive directory and some files in it<a name="line.329"></a>
+<span class="sourceLineNo">330</span>    Path archiveDir = HFileArchiveTestingUtil.getRegionArchiveDir(UTIL.getConfiguration(), region);<a name="line.330"></a>
+<span class="sourceLineNo">331</span>    assertTrue(fs.exists(archiveDir));<a name="line.331"></a>
+<span class="sourceLineNo">332</span><a name="line.332"></a>
+<span class="sourceLineNo">333</span>    // check to make sure the store directory was copied<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    FileStatus[] stores = fs.listStatus(archiveDir, new PathFilter() {<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      @Override<a name="line.335"></a>
+<span class="sourceLineNo">336</span>      public boolean accept(Path p) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>        if (p.getName().contains(HConstants.RECOVERED_EDITS_DIR)) {<a name="line.337"></a>
+<span class="sourceLineNo">338</span>          return false;<a name="line.338"></a>
+<span class="sourceLineNo">339</span>        }<a name="line.339"></a>
+<span class="sourceLineNo">340</span>        return true;<a name="line.340"></a>
+<span class="sourceLineNo">341</span>      }<a name="line.341"></a>
+<span class="sourceLineNo">342</span>    });<a name="line.342"></a>
+<span class="sourceLineNo">343</span>    assertTrue(stores.length == 1);<a name="line.343"></a>
+<span class="sourceLineNo">344</span><a name="line.344"></a>
+<span class="sourceLineNo">345</span>    // make sure we archived the store files<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    FileStatus[] storeFiles = fs.listStatus(stores[0].getPath());<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    assertTrue(storeFiles.length &gt; 0);<a name="line.347"></a>
+<span class="sourceLineNo">348</span><a name="line.348"></a>
+<span class="sourceLineNo">349</span>    // then ensure the region's directory isn't present<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    assertFalse(fs.exists(regionDir));<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>    UTIL.deleteTable(tableName);<a name="line.352"></a>
+<span class="sourceLineNo">353</span>  }<a name="line.353"></a>
 <span class="sourceLineNo">354</span><a name="line.354"></a>
-<span class="sourceLineNo">355</span>    UTIL.createTable(tableName, TEST_FAM, splitKeys);<a name="line.355"></a>
-<span class="sourceLineNo">356</span><a name="line.356"></a>
-<span class="sourceLineNo">357</span>    // get the current store files for the regions<a name="line.357"></a>
-<span class="sourceLineNo">358</span>    List&lt;HRegion&gt; regions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.358"></a>
-<span class="sourceLineNo">359</span>    // make sure we have 4 regions serving this table<a name="line.359"></a>
-<span class="sourceLineNo">360</span>    assertEquals(4, regions.size());<a name="line.360"></a>
-<span class="sourceLineNo">361</span><a name="line.361"></a>
-<span class="sourceLineNo">362</span>    // and load the table<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    try (Table table = UTIL.getConnection().getTable(tableName)) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      UTIL.loadTable(table, TEST_FAM);<a name="line.364"></a>
-<span class="sourceLineNo">365</span>    }<a name="line.365"></a>
-<span class="sourceLineNo">366</span><a name="line.366"></a>
-<span class="sourceLineNo">367</span>    // disable the table so that we can manipulate the files<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    UTIL.getAdmin().disableTable(tableName);<a name="line.368"></a>
-<span class="sourceLineNo">369</span><a name="line.369"></a>
-<span class="sourceLineNo">370</span>    return regions;<a name="line.370"></a>
-<span class="sourceLineNo">371</span>  }<a name="line.371"></a>
-<span class="sourceLineNo">372</span><a name="line.372"></a>
-<span class="sourceLineNo">373</span>  @Test<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  public void testArchiveRegions() throws Exception {<a name="line.374"></a>
-<span class="sourceLineNo">375</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.375"></a>
-<span class="sourceLineNo">376</span>    List&lt;HRegion&gt; regions = initTableForArchivingRegions(tableName);<a name="line.376"></a>
-<span class="sourceLineNo">377</span><a name="line.377"></a>
-<span class="sourceLineNo">378</span>    FileSystem fs = UTIL.getTestFileSystem();<a name="line.378"></a>
-<span class="sourceLineNo">379</span><a name="line.379"></a>
-<span class="sourceLineNo">380</span>    // now attempt to depose the regions<a name="line.380"></a>
-<span class="sourceLineNo">381</span>    Path rootDir = CommonFSUtils.getRootDir(UTIL.getConfiguration());<a name="line.381"></a>
-<span class="sourceLineNo">382</span>    Path tableDir = CommonFSUtils.getTableDir(rootDir, regions.get(0).getRegionInfo().getTable());<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    List&lt;Path&gt; regionDirList = regions.stream()<a name="line.383"></a>
-<span class="sourceLineNo">384</span>      .map(region -&gt; FSUtils.getRegionDirFromTableDir(tableDir, region.getRegionInfo()))<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      .collect(Collectors.toList());<a name="line.385"></a>
-<span class="sourceLineNo">386</span><a name="line.386"></a>
-<span class="sourceLineNo">387</span>    HFileArchiver.archiveRegions(UTIL.getConfiguration(), fs, rootDir, tableDir, regionDirList);<a name="line.387"></a>
-<span class="sourceLineNo">388</span><a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // check for the existence of the archive directory and some files in it<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    for (HRegion region : regions) {<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      Path archiveDir = HFileArchiveTestingUtil.getRegionArchiveDir(UTIL.getConfiguration(),<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        region);<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      assertTrue(fs.exists(archiveDir));<a name="line.393"></a>
-<span class="sourceLineNo">394</span><a name="line.394"></a>
-<span class="sourceLineNo">395</span>      // check to make sure the store directory was copied<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      FileStatus[] stores = fs.listStatus(archiveDir,<a name="line.396"></a>
-<span class="sourceLineNo">397</span>        p -&gt; !p.getName().contains(HConstants.RECOVERED_EDITS_DIR));<a name="line.397"></a>
-<span class="sourceLineNo">398</span>      assertTrue(stores.length == 1);<a name="line.398"></a>
+<span class="sourceLineNo">355</span>  /**<a name="line.355"></a>
+<span class="sourceLineNo">356</span>   * Test that the region directory is removed when we archive a region without store files, but<a name="line.356"></a>
+<span class="sourceLineNo">357</span>   * still has hidden files.<a name="line.357"></a>
+<span class="sourceLineNo">358</span>   * @throws IOException throws an IOException if there's problem creating a table<a name="line.358"></a>
+<span class="sourceLineNo">359</span>   *   or if there's an issue with accessing FileSystem.<a name="line.359"></a>
+<span class="sourceLineNo">360</span>   */<a name="line.360"></a>
+<span class="sourceLineNo">361</span>  @Test<a name="line.361"></a>
+<span class="sourceLineNo">362</span>  public void testDeleteRegionWithNoStoreFiles() throws IOException {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.363"></a>
+<span class="sourceLineNo">364</span>    UTIL.createTable(tableName, TEST_FAM);<a name="line.364"></a>
+<span class="sourceLineNo">365</span><a name="line.365"></a>
+<span class="sourceLineNo">366</span>    // get the current store files for the region<a name="line.366"></a>
+<span class="sourceLineNo">367</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>    // make sure we only have 1 region serving this table<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    assertEquals(1, servingRegions.size());<a name="line.369"></a>
+<span class="sourceLineNo">370</span>    HRegion region = servingRegions.get(0);<a name="line.370"></a>
+<span class="sourceLineNo">371</span><a name="line.371"></a>
+<span class="sourceLineNo">372</span>    FileSystem fs = region.getRegionFileSystem().getFileSystem();<a name="line.372"></a>
+<span class="sourceLineNo">373</span><a name="line.373"></a>
+<span class="sourceLineNo">374</span>    // make sure there are some files in the regiondir<a name="line.374"></a>
+<span class="sourceLineNo">375</span>    Path rootDir = CommonFSUtils.getRootDir(fs.getConf());<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    Path regionDir = FSUtils.getRegionDirFromRootDir(rootDir, region.getRegionInfo());<a name="line.376"></a>
+<span class="sourceLineNo">377</span>    FileStatus[] regionFiles = CommonFSUtils.listStatus(fs, regionDir, null);<a name="line.377"></a>
+<span class="sourceLineNo">378</span>    Assert.assertNotNull("No files in the region directory", regionFiles);<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    if (LOG.isDebugEnabled()) {<a name="line.379"></a>
+<span class="sourceLineNo">380</span>      List&lt;Path&gt; files = new ArrayList&lt;&gt;();<a name="line.380"></a>
+<span class="sourceLineNo">381</span>      for (FileStatus file : regionFiles) {<a name="line.381"></a>
+<span class="sourceLineNo">382</span>        files.add(file.getPath());<a name="line.382"></a>
+<span class="sourceLineNo">383</span>      }<a name="line.383"></a>
+<span class="sourceLineNo">384</span>      LOG.debug("Current files:" + files);<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    }<a name="line.385"></a>
+<span class="sourceLineNo">386</span>    // delete the visible folders so we just have hidden files/folders<a name="line.386"></a>
+<span class="sourceLineNo">387</span>    final PathFilter dirFilter = new FSUtils.DirFilter(fs);<a name="line.387"></a>
+<span class="sourceLineNo">388</span>    PathFilter nonHidden = new PathFilter() {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>      @Override<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      public boolean accept(Path file) {<a name="line.390"></a>
+<span class="sourceLineNo">391</span>        return dirFilter.accept(file) &amp;&amp; !file.getName().startsWith(".");<a name="line.391"></a>
+<span class="sourceLineNo">392</span>      }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>    };<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    FileStatus[] storeDirs = CommonFSUtils.listStatus(fs, regionDir, nonHidden);<a name="line.394"></a>
+<span class="sourceLineNo">395</span>    for (FileStatus store : storeDirs) {<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      LOG.debug("Deleting store for test");<a name="line.396"></a>
+<span class="sourceLineNo">397</span>      fs.delete(store.getPath(), true);<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    }<a name="line.398"></a>
 <span class="sourceLineNo">399</span><a name="line.399"></a>
-<span class="sourceLineNo">400</span>      // make sure we archived the store files<a name="line.400"></a>
-<span class="sourceLineNo">401</span>      FileStatus[] storeFiles = fs.listStatus(stores[0].getPath());<a name="line.401"></a>
-<span class="sourceLineNo">402</span>      assertTrue(storeFiles.length &gt; 0);<a name="line.402"></a>
-<span class="sourceLineNo">403</span>    }<a name="line.403"></a>
-<span class="sourceLineNo">404</span><a name="line.404"></a>
-<span class="sourceLineNo">405</span>    // then ensure the region's directories aren't present<a name="line.405"></a>
-<span class="sourceLineNo">406</span>    for (Path regionDir: regionDirList) {<a name="line.406"></a>
-<span class="sourceLineNo">407</span>      assertFalse(fs.exists(regionDir));<a name="line.407"></a>
-<span class="sourceLineNo">408</span>    }<a name="line.408"></a>
-<span class="sourceLineNo">409</span><a name="line.409"></a>
-<span class="sourceLineNo">410</span>    UTIL.deleteTable(tableName);<a name="line.410"></a>
-<span class="sourceLineNo">411</span>  }<a name="line.411"></a>
-<span class="sourceLineNo">412</span><a name="line.412"></a>
-<span class="sourceLineNo">413</span>  @Test(expected=IOException.class)<a name="line.413"></a>
-<span class="sourceLineNo">414</span>  public void testArchiveRegionsWhenPermissionDenied() throws Exception {<a name="line.414"></a>
-<span class="sourceLineNo">415</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.415"></a>
-<span class="sourceLineNo">416</span>    List&lt;HRegion&gt; regions = initTableForArchivingRegions(tableName);<a name="line.416"></a>
-<span class="sourceLineNo">417</span><a name="line.417"></a>
-<span class="sourceLineNo">418</span>    // now attempt to depose the regions<a name="line.418"></a>
-<span class="sourceLineNo">419</span>    Path rootDir = CommonFSUtils.getRootDir(UTIL.getConfiguration());<a name="line.419"></a>
-<span class="sourceLineNo">420</span>    Path tableDir = CommonFSUtils.getTableDir(rootDir, regions.get(0).getRegionInfo().getTable());<a name="line.420"></a>
-<span class="sourceLineNo">421</span>    List&lt;Path&gt; regionDirList = regions.stream()<a name="line.421"></a>
-<span class="sourceLineNo">422</span>      .map(region -&gt; FSUtils.getRegionDirFromTableDir(tableDir, region.getRegionInfo()))<a name="line.422"></a>
-<span class="sourceLineNo">423</span>      .collect(Collectors.toList());<a name="line.423"></a>
-<span class="sourceLineNo">424</span><a name="line.424"></a>
-<span class="sourceLineNo">425</span>    // To create a permission denied error, we do archive regions as a non-current user<a name="line.425"></a>
-<span class="sourceLineNo">426</span>    UserGroupInformation<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      ugi = UserGroupInformation.createUserForTesting("foo1234", new String[]{"group1"});<a name="line.427"></a>
+<span class="sourceLineNo">400</span>    // then archive the region<a name="line.400"></a>
+<span class="sourceLineNo">401</span>    HFileArchiver.archiveRegion(UTIL.getConfiguration(), fs, region.getRegionInfo());<a name="line.401"></a>
+<span class="sourceLineNo">402</span><a name="line.402"></a>
+<span class="sourceLineNo">403</span>    // and check to make sure the region directoy got deleted<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    assertFalse("Region directory (" + regionDir + "), still exists.", fs.exists(regionDir));<a name="line.404"></a>
+<span class="sourceLineNo">405</span><a name="line.405"></a>
+<span class="sourceLineNo">406</span>    UTIL.deleteTable(tableName);<a name="line.406"></a>
+<span class="sourceLineNo">407</span>  }<a name="line.407"></a>
+<span class="sourceLineNo">408</span><a name="line.408"></a>
+<span class="sourceLineNo">409</span>  private List&lt;HRegion&gt; initTableForArchivingRegions(TableName tableName) throws IOException {<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    final byte[][] splitKeys = new byte[][] {<a name="line.410"></a>
+<span class="sourceLineNo">411</span>      Bytes.toBytes("b"), Bytes.toBytes("c"), Bytes.toBytes("d")<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    };<a name="line.412"></a>
+<span class="sourceLineNo">413</span><a name="line.413"></a>
+<span class="sourceLineNo">414</span>    UTIL.createTable(tableName, TEST_FAM, splitKeys);<a name="line.414"></a>
+<span class="sourceLineNo">415</span><a name="line.415"></a>
+<span class="sourceLineNo">416</span>    // get the current store files for the regions<a name="line.416"></a>
+<span class="sourceLineNo">417</span>    List&lt;HRegion&gt; regions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    // make sure we have 4 regions serving this table<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    assertEquals(4, regions.size());<a name="line.419"></a>
+<span class="sourceLineNo">420</span><a name="line.420"></a>
+<span class="sourceLineNo">421</span>    // and load the table<a name="line.421"></a>
+<span class="sourceLineNo">422</span>    try (Table table = UTIL.getConnection().getTable(tableName)) {<a name="line.422"></a>
+<span class="sourceLineNo">423</span>      UTIL.loadTable(table, TEST_FAM);<a name="line.423"></a>
+<span class="sourceLineNo">424</span>    }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>    // disable the table so that we can manipulate the files<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    UTIL.getAdmin().disableTable(tableName);<a name="line.427"></a>
 <span class="sourceLineNo">428</span><a name="line.428"></a>
-<span class="sourceLineNo">429</span>    try {<a name="line.429"></a>
-<span class="sourceLineNo">430</span>      ugi.doAs((PrivilegedExceptionAction&lt;Void&gt;) () -&gt; {<a name="line.430"></a>
-<span class="sourceLineNo">431</span>        FileSystem fs = UTIL.getTestFileSystem();<a name="line.431"></a>
-<span class="sourceLineNo">432</span>        HFileArchiver.archiveRegions(UTIL.getConfiguration(), fs, rootDir, tableDir,<a name="line.432"></a>
-<span class="sourceLineNo">433</span>          regionDirList);<a name="line.433"></a>
-<span class="sourceLineNo">434</span>        return null;<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      });<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    } catch (IOException e) {<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      assertTrue(e.getCause().getMessage().contains("Permission denied"));<a name="line.437"></a>
-<span class="sourceLineNo">438</span>      throw e;<a name="line.438"></a>
-<span class="sourceLineNo">439</span>    } finally {<a name="line.439"></a>
-<span class="sourceLineNo">440</span>      UTIL.deleteTable(tableName);<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    }<a name="line.441"></a>
-<span class="sourceLineNo">442</span>  }<a name="line.442"></a>
-<span class="sourceLineNo">443</span><a name="line.443"></a>
-<span class="sourceLineNo">444</span>  @Test<a name="line.444"></a>
-<span class="sourceLineNo">445</span>  public void testArchiveOnTableDelete() throws Exception {<a name="line.445"></a>
-<span class="sourceLineNo">446</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.446"></a>
-<span class="sourceLineNo">447</span>    UTIL.createTable(tableName, TEST_FAM);<a name="line.447"></a>
-<span class="sourceLineNo">448</span><a name="line.448"></a>
-<span class="sourceLineNo">449</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    // make sure we only have 1 region serving this table<a name="line.450"></a>
-<span class="sourceLineNo">451</span>    assertEquals(1, servingRegions.size());<a name="line.451"></a>
-<span class="sourceLineNo">452</span>    HRegion region = servingRegions.get(0);<a name="line.452"></a>
+<span class="sourceLineNo">429</span>    return regions;<a name="line.429"></a>
+<span class="sourceLineNo">430</span>  }<a name="line.430"></a>
+<span class="sourceLineNo">431</span><a name="line.431"></a>
+<span class="sourceLineNo">432</span>  @Test<a name="line.432"></a>
+<span class="sourceLineNo">433</span>  public void testArchiveRegions() throws Exception {<a name="line.433"></a>
+<span class="sourceLineNo">434</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.434"></a>
+<span class="sourceLineNo">435</span>    List&lt;HRegion&gt; regions = initTableForArchivingRegions(tableName);<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>    FileSystem fs = UTIL.getTestFileSystem();<a name="line.437"></a>
+<span class="sourceLineNo">438</span><a name="line.438"></a>
+<span class="sourceLineNo">439</span>    // now attempt to depose the regions<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    Path rootDir = CommonFSUtils.getRootDir(UTIL.getConfiguration());<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    Path tableDir = CommonFSUtils.getTableDir(rootDir, regions.get(0).getRegionInfo().getTable());<a name="line.441"></a>
+<span class="sourceLineNo">442</span>    List&lt;Path&gt; regionDirList = regions.stream()<a name="line.442"></a>
+<span class="sourceLineNo">443</span>      .map(region -&gt; FSUtils.getRegionDirFromTableDir(tableDir, region.getRegionInfo()))<a name="line.443"></a>
+<span class="sourceLineNo">444</span>      .collect(Collectors.toList());<a name="line.444"></a>
+<span class="sourceLineNo">445</span><a name="line.445"></a>
+<span class="sourceLineNo">446</span>    HFileArchiver.archiveRegions(UTIL.getConfiguration(), fs, rootDir, tableDir, regionDirList);<a name="line.446"></a>
+<span class="sourceLineNo">447</span><a name="line.447"></a>
+<span class="sourceLineNo">448</span>    // check for the existence of the archive directory and some files in it<a name="line.448"></a>
+<span class="sourceLineNo">449</span>    for (HRegion region : regions) {<a name="line.449"></a>
+<span class="sourceLineNo">450</span>      Path archiveDir = HFileArchiveTestingUtil.getRegionArchiveDir(UTIL.getConfiguration(),<a name="line.450"></a>
+<span class="sourceLineNo">451</span>        region);<a name="line.451"></a>
+<span class="sourceLineNo">452</span>      assertTrue(fs.exists(archiveDir));<a name="line.452"></a>
 <span class="sourceLineNo">453</span><a name="line.453"></a>
-<span class="sourceLineNo">454</span>    // get the parent RS and monitor<a name="line.454"></a>
-<span class="sourceLineNo">455</span>    HRegionServer hrs = UTIL.getRSForFirstRegionInTable(tableName);<a name="line.455"></a>
-<span class="sourceLineNo">456</span>    FileSystem fs = hrs.getFileSystem();<a name="line.456"></a>
-<span class="sourceLineNo">457</span><a name="line.457"></a>
-<span class="sourceLineNo">458</span>    // put some data on the region<a name="line.458"></a>
-<span class="sourceLineNo">459</span>    LOG.debug("-------Loading table");<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    UTIL.loadRegion(region, TEST_FAM);<a name="line.460"></a>
-<span class="sourceLineNo">461</span><a name="line.461"></a>
-<span class="sourceLineNo">462</span>    // get the hfiles in the region<a name="line.462"></a>
-<span class="sourceLineNo">463</span>    List&lt;HRegion&gt; regions = hrs.getRegions(tableName);<a name="line.463"></a>
-<span class="sourceLineNo">464</span>    assertEquals("More that 1 region for test table.", 1, regions.size());<a name="line.464"></a>
-<span class="sourceLineNo">465</span><a name="line.465"></a>
-<span class="sourceLineNo">466</span>    region = regions.get(0);<a name="line.466"></a>
-<span class="sourceLineNo">467</span>    // wait for all the compactions to complete<a name="line.467"></a>
-<span class="sourceLineNo">468</span>    region.waitForFlushesAndCompactions();<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>    // disable table to prevent new updates<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    UTIL.getAdmin().disableTable(tableName);<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    LOG.debug("Disabled table");<a name="line.472"></a>
-<span class="sourceLineNo">473</span><a name="line.473"></a>
-<span class="sourceLineNo">474</span>    // remove all the files from the archive to get a fair comparison<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    clearArchiveDirectory();<a name="line.475"></a>
+<span class="sourceLineNo">454</span>      // check to make sure the store directory was copied<a name="line.454"></a>
+<span class="sourceLineNo">455</span>      FileStatus[] stores = fs.listStatus(archiveDir,<a name="line.455"></a>
+<span class="sourceLineNo">456</span>        p -&gt; !p.getName().contains(HConstants.RECOVERED_EDITS_DIR));<a name="line.456"></a>
+<span class="sourceLineNo">457</span>      assertTrue(stores.length == 1);<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>      // make sure we archived the store files<a name="line.459"></a>
+<span class="sourceLineNo">460</span>      FileStatus[] storeFiles = fs.listStatus(stores[0].getPath());<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      assertTrue(storeFiles.length &gt; 0);<a name="line.461"></a>
+<span class="sourceLineNo">462</span>    }<a name="line.462"></a>
+<span class="sourceLineNo">463</span><a name="line.463"></a>
+<span class="sourceLineNo">464</span>    // then ensure the region's directories aren't present<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    for (Path regionDir: regionDirList) {<a name="line.465"></a>
+<span class="sourceLineNo">466</span>      assertFalse(fs.exists(regionDir));<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    }<a name="line.467"></a>
+<span class="sourceLineNo">468</span><a name="line.468"></a>
+<span class="sourceLineNo">469</span>    UTIL.deleteTable(tableName);<a name="line.469"></a>
+<span class="sourceLineNo">470</span>  }<a name="line.470"></a>
+<span class="sourceLineNo">471</span><a name="line.471"></a>
+<span class="sourceLineNo">472</span>  @Test(expected=IOException.class)<a name="line.472"></a>
+<span class="sourceLineNo">473</span>  public void testArchiveRegionsWhenPermissionDenied() throws Exception {<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.474"></a>
+<span class="sourceLineNo">475</span>    List&lt;HRegion&gt; regions = initTableForArchivingRegions(tableName);<a name="line.475"></a>
 <span class="sourceLineNo">476</span><a name="line.476"></a>
-<span class="sourceLineNo">477</span>    // then get the current store files<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    byte[][]columns = region.getTableDescriptor().getColumnFamilyNames().toArray(new byte[0][]);<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    List&lt;String&gt; storeFiles = region.getStoreFileList(columns);<a name="line.479"></a>
-<span class="sourceLineNo">480</span><a name="line.480"></a>
-<span class="sourceLineNo">481</span>    // then delete the table so the hfiles get archived<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    UTIL.deleteTable(tableName);<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    LOG.debug("Deleted table");<a name="line.483"></a>
-<span class="sourceLineNo">484</span><a name="line.484"></a>
-<span class="sourceLineNo">485</span>    assertArchiveFiles(fs, storeFiles, 30000);<a name="line.485"></a>
-<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">477</span>    // now attempt to depose the regions<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    Path rootDir = CommonFSUtils.getRootDir(UTIL.getConfiguration());<a name="line.478"></a>
+<span class="sourceLineNo">479</span>    Path tableDir = CommonFSUtils.getTableDir(rootDir, regions.get(0).getRegionInfo().getTable());<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    List&lt;Path&gt; regionDirList = regions.stream()<a name="line.480"></a>
+<span class="sourceLineNo">481</span>      .map(region -&gt; FSUtils.getRegionDirFromTableDir(tableDir, region.getRegionInfo()))<a name="line.481"></a>
+<span class="sourceLineNo">482</span>      .collect(Collectors.toList());<a name="line.482"></a>
+<span class="sourceLineNo">483</span><a name="line.483"></a>
+<span class="sourceLineNo">484</span>    // To create a permission denied error, we do archive regions as a non-current user<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    UserGroupInformation<a name="line.485"></a>
+<span class="sourceLineNo">486</span>      ugi = UserGroupInformation.createUserForTesting("foo1234", new String[]{"group1"});<a name="line.486"></a>
 <span class="sourceLineNo">487</span><a name="line.487"></a>
-<span class="sourceLineNo">488</span>  private void assertArchiveFiles(FileSystem fs, List&lt;String&gt; storeFiles, long timeout)<a name="line.488"></a>
-<span class="sourceLineNo">489</span>          throws IOException {<a name="line.489"></a>
-<span class="sourceLineNo">490</span>    long end = EnvironmentEdgeManager.currentTime() + timeout;<a name="line.490"></a>
-<span class="sourceLineNo">491</span>    Path archiveDir = HFileArchiveUtil.getArchivePath(UTIL.getConfiguration());<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    List&lt;String&gt; archivedFiles = new ArrayList&lt;&gt;();<a name="line.492"></a>
-<span class="sourceLineNo">493</span><a name="line.493"></a>
-<span class="sourceLineNo">494</span>    // We have to ensure that the DeleteTableHandler is finished. HBaseAdmin.deleteXXX()<a name="line.494"></a>
-<span class="sourceLineNo">495</span>    // can return before all files<a name="line.495"></a>
-<span class="sourceLineNo">496</span>    // are archived. We should fix HBASE-5487 and fix synchronous operations from admin.<a name="line.496"></a>
-<span class="sourceLineNo">497</span>    while (EnvironmentEdgeManager.currentTime() &lt; end) {<a name="line.497"></a>
-<span class="sourceLineNo">498</span>      archivedFiles = getAllFileNames(fs, archiveDir);<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      if (archivedFiles.size() &gt;= storeFiles.size()) {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>        break;<a name="line.500"></a>
-<span class="sourceLineNo">501</span>      }<a name="line.501"></a>
-<span class="sourceLineNo">502</span>    }<a name="line.502"></a>
-<span class="sourceLineNo">503</span><a name="line.503"></a>
-<span class="sourceLineNo">504</span>    Collections.sort(storeFiles);<a name="line.504"></a>
-<span class="sourceLineNo">505</span>    Collections.sort(archivedFiles);<a name="line.505"></a>
-<span class="sourceLineNo">506</span><a name="line.506"></a>
-<span class="sourceLineNo">507</span>    LOG.debug("Store files:");<a name="line.507"></a>
-<span class="sourceLineNo">508</span>    for (int i = 0; i &lt; storeFiles.size(); i++) {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>      LOG.debug(i + " - " + storeFiles.get(i));<a name="line.509"></a>
-<span class="sourceLineNo">510</span>    }<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    LOG.debug("Archive files:");<a name="line.511"></a>
-<span class="sourceLineNo">512</span>    for (int i = 0; i &lt; archivedFiles.size(); i++) {<a name="line.512"></a>
-<span class="sourceLineNo">513</span>      LOG.debug(i + " - " + archivedFiles.get(i));<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    }<a name="line.514"></a>
-<span class="sourceLineNo">515</span><a name="line.515"></a>
-<span class="sourceLineNo">516</span>    assertTrue("Archived files are missing some of the store files!",<a name="line.516"></a>
-<span class="sourceLineNo">517</span>      archivedFiles.containsAll(storeFiles));<a name="line.517"></a>
-<span class="sourceLineNo">518</span>  }<a name="line.518"></a>
-<span class="sourceLineNo">519</span><a name="line.519"></a>
+<span class="sourceLineNo">488</span>    try {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>      ugi.doAs((PrivilegedExceptionAction&lt;Void&gt;) () -&gt; {<a name="line.489"></a>
+<span class="sourceLineNo">490</span>        FileSystem fs = UTIL.getTestFileSystem();<a name="line.490"></a>
+<span class="sourceLineNo">491</span>        HFileArchiver.archiveRegions(UTIL.getConfiguration(), fs, rootDir, tableDir,<a name="line.491"></a>
+<span class="sourceLineNo">492</span>          regionDirList);<a name="line.492"></a>
+<span class="sourceLineNo">493</span>        return null;<a name="line.493"></a>
+<span class="sourceLineNo">494</span>      });<a name="line.494"></a>
+<span class="sourceLineNo">495</span>    } catch (IOException e) {<a name="line.495"></a>
+<span class="sourceLineNo">496</span>      assertTrue(e.getCause().getMessage().contains("Permission denied"));<a name="line.496"></a>
+<span class="sourceLineNo">497</span>      throw e;<a name="line.497"></a>
+<span class="sourceLineNo">498</span>    } finally {<a name="line.498"></a>
+<span class="sourceLineNo">499</span>      UTIL.deleteTable(tableName);<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    }<a name="line.500"></a>
+<span class="sourceLineNo">501</span>  }<a name="line.501"></a>
+<span class="sourceLineNo">502</span><a name="line.502"></a>
+<span class="sourceLineNo">503</span>  @Test<a name="line.503"></a>
+<span class="sourceLineNo">504</span>  public void testArchiveOnTableDelete() throws Exception {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.505"></a>
+<span class="sourceLineNo">506</span>    UTIL.createTable(tableName, TEST_FAM);<a name="line.506"></a>
+<span class="sourceLineNo">507</span><a name="line.507"></a>
+<span class="sourceLineNo">508</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.508"></a>
+<span class="sourceLineNo">509</span>    // make sure we only have 1 region serving this table<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    assertEquals(1, servingRegions.size());<a name="line.510"></a>
+<span class="sourceLineNo">511</span>    HRegion region = servingRegions.get(0);<a name="line.511"></a>
+<span class="sourceLineNo">512</span><a name="line.512"></a>
+<span class="sourceLineNo">513</span>    // get the parent RS and monitor<a name="line.513"></a>
+<span class="sourceLineNo">514</span>    HRegionServer hrs = UTIL.getRSForFirstRegionInTable(tableName);<a name="line.514"></a>
+<span class="sourceLineNo">515</span>    FileSystem fs = hrs.getFileSystem();<a name="line.515"></a>
+<span class="sourceLineNo">516</span><a name="line.516"></a>
+<span class="sourceLineNo">517</span>    // put some data on the region<a name="line.517"></a>
+<span class="sourceLineNo">518</span>    LOG.debug("-------Loading table");<a name="line.518"></a>
+<span class="sourceLineNo">519</span>    UTIL.loadRegion(region, TEST_FAM);<a name="line.519"></a>
 <span class="sourceLineNo">520</span><a name="line.520"></a>
-<span class="sourceLineNo">521</span>  /**<a name="line.521"></a>
-<span class="sourceLineNo">522</span>   * Test that the store files are archived when a column family is removed.<a name="line.522"></a>
-<span class="sourceLineNo">523</span>   * @throws java.io.IOException if there's a problem creating a table.<a name="line.523"></a>
-<span class="sourceLineNo">524</span>   * @throws java.lang.InterruptedException problem getting a RegionServer.<a name="line.524"></a>
-<span class="sourceLineNo">525</span>   */<a name="line.525"></a>
-<span class="sourceLineNo">526</span>  @Test<a name="line.526"></a>
-<span class="sourceLineNo">527</span>  public void testArchiveOnTableFamilyDelete() throws IOException, InterruptedException {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>    final TableName tableName = TableName.valueOf(name.getMethodName());<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    UTIL.createTable(tableName, new byte[][] {TEST_FAM, Bytes.toBytes("fam2")});<a name="line.529"></a>
-<span class="sourceLineNo">530</span><a name="line.530"></a>
-<span class="sourceLineNo">531</span>    List&lt;HRegion&gt; servingRegions = UTIL.getHBaseCluster().getRegions(tableName);<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    // make sure we only have 1 region serving this table<a name="line.532"></a>
-<span class="sourceLineNo">533</span>    assertEquals(1, servingRegions.size());<a name="line.533"></a>
-<span class="sourceLineNo">534</span>    HRegion region = servingRegions.get(0);<a name="line.534"></a>
+<span class="sourceLineNo">521</span>    // get the hfiles in the region<a name="line.521"></a>
+<span class="sourceLineNo">522</span>    List&lt;HRegion&gt; regions = hrs.getRegions(tableName);<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    assertEquals("More that 1 region for test table.", 1, regions.size());<a name="line.523"></a>
+<span class="sourceLineNo">524</span><a name="line.524"></a>
+<span class="sourceLineNo">525</span>    region = regions.get(0);<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    // wait for all the compactions to complete<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    region.waitForFlushesAndCompactions();<a name="line.527"></a>
+<span class="sourceLineNo">528</span><a name="line.528"></a>
+<span class="sourceLineNo">529</span>    // disable table to prevent new updates<a name="line.529"></a>
+<span class="sourceLineNo">530</span>    UTIL.getAdmin().disableTable(tableName);<a name="line.530"></a>
+<span class="sourceLineNo">531</span>    LOG.debug("Disabled table");<a name="line.531"></a>
+<span class="sourceLineNo">532</span><a name="line.532"></a>
+<span class="sourceLineNo">533</span>    // remove all the files from the archive to get a fair comparison<a name="line.533"></a>
+<span class="sourceLineNo">534</span>    clearArchiveDirectory();<a name="line.534"></a>
 <span class="sourceLineNo">535</span><a name="line.535"></a>
-<span class="sourceLineNo">536</span>    // get the parent RS and monitor<a name="line.536"></a>
-<span class="sourceLineNo">537</span>    HRegionServer hrs = UTIL.getRSForFirstRegionInTable(tableName);<a name="line.537"></a>
-<span class="sourceLineNo">538</span>    FileSystem fs = hrs.getFileSystem();<a name="line.538"></a>
+<span class="sourceLineNo">536</span>    // then get the current store files<a name="line.536"></a>
+<span class="sourceLineNo">537</span>    byte[][]columns = region.getTableDescriptor().getColumnFamilyNames().toArray(new byte[0][]);<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    List&lt;String&gt; storeFiles = region.getStoreFileList(columns);<a name="line.538"></a>
 <span class="sourceLineNo">539</span><a name="line.539"></a>
-<span class="sourceLineNo">540</span>    // put some data on the region<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    LOG.debug("-------Loading table");<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    UTIL.loadRegion(region, TEST_FAM);<a name="line.542"></a>
+<span class="sourceLineNo">540</span>    // then delete the table so the hfiles get archived<a name="line.540"></a>
+<span class="sourceLineNo">541</span>    UTIL.deleteTable(tableName);<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    LOG.debug("Deleted table");<a name="line.542"></a>
 <span class="sourceLineNo">543</span><a name="line.543"></a>
-<span class="sourceLineNo">544</span>    // get the hfiles in the region<a name="line.544"></a>
-<span class="sourceLineNo">545</span>    List&lt;HRegion&gt; regions = hrs.getRegions(tableName);<a name="line.545"></a>
-<span class="sourceLineNo">546</span>    assertEquals("More that 1 region for test table.", 1, regions.size());<a name="line.546"></a>
-<span class="sourceLineNo">547</span><a name="line.547"></a>
-<span class="sourceLineNo">548</span>    region = regions.get(0);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>    // wait for all the compactions to complete<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    region.waitForFlushesAndCompactions();<a name="line.550"></a>
-<span class="sourceLineNo">551</span><a name="line.551"></a>
-<span class="sourceLineNo">552</span>    // disable table to prevent new updates<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    UTIL.getAdmin().disableTable(tableName);<a name="line.553"></a>
-<span class="sourceLineNo">554</span>    LOG.debug("Disabled table");<a name="line.554"></a>
-<span class="sourceLineNo">555</span><a name="line.555"></a>
-<span class="sourceLineNo">556</span>    // remove all the files from the archive to get a fair comparison<a name="line.556"></a>
-<span class="sourceLineNo">557</span>    clearArchiveDirectory();<a name="line.557"></a>
-<span class="sourceLineNo">558</span><a name="line.558"></a>
-<span class="sourceLineNo">559</span>    // then get the current store files<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    byte[][]columns = region.getTableDescriptor().getColumnFamilyNames().toArray(new byte[0][]);<a name="line.560"></a>
... 1879 lines suppressed ...