You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by br...@apache.org on 2019/06/05 10:00:26 UTC

[hbase] branch branch-1.4 updated: HBASE-21920 Ignoring 'empty' end_key while calculating end_key for new region in HBCK -fixHdfsOverlaps command can cause data loss

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

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


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

commit dc02cda679c23a9fb5c950e01d239db18b345558
Author: Syeda <sy...@huawei.com>
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 <br...@gmail.com>
---
 .../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 d0fa17d..6cb3d20 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
@@ -3133,7 +3133,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 917d7d3..4f76cb6 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
@@ -3221,6 +3221,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;