HBASE-20104 Fix infinite loop of RIT when creating table on a rsgroup that has no online servers
Signed-off-by: tedyu <yuzhihong@gmail.com>
This commit is contained in:
parent
a2bf2ad71e
commit
a08ade9f1a
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.apache.hadoop.hbase.rsgroup;
|
||||
|
||||
|
||||
import com.google.protobuf.RpcCallback;
|
||||
import com.google.protobuf.RpcController;
|
||||
import com.google.protobuf.Service;
|
||||
|
@ -32,6 +31,7 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.hadoop.hbase.CoprocessorEnvironment;
|
||||
import org.apache.hadoop.hbase.HBaseIOException;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
|
@ -353,6 +353,27 @@ public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver {
|
|||
}
|
||||
}
|
||||
|
||||
boolean rsgroupHasServersOnline(TableDescriptor desc) throws IOException {
|
||||
String groupName =
|
||||
master.getClusterSchema().getNamespace(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.");
|
||||
}
|
||||
|
||||
for (ServerName onlineServer : master.getServerManager().createDestinationServersList()) {
|
||||
if (rsGroupInfo.getServers().contains(onlineServer.getAddress())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void assignTableToGroup(TableDescriptor desc) throws IOException {
|
||||
String groupName =
|
||||
master.getClusterSchema().getNamespace(desc.getTableName().getNamespaceAsString())
|
||||
|
@ -375,6 +396,17 @@ public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver {
|
|||
// MasterObserver overrides
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void preCreateTableAction(
|
||||
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
final TableDescriptor desc,
|
||||
final RegionInfo[] regions) throws IOException {
|
||||
if (!desc.getTableName().isSystemTable() && !rsgroupHasServersOnline(desc)) {
|
||||
throw new HBaseIOException("No online servers in the rsgroup, which table " +
|
||||
desc.getTableName().getNameAsString() + " belongs to");
|
||||
}
|
||||
}
|
||||
|
||||
// Assign table to default RSGroup.
|
||||
@Override
|
||||
public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||
|
|
|
@ -997,4 +997,47 @@ public abstract class TestRSGroupsBase {
|
|||
assertFalse(newGroupServers.contains(targetServer.getAddress()));
|
||||
assertEquals(2, newGroupServers.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWhenRsgroupNoOnlineServers() throws Exception {
|
||||
LOG.info("testCreateWhenRsgroupNoOnlineServers");
|
||||
|
||||
// set rsgroup has no online servers and test create table
|
||||
final RSGroupInfo appInfo = addGroup("appInfo", 1);
|
||||
Iterator<Address> iterator = appInfo.getServers().iterator();
|
||||
List<ServerName> serversToDecommission = new ArrayList<>();
|
||||
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());
|
||||
assertTrue(master.getServerManager().getOnlineServers().containsKey(targetServer));
|
||||
serversToDecommission.add(targetServer);
|
||||
admin.decommissionRegionServers(serversToDecommission, true);
|
||||
assertEquals(1, admin.listDecommissionedRegionServers().size());
|
||||
|
||||
final TableName tableName = TableName.valueOf(tablePrefix + "_ns", name.getMethodName());
|
||||
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);
|
||||
}
|
||||
|
||||
// recommission and test create table
|
||||
admin.recommissionRegionServer(targetServer, null);
|
||||
assertEquals(0, admin.listDecommissionedRegionServers().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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue