diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index e11a31c..1beca70 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -2742,6 +2742,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi } @Override + public RegionScanner getScanner(Scan scan, boolean skipCheckFamily) throws IOException { + return getScanner(scan, null, HConstants.NO_NONCE, HConstants.NO_NONCE, skipCheckFamily); + } + + @Override public RegionScanner getScanner(Scan scan, List additionalScanners) throws IOException { return getScanner(scan, additionalScanners, HConstants.NO_NONCE, HConstants.NO_NONCE); @@ -2749,6 +2754,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi private RegionScanner getScanner(Scan scan, List additionalScanners, long nonceGroup, long nonce) throws IOException { + return getScanner(scan, additionalScanners, nonceGroup, nonce, false); + } + + private RegionScanner getScanner(Scan scan, List additionalScanners, + long nonceGroup, long nonce, boolean skipCheckFamily) throws IOException { startRegionOperation(Operation.SCAN); try { // Verify families are all valid @@ -2758,8 +2768,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi scan.addFamily(family); } } else { - for (byte[] family : scan.getFamilyMap().keySet()) { - checkFamily(family); + if (!skipCheckFamily) { + checkFamilies(scan.getFamilyMap().keySet()); } } return instantiateRegionScanner(scan, additionalScanners, nonceGroup, nonce); @@ -6992,7 +7002,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi @Override public Result get(final Get get) throws IOException { prepareGet(get); - List results = get(get, true); + List results = get(get, true, HConstants.NO_NONCE, HConstants.NO_NONCE, true); boolean stale = this.getRegionInfo().getReplicaId() != 0; return Result.create(results, get.isCheckExistenceOnly() ? !results.isEmpty() : null, stale); } @@ -7001,9 +7011,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi checkRow(get.getRow(), "Get"); // Verify families are all valid if (get.hasFamilies()) { - for (byte[] family : get.familySet()) { - checkFamily(family); - } + checkFamilies(get.familySet()); } else { // Adding all families to scanner for (byte[] family : this.htableDescriptor.getFamiliesKeys()) { get.addFamily(family); @@ -7019,6 +7027,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi @Override public List get(Get get, boolean withCoprocessor, long nonceGroup, long nonce) throws IOException { + return get(get, withCoprocessor, nonceGroup, nonce, false); + } + + private List get(Get get, boolean withCoprocessor, long nonceGroup, long nonce, + boolean skipCheckFamily) throws IOException { List results = new ArrayList(); // pre-get CP hook @@ -7026,6 +7039,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi if (coprocessorHost.preGet(get, results)) { return results; } + skipCheckFamily = false; } long before = EnvironmentEdgeManager.currentTime(); Scan scan = new Scan(get); @@ -7034,7 +7048,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi } RegionScanner scanner = null; try { - scanner = getScanner(scan, null, nonceGroup, nonce); + scanner = getScanner(scan, null, nonceGroup, nonce, skipCheckFamily); scanner.next(results); } finally { if (scanner != null) diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java index 4c5c935..7be95e6 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java @@ -2324,6 +2324,7 @@ public class RSRpcServices implements HBaseRPCErrorHandler, private Result get(Get get, HRegion region, RegionScannersCloseCallBack closeCallBack, RpcCallContext context) throws IOException { region.prepareGet(get); + boolean skipCheckFamily = true; List results = new ArrayList(); boolean stale = region.getRegionInfo().getReplicaId() != 0; // pre-get CP hook @@ -2332,6 +2333,8 @@ public class RSRpcServices implements HBaseRPCErrorHandler, return Result .create(results, get.isCheckExistenceOnly() ? !results.isEmpty() : null, stale); } + // It is possible that coprocessor changes families in get. + skipCheckFamily = false; } long before = EnvironmentEdgeManager.currentTime(); Scan scan = new Scan(get); @@ -2340,7 +2343,7 @@ public class RSRpcServices implements HBaseRPCErrorHandler, } RegionScanner scanner = null; try { - scanner = region.getScanner(scan); + scanner = region.getScanner(scan, skipCheckFamily); scanner.next(results); } finally { if (scanner != null) { @@ -2732,8 +2735,9 @@ public class RSRpcServices implements HBaseRPCErrorHandler, } isSmallScan = scan.isSmall(); - if (!scan.hasFamilies()) { - // Adding all families to scanner + boolean hasFamilyInScan = scan.hasFamilies(); + if (!hasFamilyInScan) { + // if no family is configured in scan, adding all families for (byte[] family: region.getTableDesc().getFamiliesKeys()) { scan.addFamily(family); } @@ -2741,9 +2745,13 @@ public class RSRpcServices implements HBaseRPCErrorHandler, if (region.getCoprocessorHost() != null) { scanner = region.getCoprocessorHost().preScannerOpen(scan); + // coprocessor may change the familes in scan, recheck the families + hasFamilyInScan = true; } if (scanner == null) { - scanner = region.getScanner(scan); + // If there is no family configured in scan, families are copied from + // table descriptor, checkFamily() can be skipped in getScanner(). + scanner = region.getScanner(scan, !hasFamilyInScan); } if (region.getCoprocessorHost() != null) { scanner = region.getCoprocessorHost().postScannerOpen(scan, scanner); diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/Region.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/Region.java index 295b825..4ffff38 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/Region.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/Region.java @@ -430,6 +430,19 @@ public interface Region extends ConfigurationObserver { RegionScanner getScanner(Scan scan) throws IOException; /** + * Return an iterator that scans over the HRegion, returning the indicated + * columns and rows specified by the {@link Scan}. + *

+ * This Iterator must be closed by the caller. + * + * @param scan configured {@link Scan} + * @param skipCheckFamily flag to tell if checking families in scan can be skipped + * @return RegionScanner + * @throws IOException read exceptions + */ + RegionScanner getScanner(Scan scan, boolean skipCheckFamily) throws IOException; + + /** * Return an iterator that scans over the HRegion, returning the indicated columns and rows * specified by the {@link Scan}. The scanner will also include the additional scanners passed * along with the scanners for the specified Scan instance. Should be careful with the usage to