HBASE-15456 CreateTableProcedure/ModifyTableProcedure needs to fail when there is no family in table descriptor (huaxiang sun)

This commit is contained in:
tedyu 2016-03-15 16:21:16 -07:00
parent 934c0274e3
commit f8bcb54479
6 changed files with 94 additions and 2 deletions

View File

@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MetaTableAccessor;
@ -302,6 +303,14 @@ public class CreateTableProcedure
return false;
}
}
// check that we have at least 1 CF
if (hTableDescriptor.getColumnFamilies().length == 0) {
setFailure("master-create-table", new DoNotRetryIOException("Table " +
getTableName().toString() + " should have at least one column family."));
return false;
}
return true;
}

View File

@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
@ -286,6 +287,12 @@ public class ModifyTableProcedure
throw new TableNotFoundException(getTableName());
}
// check that we have at least 1 CF
if (modifiedHTableDescriptor.getColumnFamilies().length == 0) {
throw new DoNotRetryIOException("Table " + getTableName().toString() +
" should have at least one column family.");
}
// In order to update the descriptor, we need to retrieve the old descriptor for comparison.
this.unmodifiedHTableDescriptor =
env.getMasterServices().getTableDescriptors().get(getTableName());

View File

@ -798,6 +798,13 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
* @throws IOException e
*/
private long initialize(final CancelableProgressable reporter) throws IOException {
//Refuse to open the region if there is no column family in the table
if (htableDescriptor.getColumnFamilies().length == 0) {
throw new DoNotRetryIOException("Table " + htableDescriptor.getNameAsString() +
" should have at least one column family.");
}
MonitoredTask status = TaskMonitor.get().createStatus("Initializing region " + this);
long nextSeqId = -1;
try {

View File

@ -23,10 +23,12 @@ import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.ProcedureInfo;
import org.apache.hadoop.hbase.TableExistsException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
@ -42,6 +44,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@Category(MediumTests.class)
@ -118,6 +121,27 @@ public class TestCreateTableProcedure {
UTIL.getHBaseCluster().getMaster(), tableName, regions, "f1", "f2");
}
@Test(timeout=60000)
public void testCreateWithoutColumnFamily() throws Exception {
final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
final TableName tableName = TableName.valueOf("testCreateWithoutColumnFamily");
// create table with 0 families will fail
final HTableDescriptor htd = MasterProcedureTestingUtility.createHTD(tableName);
// disable sanity check
htd.setConfiguration("hbase.table.sanity.checks", Boolean.FALSE.toString());
final HRegionInfo[] regions = ModifyRegionUtils.createHRegionInfos(htd, null);
long procId =
ProcedureTestingUtility.submitAndWait(procExec,
new CreateTableProcedure(procExec.getEnvironment(), htd, regions));
final ProcedureInfo result = procExec.getResult(procId);
assertEquals(true, result.isFailed());
Throwable cause = ProcedureTestingUtility.getExceptionCause(result);
assertTrue("expected DoNotRetryIOException, got " + cause,
cause instanceof DoNotRetryIOException);
}
@Test(timeout=60000, expected=TableExistsException.class)
public void testCreateExisting() throws Exception {
final TableName tableName = TableName.valueOf("testCreateExisting");

View File

@ -25,11 +25,13 @@ import static org.junit.Assert.assertTrue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.ProcedureInfo;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
@ -167,12 +169,13 @@ public class TestModifyTableProcedure {
@Test(timeout = 60000)
public void testModifyTableDeleteCF() throws Exception {
final TableName tableName = TableName.valueOf("testModifyTableAddCF");
final TableName tableName = TableName.valueOf("testModifyTableDeleteCF");
final String cf1 = "cf1";
final String cf2 = "cf2";
final String cf3 = "cf3";
final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
MasterProcedureTestingUtility.createTable(procExec, tableName, null, "cf1", cf2, cf3);
MasterProcedureTestingUtility.createTable(procExec, tableName, null, cf1, cf2, cf3);
HTableDescriptor currentHtd = UTIL.getHBaseAdmin().getTableDescriptor(tableName);
assertEquals(3, currentHtd.getFamiliesKeys().size());
@ -195,6 +198,8 @@ public class TestModifyTableProcedure {
HTableDescriptor htd2 =
new HTableDescriptor(UTIL.getHBaseAdmin().getTableDescriptor(tableName));
htd2.removeFamily(cf3.getBytes());
// Disable Sanity check
htd2.setConfiguration("hbase.table.sanity.checks", Boolean.FALSE.toString());
long procId2 =
ProcedureTestingUtility.submitAndWait(procExec,
@ -204,6 +209,21 @@ public class TestModifyTableProcedure {
currentHtd = UTIL.getHBaseAdmin().getTableDescriptor(tableName);
assertEquals(1, currentHtd.getFamiliesKeys().size());
assertFalse(currentHtd.hasFamily(cf3.getBytes()));
//Removing the last family will fail
HTableDescriptor htd3 =
new HTableDescriptor(UTIL.getHBaseAdmin().getTableDescriptor(tableName));
htd3.removeFamily(cf1.getBytes());
long procId3 =
ProcedureTestingUtility.submitAndWait(procExec,
new ModifyTableProcedure(procExec.getEnvironment(), htd3));
final ProcedureInfo result = procExec.getResult(procId3);
assertEquals(true, result.isFailed());
Throwable cause = ProcedureTestingUtility.getExceptionCause(result);
assertTrue("expected DoNotRetryIOException, got " + cause,
cause instanceof DoNotRetryIOException);
assertEquals(1, currentHtd.getFamiliesKeys().size());
assertTrue(currentHtd.hasFamily(cf1.getBytes()));
}
@Test(timeout=60000)

View File

@ -144,12 +144,17 @@ public class TestNamespaceAuditor {
ADMIN.createNamespace(nspDesc);
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(nsp));
assertEquals(ADMIN.listNamespaceDescriptors().length, 3);
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne =
new HTableDescriptor(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1"));
tableDescOne.addFamily(fam1);
HTableDescriptor tableDescTwo =
new HTableDescriptor(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2"));
tableDescTwo.addFamily(fam1);
HTableDescriptor tableDescThree =
new HTableDescriptor(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table3"));
tableDescThree.addFamily(fam1);
ADMIN.createTable(tableDescOne);
boolean constraintViolated = false;
try {
@ -248,10 +253,13 @@ public class TestNamespaceAuditor {
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(namespace));
NamespaceTableAndRegionInfo stateInfo = getNamespaceState(nspDesc.getName());
assertNotNull("Namespace state found null for " + namespace, stateInfo);
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne =
new HTableDescriptor(TableName.valueOf(namespace + TableName.NAMESPACE_DELIM + "table1"));
tableDescOne.addFamily(fam1);
HTableDescriptor tableDescTwo =
new HTableDescriptor(TableName.valueOf(namespace + TableName.NAMESPACE_DELIM + "table2"));
tableDescTwo.addFamily(fam1);
ADMIN.createTable(tableDescOne);
ADMIN.createTable(tableDescTwo, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 5);
stateInfo = getNamespaceState(nspDesc.getName());
@ -589,9 +597,13 @@ public class TestNamespaceAuditor {
TableName tableOne = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table1");
TableName tableTwo = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table2");
TableName tableThree = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table3");
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne = new HTableDescriptor(tableOne);
tableDescOne.addFamily(fam1);
HTableDescriptor tableDescTwo = new HTableDescriptor(tableTwo);
tableDescTwo.addFamily(fam1);
HTableDescriptor tableDescThree = new HTableDescriptor(tableThree);
tableDescThree.addFamily(fam1);
ADMIN.createTable(tableDescOne, Bytes.toBytes("1"), Bytes.toBytes("1000"), 3);
ADMIN.createTable(tableDescTwo, Bytes.toBytes("1"), Bytes.toBytes("1000"), 3);
ADMIN.createTable(tableDescThree, Bytes.toBytes("1"), Bytes.toBytes("1000"), 4);
@ -680,10 +692,13 @@ public class TestNamespaceAuditor {
ADMIN.createNamespace(nspDesc);
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(nsp));
assertEquals(ADMIN.listNamespaceDescriptors().length, 3);
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne =
new HTableDescriptor(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1"));
tableDescOne.addFamily(fam1);
HTableDescriptor tableDescTwo =
new HTableDescriptor(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2"));
tableDescTwo.addFamily(fam1);
ADMIN.createTable(tableDescOne);
ADMIN.createTable(tableDescTwo, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 4);
}
@ -698,7 +713,9 @@ public class TestNamespaceAuditor {
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(nsp));
TableName tableName = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1");
TableName cloneTableName = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2");
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne = new HTableDescriptor(tableName);
tableDescOne.addFamily(fam1);
ADMIN.createTable(tableDescOne);
String snapshot = "snapshot_testTableQuotaExceedWithCloneSnapshot";
ADMIN.snapshot(snapshot, tableName);
@ -716,7 +733,10 @@ public class TestNamespaceAuditor {
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(nsp));
TableName tableName = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1");
TableName cloneTableName = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2");
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
HTableDescriptor tableDescOne = new HTableDescriptor(tableName);
tableDescOne.addFamily(fam1);
ADMIN.createTable(tableDescOne, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 4);
String snapshot = "snapshot_testCloneSnapshot";
@ -751,6 +771,8 @@ public class TestNamespaceAuditor {
assertNotNull("Namespace descriptor found null.", ADMIN.getNamespaceDescriptor(nsp));
TableName tableName1 = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1");
HTableDescriptor tableDescOne = new HTableDescriptor(tableName1);
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
tableDescOne.addFamily(fam1);
ADMIN.createTable(tableDescOne, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 4);
NamespaceTableAndRegionInfo nstate = getNamespaceState(nsp);
@ -786,6 +808,9 @@ public class TestNamespaceAuditor {
assertNotNull("Namespace descriptor found null.", ndesc);
TableName tableName1 = TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1");
HTableDescriptor tableDescOne = new HTableDescriptor(tableName1);
HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
tableDescOne.addFamily(fam1);
ADMIN.createTable(tableDescOne, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 4);
NamespaceTableAndRegionInfo nstate = getNamespaceState(nsp);