HBASE-17118 StoreScanner leaked in KeyValueHeap (binlijin)
This commit is contained in:
parent
b9319496bc
commit
f6fc94ede9
|
@ -26,6 +26,8 @@ import java.util.List;
|
|||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.hbase.Cell;
|
||||
import org.apache.hadoop.hbase.CellComparator;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
|
@ -46,6 +48,7 @@ import org.apache.hadoop.hbase.regionserver.ScannerContext.NextState;
|
|||
@InterfaceAudience.Private
|
||||
public class KeyValueHeap extends NonReversedNonLazyKeyValueScanner
|
||||
implements KeyValueScanner, InternalScanner {
|
||||
private static final Log LOG = LogFactory.getLog(KeyValueHeap.class);
|
||||
protected PriorityQueue<KeyValueScanner> heap = null;
|
||||
// Holds the scanners when a ever a eager close() happens. All such eagerly closed
|
||||
// scans are collected and when the final scanner.close() happens will perform the
|
||||
|
@ -292,38 +295,51 @@ public class KeyValueHeap extends NonReversedNonLazyKeyValueScanner
|
|||
}
|
||||
|
||||
KeyValueScanner scanner = current;
|
||||
while (scanner != null) {
|
||||
Cell topKey = scanner.peek();
|
||||
if (comparator.getComparator().compare(seekKey, topKey) <= 0) {
|
||||
// Top KeyValue is at-or-after Seek KeyValue. We only know that all
|
||||
// scanners are at or after seekKey (because fake keys of
|
||||
// scanners where a lazy-seek operation has been done are not greater
|
||||
// than their real next keys) but we still need to enforce our
|
||||
// invariant that the top scanner has done a real seek. This way
|
||||
// StoreScanner and RegionScanner do not have to worry about fake keys.
|
||||
heap.add(scanner);
|
||||
current = pollRealKV();
|
||||
return current != null;
|
||||
}
|
||||
try {
|
||||
while (scanner != null) {
|
||||
Cell topKey = scanner.peek();
|
||||
if (comparator.getComparator().compare(seekKey, topKey) <= 0) {
|
||||
// Top KeyValue is at-or-after Seek KeyValue. We only know that all
|
||||
// scanners are at or after seekKey (because fake keys of
|
||||
// scanners where a lazy-seek operation has been done are not greater
|
||||
// than their real next keys) but we still need to enforce our
|
||||
// invariant that the top scanner has done a real seek. This way
|
||||
// StoreScanner and RegionScanner do not have to worry about fake
|
||||
// keys.
|
||||
heap.add(scanner);
|
||||
scanner = null;
|
||||
current = pollRealKV();
|
||||
return current != null;
|
||||
}
|
||||
|
||||
boolean seekResult;
|
||||
if (isLazy && heap.size() > 0) {
|
||||
// If there is only one scanner left, we don't do lazy seek.
|
||||
seekResult = scanner.requestSeek(seekKey, forward, useBloom);
|
||||
} else {
|
||||
seekResult = NonLazyKeyValueScanner.doRealSeek(
|
||||
scanner, seekKey, forward);
|
||||
}
|
||||
boolean seekResult;
|
||||
if (isLazy && heap.size() > 0) {
|
||||
// If there is only one scanner left, we don't do lazy seek.
|
||||
seekResult = scanner.requestSeek(seekKey, forward, useBloom);
|
||||
} else {
|
||||
seekResult = NonLazyKeyValueScanner.doRealSeek(scanner, seekKey,
|
||||
forward);
|
||||
}
|
||||
|
||||
if (!seekResult) {
|
||||
this.scannersForDelayedClose.add(scanner);
|
||||
} else {
|
||||
heap.add(scanner);
|
||||
if (!seekResult) {
|
||||
this.scannersForDelayedClose.add(scanner);
|
||||
} else {
|
||||
heap.add(scanner);
|
||||
}
|
||||
scanner = heap.poll();
|
||||
if (scanner == null) {
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
scanner = heap.poll();
|
||||
if (scanner == null) {
|
||||
current = null;
|
||||
} catch (Exception e) {
|
||||
if (scanner != null) {
|
||||
try {
|
||||
scanner.close();
|
||||
} catch (Exception ce) {
|
||||
LOG.warn("close KeyValueScanner error", ce);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Heap is returning empty, scanner is done
|
||||
|
|
Loading…
Reference in New Issue