You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jx...@apache.org on 2014/08/09 00:03:45 UTC

git commit: HBASE-11659 Region state RPC call is not idempotent (Virag Kothari)

Repository: hbase
Updated Branches:
  refs/heads/master 4b8a38ebb -> fa46724f3


HBASE-11659 Region state RPC call is not idempotent (Virag Kothari)


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/fa46724f
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/fa46724f
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/fa46724f

Branch: refs/heads/master
Commit: fa46724f363fc95c183a890b9cab06ed3d2b8dd2
Parents: 4b8a38e
Author: Jimmy Xiang <jx...@cloudera.com>
Authored: Fri Aug 8 14:56:38 2014 -0700
Committer: Jimmy Xiang <jx...@cloudera.com>
Committed: Fri Aug 8 15:02:38 2014 -0700

----------------------------------------------------------------------
 .../hadoop/hbase/master/AssignmentManager.java  |  5 ++
 .../master/TestAssignmentManagerOnCluster.java  | 49 +++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/fa46724f/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
index c234767..1b7aea0 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
@@ -2512,6 +2512,11 @@ public class AssignmentManager {
     String errorMsg = null;
     switch (code) {
     case OPENED:
+      if (current != null && current.isOpened() && current.isOnServer(serverName)) {
+        LOG.info("Region " + hri.getShortNameToLog() + " is already " + current.getState() + " on "
+            + serverName);
+        break;
+      }
     case FAILED_OPEN:
       if (current == null
           || !current.isPendingOpenOrOpeningOnServer(serverName)) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/fa46724f/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java
index 469a5d2..ff3a8d9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java
@@ -57,6 +57,7 @@ import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.master.RegionState.State;
 import org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer;
+import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.RegionStateTransition.TransitionCode;
 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
 import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.util.Bytes;
@@ -136,7 +137,7 @@ public class TestAssignmentManagerOnCluster {
       TEST_UTIL.deleteTable(Bytes.toBytes(table));
     }
   }
-
+  
   /**
    * This tests region assignment on a simulated restarted server
    */
@@ -970,6 +971,40 @@ public class TestAssignmentManagerOnCluster {
       cluster.startRegionServer();
     }
   }
+  
+  /**
+   * Test that region state transition call is idempotent
+   */
+  @Test(timeout = 60000)
+  public void testReportRegionStateTransition() throws Exception {
+    String table = "testReportRegionStateTransition";
+    try {
+      MyRegionServer.simulateRetry = true;
+      HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(table));
+      desc.addFamily(new HColumnDescriptor(FAMILY));
+      admin.createTable(desc);
+      HTable meta = new HTable(conf, TableName.META_TABLE_NAME);
+      HRegionInfo hri =
+          new HRegionInfo(desc.getTableName(), Bytes.toBytes("A"), Bytes.toBytes("Z"));
+      MetaTableAccessor.addRegionToMeta(meta, hri);
+      HMaster master = TEST_UTIL.getHBaseCluster().getMaster();
+      master.assignRegion(hri);
+      AssignmentManager am = master.getAssignmentManager();
+      am.waitForAssignment(hri);
+      RegionStates regionStates = am.getRegionStates();
+      ServerName serverName = regionStates.getRegionServerOfRegion(hri);
+      // Assert the the region is actually open on the server
+      TEST_UTIL.assertRegionOnServer(hri, serverName, 200);
+      // Closing region should just work fine
+      admin.disableTable(TableName.valueOf(table));
+      assertTrue(regionStates.isRegionOffline(hri));
+      List<HRegionInfo> regions = TEST_UTIL.getHBaseAdmin().getOnlineRegions(serverName);
+      assertTrue(!regions.contains(hri));
+    } finally {
+      MyRegionServer.simulateRetry = false;
+      TEST_UTIL.deleteTable(Bytes.toBytes(table));
+    }
+  }
 
   static class MyLoadBalancer extends StochasticLoadBalancer {
     // For this region, if specified, always assign to nowhere
@@ -1009,6 +1044,7 @@ public class TestAssignmentManagerOnCluster {
 
   public static class MyRegionServer extends MiniHBaseClusterRegionServer {
     static volatile ServerName abortedServer = null;
+    static volatile boolean simulateRetry = false;
 
     public MyRegionServer(Configuration conf, CoordinatedStateManager cp)
       throws IOException, KeeperException,
@@ -1017,6 +1053,17 @@ public class TestAssignmentManagerOnCluster {
     }
 
     @Override
+    public boolean reportRegionStateTransition(TransitionCode code, long openSeqNum,
+        HRegionInfo... hris) {
+      if (simulateRetry) {
+        // Simulate retry by calling the method twice
+        super.reportRegionStateTransition(code, openSeqNum, hris);
+        return super.reportRegionStateTransition(code, openSeqNum, hris);
+      }
+      return super.reportRegionStateTransition(code, openSeqNum, hris);
+    }
+
+    @Override
     public boolean isAborted() {
       return getServerName().equals(abortedServer) || super.isAborted();
     }