HBASE-17319 Truncate table with preserve after split may cause truncation to fail (Allan Yang)
This commit is contained in:
parent
ffe70158cc
commit
f3a3069796
|
@ -149,17 +149,22 @@ public final class ProcedureSyncWait {
|
|||
|
||||
protected static List<HRegionInfo> getRegionsFromMeta(final MasterProcedureEnv env,
|
||||
final TableName tableName) throws IOException {
|
||||
return getRegionsFromMeta(env, tableName, false);
|
||||
}
|
||||
|
||||
protected static List<HRegionInfo> getRegionsFromMeta(final MasterProcedureEnv env,
|
||||
final TableName tableName, final boolean excludeOfflinedSplitParents) throws IOException {
|
||||
return ProcedureSyncWait.waitFor(env, "regions of table=" + tableName + " from meta",
|
||||
new ProcedureSyncWait.Predicate<List<HRegionInfo>>() {
|
||||
@Override
|
||||
public List<HRegionInfo> evaluate() throws IOException {
|
||||
if (TableName.META_TABLE_NAME.equals(tableName)) {
|
||||
return new MetaTableLocator().getMetaRegions(env.getMasterServices().getZooKeeper());
|
||||
}
|
||||
return MetaTableAccessor.getTableRegions(env.getMasterServices().getZooKeeper(),
|
||||
env.getMasterServices().getConnection(), tableName);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public List<HRegionInfo> evaluate() throws IOException {
|
||||
if (TableName.META_TABLE_NAME.equals(tableName)) {
|
||||
return new MetaTableLocator().getMetaRegions(env.getMasterServices().getZooKeeper());
|
||||
}
|
||||
return MetaTableAccessor.getTableRegions(env.getMasterServices().getZooKeeper(),
|
||||
env.getMasterServices().getConnection(), tableName, excludeOfflinedSplitParents);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected static void waitRegionInTransition(final MasterProcedureEnv env,
|
||||
|
|
|
@ -85,7 +85,7 @@ public class TruncateTableProcedure
|
|||
|
||||
// TODO: Move out... in the acquireLock()
|
||||
LOG.debug("waiting for '" + getTableName() + "' regions in transition");
|
||||
regions = ProcedureSyncWait.getRegionsFromMeta(env, getTableName());
|
||||
regions = ProcedureSyncWait.getRegionsFromMeta(env, getTableName(), true);
|
||||
assert regions != null && !regions.isEmpty() : "unexpected 0 regions";
|
||||
ProcedureSyncWait.waitRegionInTransition(env, regions);
|
||||
|
||||
|
@ -102,15 +102,17 @@ public class TruncateTableProcedure
|
|||
break;
|
||||
case TRUNCATE_TABLE_CLEAR_FS_LAYOUT:
|
||||
DeleteTableProcedure.deleteFromFs(env, getTableName(), regions, true);
|
||||
setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
|
||||
break;
|
||||
case TRUNCATE_TABLE_CREATE_FS_LAYOUT:
|
||||
if (!preserveSplits) {
|
||||
// if we are not preserving splits, generate a new single region
|
||||
//recreateRegionInfo in TRUNCATE_TABLE_CREATE_FS_LAYOUT phase, since if create fs layout fails
|
||||
//we need to refresh the region encoded name to prevent dir name conflict
|
||||
regions = Arrays.asList(ModifyRegionUtils.createHRegionInfos(hTableDescriptor, null));
|
||||
} else {
|
||||
regions = recreateRegionInfo(regions);
|
||||
}
|
||||
setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
|
||||
break;
|
||||
case TRUNCATE_TABLE_CREATE_FS_LAYOUT:
|
||||
regions = CreateTableProcedure.createFsLayout(env, hTableDescriptor, regions);
|
||||
CreateTableProcedure.updateTableDescCache(env, getTableName());
|
||||
setNextState(TruncateTableState.TRUNCATE_TABLE_ADD_TO_META);
|
||||
|
|
|
@ -250,4 +250,35 @@ public class TestTruncateTableProcedure {
|
|||
private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
|
||||
return UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor();
|
||||
}
|
||||
|
||||
@Test(timeout=60000)
|
||||
public void testTruncateWithPreserveAfterSplit() throws Exception{
|
||||
final String[] families = new String[] { "f1", "f2" };
|
||||
final byte[][] splitKeys = new byte[][] {
|
||||
Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("c")
|
||||
};
|
||||
TableName tableName = TableName.valueOf("testTruncateWithPreserveAfterSplit");
|
||||
HRegionInfo[] regions = MasterProcedureTestingUtility.createTable(
|
||||
getMasterProcedureExecutor(), tableName, splitKeys, families);
|
||||
// load enough data so the table can split
|
||||
MasterProcedureTestingUtility.loadData(
|
||||
UTIL.getConnection(), tableName, 5000, splitKeys, families);
|
||||
assertEquals(5000, UTIL.countRows(tableName));
|
||||
UTIL.getHBaseAdmin().split(tableName);
|
||||
UTIL.waitUntilAllRegionsAssigned(tableName);
|
||||
//wait until split really happens
|
||||
while(UTIL.getHBaseAdmin().getTableRegions(tableName).size() <= regions.length) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
// disable the table
|
||||
UTIL.getHBaseAdmin().disableTable(tableName);
|
||||
// truncate the table
|
||||
final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
|
||||
long procId = ProcedureTestingUtility.submitAndWait(procExec,
|
||||
new TruncateTableProcedure(procExec.getEnvironment(), tableName, true));
|
||||
ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
|
||||
|
||||
UTIL.waitUntilAllRegionsAssigned(tableName);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue