http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-protocol-shaded/src/main/protobuf/Admin.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/Admin.proto 
b/hbase-protocol-shaded/src/main/protobuf/Admin.proto
index e8cf10c..338c80b 100644
--- a/hbase-protocol-shaded/src/main/protobuf/Admin.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/Admin.proto
@@ -189,22 +189,6 @@ message UpdateFavoredNodesResponse {
   optional uint32 response = 1;
 }
 
-/**
- * Merges the specified regions.
- * <p>
- * This method currently closes the regions and then merges them
- */
-message MergeRegionsRequest {
-  required RegionSpecifier region_a = 1;
-  required RegionSpecifier region_b = 2;
-  optional bool forcible = 3 [default = false];
-  // wall clock time from master
-  optional uint64 master_system_time = 4;
-}
-
-message MergeRegionsResponse {
-}
-
 // Protocol buffer version of WAL for replication
 message WALEntry {
   required WALKey key = 1;
@@ -307,9 +291,6 @@ service AdminService {
   rpc CompactRegion(CompactRegionRequest)
     returns(CompactRegionResponse);
 
-  rpc MergeRegions(MergeRegionsRequest)
-    returns(MergeRegionsResponse);
-
   rpc ReplicateWALEntry(ReplicateWALEntryRequest)
     returns(ReplicateWALEntryResponse);
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-protocol-shaded/src/main/protobuf/Master.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/Master.proto 
b/hbase-protocol-shaded/src/main/protobuf/Master.proto
index 7cd9921..e62f52c 100644
--- a/hbase-protocol-shaded/src/main/protobuf/Master.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/Master.proto
@@ -80,21 +80,6 @@ message MoveRegionResponse {
 }
 
 /**
- * Dispatch merging the specified regions.
- */
-message DispatchMergingRegionsRequest {
-  required RegionSpecifier region_a = 1;
-  required RegionSpecifier region_b = 2;
-  optional bool forcible = 3 [default = false];
-  optional uint64 nonce_group = 4 [default = 0];
-  optional uint64 nonce = 5 [default = 0];
-}
-
-message DispatchMergingRegionsResponse {
-  optional uint64 proc_id = 1;
-}
-
-/**
  * Merging the specified regions in a table.
  */
 message MergeTableRegionsRequest {
@@ -625,10 +610,6 @@ service MasterService {
   rpc MoveRegion(MoveRegionRequest)
     returns(MoveRegionResponse);
 
- /** Master dispatch merging the regions */
-  rpc DispatchMergingRegions(DispatchMergingRegionsRequest)
-    returns(DispatchMergingRegionsResponse);
-
  /** Master merge the regions */
   rpc MergeTableRegions(MergeTableRegionsRequest)
     returns(MergeTableRegionsResponse);

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto 
b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto
index 23d914e..ef3f973 100644
--- a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto
@@ -262,21 +262,6 @@ message RestoreSnapshotStateData {
   repeated RestoreParentToChildRegionsPair parent_to_child_regions_pair_list = 
7;
 }
 
-enum DispatchMergingRegionsState {
-  DISPATCH_MERGING_REGIONS_PREPARE = 1;
-  DISPATCH_MERGING_REGIONS_PRE_OPERATION = 2;
-  DISPATCH_MERGING_REGIONS_MOVE_REGION_TO_SAME_RS = 3;
-  DISPATCH_MERGING_REGIONS_DO_MERGE_IN_RS = 4;
-  DISPATCH_MERGING_REGIONS_POST_OPERATION = 5;
-}
-
-message DispatchMergingRegionsStateData {
-  required UserInformation user_info = 1;
-  required TableName table_name = 2;
-  repeated RegionInfo region_info = 3;
-  optional bool forcible = 4;
-}
-
 enum MergeTableRegionsState {
   MERGE_TABLE_REGIONS_PREPARE = 1;
   MERGE_TABLE_REGIONS_MOVE_REGION_TO_SAME_RS = 2;

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java
index 00376cb..a0a1d49 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java
@@ -59,11 +59,23 @@ public class BaseMasterAndRegionObserver extends 
BaseRegionObserver
       HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
   }
 
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #preMergeRegions(ObserverContext, HRegionInfo[])}
+   */
+  @Deprecated
   @Override
   public void preDispatchMerge(final 
ObserverContext<MasterCoprocessorEnvironment> ctx,
       HRegionInfo regionA, HRegionInfo regionB) throws IOException {
   }
 
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #postMergeRegions(ObserverContext, HRegionInfo[])}
+   */
+  @Deprecated
   @Override
   public void postDispatchMerge(final 
ObserverContext<MasterCoprocessorEnvironment> ctx,
       HRegionInfo regionA, HRegionInfo regionB) throws IOException {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
index 461148b..98f21b2 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java
@@ -111,11 +111,23 @@ public class BaseMasterObserver implements MasterObserver 
{
       final HRegionInfo[] regions) throws IOException {
   }
 
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #preMergeRegions(ObserverContext, HRegionInfo[])}
+   */
+  @Deprecated
   @Override
   public void preDispatchMerge(final 
ObserverContext<MasterCoprocessorEnvironment> ctx,
       HRegionInfo regionA, HRegionInfo regionB) throws IOException {
   }
 
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #postMergeRegions(ObserverContext, HRegionInfo[])}
+   */
+  @Deprecated
   @Override
   public void postDispatchMerge(final 
ObserverContext<MasterCoprocessorEnvironment> ctx,
       HRegionInfo regionA, HRegionInfo regionB) throws IOException {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
index 82b3cfa..bb0e732 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
@@ -1699,7 +1699,11 @@ public interface MasterObserver extends Coprocessor {
    * @param regionA first region to be merged
    * @param regionB second region to be merged
    * @throws IOException if an error occurred on the coprocessor
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #preMergeRegions(ObserverContext, HRegionInfo[])}
    */
+  @Deprecated
   void preDispatchMerge(final ObserverContext<MasterCoprocessorEnvironment> 
ctx,
       HRegionInfo regionA, HRegionInfo regionB) throws IOException;
 
@@ -1709,7 +1713,11 @@ public interface MasterObserver extends Coprocessor {
    * @param regionA first region to be merged
    * @param regionB second region to be merged
    * @throws IOException if an error occurred on the coprocessor
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
+   *   (<a href="https://issues.apache.org/jira/browse/HBASE-";>HBASE-</a>).
+   *   Use {@link #postMergeRegions(ObserverContext, HRegionInfo[])}
    */
+  @Deprecated
   void postDispatchMerge(final ObserverContext<MasterCoprocessorEnvironment> c,
       final HRegionInfo regionA, final HRegionInfo regionB) throws IOException;
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index a41960b..ab7a25e 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -109,7 +109,6 @@ import 
org.apache.hadoop.hbase.master.procedure.CreateTableProcedure;
 import org.apache.hadoop.hbase.master.procedure.DeleteColumnFamilyProcedure;
 import org.apache.hadoop.hbase.master.procedure.DeleteTableProcedure;
 import org.apache.hadoop.hbase.master.procedure.DisableTableProcedure;
-import 
org.apache.hadoop.hbase.master.procedure.DispatchMergingRegionsProcedure;
 import org.apache.hadoop.hbase.master.procedure.EnableTableProcedure;
 import org.apache.hadoop.hbase.master.procedure.MasterProcedureConstants;
 import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
@@ -1419,55 +1418,6 @@ public class HMaster extends HRegionServer implements 
MasterServices {
   }
 
   @Override
-  public long dispatchMergingRegions(
-      final HRegionInfo regionInfoA,
-      final HRegionInfo regionInfoB,
-      final boolean forcible,
-      final long nonceGroup,
-      final long nonce) throws IOException {
-    checkInitialized();
-
-    TableName tableName = regionInfoA.getTable();
-    if (tableName == null || regionInfoB.getTable() == null) {
-      throw new UnknownRegionException ("Can't merge regions without table 
associated");
-    }
-
-    if (!tableName.equals(regionInfoB.getTable())) {
-      throw new IOException ("Cannot merge regions from two different tables");
-    }
-
-    if (regionInfoA.compareTo(regionInfoB) == 0) {
-      throw new MergeRegionException(
-        "Cannot merge a region to itself " + regionInfoA + ", " + regionInfoB);
-    }
-
-    HRegionInfo [] regionsToMerge = new HRegionInfo[2];
-    regionsToMerge [0] = regionInfoA;
-    regionsToMerge [1] = regionInfoB;
-
-    return MasterProcedureUtil.submitProcedure(
-        new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, 
nonce) {
-      @Override
-      protected void run() throws IOException {
-        getMaster().getMasterCoprocessorHost().preDispatchMerge(regionInfoA, 
regionInfoB);
-
-        LOG.info(getClientIdAuditPrefix() + " Merge regions "
-            + regionInfoA.getEncodedName() + " and " + 
regionInfoB.getEncodedName());
-
-        submitProcedure(new 
DispatchMergingRegionsProcedure(procedureExecutor.getEnvironment(),
-            tableName, regionsToMerge, forcible));
-
-        getMaster().getMasterCoprocessorHost().postDispatchMerge(regionInfoA, 
regionInfoB);
-      }
-
-      @Override
-      protected String getDescription() {
-        return "DisableTableProcedure";
-      }
-    });
-  }
-
-  @Override
   public long mergeRegions(
       final HRegionInfo[] regionsToMerge,
       final boolean forcible,

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
index 2f17a5f..3dec2e8 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
@@ -773,28 +773,6 @@ public class MasterCoprocessorHost
     });
   }
 
-  public void preDispatchMerge(final HRegionInfo regionInfoA, final 
HRegionInfo regionInfoB)
-      throws IOException {
-    execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
-      @Override
-      public void call(MasterObserver oserver, 
ObserverContext<MasterCoprocessorEnvironment> ctx)
-          throws IOException {
-        oserver.preDispatchMerge(ctx, regionInfoA, regionInfoB);
-      }
-    });
-  }
-
-  public void postDispatchMerge(final HRegionInfo regionInfoA, final 
HRegionInfo regionInfoB)
-      throws IOException {
-    execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
-      @Override
-      public void call(MasterObserver oserver, 
ObserverContext<MasterCoprocessorEnvironment> ctx)
-          throws IOException {
-        oserver.postDispatchMerge(ctx, regionInfoA, regionInfoB);
-      }
-    });
-  }
-
   public void preMergeRegions(final HRegionInfo[] regionsToMerge)
       throws IOException {
     execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index 5873986..1151c92 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -501,52 +501,6 @@ public class MasterRpcServices extends RSRpcServices
   }
 
   @Override
-  public DispatchMergingRegionsResponse dispatchMergingRegions(RpcController c,
-      DispatchMergingRegionsRequest request) throws ServiceException {
-    try {
-      master.checkInitialized();
-    } catch (IOException ioe) {
-      throw new ServiceException(ioe);
-    }
-
-    final byte[] encodedNameOfRegionA = request.getRegionA().getValue()
-      .toByteArray();
-    final byte[] encodedNameOfRegionB = request.getRegionB().getValue()
-      .toByteArray();
-    if (request.getRegionA().getType() != 
RegionSpecifierType.ENCODED_REGION_NAME
-        || request.getRegionB().getType() != 
RegionSpecifierType.ENCODED_REGION_NAME) {
-      LOG.warn("mergeRegions specifier type: expected: "
-        + RegionSpecifierType.ENCODED_REGION_NAME + " actual: region_a="
-        + request.getRegionA().getType() + ", region_b="
-        + request.getRegionB().getType());
-    }
-
-    RegionStates regionStates = 
master.getAssignmentManager().getRegionStates();
-    RegionState regionStateA = 
regionStates.getRegionState(Bytes.toString(encodedNameOfRegionA));
-    RegionState regionStateB = 
regionStates.getRegionState(Bytes.toString(encodedNameOfRegionB));
-    if (regionStateA == null || regionStateB == null) {
-      throw new ServiceException(new UnknownRegionException(
-          Bytes.toStringBinary(regionStateA == null ? encodedNameOfRegionA
-              : encodedNameOfRegionB)));
-    }
-
-    final HRegionInfo regionInfoA = regionStateA.getRegion();
-    final HRegionInfo regionInfoB = regionStateB.getRegion();
-
-    try {
-      long procId = master.dispatchMergingRegions(
-        regionInfoA,
-        regionInfoB,
-        request.getForcible(),
-        request.getNonceGroup(),
-        request.getNonce());
-      return 
DispatchMergingRegionsResponse.newBuilder().setProcId(procId).build();
-    } catch (IOException ioe) {
-      throw new ServiceException(ioe);
-    }
-  }
-
-  @Override
   public EnableCatalogJanitorResponse enableCatalogJanitor(RpcController c,
       EnableCatalogJanitorRequest req) throws ServiceException {
     try {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java
index 5019eda..79ebca5 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterServices.java
@@ -326,23 +326,6 @@ public interface MasterServices extends Server {
   boolean registerService(Service instance);
 
   /**
-   * Merge two regions. The real implementation is on the regionserver, master
-   * just move the regions together and send MERGE RPC to regionserver
-   * @param region_a region to merge
-   * @param region_b region to merge
-   * @param forcible true if do a compulsory merge, otherwise we will only 
merge
-   *          two adjacent regions
-   * @return procedure Id
-   * @throws IOException
-   */
-  long dispatchMergingRegions(
-    final HRegionInfo region_a,
-    final HRegionInfo region_b,
-    final boolean forcible,
-    final long nonceGroup,
-    final long nonce) throws IOException;
-
-  /**
    * @return true if master is the active one
    */
   boolean isActiveMaster();

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
index f3b21ac..38493cd 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
@@ -896,37 +896,6 @@ public class ServerManager {
   }
 
   /**
-   * Sends an MERGE REGIONS RPC to the specified server to merge the specified
-   * regions.
-   * <p>
-   * A region server could reject the close request because it either does not
-   * have the specified region.
-   * @param server server to merge regions
-   * @param region_a region to merge
-   * @param region_b region to merge
-   * @param forcible true if do a compulsory merge, otherwise we will only 
merge
-   *          two adjacent regions
-   * @throws IOException
-   */
-  public void sendRegionsMerge(ServerName server, HRegionInfo region_a,
-      HRegionInfo region_b, boolean forcible, final User user) throws 
IOException {
-    if (server == null)
-      throw new NullPointerException("Passed server is null");
-    if (region_a == null || region_b == null)
-      throw new NullPointerException("Passed region is null");
-    AdminService.BlockingInterface admin = getRsAdmin(server);
-    if (admin == null) {
-      throw new IOException("Attempting to send MERGE REGIONS RPC to server "
-          + server.toString() + " for region "
-          + region_a.getRegionNameAsString() + ","
-          + region_b.getRegionNameAsString()
-          + " failed because no RPC connection found to this server");
-    }
-    HBaseRpcController controller = newRpcController();
-    ProtobufUtil.mergeRegions(controller, admin, region_a, region_b, forcible, 
user);
-  }
-
-  /**
    * Check if a region server is reachable and has the expected start code
    */
   public boolean isServerReachable(ServerName server) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DispatchMergingRegionsProcedure.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DispatchMergingRegionsProcedure.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DispatchMergingRegionsProcedure.java
deleted file mode 100644
index ee92932..0000000
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DispatchMergingRegionsProcedure.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.hbase.master.procedure;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.RegionLoad;
-import org.apache.hadoop.hbase.ServerLoad;
-import org.apache.hadoop.hbase.ServerName;
-import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.UnknownRegionException;
-import org.apache.hadoop.hbase.classification.InterfaceAudience;
-import org.apache.hadoop.hbase.exceptions.MergeRegionException;
-import org.apache.hadoop.hbase.exceptions.RegionOpeningException;
-import org.apache.hadoop.hbase.master.AssignmentManager;
-import org.apache.hadoop.hbase.master.CatalogJanitor;
-import org.apache.hadoop.hbase.master.RegionPlan;
-import org.apache.hadoop.hbase.master.RegionState;
-import org.apache.hadoop.hbase.master.RegionStates;
-import org.apache.hadoop.hbase.master.ServerManager;
-import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos;
-import 
org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.DispatchMergingRegionsState;
-import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-
-/**
- * The procedure to Merge a region in a table.
- */
-@InterfaceAudience.Private
-public class DispatchMergingRegionsProcedure
-    extends AbstractStateMachineTableProcedure<DispatchMergingRegionsState> {
-  private static final Log LOG = 
LogFactory.getLog(DispatchMergingRegionsProcedure.class);
-
-  private final AtomicBoolean aborted = new AtomicBoolean(false);
-  private Boolean traceEnabled;
-  private AssignmentManager assignmentManager;
-  private int timeout;
-  private ServerName regionLocation;
-  private String regionsToMergeListFullName;
-  private String regionsToMergeListEncodedName;
-
-  private TableName tableName;
-  private HRegionInfo [] regionsToMerge;
-  private boolean forcible;
-
-  public DispatchMergingRegionsProcedure() {
-    this.traceEnabled = isTraceEnabled();
-    this.assignmentManager = null;
-    this.timeout = -1;
-    this.regionLocation = null;
-    this.regionsToMergeListFullName = null;
-    this.regionsToMergeListEncodedName = null;
-  }
-
-  public DispatchMergingRegionsProcedure(
-      final MasterProcedureEnv env,
-      final TableName tableName,
-      final HRegionInfo [] regionsToMerge,
-      final boolean forcible) {
-    super(env);
-    this.traceEnabled = isTraceEnabled();
-    this.assignmentManager = getAssignmentManager(env);
-    this.tableName = tableName;
-    // For now, we only merge 2 regions.  It could be extended to more than 2 
regions in
-    // the future.
-    assert(regionsToMerge.length == 2);
-    this.regionsToMerge = regionsToMerge;
-    this.forcible = forcible;
-
-    this.timeout = -1;
-    this.regionsToMergeListFullName = getRegionsToMergeListFullNameString();
-    this.regionsToMergeListEncodedName = 
getRegionsToMergeListEncodedNameString();
-  }
-
-  @Override
-  protected Flow executeFromState(
-      final MasterProcedureEnv env,
-      final DispatchMergingRegionsState state) throws InterruptedException {
-    if (isTraceEnabled()) {
-      LOG.trace(this + " execute state=" + state);
-    }
-
-    try {
-      switch (state) {
-      case DISPATCH_MERGING_REGIONS_PREPARE:
-        prepareMergeRegion(env);
-        
setNextState(DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_PRE_OPERATION);
-        break;
-      case DISPATCH_MERGING_REGIONS_PRE_OPERATION:
-        //Unused for now - reserve to add preMerge coprocessor in the future
-        
setNextState(DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_MOVE_REGION_TO_SAME_RS);
-        break;
-      case DISPATCH_MERGING_REGIONS_MOVE_REGION_TO_SAME_RS:
-        if (MoveRegionsToSameRS(env)) {
-          
setNextState(DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_DO_MERGE_IN_RS);
-        } else {
-          LOG.info("Cancel merging regions " + 
getRegionsToMergeListFullNameString()
-            + ", because can't move them to the same RS");
-          
setNextState(DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_POST_OPERATION);
-        }
-        break;
-      case DISPATCH_MERGING_REGIONS_DO_MERGE_IN_RS:
-        doMergeInRS(env);
-        
setNextState(DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_POST_OPERATION);
-        break;
-      case DISPATCH_MERGING_REGIONS_POST_OPERATION:
-        //Unused for now - reserve to add postCompletedMerge coprocessor in 
the future
-        return Flow.NO_MORE_STATE;
-      default:
-        throw new UnsupportedOperationException(this + " unhandled state=" + 
state);
-      }
-    } catch (IOException e) {
-      LOG.warn("Error trying to merge regions " + 
getRegionsToMergeListFullNameString() +
-        " in the table " + tableName + " (in state=" + state + ")", e);
-
-      setFailure("master-merge-regions", e);
-    }
-    return Flow.HAS_MORE_STATE;
-  }
-
-  @Override
-  protected void rollbackState(
-      final MasterProcedureEnv env,
-      final DispatchMergingRegionsState state) throws IOException, 
InterruptedException {
-    if (isTraceEnabled()) {
-      LOG.trace(this + " rollback state=" + state);
-    }
-
-    try {
-      switch (state) {
-      case DISPATCH_MERGING_REGIONS_POST_OPERATION:
-      case DISPATCH_MERGING_REGIONS_DO_MERGE_IN_RS:
-        String msg = this + " We are in the " + state + " state."
-            + " It is complicated to rollback the merge operation that region 
server is working on."
-            + " Rollback is not supported and we should let the merge 
operation to complete";
-        LOG.warn(msg);
-        // PONR
-        throw new UnsupportedOperationException(this + " unhandled state=" + 
state);
-      case DISPATCH_MERGING_REGIONS_MOVE_REGION_TO_SAME_RS:
-        break; // nothing to rollback
-      case DISPATCH_MERGING_REGIONS_PRE_OPERATION:
-        break; // nothing to rollback
-      case DISPATCH_MERGING_REGIONS_PREPARE:
-        break; // nothing to rollback
-      default:
-        throw new UnsupportedOperationException(this + " unhandled state=" + 
state);
-      }
-    } catch (Exception e) {
-      // This will be retried. Unless there is a bug in the code,
-      // this should be just a "temporary error" (e.g. network down)
-      LOG.warn("Failed rollback attempt step " + state + " for merging the 
regions "
-          + getRegionsToMergeListFullNameString() + " in table " + tableName, 
e);
-      throw e;
-    }
-  }
-
-  @Override
-  protected DispatchMergingRegionsState getState(final int stateId) {
-    return DispatchMergingRegionsState.valueOf(stateId);
-  }
-
-  @Override
-  protected int getStateId(final DispatchMergingRegionsState state) {
-    return state.getNumber();
-  }
-
-  @Override
-  protected DispatchMergingRegionsState getInitialState() {
-    return DispatchMergingRegionsState.DISPATCH_MERGING_REGIONS_PREPARE;
-  }
-
-  /*
-   * Check whether we are in the state that can be rollback
-   */
-  @Override
-  protected boolean isRollbackSupported(final DispatchMergingRegionsState 
state) {
-    switch (state) {
-    case DISPATCH_MERGING_REGIONS_POST_OPERATION:
-    case DISPATCH_MERGING_REGIONS_DO_MERGE_IN_RS:
-        // It is not safe to rollback if we reach to these states.
-        return false;
-      default:
-        break;
-    }
-    return true;
-  }
-
-  @Override
-  public void serializeStateData(final OutputStream stream) throws IOException 
{
-    super.serializeStateData(stream);
-
-    MasterProcedureProtos.DispatchMergingRegionsStateData.Builder 
dispatchMergingRegionsMsg =
-        MasterProcedureProtos.DispatchMergingRegionsStateData.newBuilder()
-        .setUserInfo(MasterProcedureUtil.toProtoUserInfo(getUser()))
-        .setTableName(ProtobufUtil.toProtoTableName(tableName))
-        .setForcible(forcible);
-    for (HRegionInfo hri: regionsToMerge) {
-      dispatchMergingRegionsMsg.addRegionInfo(HRegionInfo.convert(hri));
-    }
-    dispatchMergingRegionsMsg.build().writeDelimitedTo(stream);
-  }
-
-  @Override
-  public void deserializeStateData(final InputStream stream) throws 
IOException {
-    super.deserializeStateData(stream);
-
-    MasterProcedureProtos.DispatchMergingRegionsStateData 
dispatchMergingRegionsMsg =
-        
MasterProcedureProtos.DispatchMergingRegionsStateData.parseDelimitedFrom(stream);
-    
setUser(MasterProcedureUtil.toUserInfo(dispatchMergingRegionsMsg.getUserInfo()));
-    tableName = 
ProtobufUtil.toTableName(dispatchMergingRegionsMsg.getTableName());
-
-    assert(dispatchMergingRegionsMsg.getRegionInfoCount() == 2);
-    regionsToMerge = new 
HRegionInfo[dispatchMergingRegionsMsg.getRegionInfoCount()];
-    for (int i = 0; i < regionsToMerge.length; i++) {
-      regionsToMerge[i] = 
HRegionInfo.convert(dispatchMergingRegionsMsg.getRegionInfo(i));
-    }
-  }
-
-  @Override
-  public void toStringClassDetails(StringBuilder sb) {
-    sb.append(getClass().getSimpleName());
-    sb.append(" (table=");
-    sb.append(tableName);
-    sb.append(" regions=");
-    sb.append(getRegionsToMergeListFullNameString());
-    sb.append(" forcible=");
-    sb.append(forcible);
-    sb.append(")");
-  }
-
-  @Override
-  protected boolean acquireLock(final MasterProcedureEnv env) {
-    return !env.getProcedureQueue().waitRegions(
-      this, getTableName(), regionsToMerge[0], regionsToMerge[1]);
-  }
-
-  @Override
-  protected void releaseLock(final MasterProcedureEnv env) {
-    env.getProcedureQueue().wakeRegions(this, getTableName(), 
regionsToMerge[0], regionsToMerge[1]);
-  }
-
-  @Override
-  public TableName getTableName() {
-    return tableName;
-  }
-
-  @Override
-  public TableOperationType getTableOperationType() {
-    return TableOperationType.MERGE;
-  }
-
-  /**
-   * Prepare merge and do some check
-   * @param env MasterProcedureEnv
-   * @throws IOException
-   */
-  private void prepareMergeRegion(final MasterProcedureEnv env) throws 
IOException {
-    // Note: the following logic assumes that we only have 2 regions to merge. 
 In the future,
-    // if we want to extend to more than 2 regions, the code needs to modify a 
little bit.
-    //
-    CatalogJanitor catalogJanitor = 
env.getMasterServices().getCatalogJanitor();
-    boolean regionAHasMergeQualifier = 
!catalogJanitor.cleanMergeQualifier(regionsToMerge[0]);
-    if (regionAHasMergeQualifier
-        || !catalogJanitor.cleanMergeQualifier(regionsToMerge[1])) {
-      String msg = "Skip merging regions " + 
regionsToMerge[0].getRegionNameAsString()
-          + ", " + regionsToMerge[1].getRegionNameAsString() + ", because 
region "
-          + (regionAHasMergeQualifier ? regionsToMerge[0].getEncodedName() : 
regionsToMerge[1]
-              .getEncodedName()) + " has merge qualifier";
-      LOG.info(msg);
-      throw new MergeRegionException(msg);
-    }
-
-      RegionStates regionStates = getAssignmentManager(env).getRegionStates();
-      RegionState regionStateA = 
regionStates.getRegionState(regionsToMerge[0].getEncodedName());
-      RegionState regionStateB = 
regionStates.getRegionState(regionsToMerge[1].getEncodedName());
-      if (regionStateA == null || regionStateB == null) {
-        throw new UnknownRegionException(
-          regionStateA == null ?
-              regionsToMerge[0].getEncodedName() : 
regionsToMerge[1].getEncodedName());
-      }
-
-      if (!regionStateA.isOpened() || !regionStateB.isOpened()) {
-        throw new MergeRegionException(
-          "Unable to merge regions not online " + regionStateA + ", " + 
regionStateB);
-      }
-
-      if (regionsToMerge[0].getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID ||
-          regionsToMerge[1].getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) {
-        throw new MergeRegionException("Can't merge non-default replicas");
-      }
-
-      if (!forcible && !HRegionInfo.areAdjacent(regionsToMerge[0], 
regionsToMerge[1])) {
-        throw new MergeRegionException(
-          "Unable to merge not adjacent regions "
-            + regionsToMerge[0].getRegionNameAsString() + ", "
-            + regionsToMerge[1].getRegionNameAsString()
-            + " where forcible = " + forcible);
-      }
-  }
-
-  /**
-   * Move all regions to the same region server
-   * @param env MasterProcedureEnv
-   * @return whether target regions hosted by the same RS
-   * @throws IOException
-   */
-  private boolean MoveRegionsToSameRS(final MasterProcedureEnv env) throws 
IOException {
-    // Make sure regions are on the same regionserver before send merge
-    // regions request to region server.
-    //
-    boolean onSameRS = isRegionsOnTheSameServer(env);
-    if (!onSameRS) {
-      // Note: the following logic assumes that we only have 2 regions to 
merge.  In the future,
-      // if we want to extend to more than 2 regions, the code needs to modify 
a little bit.
-      //
-      RegionStates regionStates = getAssignmentManager(env).getRegionStates();
-      ServerName regionLocation2 = 
regionStates.getRegionServerOfRegion(regionsToMerge[1]);
-
-      RegionLoad loadOfRegionA = getRegionLoad(env, regionLocation, 
regionsToMerge[0]);
-      RegionLoad loadOfRegionB = getRegionLoad(env, regionLocation2, 
regionsToMerge[1]);
-      if (loadOfRegionA != null && loadOfRegionB != null
-          && loadOfRegionA.getRequestsCount() < 
loadOfRegionB.getRequestsCount()) {
-        // switch regionsToMerge[0] and regionsToMerge[1]
-        HRegionInfo tmpRegion = this.regionsToMerge[0];
-        this.regionsToMerge[0] = this.regionsToMerge[1];
-        this.regionsToMerge[1] = tmpRegion;
-        ServerName tmpLocation = regionLocation;
-        regionLocation = regionLocation2;
-        regionLocation2 = tmpLocation;
-      }
-
-      long startTime = EnvironmentEdgeManager.currentTime();
-
-      RegionPlan regionPlan = new RegionPlan(regionsToMerge[1], 
regionLocation2, regionLocation);
-      LOG.info("Moving regions to same server for merge: " + 
regionPlan.toString());
-      getAssignmentManager(env).balance(regionPlan);
-      do {
-        try {
-          Thread.sleep(20);
-          // Make sure check RIT first, then get region location, otherwise
-          // we would make a wrong result if region is online between getting
-          // region location and checking RIT
-          boolean isRIT = regionStates.isRegionInTransition(regionsToMerge[1]);
-          regionLocation2 = 
regionStates.getRegionServerOfRegion(regionsToMerge[1]);
-          onSameRS = regionLocation.equals(regionLocation2);
-          if (onSameRS || !isRIT) {
-            // Regions are on the same RS, or regionsToMerge[1] is not in
-            // RegionInTransition any more
-            break;
-          }
-        } catch (InterruptedException e) {
-          InterruptedIOException iioe = new InterruptedIOException();
-          iioe.initCause(e);
-          throw iioe;
-        }
-      } while ((EnvironmentEdgeManager.currentTime() - startTime) <= 
getTimeout(env));
-    }
-    return onSameRS;
-  }
-
-  /**
-   * Do the real merge operation in the region server that hosts regions
-   * @param env MasterProcedureEnv
-   * @throws IOException
-   */
-  private void doMergeInRS(final MasterProcedureEnv env) throws IOException {
-    long duration = 0;
-    long startTime = EnvironmentEdgeManager.currentTime();
-    do {
-      try {
-        if (getServerName(env) == null) {
-          // The merge probably already happen. Check
-          RegionState regionState = 
getAssignmentManager(env).getRegionStates().getRegionState(
-            regionsToMerge[0].getEncodedName());
-          if (regionState.isMerging() || regionState.isMerged()) {
-            LOG.info("Merge regions " +  
getRegionsToMergeListEncodedNameString() +
-              " is in progress or completed.  No need to send a new request.");
-          } else {
-            LOG.warn("Cannot sending merge to hosting server of the regions " +
-              getRegionsToMergeListEncodedNameString() + " as the server is 
unknown");
-          }
-          return;
-        }
-        // TODO: the following RPC call is not idempotent.  Multiple calls 
(eg. after master
-        // failover, re-execute this step) could result in some exception 
thrown that does not
-        // paint the correct picture.  This behavior is on-par with old 
releases.  Improvement
-        // could happen in the future.
-        env.getMasterServices().getServerManager().sendRegionsMerge(
-          getServerName(env),
-          regionsToMerge[0],
-          regionsToMerge[1],
-          forcible,
-          getUser());
-        LOG.info("Sent merge to server " + getServerName(env) + " for region " 
+
-            getRegionsToMergeListEncodedNameString() + ", forcible=" + 
forcible);
-        return;
-      } catch (RegionOpeningException roe) {
-        // Do a retry since region should be online on RS immediately
-        LOG.warn("Failed mergering regions in " + getServerName(env) + ", 
retrying...", roe);
-      } catch (Exception ie) {
-        LOG.warn("Failed sending merge to " + getServerName(env) + " for 
regions " +
-            getRegionsToMergeListEncodedNameString() + ", forcible=" + 
forcible, ie);
-        return;
-      }
-    } while ((duration = EnvironmentEdgeManager.currentTime() - startTime) <= 
getTimeout(env));
-
-    // If we reaches here, it means that we get timed out.
-    String msg = "Failed sending merge to " + getServerName(env) + " after " + 
duration + "ms";
-    LOG.warn(msg);
-    throw new IOException(msg);
-  }
-
-  private RegionLoad getRegionLoad(
-      final MasterProcedureEnv env,
-      final ServerName sn,
-      final HRegionInfo hri) {
-    ServerManager serverManager =  env.getMasterServices().getServerManager();
-    ServerLoad load = serverManager.getLoad(sn);
-    if (load != null) {
-      Map<byte[], RegionLoad> regionsLoad = load.getRegionsLoad();
-      if (regionsLoad != null) {
-        return regionsLoad.get(hri.getRegionName());
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @param env MasterProcedureEnv
-   * @return whether target regions hosted by the same RS
-   */
-  private boolean isRegionsOnTheSameServer(final MasterProcedureEnv env) 
throws IOException{
-    Boolean onSameRS = true;
-    int i = 0;
-    RegionStates regionStates = getAssignmentManager(env).getRegionStates();
-    regionLocation = regionStates.getRegionServerOfRegion(regionsToMerge[i]);
-    if (regionLocation != null) {
-      for(i = 1; i < regionsToMerge.length; i++) {
-        ServerName regionLocation2 = 
regionStates.getRegionServerOfRegion(regionsToMerge[i]);
-        if (regionLocation2 != null) {
-          if (onSameRS) {
-            onSameRS = regionLocation.equals(regionLocation2);
-          }
-        } else {
-          // At least one region is not online, merge will fail, no need to 
continue.
-          break;
-        }
-      }
-      if (i == regionsToMerge.length) {
-        // Finish checking all regions, return the result;
-        return onSameRS;
-      }
-    }
-
-    // If reaching here, at least one region is not online.
-    String msg = "Skip merging regions " + 
getRegionsToMergeListFullNameString() +
-        ", because region " + regionsToMerge[i].getEncodedName() + " is not 
online now.";
-    LOG.warn(msg);
-    throw new IOException(msg);
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @param env MasterProcedureEnv
-   * @return assignmentManager
-   */
-  private AssignmentManager getAssignmentManager(final MasterProcedureEnv env) 
{
-    if (assignmentManager == null) {
-      assignmentManager = env.getMasterServices().getAssignmentManager();
-    }
-    return assignmentManager;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @param env MasterProcedureEnv
-   * @return timeout value
-   */
-  private int getTimeout(final MasterProcedureEnv env) {
-    if (timeout == -1) {
-      timeout = env.getMasterConfiguration().getInt(
-        "hbase.master.regionmerge.timeout", regionsToMerge.length * 60 * 1000);
-    }
-    return timeout;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @param env MasterProcedureEnv
-   * @return serverName
-   */
-  private ServerName getServerName(final MasterProcedureEnv env) {
-    if (regionLocation == null) {
-      regionLocation =
-          
getAssignmentManager(env).getRegionStates().getRegionServerOfRegion(regionsToMerge[0]);
-    }
-    return regionLocation;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @param fullName whether return only encoded name
-   * @return region names in a list
-   */
-  private String getRegionsToMergeListFullNameString() {
-    if (regionsToMergeListFullName == null) {
-      StringBuilder sb = new StringBuilder("[");
-      int i = 0;
-      while(i < regionsToMerge.length - 1) {
-        sb.append(regionsToMerge[i].getRegionNameAsString() + ", ");
-        i++;
-      }
-      sb.append(regionsToMerge[i].getRegionNameAsString() + " ]");
-      regionsToMergeListFullName = sb.toString();
-    }
-    return regionsToMergeListFullName;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @return encoded region names
-   */
-  private String getRegionsToMergeListEncodedNameString() {
-    if (regionsToMergeListEncodedName == null) {
-      StringBuilder sb = new StringBuilder("[");
-      int i = 0;
-      while(i < regionsToMerge.length - 1) {
-        sb.append(regionsToMerge[i].getEncodedName() + ", ");
-        i++;
-      }
-      sb.append(regionsToMerge[i].getEncodedName() + " ]");
-      regionsToMergeListEncodedName = sb.toString();
-    }
-    return regionsToMergeListEncodedName;
-  }
-
-  /**
-   * The procedure could be restarted from a different machine. If the 
variable is null, we need to
-   * retrieve it.
-   * @return traceEnabled
-   */
-  private Boolean isTraceEnabled() {
-    if (traceEnabled == null) {
-      traceEnabled = LOG.isTraceEnabled();
-    }
-    return traceEnabled;
-  }
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactSplitThread.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactSplitThread.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactSplitThread.java
index 1331b86..63929a8 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactSplitThread.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/CompactSplitThread.java
@@ -217,20 +217,6 @@ public class CompactSplitThread implements 
CompactionRequestor, PropagatingConfi
     return queueLists.toString();
   }
 
-  public synchronized void requestRegionsMerge(final Region a,
-      final Region b, final boolean forcible, long masterSystemTime, User 
user) {
-    try {
-      mergePool.execute(new RegionMergeRequest(a, b, this.server, forcible, 
masterSystemTime,user));
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Region merge requested for " + a + "," + b + ", forcible="
-            + forcible + ".  " + this);
-      }
-    } catch (RejectedExecutionException ree) {
-      LOG.warn("Could not execute merge for " + a + "," + b + ", forcible="
-          + forcible, ree);
-    }
-  }
-
   public synchronized boolean requestSplit(final Region r) {
     // don't split regions that are blocking
     if (shouldSplitRegion() && ((HRegion)r).getCompactPriority() >= 
Store.PRIORITY_USER) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
index a5172bb..b574c50 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
@@ -6881,112 +6881,6 @@ public class HRegion implements HeapSize, 
PropagatingConfigurationObserver, Regi
           (Bytes.compareTo(info.getEndKey(), 0, info.getEndKey().length, row, 
offset, length) > 0));
   }
 
-  /**
-   * Merge two HRegions.  The regions must be adjacent and must not overlap.
-   *
-   * @return new merged HRegion
-   * @throws IOException
-   */
-  public static HRegion mergeAdjacent(final HRegion srcA, final HRegion srcB)
-  throws IOException {
-    HRegion a = srcA;
-    HRegion b = srcB;
-
-    // Make sure that srcA comes first; important for key-ordering during
-    // write of the merged file.
-    if (srcA.getRegionInfo().getStartKey() == null) {
-      if (srcB.getRegionInfo().getStartKey() == null) {
-        throw new IOException("Cannot merge two regions with null start key");
-      }
-      // A's start key is null but B's isn't. Assume A comes before B
-    } else if ((srcB.getRegionInfo().getStartKey() == null) ||
-      (Bytes.compareTo(srcA.getRegionInfo().getStartKey(),
-        srcB.getRegionInfo().getStartKey()) > 0)) {
-      a = srcB;
-      b = srcA;
-    }
-
-    if (!(Bytes.compareTo(a.getRegionInfo().getEndKey(),
-        b.getRegionInfo().getStartKey()) == 0)) {
-      throw new IOException("Cannot merge non-adjacent regions");
-    }
-    return merge(a, b);
-  }
-
-  /**
-   * Merge two regions whether they are adjacent or not.
-   *
-   * @param a region a
-   * @param b region b
-   * @return new merged region
-   * @throws IOException
-   */
-  public static HRegion merge(final HRegion a, final HRegion b) throws 
IOException {
-    if (!a.getRegionInfo().getTable().equals(b.getRegionInfo().getTable())) {
-      throw new IOException("Regions do not belong to the same table");
-    }
-
-    FileSystem fs = a.getRegionFileSystem().getFileSystem();
-    // Make sure each region's cache is empty
-    a.flush(true);
-    b.flush(true);
-
-    // Compact each region so we only have one store file per family
-    a.compact(true);
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Files for region: " + a);
-      a.getRegionFileSystem().logFileSystemState(LOG);
-    }
-    b.compact(true);
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Files for region: " + b);
-      b.getRegionFileSystem().logFileSystemState(LOG);
-    }
-
-    RegionMergeTransactionImpl rmt = new RegionMergeTransactionImpl(a, b, 
true);
-    if (!rmt.prepare(null)) {
-      throw new IOException("Unable to merge regions " + a + " and " + b);
-    }
-    HRegionInfo mergedRegionInfo = rmt.getMergedRegionInfo();
-    LOG.info("starting merge of regions: " + a + " and " + b
-        + " into new region " + mergedRegionInfo.getRegionNameAsString()
-        + " with start key <"
-        + Bytes.toStringBinary(mergedRegionInfo.getStartKey())
-        + "> and end key <"
-        + Bytes.toStringBinary(mergedRegionInfo.getEndKey()) + ">");
-    HRegion dstRegion;
-    try {
-      dstRegion = (HRegion)rmt.execute(null, null);
-    } catch (IOException ioe) {
-      rmt.rollback(null, null);
-      throw new IOException("Failed merging region " + a + " and " + b
-          + ", and successfully rolled back");
-    }
-    dstRegion.compact(true);
-
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("Files for new region");
-      dstRegion.getRegionFileSystem().logFileSystemState(LOG);
-    }
-
-    // clear the compacted files if any
-    for (Store s : dstRegion.getStores()) {
-      s.closeAndArchiveCompactedFiles();
-    }
-    if 
(dstRegion.getRegionFileSystem().hasReferences(dstRegion.getTableDesc())) {
-      throw new IOException("Merged region " + dstRegion
-          + " still has references after the compaction, is compaction 
canceled?");
-    }
-
-    // Archiving the 'A' region
-    HFileArchiver.archiveRegion(a.getBaseConf(), fs, a.getRegionInfo());
-    // Archiving the 'B' region
-    HFileArchiver.archiveRegion(b.getBaseConf(), fs, b.getRegionInfo());
-
-    LOG.info("merge completed. New region is " + dstRegion);
-    return dstRegion;
-  }
-
   @Override
   public Result get(final Get get) throws IOException {
     prepareGet(get);

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
index 7b5f799..1e9f16b 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java
@@ -115,8 +115,6 @@ import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetServerIn
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetServerInfoResponse;
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetStoreFileRequest;
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetStoreFileResponse;
-import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.MergeRegionsRequest;
-import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.MergeRegionsResponse;
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.OpenRegionRequest;
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.OpenRegionRequest.RegionOpenInfo;
 import 
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.OpenRegionResponse;
@@ -1642,46 +1640,6 @@ public class RSRpcServices implements 
HBaseRPCErrorHandler,
   }
 
   /**
-   * Merge regions on the region server.
-   *
-   * @param controller the RPC controller
-   * @param request the request
-   * @return merge regions response
-   * @throws ServiceException
-   */
-  @Override
-  @QosPriority(priority = HConstants.ADMIN_QOS)
-  public MergeRegionsResponse mergeRegions(final RpcController controller,
-      final MergeRegionsRequest request) throws ServiceException {
-    try {
-      checkOpen();
-      requestCount.increment();
-      Region regionA = getRegion(request.getRegionA());
-      Region regionB = getRegion(request.getRegionB());
-      boolean forcible = request.getForcible();
-      long masterSystemTime = request.hasMasterSystemTime() ? 
request.getMasterSystemTime() : -1;
-      regionA.startRegionOperation(Operation.MERGE_REGION);
-      regionB.startRegionOperation(Operation.MERGE_REGION);
-      if (regionA.getRegionInfo().getReplicaId() != 
HRegionInfo.DEFAULT_REPLICA_ID ||
-          regionB.getRegionInfo().getReplicaId() != 
HRegionInfo.DEFAULT_REPLICA_ID) {
-        throw new ServiceException(new MergeRegionException("Can't merge 
non-default replicas"));
-      }
-      LOG.info("Receiving merging request for  " + regionA + ", " + regionB
-          + ",forcible=" + forcible);
-      regionA.flush(true);
-      regionB.flush(true);
-      regionServer.compactSplitThread.requestRegionsMerge(regionA, regionB, 
forcible,
-          masterSystemTime, RpcServer.getRequestUser());
-      return MergeRegionsResponse.newBuilder().build();
-    } catch (DroppedSnapshotException ex) {
-      regionServer.abort("Replay of WAL required. Forcing server shutdown", 
ex);
-      throw new ServiceException(ex);
-    } catch (IOException ie) {
-      throw new ServiceException(ie);
-    }
-  }
-
-  /**
    * Open asynchronously a region or a set of regions on the region server.
    *
    * The opening is coordinated by ZooKeeper, and this method requires the 
znode to be created

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeRequest.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeRequest.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeRequest.java
deleted file mode 100644
index ce69ad3..0000000
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeRequest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * Copyright The Apache Software Foundation
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.hadoop.hbase.regionserver;
-
-import java.io.IOException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.classification.InterfaceAudience;
-import org.apache.hadoop.hbase.DroppedSnapshotException;
-import org.apache.hadoop.hbase.master.TableLockManager.TableLock;
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.apache.hadoop.ipc.RemoteException;
-import org.apache.hadoop.util.StringUtils;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Handles processing region merges. Put in a queue, owned by HRegionServer.
- */
-@InterfaceAudience.Private
-class RegionMergeRequest implements Runnable {
-  private static final Log LOG = LogFactory.getLog(RegionMergeRequest.class);
-  private final HRegion region_a;
-  private final HRegion region_b;
-  private final HRegionServer server;
-  private final boolean forcible;
-  private TableLock tableLock;
-  private final long masterSystemTime;
-  private final User user;
-
-  RegionMergeRequest(Region a, Region b, HRegionServer hrs, boolean forcible,
-    long masterSystemTime, User user) {
-    Preconditions.checkNotNull(hrs);
-    this.region_a = (HRegion)a;
-    this.region_b = (HRegion)b;
-    this.server = hrs;
-    this.forcible = forcible;
-    this.masterSystemTime = masterSystemTime;
-    this.user = user;
-  }
-
-  @Override
-  public String toString() {
-    return "MergeRequest,regions:" + region_a + ", " + region_b + ", forcible="
-        + forcible;
-  }
-
-  @Override
-  public void run() {
-    if (this.server.isStopping() || this.server.isStopped()) {
-      LOG.debug("Skipping merge because server is stopping="
-          + this.server.isStopping() + " or stopped=" + 
this.server.isStopped());
-      return;
-    }
-    try {
-      final long startTime = EnvironmentEdgeManager.currentTime();
-      RegionMergeTransactionImpl mt = new RegionMergeTransactionImpl(region_a,
-          region_b, forcible, masterSystemTime);
-
-      //acquire a shared read lock on the table, so that table schema 
modifications
-      //do not happen concurrently
-      tableLock = 
server.getTableLockManager().readLock(region_a.getTableDesc().getTableName()
-          , "MERGE_REGIONS:" + 
region_a.getRegionInfo().getRegionNameAsString() + ", " +
-              region_b.getRegionInfo().getRegionNameAsString());
-      try {
-        tableLock.acquire();
-      } catch (IOException ex) {
-        tableLock = null;
-        throw ex;
-      }
-
-      // If prepare does not return true, for some reason -- logged inside in
-      // the prepare call -- we are not ready to merge just now. Just return.
-      if (!mt.prepare(this.server)) return;
-      try {
-        mt.execute(this.server, this.server, this.user);
-      } catch (Exception e) {
-        if (this.server.isStopping() || this.server.isStopped()) {
-          LOG.info(
-              "Skip rollback/cleanup of failed merge of " + region_a + " and "
-                  + region_b + " because server is"
-                  + (this.server.isStopping() ? " stopping" : " stopped"), e);
-          return;
-        }
-        if (e instanceof DroppedSnapshotException) {
-          server.abort("Replay of WAL required. Forcing server shutdown", e);
-          return;
-        }
-        try {
-          LOG.warn("Running rollback/cleanup of failed merge of "
-                  + region_a +" and "+ region_b + "; " + e.getMessage(), e);
-          if (mt.rollback(this.server, this.server)) {
-            LOG.info("Successful rollback of failed merge of "
-                + region_a +" and "+ region_b);
-          } else {
-            this.server.abort("Abort; we got an error after point-of-no-return"
-                + "when merging " + region_a + " and " + region_b);
-          }
-        } catch (RuntimeException ee) {
-          String msg = "Failed rollback of failed merge of "
-              + region_a +" and "+ region_b + " -- aborting server";
-          // If failed rollback, kill this server to avoid having a hole in
-          // table.
-          LOG.info(msg, ee);
-          this.server.abort(msg);
-        }
-        return;
-      }
-      LOG.info("Regions merged, hbase:meta updated, and report to master. 
region_a="
-          + region_a + ", region_b=" + region_b + ",merged region="
-          + mt.getMergedRegionInfo().getRegionNameAsString()
-          + ". Region merge took "
-          + StringUtils.formatTimeDiff(EnvironmentEdgeManager.currentTime(), 
startTime));
-    } catch (IOException ex) {
-      ex = ex instanceof RemoteException ? ((RemoteException) 
ex).unwrapRemoteException() : ex;
-      LOG.error("Merge failed " + this, ex);
-      server.checkFileSystem();
-    } finally {
-      releaseTableLock();
-    }
-  }
-
-  protected void releaseTableLock() {
-    if (this.tableLock != null) {
-      try {
-        this.tableLock.release();
-      } catch (IOException ex) {
-        LOG.error("Could not release the table lock (something is really 
wrong). " 
-           + "Aborting this server to avoid holding the lock forever.");
-        this.server.abort("Abort; we got an error when releasing the table 
lock "
-                         + "on " + 
region_a.getRegionInfo().getRegionNameAsString());
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/hbase/blob/805d39fc/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeTransactionFactory.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeTransactionFactory.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeTransactionFactory.java
deleted file mode 100644
index c844d54..0000000
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionMergeTransactionFactory.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.hbase.regionserver;
-
-import org.apache.hadoop.conf.Configurable;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseInterfaceAudience;
-import org.apache.hadoop.hbase.classification.InterfaceAudience;
-import org.apache.hadoop.hbase.classification.InterfaceStability;
-import org.apache.hadoop.hbase.util.ReflectionUtils;
-
-/**
- * A factory for creating RegionMergeTransactions, which execute region split 
as a "transaction".
- * See {@link RegionMergeTransactionImpl}
- */
-@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
-@InterfaceStability.Evolving
-public class RegionMergeTransactionFactory implements Configurable {
-
-  public static final String MERGE_TRANSACTION_IMPL_KEY =
-      "hbase.regionserver.merge.transaction.impl";
-
-  private Configuration conf;
-
-  public RegionMergeTransactionFactory(Configuration conf) {
-    this.conf = conf;
-  }
-
-  @Override
-  public Configuration getConf() {
-    return conf;
-  }
-
-  @Override
-  public void setConf(Configuration conf) {
-    this.conf = conf;
-  }
-
-  /**
-   * Create a merge transaction
-   * @param a region a to merge
-   * @param b region b to merge
-   * @param forcible if false, we will only merge adjacent regions
-   * @return transaction instance
-   */
-  public RegionMergeTransactionImpl create(final Region a, final Region b,
-      final boolean forcible) {
-    // The implementation class must extend RegionMergeTransactionImpl, not 
only
-    // implement the RegionMergeTransaction interface like you might expect,
-    // because various places such as AssignmentManager use static methods
-    // from RegionMergeTransactionImpl. Whatever we use for implementation must
-    // be compatible, so it's safest to require ? extends 
RegionMergeTransactionImpl.
-    // If not compatible we will throw a runtime exception from here.
-    return ReflectionUtils.instantiateWithCustomCtor(
-      conf.getClass(MERGE_TRANSACTION_IMPL_KEY, 
RegionMergeTransactionImpl.class,
-        RegionMergeTransactionImpl.class).getName(),
-      new Class[] { Region.class, Region.class, boolean.class },
-      new Object[] { a, b, forcible });
-  }
-
-}

Reply via email to