diff --git a/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java b/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java index 1180249d2b..4e4c144a5d 100644 --- a/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java +++ b/hbase-examples/src/main/java/org/apache/hadoop/hbase/coprocessor/example/ZooKeeperScanPolicyObserver.java @@ -200,6 +200,9 @@ public class ZooKeeperScanPolicyObserver extends BaseRegionObserver { // take default action return null; } + // close the existing scanner, since we are creating a brand-new one. + if (s != null) s.close(); + Scan scan = new Scan(); scan.setMaxVersions(scanInfo.getMaxVersions()); return new StoreScanner(store, scanInfo, scan, Collections.singletonList(memstoreScanner), @@ -216,6 +219,9 @@ public class ZooKeeperScanPolicyObserver extends BaseRegionObserver { // take default action return null; } + // close the existing scanner, since we are creating a brand-new one. + if (s != null) s.close(); + Scan scan = new Scan(); scan.setMaxVersions(scanInfo.getMaxVersions()); return new StoreScanner(store, scanInfo, scan, scanners, scanType, @@ -231,6 +237,9 @@ public class ZooKeeperScanPolicyObserver extends BaseRegionObserver { // take default action return null; } + // close the existing scanner, since we are creating a brand-new one. + if (s != null) s.close(); + return new StoreScanner(store, scanInfo, scan, targetCols, ((HStore)store).getHRegion().getReadpoint(IsolationLevel.READ_COMMITTED)); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java index d39420bfb8..a44e7dd1aa 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java @@ -108,6 +108,8 @@ public interface RegionObserver extends Coprocessor { * @param store the store being flushed * @param memstoreScanner the scanner for the memstore that is flushed * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain + * NOTE: If s is not null and it is not used (wrapped) by the returned scanner, + * the observer HAS to properly close this scanner {@link InternalScanner#close()} * @return the scanner to use during the flush. {@code null} if the default implementation * is to be used. * @throws IOException if an error occurred on the coprocessor @@ -275,6 +277,8 @@ public interface RegionObserver extends Coprocessor { * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store * files * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain + * NOTE: If s is not null and it is not used (wrapped) by the returned scanner, + * the observer HAS to properly close this scanner {@link InternalScanner#close()} * @param request the requested compaction * @return the scanner to use during compaction. {@code null} if the default implementation is to * be used. @@ -299,6 +303,8 @@ public interface RegionObserver extends Coprocessor { * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store * files * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain + * NOTE: If s is not null and it is not used (wrapped) by the returned scanner, + * the observer HAS to properly close this scanner {@link InternalScanner#close()} * @return the scanner to use during compaction. {@code null} if the default implementation is to * be used. * @throws IOException if an error occurred on the coprocessor @@ -1010,6 +1016,8 @@ public interface RegionObserver extends Coprocessor { * @param scan the Scan specification * @param targetCols columns to be used in the scanner * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain + * NOTE: If s is not null and it is not used (wrapped) by the returned scanner, + * the observer HAS to properly close this scanner {@link KeyValueScanner#close()} * @return a KeyValueScanner instance to use or {@code null} to use the default implementation * @throws IOException if an error occurred on the coprocessor */