Repository: hbase
Updated Branches:
  refs/heads/branch-1 c4401b607 -> 1fbe4deb0


HBASE-20104 Fix infinite loop of RIT when creating table on a rsgroup that has 
no online servers

Signed-off-by: tedyu <yuzhih...@gmail.com>


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

Branch: refs/heads/branch-1
Commit: 1fbe4deb01cd543ca0ebb08791acdf1ecd34203e
Parents: c4401b6
Author: haxiaolin <haxiao...@xiaomi.com>
Authored: Thu Mar 1 15:58:20 2018 +0800
Committer: tedyu <yuzhih...@gmail.com>
Committed: Thu Mar 1 08:35:45 2018 -0800

----------------------------------------------------------------------
 .../hbase/rsgroup/RSGroupAdminEndpoint.java     | 38 +++++++---
 .../hadoop/hbase/rsgroup/TestRSGroups.java      |  3 +-
 .../hadoop/hbase/rsgroup/TestRSGroupsBase.java  | 73 ++++++++++++++++++--
 3 files changed, 97 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/1fbe4deb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
----------------------------------------------------------------------
diff --git 
a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
 
b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
index 26111c2..0b39ae6 100644
--- 
a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
+++ 
b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
@@ -34,6 +34,7 @@ import java.util.Set;
 import org.apache.hadoop.hbase.ClusterStatus;
 import org.apache.hadoop.hbase.Coprocessor;
 import org.apache.hadoop.hbase.CoprocessorEnvironment;
+import org.apache.hadoop.hbase.HBaseIOException;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -361,20 +362,34 @@ public class RSGroupAdminEndpoint extends 
RSGroupAdminService
   }
 
   void assignTableToGroup(HTableDescriptor desc) throws IOException {
+    RSGroupInfo rsGroupInfo = preGetRSGroupInfoOfTable(desc);
+    if (!rsGroupInfo.containsTable(desc.getTableName())) {
+      groupAdminServer.moveTables(Sets.newHashSet(desc.getTableName()), 
rsGroupInfo.getName());
+    }
+  }
+
+  public boolean rsgroupHasOnlineServers(HTableDescriptor desc) throws 
IOException {
+    RSGroupInfo rsGroupInfo = preGetRSGroupInfoOfTable(desc);
+    for (ServerName onlineServer : 
master.getServerManager().createDestinationServersList()) {
+      if (rsGroupInfo.getServers().contains(onlineServer.getAddress())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public RSGroupInfo preGetRSGroupInfoOfTable(HTableDescriptor desc) throws 
IOException{
     String groupName =
-        
master.getNamespaceDescriptor(desc.getTableName().getNamespaceAsString())
-                .getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP);
+        
master.getTableNamespaceManager().get(desc.getTableName().getNamespaceAsString())
+            .getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP);
     if (groupName == null) {
       groupName = RSGroupInfo.DEFAULT_GROUP;
     }
-    RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName);
-    if (rsGroupInfo == null) {
-      throw new ConstraintException("Default RSGroup (" + groupName + ") for 
this table's "
-          + "namespace does not exist.");
-    }
-    if (!rsGroupInfo.containsTable(desc.getTableName())) {
-      groupAdminServer.moveTables(Sets.newHashSet(desc.getTableName()), 
groupName);
+    RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfo(groupName);
+    if (RSGroupInfo == null) {
+      throw new ConstraintException("RSGroup " + groupName + " does not 
exist.");
     }
+    return RSGroupInfo;
   }
 
   /////////////////////////////////////////////////////////////////////////////
@@ -408,7 +423,10 @@ public class RSGroupAdminEndpoint extends 
RSGroupAdminService
   public void 
preCreateTableHandler(ObserverContext<MasterCoprocessorEnvironment> ctx,
                                     HTableDescriptor desc,
                                     HRegionInfo[] regions) throws IOException {
-
+    if (!desc.getTableName().isSystemTable() && 
!rsgroupHasOnlineServers(desc)) {
+      throw new HBaseIOException("No online servers in the rsgroup, which 
table " +
+          desc.getTableName().getNameAsString() + " belongs to");
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/hbase/blob/1fbe4deb/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups.java
----------------------------------------------------------------------
diff --git 
a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups.java 
b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups.java
index 081c0a3..6ae7858 100644
--- 
a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups.java
+++ 
b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroups.java
@@ -34,7 +34,6 @@ import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.Waiter;
 import org.apache.hadoop.hbase.Waiter.Predicate;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
-import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.master.ServerManager;
 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
 import org.apache.hadoop.hbase.net.Address;
@@ -61,7 +60,7 @@ import static org.junit.Assert.fail;
 @Category({MediumTests.class})
 public class TestRSGroups extends TestRSGroupsBase {
   protected static final Log LOG = LogFactory.getLog(TestRSGroups.class);
-  private static HMaster master;
+
   private static boolean init = false;
   private static RSGroupAdminEndpoint RSGroupAdminEndpoint;
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/1fbe4deb/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java
----------------------------------------------------------------------
diff --git 
a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java
 
b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java
index ac82e4c..0c3574a 100644
--- 
a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java
+++ 
b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java
@@ -26,9 +26,14 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
 import java.io.IOException;
 import java.security.SecureRandom;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -58,14 +63,9 @@ import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
 import 
org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetServerInfoRequest;
 import org.apache.hadoop.hbase.util.Bytes;
-
 import org.junit.Assert;
 import org.junit.Test;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
 public abstract class TestRSGroupsBase {
   protected static final Log LOG = LogFactory.getLog(TestRSGroupsBase.class);
 
@@ -79,6 +79,7 @@ public abstract class TestRSGroupsBase {
   protected static HBaseAdmin admin;
   protected static HBaseCluster cluster;
   protected static RSGroupAdmin rsGroupAdmin;
+  protected static HMaster master;
 
   public final static long WAIT_TIMEOUT = 60000*5;
   public final static int NUM_SLAVES_BASE = 4; //number of slaves for the 
smallest cluster
@@ -965,4 +966,66 @@ public abstract class TestRSGroupsBase {
     assertFalse(newGroupServers.contains(targetServer.getAddress()));
     assertEquals(2, newGroupServers.size());
   }
+
+  @Test
+  public void testCreateWhenRsgroupNoOnlineServers() throws Exception {
+    LOG.info("testCreateWhenRsgroupNoOnlineServers");
+    String testRSGroupName = "appInfo";
+
+    // make rsgroup has only one server and stop this server
+    final RSGroupInfo appInfo = addGroup(rsGroupAdmin, testRSGroupName, 1);
+    Iterator<Address> iterator = appInfo.getServers().iterator();
+    ServerName targetServer = 
ServerName.parseServerName(iterator.next().toString());
+    AdminProtos.AdminService.BlockingInterface targetRS =
+        ((ClusterConnection) admin.getConnection()).getAdmin(targetServer);
+    targetServer = ProtobufUtil.toServerName(targetRS.getServerInfo(null,
+        
GetServerInfoRequest.newBuilder().build()).getServerInfo().getServerName());
+    assertEquals(1, 
rsGroupAdmin.getRSGroupInfo(testRSGroupName).getServers().size());
+    
assertTrue(master.getServerManager().getOnlineServers().containsKey(targetServer));
+    try {
+      targetRS.stopServer(null,
+          AdminProtos.StopServerRequest.newBuilder().setReason("Die").build());
+    } catch(Exception e) {
+    }
+    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
+      @Override
+      public boolean evaluate() throws Exception {
+        return !master.getServerManager().areDeadServersInProgress()
+            && cluster.getClusterStatus().getDeadServerNames().size() > 0;
+      }
+    });
+    
assertTrue(!master.getServerManager().getOnlineServers().containsKey(targetServer));
+
+    // test create table when rsgroup has no online servers
+    final TableName tableName = TableName.valueOf(tablePrefix + "_ns", 
"_testCreate");
+    
admin.createNamespace(NamespaceDescriptor.create(tableName.getNamespaceAsString())
+        .addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, 
appInfo.getName()).build());
+    final HTableDescriptor desc = new HTableDescriptor(tableName);
+    desc.addFamily(new HColumnDescriptor("f"));
+    try {
+      admin.createTable(desc);
+      fail("Shouldn't create table successfully!");
+    } catch (Exception e) {
+      LOG.debug("create table error", e);
+    }
+
+    // add another online server to rsgroup, and test create table
+    RSGroupInfo defaultInfo = 
rsGroupAdmin.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP);
+    Set<Address> set = new HashSet<Address>();
+    for(ServerName sn : master.getServerManager().getOnlineServersList()) {
+      if(defaultInfo.getServers().contains(sn.getAddress())) {
+        set.add(sn.getAddress());
+        break;
+      }
+    }
+    rsGroupAdmin.moveServers(set, testRSGroupName);
+    assertEquals(2, 
rsGroupAdmin.getRSGroupInfo(testRSGroupName).getServers().size());
+    admin.createTable(desc);
+    // wait for created table to be assigned
+    TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
+      @Override public boolean evaluate() throws Exception {
+        return getTableRegionMap().get(desc.getTableName()) != null;
+      }
+    });
+  }
 }
\ No newline at end of file

Reply via email to