HBASE-21961 Infinite loop in AsyncNonMetaRegionLocator if there is only one region and we tried to locate before a non empty row

Signed-off-by: Guanghao Zhang <zghao@apache.org>
This commit is contained in:
Duo Zhang 2019-02-27 17:54:30 +08:00
parent 4d9ce7706b
commit 11624c63e3
2 changed files with 16 additions and 3 deletions

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.hbase.client; package org.apache.hadoop.hbase.client;
import static org.apache.hadoop.hbase.HConstants.EMPTY_END_ROW;
import static org.apache.hadoop.hbase.HConstants.NINES; import static org.apache.hadoop.hbase.HConstants.NINES;
import static org.apache.hadoop.hbase.HConstants.ZEROES; import static org.apache.hadoop.hbase.HConstants.ZEROES;
import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
@ -169,9 +170,10 @@ class AsyncNonMetaRegionLocator {
// startKey < req.row and endKey >= req.row. Here we split it to endKey == req.row || // startKey < req.row and endKey >= req.row. Here we split it to endKey == req.row ||
// (endKey > req.row && startKey < req.row). The two conditions are equal since startKey < // (endKey > req.row && startKey < req.row). The two conditions are equal since startKey <
// endKey. // endKey.
int c = Bytes.compareTo(loc.getRegion().getEndKey(), req.row); byte[] endKey = loc.getRegion().getEndKey();
completed = int c = Bytes.compareTo(endKey, req.row);
c == 0 || (c > 0 && Bytes.compareTo(loc.getRegion().getStartKey(), req.row) < 0); completed = c == 0 || ((c > 0 || Bytes.equals(EMPTY_END_ROW, endKey)) &&
Bytes.compareTo(loc.getRegion().getStartKey(), req.row) < 0);
} else { } else {
completed = loc.getRegion().containsRow(req.row); completed = loc.getRegion().containsRow(req.row);
} }

View File

@ -389,4 +389,15 @@ public class TestAsyncNonMetaRegionLocator {
} }
}); });
} }
// Testcase for HBASE-21961
@Test
public void testLocateBeforeInOnlyRegion() throws IOException, InterruptedException {
createSingleRegionTable();
HRegionLocation loc =
getDefaultRegionLocation(TABLE_NAME, Bytes.toBytes(1), RegionLocateType.BEFORE, false).join();
// should locate to the only region
assertArrayEquals(loc.getRegion().getStartKey(), EMPTY_START_ROW);
assertArrayEquals(loc.getRegion().getEndKey(), EMPTY_END_ROW);
}
} }