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 2013/08/13 01:37:13 UTC

svn commit: r1513296 - in /hbase/branches/0.95/hbase-server/src: main/java/org/apache/hadoop/hbase/master/ test/java/org/apache/hadoop/hbase/master/

Author: jxiang
Date: Mon Aug 12 23:37:13 2013
New Revision: 1513296

URL: http://svn.apache.org/r1513296
Log:
HBASE-9184 Ignore zk assign event if region is not known in transition

Modified:
    hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
    hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
    hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java

Modified: hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java?rev=1513296&r1=1513295&r2=1513296&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (original)
+++ hbase/branches/0.95/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java Mon Aug 12 23:37:13 2013
@@ -751,7 +751,7 @@ public class AssignmentManager extends Z
    * @param rt
    * @param expectedVersion
    */
-  private void handleRegion(final RegionTransition rt, int expectedVersion) {
+  void handleRegion(final RegionTransition rt, int expectedVersion) {
     if (rt == null) {
       LOG.warn("Unexpected NULL input for RegionTransition rt");
       return;
@@ -892,12 +892,11 @@ public class AssignmentManager extends Z
         case M_ZK_REGION_CLOSING:
           // Should see CLOSING after we have asked it to CLOSE or additional
           // times after already being in state of CLOSING
-          if (regionState != null
-              && !regionState.isPendingCloseOrClosingOnServer(sn)) {
+          if (regionState == null
+              || !regionState.isPendingCloseOrClosingOnServer(sn)) {
             LOG.warn("Received CLOSING for " + prettyPrintedRegionName
-              + " from server " + sn + " but region was in the state " + regionState
-              + " and not in expected PENDING_CLOSE or CLOSING states,"
-              + " or not on the expected server");
+              + " from " + sn + " but the region isn't PENDING_CLOSE/CLOSING here: "
+              + regionStates.getRegionState(encodedName));
             return;
           }
           // Transition to CLOSING (or update stamp if already CLOSING)
@@ -906,12 +905,11 @@ public class AssignmentManager extends Z
 
         case RS_ZK_REGION_CLOSED:
           // Should see CLOSED after CLOSING but possible after PENDING_CLOSE
-          if (regionState != null
-              && !regionState.isPendingCloseOrClosingOnServer(sn)) {
+          if (regionState == null
+              || !regionState.isPendingCloseOrClosingOnServer(sn)) {
             LOG.warn("Received CLOSED for " + prettyPrintedRegionName
-              + " from server " + sn + " but region was in the state " + regionState
-              + " and not in expected PENDING_CLOSE or CLOSING states,"
-              + " or not on the expected server");
+              + " from " + sn + " but the region isn't PENDING_CLOSE/CLOSING here: "
+              + regionStates.getRegionState(encodedName));
             return;
           }
           // Handle CLOSED by assigning elsewhere or stopping if a disable
@@ -926,12 +924,11 @@ public class AssignmentManager extends Z
           break;
 
         case RS_ZK_REGION_FAILED_OPEN:
-          if (regionState != null
-              && !regionState.isPendingOpenOrOpeningOnServer(sn)) {
+          if (regionState == null
+              || !regionState.isPendingOpenOrOpeningOnServer(sn)) {
             LOG.warn("Received FAILED_OPEN for " + prettyPrintedRegionName
-              + " from server " + sn + " but region was in the state " + regionState
-              + " and not in expected PENDING_OPEN or OPENING states,"
-              + " or not on the expected server");
+              + " from " + sn + " but the region isn't PENDING_OPEN/OPENING here: "
+              + regionStates.getRegionState(encodedName));
             return;
           }
           AtomicInteger failedOpenCount = failedOpenTracker.get(encodedName);
@@ -962,12 +959,11 @@ public class AssignmentManager extends Z
         case RS_ZK_REGION_OPENING:
           // Should see OPENING after we have asked it to OPEN or additional
           // times after already being in state of OPENING
-          if (regionState != null
-              && !regionState.isPendingOpenOrOpeningOnServer(sn)) {
+          if (regionState == null
+              || !regionState.isPendingOpenOrOpeningOnServer(sn)) {
             LOG.warn("Received OPENING for " + prettyPrintedRegionName
-              + " from server " + sn + " but region was in the state " + regionState
-              + " and not in expected PENDING_OPEN or OPENING states,"
-              + " or not on the expected server");
+              + " from " + sn + " but the region isn't PENDING_OPEN/OPENING here: "
+              + regionStates.getRegionState(encodedName));
             return;
           }
           // Transition to OPENING (or update stamp if already OPENING)
@@ -975,13 +971,13 @@ public class AssignmentManager extends Z
           break;
 
         case RS_ZK_REGION_OPENED:
-          // Should see OPENED after OPENING but possible after PENDING_OPEN
-          if (regionState != null
-              && !regionState.isPendingOpenOrOpeningOnServer(sn)) {
+          // Should see OPENED after OPENING but possible after PENDING_OPEN.
+          if (regionState == null
+              || !regionState.isPendingOpenOrOpeningOnServer(sn)) {
             LOG.warn("Received OPENED for " + prettyPrintedRegionName
-              + " from server " + sn + " but region was in the state " + regionState
-              + " and not in expected PENDING_OPEN or OPENING states,"
-              + " or not on the expected server");
+              + " from " + sn + " but the region isn't PENDING_OPEN/OPENING here: "
+              + regionStates.getRegionState(encodedName));
+
             // Close it without updating the internal region states,
             // so as not to create double assignments in unlucky scenarios
             // mentioned in OpenRegionHandler#process

Modified: hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java?rev=1513296&r1=1513295&r2=1513296&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (original)
+++ hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java Mon Aug 12 23:37:13 2013
@@ -32,7 +32,6 @@ import java.util.concurrent.atomic.Atomi
 
 import org.apache.hadoop.hbase.CellScannable;
 import org.apache.hadoop.hbase.CellUtil;
-import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
@@ -43,6 +42,7 @@ import org.apache.hadoop.hbase.RegionTra
 import org.apache.hadoop.hbase.Server;
 import org.apache.hadoop.hbase.ServerLoad;
 import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
 import org.apache.hadoop.hbase.catalog.CatalogTracker;
 import org.apache.hadoop.hbase.catalog.MetaMockingUtil;
@@ -69,6 +69,8 @@ import org.apache.hadoop.hbase.protobuf.
 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.Table;
 import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.Threads;
 import org.apache.hadoop.hbase.zookeeper.RecoverableZooKeeper;
 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
@@ -1241,4 +1243,58 @@ public class TestAssignmentManager {
       am.shutdown();
     }
   }
+
+  /**
+   * Test assignment related ZK events are ignored by AM if the region is not known
+   * by AM to be in transition. During normal operation, all assignments are started
+   * by AM (not considering split/merge), if an event is received but the region
+   * is not in transition, the event must be a very late one. So it can be ignored.
+   * During master failover, since AM watches assignment znodes after failover cleanup
+   * is completed, when an event comes in, AM should already have the region in transition
+   * if ZK is used during the assignment action (only hbck doesn't use ZK for region
+   * assignment). So during master failover, we can ignored such events too.
+   */
+  @Test
+  public void testAssignmentEventIgnoredIfNotExpected() throws KeeperException, IOException {
+    // Region to use in test.
+    final HRegionInfo hri = HRegionInfo.FIRST_META_REGIONINFO;
+    // Need a mocked catalog tracker.
+    CatalogTracker ct = Mockito.mock(CatalogTracker.class);
+    LoadBalancer balancer = LoadBalancerFactory.getLoadBalancer(
+      server.getConfiguration());
+    final AtomicBoolean zkEventProcessed = new AtomicBoolean(false);
+    // Create an AM.
+    AssignmentManager am = new AssignmentManager(this.server,
+      this.serverManager, ct, balancer, null, null, master.getTableLockManager()) {
+
+      @Override
+      void handleRegion(final RegionTransition rt, int expectedVersion) {
+        super.handleRegion(rt, expectedVersion);
+        if (rt != null && Bytes.equals(hri.getRegionName(),
+          rt.getRegionName()) && rt.getEventType() == EventType.RS_ZK_REGION_OPENING) {
+          zkEventProcessed.set(true);
+        }
+      }
+    };
+    try {
+      // First make sure the region is not in transition
+      am.getRegionStates().regionOffline(hri);
+      zkEventProcessed.set(false); // Reset it before faking zk transition
+      this.watcher.registerListenerFirst(am);
+      assertFalse("The region should not be in transition",
+        am.getRegionStates().isRegionInTransition(hri));
+      ZKAssign.createNodeOffline(this.watcher, hri, SERVERNAME_A);
+      // Trigger a transition event
+      ZKAssign.transitionNodeOpening(this.watcher, hri, SERVERNAME_A);
+      long startTime = EnvironmentEdgeManager.currentTimeMillis();
+      while (!zkEventProcessed.get()) {
+        assertTrue("Timed out in waiting for ZK event to be processed",
+          EnvironmentEdgeManager.currentTimeMillis() - startTime < 30000);
+        Threads.sleepWithoutInterrupt(100);
+      }
+      assertFalse(am.getRegionStates().isRegionInTransition(hri));
+    } finally {
+      am.shutdown();
+    }
+  }
 }

Modified: hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java?rev=1513296&r1=1513295&r2=1513296&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java (original)
+++ hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java Mon Aug 12 23:37:13 2013
@@ -49,6 +49,7 @@ import org.apache.hadoop.hbase.coprocess
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.executor.EventType;
+import org.apache.hadoop.hbase.master.RegionState.State;
 import org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer;
 import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.util.Bytes;
@@ -485,6 +486,7 @@ public class TestAssignmentManagerOnClus
       }
       am.regionOffline(hri);
       ZooKeeperWatcher zkw = TEST_UTIL.getHBaseCluster().getMaster().getZooKeeper();
+      am.getRegionStates().updateRegionState(hri, State.OFFLINE);
       ZKAssign.createNodeOffline(zkw, hri, destServerName);
       ZKAssign.transitionNodeOpening(zkw, hri, destServerName);