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


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/f06c0060
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/f06c0060
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/f06c0060

Branch: refs/heads/hbase-14439
Commit: f06c0060aa13a2b5b18edeb66b7479bdd3c6fdc8
Parents: 43f47a8
Author: Matteo Bertozzi <[email protected]>
Authored: Mon Sep 26 12:58:04 2016 -0700
Committer: Matteo Bertozzi <[email protected]>
Committed: Mon Sep 26 12:58:04 2016 -0700

----------------------------------------------------------------------
 .../hadoop/hbase/master/CatalogJanitor.java       |  3 +++
 .../apache/hadoop/hbase/master/ServerManager.java | 18 ++++++++++++++++++
 .../master/procedure/DeleteTableProcedure.java    |  3 +++
 .../master/procedure/TruncateTableProcedure.java  | 10 ++++++++++
 .../hadoop/hbase/master/TestCatalogJanitor.java   |  7 +++++++
 .../procedure/TestTruncateTableProcedure.java     |  8 ++++----
 6 files changed, 45 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
index d14a925..e748c3b 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
@@ -213,6 +213,8 @@ public class CatalogJanitor extends ScheduledChore {
       HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, 
regionA);
       HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, 
regionB);
       MetaTableAccessor.deleteMergeQualifiers(services.getConnection(), 
mergedRegion);
+      services.getServerManager().removeRegion(regionA);
+      services.getServerManager().removeRegion(regionB);
       return true;
     }
     return false;
@@ -357,6 +359,7 @@ public class CatalogJanitor extends ScheduledChore {
       if (LOG.isTraceEnabled()) LOG.trace("Archiving parent region: " + 
parent);
       HFileArchiver.archiveRegion(this.services.getConfiguration(), fs, 
parent);
       MetaTableAccessor.deleteRegion(this.connection, parent);
+      services.getServerManager().removeRegion(parent);
       result = true;
     }
     return result;

http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
index f97dfb4..3d8715a 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java
@@ -1184,4 +1184,22 @@ public class ServerManager {
       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);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
index f8dd0b6..fdf0b82 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
@@ -363,6 +363,9 @@ public class DeleteTableProcedure
 
     // Clean any remaining rows for this table.
     cleanAnyRemainingRows(env, tableName);
+
+    // clean region references from the server manager
+    env.getMasterServices().getServerManager().removeRegions(regions);
   }
 
   protected static void deleteAssignmentState(final MasterProcedureEnv env,

http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateTableProcedure.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateTableProcedure.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateTableProcedure.java
index 701eaf7..95c3192 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateTableProcedure.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateTableProcedure.java
@@ -107,6 +107,8 @@ public class TruncateTableProcedure
           if (!preserveSplits) {
             // if we are not preserving splits, generate a new single region
             regions = 
Arrays.asList(ModifyRegionUtils.createHRegionInfos(hTableDescriptor, null));
+          } else {
+            regions = recreateRegionInfo(regions);
           }
           setNextState(TruncateTableState.TRUNCATE_TABLE_CREATE_FS_LAYOUT);
           break;
@@ -256,6 +258,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 {
     try {
       env.getMasterServices().checkTableModifiable(getTableName());

http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
index 67ea5f6..140dcd9 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
@@ -91,6 +91,7 @@ public class TestCatalogJanitor {
     private final ClusterConnection connection;
     private final MasterFileSystem mfs;
     private final AssignmentManager asm;
+    private final ServerManager sm;
 
     MockMasterServices(final HBaseTestingUtility htu) throws IOException {
       super(htu.getConfiguration());
@@ -134,6 +135,7 @@ public class TestCatalogJanitor {
 
       this.mfs = new MasterFileSystem(this);
       this.asm = Mockito.mock(AssignmentManager.class);
+      this.sm = Mockito.mock(ServerManager.class);
     }
 
     @Override
@@ -157,6 +159,11 @@ public class TestCatalogJanitor {
     }
 
     @Override
+    public ServerManager getServerManager() {
+      return this.sm;
+    }
+
+    @Override
     public CoordinatedStateManager getCoordinatedStateManager() {
       BaseCoordinatedStateManager m = 
Mockito.mock(BaseCoordinatedStateManager.class);
       SplitLogManagerCoordination c = 
Mockito.mock(SplitLogManagerCoordination.class);

http://git-wip-us.apache.org/repos/asf/hbase/blob/f06c0060/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTruncateTableProcedure.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTruncateTableProcedure.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTruncateTableProcedure.java
index a7bfe18..c72e3f3 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTruncateTableProcedure.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestTruncateTableProcedure.java
@@ -165,10 +165,10 @@ public class TestTruncateTableProcedure {
     UTIL.waitUntilAllRegionsAssigned(tableName);
 
     // validate the table regions and layout
+    regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new 
HRegionInfo[0]);
     if (preserveSplits) {
-      assertEquals(1 + splitKeys.length, 
UTIL.getHBaseAdmin().getTableRegions(tableName).size());
+      assertEquals(1 + splitKeys.length, regions.length);
     } else {
-      regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new 
HRegionInfo[1]);
       assertEquals(1, regions.length);
     }
     MasterProcedureTestingUtility.validateTableCreation(
@@ -231,10 +231,10 @@ public class TestTruncateTableProcedure {
     UTIL.waitUntilAllRegionsAssigned(tableName);
 
     // validate the table regions and layout
+    regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new 
HRegionInfo[0]);
     if (preserveSplits) {
-      assertEquals(1 + splitKeys.length, 
UTIL.getHBaseAdmin().getTableRegions(tableName).size());
+      assertEquals(1 + splitKeys.length, regions.length);
     } else {
-      regions = UTIL.getHBaseAdmin().getTableRegions(tableName).toArray(new 
HRegionInfo[1]);
       assertEquals(1, regions.length);
     }
     MasterProcedureTestingUtility.validateTableCreation(

Reply via email to