diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/ReplicationBarrierCleaner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/ReplicationBarrierCleaner.java index ed631ded6f5..ff1da0b1b25 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/ReplicationBarrierCleaner.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/ReplicationBarrierCleaner.java @@ -99,13 +99,22 @@ public class ReplicationBarrierCleaner extends ScheduledChore { peerIds = peerManager.getSerialPeerIdsBelongsTo(tableName); } if (peerIds.isEmpty()) { - // no serial replication, only keep the newest barrier - Cell cell = result.getColumnLatestCell(HConstants.REPLICATION_BARRIER_FAMILY, - HConstants.SEQNUM_QUALIFIER); - metaTable.delete(new Delete(regionName).addFamily(HConstants.REPLICATION_BARRIER_FAMILY, - cell.getTimestamp() - 1)); + // no serial replication + // check if the region has already been removed, i.e, no catalog family + if (metaTable.exists(new Get(regionName).addFamily(HConstants.CATALOG_FAMILY))) { + // exists, then only keep the newest barrier + Cell cell = result.getColumnLatestCell(HConstants.REPLICATION_BARRIER_FAMILY, + HConstants.SEQNUM_QUALIFIER); + metaTable.delete(new Delete(regionName).addFamily(HConstants.REPLICATION_BARRIER_FAMILY, + cell.getTimestamp() - 1)); + deletedBarriers += barriers.length - 1; + } else { + // not exists, delete all the barriers + metaTable + .delete(new Delete(regionName).addFamily(HConstants.REPLICATION_BARRIER_FAMILY)); + deletedBarriers += barriers.length; + } cleanedRows++; - deletedBarriers += barriers.length - 1; continue; } String encodedRegionName = RegionInfo.encodeRegionName(regionName); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/cleaner/TestReplicationBarrierCleaner.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/cleaner/TestReplicationBarrierCleaner.java index 6e0d6484a0f..52973e448ed 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/cleaner/TestReplicationBarrierCleaner.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/cleaner/TestReplicationBarrierCleaner.java @@ -181,17 +181,21 @@ public class TestReplicationBarrierCleaner { RegionInfo region11 = RegionInfoBuilder.newBuilder(tableName1).setEndKey(Bytes.toBytes(1)).build(); addBarrier(region11, 10, 20, 30, 40, 50, 60); + fillCatalogFamily(region11); RegionInfo region12 = RegionInfoBuilder.newBuilder(tableName1).setStartKey(Bytes.toBytes(1)).build(); addBarrier(region12, 20, 30, 40, 50, 60, 70); + fillCatalogFamily(region12); TableName tableName2 = TableName.valueOf(name.getMethodName() + "_2"); RegionInfo region21 = RegionInfoBuilder.newBuilder(tableName2).setEndKey(Bytes.toBytes(1)).build(); addBarrier(region21, 100, 200, 300, 400); + fillCatalogFamily(region21); RegionInfo region22 = RegionInfoBuilder.newBuilder(tableName2).setStartKey(Bytes.toBytes(1)).build(); addBarrier(region22, 200, 300, 400, 500, 600); + fillCatalogFamily(region22); @SuppressWarnings("unchecked") ReplicationPeerManager peerManager = @@ -285,6 +289,25 @@ public class TestReplicationBarrierCleaner { Arrays.asList(region.getEncodedName())); } + @Test + public void testDeleteRowForDeletedRegionNoPeers() throws IOException { + TableName tableName = TableName.valueOf(name.getMethodName()); + RegionInfo region = RegionInfoBuilder.newBuilder(tableName).build(); + addBarrier(region, 40, 50, 60); + + ReplicationPeerManager peerManager = mock(ReplicationPeerManager.class); + ReplicationBarrierCleaner cleaner = create(peerManager); + cleaner.chore(); + + verify(peerManager, times(1)).getSerialPeerIdsBelongsTo(tableName); + // There are no peers, and no catalog family for this region either, so we should remove the + // barriers. And since there is no catalog family, after we delete the barrier family, the whole + // row is deleted. + try (Table table = UTIL.getConnection().getTable(TableName.META_TABLE_NAME)) { + assertFalse(table.exists(new Get(region.getRegionName()))); + } + } + private static class WarnOnlyStoppable implements Stoppable { @Override public void stop(String why) {