HBASE-21347 Backport HBASE-21200 "Memstore flush doesn't finish because of seekToPreviousRow() in memstore scanner." to branch-1

Signed-off-by: Josh Elser <elserj@apache.org>
Signed-off-by: Ted Yu <tedyu@apache.org>
This commit is contained in:
Toshihiro Suzuki 2018-10-20 13:16:32 +09:00 committed by Josh Elser
parent f967bfdca7
commit 5fcfdcdc51
2 changed files with 45 additions and 3 deletions

View File

@ -719,6 +719,8 @@ public class DefaultMemStore implements MemStore {
// A flag represents whether could stop skipping Cells for MVCC
// if have encountered the next row. Only used for reversed scan
private boolean stopSkippingCellsIfNextRow = false;
// Stop skipping KeyValues for MVCC if finish this row. Only used for reversed scan
private Cell stopSkippingKVsRow;
private final long readPoint;
private final KeyValue.KVComparator comparator;
@ -765,7 +767,6 @@ public class DefaultMemStore implements MemStore {
* @return Next Cell
*/
private Cell getNext(Iterator<Cell> it) {
Cell startCell = theNext;
Cell v = null;
try {
while (it.hasNext()) {
@ -773,8 +774,8 @@ public class DefaultMemStore implements MemStore {
if (v.getSequenceId() <= this.readPoint) {
return v;
}
if (stopSkippingCellsIfNextRow && startCell != null
&& comparator.compareRows(v, startCell) > 0) {
if (stopSkippingCellsIfNextRow && stopSkippingKVsRow != null
&& comparator.compareRows(v, stopSkippingKVsRow) > 0) {
return null;
}
}
@ -994,6 +995,7 @@ public class DefaultMemStore implements MemStore {
Cell firstKeyOnPreviousRow = KeyValueUtil.createFirstOnRow(lastCellBeforeRow.getRowArray(),
lastCellBeforeRow.getRowOffset(), lastCellBeforeRow.getRowLength());
this.stopSkippingCellsIfNextRow = true;
this.stopSkippingKVsRow = firstKeyOnPreviousRow;
seek(firstKeyOnPreviousRow);
this.stopSkippingCellsIfNextRow = false;
if (peek() == null

View File

@ -6538,4 +6538,44 @@ public class TestHRegion {
assertEquals("19995", Bytes.toString(currRow.get(1).getRowArray(),
currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));
}
@Test
public void testReverseScanWhenPutCellsAfterOpenReverseScan() throws Exception {
byte[] cf1 = Bytes.toBytes("CF1");
byte[][] families = { cf1 };
byte[] col = Bytes.toBytes("C");
HBaseConfiguration conf = new HBaseConfiguration();
this.region = initHRegion(tableName, method, conf, families);
Put put = new Put(Bytes.toBytes("199996"));
put.addColumn(cf1, col, Bytes.toBytes("val"));
region.put(put);
Put put2 = new Put(Bytes.toBytes("199995"));
put2.addColumn(cf1, col, Bytes.toBytes("val"));
region.put(put2);
// Create a reverse scan
Scan scan = new Scan(Bytes.toBytes("199996"));
scan.setReversed(true);
RegionScanner scanner = region.getScanner(scan);
// Put a lot of cells that have sequenceIDs grater than the readPt of the reverse scan
for (int i = 100000; i < 200000; i++) {
Put p = new Put(Bytes.toBytes("" + i));
p.addColumn(cf1, col, Bytes.toBytes("" + i));
region.put(p);
}
List<Cell> currRow = new ArrayList<>();
boolean hasNext;
do {
hasNext = scanner.next(currRow);
} while (hasNext);
assertEquals(2, currRow.size());
assertEquals("199996", Bytes.toString(currRow.get(0).getRowArray(),
currRow.get(0).getRowOffset(), currRow.get(0).getRowLength()));
assertEquals("199995", Bytes.toString(currRow.get(1).getRowArray(),
currRow.get(1).getRowOffset(), currRow.get(1).getRowLength()));
}
}