This is an automated email from the ASF dual-hosted git repository.

brfrn169 pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-1.3 by this push:
     new 9dbce67  HBASE-21920 Ignoring 'empty' end_key while calculating 
end_key for new region in HBCK -fixHdfsOverlaps command can cause data loss
9dbce67 is described below

commit 9dbce675ec7902e7947bd59a0c13739eb08a9e6b
Author: Syeda <[email protected]>
AuthorDate: Tue Apr 16 19:14:47 2019 +0530

    HBASE-21920 Ignoring 'empty' end_key while calculating end_key for new 
region in HBCK -fixHdfsOverlaps command can cause data loss
    
    Signed-off-by: Toshihiro Suzuki <[email protected]>
---
 .../org/apache/hadoop/hbase/util/HBaseFsck.java    |  7 +++-
 .../apache/hadoop/hbase/util/TestHBaseFsck.java    | 43 ++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
index 620a66d..148124f 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
@@ -3002,7 +3002,12 @@ public class HBaseFsck extends Configured implements 
Closeable {
                 .compare(hi.getStartKey(), range.getFirst()) < 0) {
               range.setFirst(hi.getStartKey());
             }
-            if (RegionSplitCalculator.BYTES_COMPARATOR
+            if ((RegionSplitCalculator.BYTES_COMPARATOR
+                .compare(range.getSecond(), HConstants.EMPTY_END_ROW) == 0)
+                || 
(RegionSplitCalculator.BYTES_COMPARATOR.compare(hi.getEndKey(),
+                  HConstants.EMPTY_END_ROW) == 0)) {
+              range.setSecond(HConstants.EMPTY_END_ROW);
+            } else if (RegionSplitCalculator.BYTES_COMPARATOR
                 .compare(hi.getEndKey(), range.getSecond()) > 0) {
               range.setSecond(hi.getEndKey());
             }
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
index c316c98..cfdbbbc 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
@@ -3145,6 +3145,49 @@ public class TestHBaseFsck {
     }
   }
 
+  /**
+   * This creates and fixes a bad table where a region is completely contained 
by another region.
+   * Verify there is no data loss during scan using 'start-row' and 'end-row' 
after region overlap
+   * fix.
+   */
+  @Test(timeout = 180000)
+  public void testNoDataLossAfterRegionOverlapFix() throws Exception {
+    int startRow = 0;
+    int endRow = 5;
+    TableName table = TableName.valueOf("testNoDataLossAfterRegionOverlapFix");
+    try {
+      TEST_UTIL.createTable(table, FAM);
+      tbl = new HTable(TEST_UTIL.getConfiguration(), table);
+      // Load data.
+      TEST_UTIL.loadNumericRows(tbl, FAM, startRow, endRow);
+      admin.flush(table);
+      // Mess it up by creating an overlap.
+      HRegionInfo hriOverlap =
+          createRegion(tbl.getTableDescriptor(), HConstants.EMPTY_START_ROW, 
Bytes.toBytes("3"));
+      TEST_UTIL.assignRegion(hriOverlap);
+      // Verify overlaps exists.
+      HBaseFsck hbck = doFsck(conf, false);
+      assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.DUPE_STARTKEYS, 
ERROR_CODE.DUPE_STARTKEYS });
+      assertEquals(2, hbck.getOverlapGroups(table).size());
+      // Fix the problem.
+      doFsck(conf, true);
+      // Verify that overlaps are fixed.
+      HBaseFsck hbck2 = doFsck(conf, false);
+      assertNoErrors(hbck2);
+      assertEquals(0, hbck2.getOverlapGroups(table).size());
+      // Scan the table using start-row and end-row.
+      for (int i = startRow; i < endRow; i++) {
+        assertEquals(endRow - i,
+          countRows(Bytes.toBytes(String.valueOf(i)), 
HConstants.EMPTY_BYTE_ARRAY));
+      }
+    } finally {
+      if (tbl != null) {
+        tbl.close();
+        tbl = null;
+      }
+      cleanupTable(table);
+    }
+  }
 
   public static class MasterSyncObserver extends BaseMasterObserver {
     volatile CountDownLatch tableCreationLatch = null;

Reply via email to