HBASE-18786 FileNotFoundException should not be silently handled for primary region replicas
This commit is contained in:
parent
bb9f01c1e4
commit
b27f9b582a
|
@ -204,9 +204,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
public static final String LOAD_CFS_ON_DEMAND_CONFIG_KEY =
|
||||
"hbase.hregion.scan.loadColumnFamiliesOnDemand";
|
||||
|
||||
public static final String HREGION_UNASSIGN_FOR_FNFE = "hbase.hregion.unassign.for.fnfe";
|
||||
public static final boolean DEFAULT_HREGION_UNASSIGN_FOR_FNFE = true;
|
||||
|
||||
public static final String HBASE_MAX_CELL_SIZE_KEY = "hbase.server.keyvalue.maxsize";
|
||||
public static final int DEFAULT_MAX_CELL_SIZE = 10485760;
|
||||
|
||||
|
@ -654,8 +651,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
private final NavigableMap<byte[], Integer> replicationScope = new TreeMap<>(
|
||||
Bytes.BYTES_COMPARATOR);
|
||||
|
||||
// whether to unassign region if we hit FNFE
|
||||
private final RegionUnassigner regionUnassigner;
|
||||
/**
|
||||
* HRegion constructor. This constructor should only be used for testing and
|
||||
* extensions. Instances of HRegion should be instantiated with the
|
||||
|
@ -815,14 +810,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE);
|
||||
|
||||
this.maxCellSize = conf.getLong(HBASE_MAX_CELL_SIZE_KEY, DEFAULT_MAX_CELL_SIZE);
|
||||
|
||||
boolean unassignForFNFE =
|
||||
conf.getBoolean(HREGION_UNASSIGN_FOR_FNFE, DEFAULT_HREGION_UNASSIGN_FOR_FNFE);
|
||||
if (unassignForFNFE) {
|
||||
this.regionUnassigner = new RegionUnassigner(rsServices, fs.getRegionInfo());
|
||||
} else {
|
||||
this.regionUnassigner = null;
|
||||
}
|
||||
}
|
||||
|
||||
void setHTableSpecificConf() {
|
||||
|
@ -5873,12 +5860,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
try {
|
||||
for (Map.Entry<byte[], NavigableSet<byte[]>> entry : scan.getFamilyMap().entrySet()) {
|
||||
HStore store = stores.get(entry.getKey());
|
||||
KeyValueScanner scanner;
|
||||
try {
|
||||
scanner = store.getScanner(scan, entry.getValue(), this.readPt);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw handleFileNotFound(e);
|
||||
}
|
||||
KeyValueScanner scanner = store.getScanner(scan, entry.getValue(), this.readPt);
|
||||
instantiatedScanners.add(scanner);
|
||||
if (this.filter == null || !scan.doLoadColumnFamiliesOnDemand()
|
||||
|| this.filter.isFamilyEssential(entry.getKey())) {
|
||||
|
@ -5902,21 +5884,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
}
|
||||
}
|
||||
|
||||
private FileNotFoundException handleFileNotFound(FileNotFoundException fnfe) {
|
||||
// Try reopening the region since we have lost some storefiles.
|
||||
// See HBASE-17712 for more details.
|
||||
LOG.warn("Store file is lost; close and reopen region", fnfe);
|
||||
if (regionUnassigner != null) {
|
||||
regionUnassigner.unassign();
|
||||
}
|
||||
return fnfe;
|
||||
}
|
||||
|
||||
private IOException handleException(List<KeyValueScanner> instantiatedScanners,
|
||||
Throwable t) {
|
||||
if (t instanceof FileNotFoundException) {
|
||||
handleFileNotFound((FileNotFoundException)t);
|
||||
}
|
||||
// remove scaner read point before throw the exception
|
||||
scannerReadPoints.remove(this);
|
||||
if (storeHeap != null) {
|
||||
|
@ -5999,19 +5968,14 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
throw new UnknownScannerException("Scanner was closed");
|
||||
}
|
||||
boolean moreValues = false;
|
||||
try {
|
||||
if (outResults.isEmpty()) {
|
||||
// Usually outResults is empty. This is true when next is called
|
||||
// to handle scan or get operation.
|
||||
moreValues = nextInternal(outResults, scannerContext);
|
||||
} else {
|
||||
List<Cell> tmpList = new ArrayList<Cell>();
|
||||
moreValues = nextInternal(tmpList, scannerContext);
|
||||
outResults.addAll(tmpList);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
handleFileNotFound(e);
|
||||
throw e;
|
||||
if (outResults.isEmpty()) {
|
||||
// Usually outResults is empty. This is true when next is called
|
||||
// to handle scan or get operation.
|
||||
moreValues = nextInternal(outResults, scannerContext);
|
||||
} else {
|
||||
List<Cell> tmpList = new ArrayList<Cell>();
|
||||
moreValues = nextInternal(tmpList, scannerContext);
|
||||
outResults.addAll(tmpList);
|
||||
}
|
||||
|
||||
// If the size limit was reached it means a partial Result is being returned. Returning a
|
||||
|
@ -6061,33 +6025,29 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
boolean tmpKeepProgress = scannerContext.getKeepProgress();
|
||||
// Scanning between column families and thus the scope is between cells
|
||||
LimitScope limitScope = LimitScope.BETWEEN_CELLS;
|
||||
try {
|
||||
do {
|
||||
// We want to maintain any progress that is made towards the limits while scanning across
|
||||
// different column families. To do this, we toggle the keep progress flag on during calls
|
||||
// to the StoreScanner to ensure that any progress made thus far is not wiped away.
|
||||
scannerContext.setKeepProgress(true);
|
||||
heap.next(results, scannerContext);
|
||||
scannerContext.setKeepProgress(tmpKeepProgress);
|
||||
do {
|
||||
// We want to maintain any progress that is made towards the limits while scanning across
|
||||
// different column families. To do this, we toggle the keep progress flag on during calls
|
||||
// to the StoreScanner to ensure that any progress made thus far is not wiped away.
|
||||
scannerContext.setKeepProgress(true);
|
||||
heap.next(results, scannerContext);
|
||||
scannerContext.setKeepProgress(tmpKeepProgress);
|
||||
|
||||
nextKv = heap.peek();
|
||||
moreCellsInRow = moreCellsInRow(nextKv, currentRowCell);
|
||||
if (!moreCellsInRow) incrementCountOfRowsScannedMetric(scannerContext);
|
||||
if (moreCellsInRow && scannerContext.checkBatchLimit(limitScope)) {
|
||||
return scannerContext.setScannerState(NextState.BATCH_LIMIT_REACHED).hasMoreValues();
|
||||
} else if (scannerContext.checkSizeLimit(limitScope)) {
|
||||
ScannerContext.NextState state =
|
||||
moreCellsInRow ? NextState.SIZE_LIMIT_REACHED_MID_ROW : NextState.SIZE_LIMIT_REACHED;
|
||||
return scannerContext.setScannerState(state).hasMoreValues();
|
||||
} else if (scannerContext.checkTimeLimit(limitScope)) {
|
||||
ScannerContext.NextState state =
|
||||
moreCellsInRow ? NextState.TIME_LIMIT_REACHED_MID_ROW : NextState.TIME_LIMIT_REACHED;
|
||||
return scannerContext.setScannerState(state).hasMoreValues();
|
||||
}
|
||||
} while (moreCellsInRow);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw handleFileNotFound(e);
|
||||
}
|
||||
nextKv = heap.peek();
|
||||
moreCellsInRow = moreCellsInRow(nextKv, currentRowCell);
|
||||
if (!moreCellsInRow) incrementCountOfRowsScannedMetric(scannerContext);
|
||||
if (moreCellsInRow && scannerContext.checkBatchLimit(limitScope)) {
|
||||
return scannerContext.setScannerState(NextState.BATCH_LIMIT_REACHED).hasMoreValues();
|
||||
} else if (scannerContext.checkSizeLimit(limitScope)) {
|
||||
ScannerContext.NextState state =
|
||||
moreCellsInRow ? NextState.SIZE_LIMIT_REACHED_MID_ROW : NextState.SIZE_LIMIT_REACHED;
|
||||
return scannerContext.setScannerState(state).hasMoreValues();
|
||||
} else if (scannerContext.checkTimeLimit(limitScope)) {
|
||||
ScannerContext.NextState state =
|
||||
moreCellsInRow ? NextState.TIME_LIMIT_REACHED_MID_ROW : NextState.TIME_LIMIT_REACHED;
|
||||
return scannerContext.setScannerState(state).hasMoreValues();
|
||||
}
|
||||
} while (moreCellsInRow);
|
||||
return nextKv != null;
|
||||
}
|
||||
|
||||
|
@ -6435,8 +6395,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
|
|||
if (this.joinedHeap != null) {
|
||||
result = this.joinedHeap.requestSeek(kv, true, true) || result;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
throw handleFileNotFound(e);
|
||||
} finally {
|
||||
closeRegionOperation();
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.regionserver;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
import org.apache.yetus.audience.InterfaceAudience;
|
||||
|
||||
/**
|
||||
* Used to unssign a region when we hit FNFE.
|
||||
*/
|
||||
@InterfaceAudience.Private
|
||||
class RegionUnassigner {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(RegionUnassigner.class);
|
||||
|
||||
private final RegionServerServices rsServices;
|
||||
|
||||
private final HRegionInfo regionInfo;
|
||||
|
||||
private boolean unassigning = false;
|
||||
|
||||
RegionUnassigner(RegionServerServices rsServices, HRegionInfo regionInfo) {
|
||||
this.rsServices = rsServices;
|
||||
this.regionInfo = regionInfo;
|
||||
}
|
||||
|
||||
synchronized void unassign() {
|
||||
if (unassigning) {
|
||||
return;
|
||||
}
|
||||
unassigning = true;
|
||||
new Thread("RegionUnassigner." + regionInfo.getEncodedName()) {
|
||||
@Override
|
||||
public void run() {
|
||||
LOG.info("Unassign " + regionInfo.getRegionNameAsString());
|
||||
try {
|
||||
rsServices.unassign(regionInfo.getRegionName());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Unassigned " + regionInfo.getRegionNameAsString() + " failed", e);
|
||||
} finally {
|
||||
synchronized (RegionUnassigner.this) {
|
||||
unassigning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue