You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2016/12/15 21:45:21 UTC

hbase git commit: HBASE-17319 Truncate table with preserve after split may cause truncation to fail (Allan Yang)

Repository: hbase
Updated Branches:
  refs/heads/branch-1 ffe70158c -> f3a306979


HBASE-17319 Truncate table with preserve after split may cause truncation to fail (Allan Yang)


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

Branch: refs/heads/branch-1
Commit: f3a30697966afd3adac698b83be14b830eaad942
Parents: ffe7015
Author: tedyu <yu...@gmail.com>
Authored: Thu Dec 15 13:45:11 2016 -0800
Committer: tedyu <yu...@gmail.com>
Committed: Thu Dec 15 13:45:11 2016 -0800

----------------------------------------------------------------------
 .../master/procedure/ProcedureSyncWait.java     | 23 +++++++++------
 .../procedure/TruncateTableProcedure.java       | 10 ++++---
 .../procedure/TestTruncateTableProcedure.java   | 31 ++++++++++++++++++++
 3 files changed, 51 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/f3a30697/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
index 5c03a4a..d0dea0a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
@@ -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,

http://git-wip-us.apache.org/repos/asf/hbase/blob/f3a30697/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 9dccef6..735e94f 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
@@ -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);

http://git-wip-us.apache.org/repos/asf/hbase/blob/f3a30697/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 941dd2f..7a3df0f 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
@@ -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);
+
+  }
 }