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,
|
protected static List<HRegionInfo> getRegionsFromMeta(final MasterProcedureEnv env,
|
||||||
final TableName tableName) throws IOException {
|
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",
|
return ProcedureSyncWait.waitFor(env, "regions of table=" + tableName + " from meta",
|
||||||
new ProcedureSyncWait.Predicate<List<HRegionInfo>>() {
|
new ProcedureSyncWait.Predicate<List<HRegionInfo>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<HRegionInfo> evaluate() throws IOException {
|
public List<HRegionInfo> evaluate() throws IOException {
|
||||||
if (TableName.META_TABLE_NAME.equals(tableName)) {
|
if (TableName.META_TABLE_NAME.equals(tableName)) {
|
||||||
return new MetaTableLocator().getMetaRegions(env.getMasterServices().getZooKeeper());
|
return new MetaTableLocator().getMetaRegions(env.getMasterServices().getZooKeeper());
|
||||||
}
|
}
|
||||||
return MetaTableAccessor.getTableRegions(env.getMasterServices().getZooKeeper(),
|
return MetaTableAccessor.getTableRegions(env.getMasterServices().getZooKeeper(),
|
||||||
env.getMasterServices().getConnection(), tableName);
|
env.getMasterServices().getConnection(), tableName, excludeOfflinedSplitParents);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void waitRegionInTransition(final MasterProcedureEnv env,
|
protected static void waitRegionInTransition(final MasterProcedureEnv env,
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class TruncateTableProcedure
|
||||||
|
|
||||||
// TODO: Move out... in the acquireLock()
|
// TODO: Move out... in the acquireLock()
|
||||||
LOG.debug("waiting for '" + getTableName() + "' regions in transition");
|
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";
|
assert regions != null && !regions.isEmpty() : "unexpected 0 regions";
|
||||||
ProcedureSyncWait.waitRegionInTransition(env, regions);
|
ProcedureSyncWait.waitRegionInTransition(env, regions);
|
||||||
|
|
||||||
|
@ -102,15 +102,17 @@ public class TruncateTableProcedure
|
||||||
break;
|
break;
|
||||||
case TRUNCATE_TABLE_CLEAR_FS_LAYOUT:
|
case TRUNCATE_TABLE_CLEAR_FS_LAYOUT:
|
||||||
DeleteTableProcedure.deleteFromFs(env, getTableName(), regions, true);
|
DeleteTableProcedure.deleteFromFs(env, getTableName(), regions, true);
|
||||||
|
setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
|
||||||
|
break;
|
||||||
|
case TRUNCATE_TABLE_CREATE_FS_LAYOUT:
|
||||||
if (!preserveSplits) {
|
if (!preserveSplits) {
|
||||||
// if we are not preserving splits, generate a new single region
|
// 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));
|
regions = Arrays.asList(ModifyRegionUtils.createHRegionInfos(hTableDescriptor, null));
|
||||||
} else {
|
} else {
|
||||||
regions = recreateRegionInfo(regions);
|
regions = recreateRegionInfo(regions);
|
||||||
}
|
}
|
||||||
setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
|
|
||||||
break;
|
|
||||||
case TRUNCATE_TABLE_CREATE_FS_LAYOUT:
|
|
||||||
regions = CreateTableProcedure.createFsLayout(env, hTableDescriptor, regions);
|
regions = CreateTableProcedure.createFsLayout(env, hTableDescriptor, regions);
|
||||||
CreateTableProcedure.updateTableDescCache(env, getTableName());
|
CreateTableProcedure.updateTableDescCache(env, getTableName());
|
||||||
setNextState(TruncateTableState.TRUNCATE_TABLE_ADD_TO_META);
|
setNextState(TruncateTableState.TRUNCATE_TABLE_ADD_TO_META);
|
||||||
|
|
|
@ -250,4 +250,35 @@ public class TestTruncateTableProcedure {
|
||||||
private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
|
private ProcedureExecutor<MasterProcedureEnv> getMasterProcedureExecutor() {
|
||||||
return UTIL.getHBaseCluster().getMaster().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