Repository: hbase
Updated Branches:
  refs/heads/0.98 c88bec7cd -> 33cd2d85f
  refs/heads/branch-1 b362dc71d -> 0fb931672
  refs/heads/master dd34b91c3 -> c88a6c93a


HBASE-12065 Import tool is not restoring multiple DeleteFamily markers of a row 
(Maddineni Sukumar)


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

Branch: refs/heads/master
Commit: c88a6c93ada0b331db0478c14aa797313c9927b1
Parents: dd34b91
Author: Andrew Purtell <apurt...@apache.org>
Authored: Wed Oct 1 14:53:03 2014 -0700
Committer: Andrew Purtell <apurt...@apache.org>
Committed: Wed Oct 1 14:53:03 2014 -0700

----------------------------------------------------------------------
 .../apache/hadoop/hbase/mapreduce/Import.java   | 17 ++++-
 .../hbase/mapreduce/TestImportExport.java       | 77 ++++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/c88a6c93/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
index c2453fa..1033dac 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
@@ -173,7 +173,22 @@ public class Import extends Configured implements Tool {
 
         kv = convertKv(kv, cfRenameMap);
         // Deletes and Puts are gathered and written when finished
-        if (CellUtil.isDelete(kv)) {
+        /*
+         * If there are sequence of mutations and tombstones in an Export, and 
after Import the same
+         * sequence should be restored as it is. If we combine all Delete 
tombstones into single
+         * request then there is chance of ignoring few DeleteFamily 
tombstones, because if we
+         * submit multiple DeleteFamily tombstones in single Delete request 
then we are maintaining
+         * only newest in hbase table and ignoring other. Check - HBASE-12065
+         */
+        if (CellUtil.isDeleteFamily(kv)) {
+          Delete deleteFamily = new Delete(key.get());
+          deleteFamily.addDeleteMarker(kv);
+          if (durability != null) {
+            deleteFamily.setDurability(durability);
+          }
+          deleteFamily.setClusterIds(clusterIds);
+          context.write(key, deleteFamily);
+        } else if (CellUtil.isDelete(kv)) {
           if (delete == null) {
             delete = new Delete(key.get());
           }

http://git-wip-us.apache.org/repos/asf/hbase/blob/c88a6c93/hbase-server/src/test/java/org/apache/hadoop/hbase/mapreduce/TestImportExport.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/mapreduce/TestImportExport.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/mapreduce/TestImportExport.java
index 04b1a92..6f39ea5 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/mapreduce/TestImportExport.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/mapreduce/TestImportExport.java
@@ -339,6 +339,83 @@ public class TestImportExport {
     assertEquals(now, res[6].getTimestamp());
     t.close();
   }
+  
+  
+  @Test
+  public void testWithMultipleDeleteFamilyMarkersOfSameRowSameFamily() throws 
Exception {
+    String EXPORT_TABLE = 
"exportWithMultipleDeleteFamilyMarkersOfSameRowSameFamily";
+    HTableDescriptor desc = new 
HTableDescriptor(TableName.valueOf(EXPORT_TABLE));
+    desc.addFamily(new HColumnDescriptor(FAMILYA)
+        .setMaxVersions(5)
+        .setKeepDeletedCells(true)
+    );
+    UTIL.getHBaseAdmin().createTable(desc);
+    HTable exportT = new HTable(UTIL.getConfiguration(), EXPORT_TABLE);
+
+    //Add first version of QUAL
+    Put p = new Put(ROW1);
+    p.add(FAMILYA, QUAL, now, QUAL);
+    exportT.put(p);
+
+    //Add Delete family marker
+    Delete d = new Delete(ROW1, now+3);
+    exportT.delete(d);
+
+    //Add second version of QUAL
+    p = new Put(ROW1);
+    p.add(FAMILYA, QUAL, now+5, "s".getBytes());
+    exportT.put(p);
+
+    //Add second Delete family marker
+    d = new Delete(ROW1, now+7);
+    exportT.delete(d);
+    
+    
+    String[] args = new String[] {
+        "-D" + Export.RAW_SCAN + "=true",
+        EXPORT_TABLE,
+        FQ_OUTPUT_DIR,
+        "1000", // max number of key versions per key to export
+    };
+    assertTrue(runExport(args));
+
+    String IMPORT_TABLE = 
"importWithMultipleDeleteFamilyMarkersOfSameRowSameFamily";
+    desc = new HTableDescriptor(TableName.valueOf(IMPORT_TABLE));
+    desc.addFamily(new HColumnDescriptor(FAMILYA)
+        .setMaxVersions(5)
+        .setKeepDeletedCells(true)
+    );
+    UTIL.getHBaseAdmin().createTable(desc);
+    
+    HTable importT = new HTable(UTIL.getConfiguration(), IMPORT_TABLE);
+    args = new String[] {
+        IMPORT_TABLE,
+        FQ_OUTPUT_DIR
+    };
+    assertTrue(runImport(args));
+
+    Scan s = new Scan();
+    s.setMaxVersions();
+    s.setRaw(true);
+    
+    ResultScanner importedTScanner = importT.getScanner(s);
+    Result importedTResult = importedTScanner.next();
+    
+    ResultScanner exportedTScanner = exportT.getScanner(s);
+    Result  exportedTResult =  exportedTScanner.next();
+    try
+    {
+      Result.compareResults(exportedTResult, importedTResult);
+    }
+    catch (Exception e) {
+      fail("Original and imported tables data comparision failed with 
error:"+e.getMessage());
+    }
+    finally
+    {
+      exportT.close();
+      importT.close();
+    }
+  }
 
   /**
    * Create a simple table, run an Export Job on it, Import with filtering on, 
 verify counts,

Reply via email to