HBASE-16649 Truncate table with splits preserved can cause both data loss and truncated data appeared again

This commit is contained in:
Matteo Bertozzi 2016-09-26 12:58:04 -07:00
parent d6f9eab4be
commit 4566e4df58
6 changed files with 43 additions and 8 deletions

View File

@ -216,8 +216,9 @@ public class CatalogJanitor extends ScheduledChore {
+ " from fs because merged region no longer holds references"); + " from fs because merged region no longer holds references");
HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, regionA); HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, regionA);
HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, regionB); HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, regionB);
MetaTableAccessor.deleteMergeQualifiers(server.getConnection(), MetaTableAccessor.deleteMergeQualifiers(services.getConnection(), mergedRegion);
mergedRegion); services.getServerManager().removeRegion(regionA);
services.getServerManager().removeRegion(regionB);
return true; return true;
} }
return false; return false;
@ -360,6 +361,7 @@ public class CatalogJanitor extends ScheduledChore {
if (LOG.isTraceEnabled()) LOG.trace("Archiving parent region: " + parent); if (LOG.isTraceEnabled()) LOG.trace("Archiving parent region: " + parent);
HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, parent); HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, parent);
MetaTableAccessor.deleteRegion(this.connection, parent); MetaTableAccessor.deleteRegion(this.connection, parent);
services.getServerManager().removeRegion(parent);
result = true; result = true;
} }
return result; return result;
@ -461,4 +463,4 @@ public class CatalogJanitor extends ScheduledChore {
return cleanMergeRegion(region, mergeRegions.getFirst(), return cleanMergeRegion(region, mergeRegions.getFirst(),
mergeRegions.getSecond()); mergeRegions.getSecond());
} }
} }

View File

@ -1212,4 +1212,22 @@ public class ServerManager {
deadservers.cleanAllPreviousInstances(serverName); deadservers.cleanAllPreviousInstances(serverName);
} }
} }
/**
* Called by delete table and similar to notify the ServerManager that a region was removed.
*/
public void removeRegion(final HRegionInfo regionInfo) {
final byte[] encodedName = regionInfo.getEncodedNameAsBytes();
storeFlushedSequenceIdsByRegion.remove(encodedName);
flushedSequenceIdByRegion.remove(encodedName);
}
/**
* Called by delete table and similar to notify the ServerManager that a region was removed.
*/
public void removeRegions(final List<HRegionInfo> regions) {
for (HRegionInfo hri: regions) {
removeRegion(hri);
}
}
} }

View File

@ -379,6 +379,9 @@ public class DeleteTableProcedure
// Clean any remaining rows for this table. // Clean any remaining rows for this table.
cleanAnyRemainingRows(env, tableName); cleanAnyRemainingRows(env, tableName);
// clean region references from the server manager
env.getMasterServices().getServerManager().removeRegions(regions);
} }
protected static void deleteAssignmentState(final MasterProcedureEnv env, protected static void deleteAssignmentState(final MasterProcedureEnv env,

View File

@ -105,6 +105,8 @@ public class TruncateTableProcedure
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
regions = Arrays.asList(ModifyRegionUtils.createHRegionInfos(hTableDescriptor, null)); regions = Arrays.asList(ModifyRegionUtils.createHRegionInfos(hTableDescriptor, null));
} else {
regions = recreateRegionInfo(regions);
} }
setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT); setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
break; break;
@ -245,6 +247,14 @@ public class TruncateTableProcedure
} }
} }
private static List<HRegionInfo> recreateRegionInfo(final List<HRegionInfo> regions) {
ArrayList<HRegionInfo> newRegions = new ArrayList<HRegionInfo>(regions.size());
for (HRegionInfo hri: regions) {
newRegions.add(new HRegionInfo(hri.getTable(), hri.getStartKey(), hri.getEndKey()));
}
return newRegions;
}
private boolean prepareTruncate(final MasterProcedureEnv env) throws IOException { private boolean prepareTruncate(final MasterProcedureEnv env) throws IOException {
try { try {
env.getMasterServices().checkTableModifiable(getTableName()); env.getMasterServices().checkTableModifiable(getTableName());

View File

@ -216,10 +216,12 @@ public class TestCatalogJanitor {
class MockMasterServices implements MasterServices { class MockMasterServices implements MasterServices {
private final MasterFileSystem mfs; private final MasterFileSystem mfs;
private final AssignmentManager asm; private final AssignmentManager asm;
private final ServerManager sm;
MockMasterServices(final Server server) throws IOException { MockMasterServices(final Server server) throws IOException {
this.mfs = new MasterFileSystem(server, this); this.mfs = new MasterFileSystem(server, this);
this.asm = Mockito.mock(AssignmentManager.class); this.asm = Mockito.mock(AssignmentManager.class);
this.sm = Mockito.mock(ServerManager.class);
} }
@Override @Override
@ -289,7 +291,7 @@ public class TestCatalogJanitor {
@Override @Override
public ServerManager getServerManager() { public ServerManager getServerManager() {
return null; return sm;
} }
@Override @Override

View File

@ -162,10 +162,10 @@ public class TestTruncateTableProcedure {
UTIL.waitUntilAllRegionsAssigned(tableName); UTIL.waitUntilAllRegionsAssigned(tableName);
// validate the table regions and layout // validate the table regions and layout
regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new HRegionInfo[0]);
if (preserveSplits) { if (preserveSplits) {
assertEquals(1 + splitKeys.length, UTIL.getHBaseAdmin().getTableRegions(tableName).size()); assertEquals(1 + splitKeys.length, regions.length);
} else { } else {
regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new HRegionInfo[1]);
assertEquals(1, regions.length); assertEquals(1, regions.length);
} }
MasterProcedureTestingUtility.validateTableCreation( MasterProcedureTestingUtility.validateTableCreation(
@ -229,10 +229,10 @@ public class TestTruncateTableProcedure {
UTIL.waitUntilAllRegionsAssigned(tableName); UTIL.waitUntilAllRegionsAssigned(tableName);
// validate the table regions and layout // validate the table regions and layout
regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new HRegionInfo[0]);
if (preserveSplits) { if (preserveSplits) {
assertEquals(1 + splitKeys.length, UTIL.getHBaseAdmin().getTableRegions(tableName).size()); assertEquals(1 + splitKeys.length, regions.length);
} else { } else {
regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new HRegionInfo[1]);
assertEquals(1, regions.length); assertEquals(1, regions.length);
} }
MasterProcedureTestingUtility.validateTableCreation( MasterProcedureTestingUtility.validateTableCreation(