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 <brfrn169@gmail.com>
This commit is contained in:
Syeda 2019-04-16 19:14:47 +05:30 committed by Toshihiro Suzuki
parent c950de7834
commit 0f470e2f92
2 changed files with 49 additions and 1 deletions

View File

@ -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());
}

View File

@ -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;