You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by an...@apache.org on 2015/06/16 11:33:09 UTC

hbase git commit: HBASE-13737 [HBase MOB] MOBTable cloned from a snapshot leads to data loss, when that actual snapshot and main table is deleted. (Ashutosh Jindal)

Repository: hbase
Updated Branches:
  refs/heads/hbase-11339 faefb9073 -> 2e2742183


HBASE-13737 [HBase MOB] MOBTable cloned from a snapshot leads to data loss, when that actual snapshot and main table is deleted. (Ashutosh Jindal)


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

Branch: refs/heads/hbase-11339
Commit: 2e2742183fac824dcf19c556fdc8ae1da326ba7c
Parents: faefb90
Author: anoopsjohn <an...@gmail.com>
Authored: Tue Jun 16 15:02:50 2015 +0530
Committer: anoopsjohn <an...@gmail.com>
Committed: Tue Jun 16 15:02:50 2015 +0530

----------------------------------------------------------------------
 .../hbase/master/cleaner/HFileLinkCleaner.java  |  6 ++
 .../TestMobSnapshotCloneIndependence.java       | 58 ++++++++++++++++++++
 2 files changed, 64 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/2e274218/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileLinkCleaner.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileLinkCleaner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileLinkCleaner.java
index 46e74d4..0570479 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileLinkCleaner.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/HFileLinkCleaner.java
@@ -28,6 +28,7 @@ import org.apache.hadoop.hbase.HBaseInterfaceAudience;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.hbase.io.HFileLink;
+import org.apache.hadoop.hbase.mob.MobUtils;
 import org.apache.hadoop.hbase.util.FSUtils;
 
 /**
@@ -64,6 +65,11 @@ public class HFileLinkCleaner extends BaseHFileCleanerDelegate {
         if (fs.exists(hfilePath)) {
           return false;
         }
+        // check whether the HFileLink still exists in mob dir.
+        hfilePath = HFileLink.getHFileFromBackReference(MobUtils.getMobHome(getConf()), filePath);
+        if (fs.exists(hfilePath)) {
+          return false;
+        }
         hfilePath = HFileLink.getHFileFromBackReference(FSUtils.getRootDir(getConf()), filePath);
         return !fs.exists(hfilePath);
       } catch (IOException e) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/2e274218/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMobSnapshotCloneIndependence.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMobSnapshotCloneIndependence.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMobSnapshotCloneIndependence.java
index a2cd51c..5f1b85f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMobSnapshotCloneIndependence.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMobSnapshotCloneIndependence.java
@@ -25,12 +25,17 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.master.cleaner.HFileCleaner;
+import org.apache.hadoop.hbase.master.cleaner.HFileLinkCleaner;
+import org.apache.hadoop.hbase.master.snapshot.SnapshotHFileCleaner;
 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
 import org.apache.hadoop.hbase.mob.MobConstants;
 import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy;
@@ -90,6 +95,8 @@ public class TestMobSnapshotCloneIndependence {
     conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
       ConstantSizeRegionSplitPolicy.class.getName());
     conf.setInt(MobConstants.MOB_FILE_CACHE_SIZE_KEY, 0);
+    conf.set(HFileCleaner.MASTER_HFILE_CLEANER_PLUGINS, SnapshotHFileCleaner.class.getName() + ","
+      + HFileLinkCleaner.class.getName());
   }
 
   @Before
@@ -167,6 +174,57 @@ public class TestMobSnapshotCloneIndependence {
     runTestRegionOperationsIndependent(true);
   }
 
+  /**
+   * Verify the mob cells still exist after the table to be cloned is deleted.
+   */
+  @Test (timeout=300000)
+  public void testDeleteTableToBeCloned() throws Exception {
+    FileSystem fs = UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getFileSystem();
+    Path rootDir = UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getRootDir();
+    TableName tn = TableName.valueOf("testDeleteTableToBeCloned");
+    byte[] qf = Bytes.toBytes("qf");
+    MobSnapshotTestingUtils.createMobTable(UTIL, tn, TEST_FAM);
+    String row = "row";
+    String value = "value";
+    Put put = new Put(Bytes.toBytes(row));
+    put.addColumn(TEST_FAM, qf, Bytes.toBytes(value));
+    Admin admin = UTIL.getHBaseAdmin();
+    BufferedMutator mutator = UTIL.getConnection().getBufferedMutator(tn);
+    mutator.mutate(put);
+    mutator.flush();
+    admin.flush(tn);
+    // Take a snapshot
+    final String snapshotNameAsString = "snapshot_" + tn;
+    byte[] snapshotName = Bytes.toBytes(snapshotNameAsString);
+    Table table = ConnectionFactory.createConnection(UTIL.getConfiguration()).getTable(tn);
+    Table clonedTable = null;
+    try {
+      SnapshotTestingUtils.createSnapshotAndValidate(admin, tn, TEST_FAM_STR, snapshotNameAsString,
+        rootDir, fs, true);
+      TableName cloneTableName = TableName.valueOf("test-clone-" + tn);
+      admin.cloneSnapshot(snapshotName, cloneTableName);
+      clonedTable = ConnectionFactory.createConnection(UTIL.getConfiguration()).getTable(
+        cloneTableName);
+      admin.deleteSnapshot(snapshotName);
+      admin.disableTable(tn);
+      admin.deleteTable(tn);
+      // run the cleaner
+      UTIL.getHBaseCluster().getMaster().getHFileCleaner().choreForTesting();
+      // make sure the mob cell exists
+      Scan scan = new Scan();
+      ResultScanner scanner = clonedTable.getScanner(scan);
+      Result rs = scanner.next();
+      Cell cell = rs.getColumnLatestCell(TEST_FAM, qf);
+      Assert.assertEquals(value, Bytes.toString(CellUtil.cloneValue(cell)));
+      Assert.assertNull(scanner.next());
+    } finally {
+      table.close();
+      if (clonedTable != null) {
+        clonedTable.close();
+      }
+    }
+  }
+
   private static void waitOnSplit(final HTable t, int originalCount) throws Exception {
     for (int i = 0; i < 200; i++) {
       try {