HBASE-24021 Fail fast when bulkLoadHFiles method catch some IOException (#1343)

Signed-off-by: Guanghao Zhang <zghao@apache.org>
This commit is contained in:
niuyulin 2020-04-02 23:15:14 +08:00 committed by Guanghao Zhang
parent 253692cccd
commit 4da6402298
2 changed files with 28 additions and 15 deletions

View File

@ -179,7 +179,6 @@ import org.apache.hadoop.hbase.wal.WALKey;
import org.apache.hadoop.hbase.wal.WALKeyImpl; import org.apache.hadoop.hbase.wal.WALKeyImpl;
import org.apache.hadoop.hbase.wal.WALSplitUtil; import org.apache.hadoop.hbase.wal.WALSplitUtil;
import org.apache.hadoop.hbase.wal.WALSplitUtil.MutationReplay; import org.apache.hadoop.hbase.wal.WALSplitUtil.MutationReplay;
import org.apache.hadoop.io.MultipleIOException;
import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.StringUtils;
import org.apache.htrace.core.TraceScope; import org.apache.htrace.core.TraceScope;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
@ -6269,8 +6268,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
* @throws IOException if failed unrecoverably. * @throws IOException if failed unrecoverably.
*/ */
public Map<byte[], List<Path>> bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths, public Map<byte[], List<Path>> bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths,
boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile,
boolean copyFile, List<String> clusterIds, boolean replicate) throws IOException { List<String> clusterIds, boolean replicate) throws IOException {
long seqId = -1; long seqId = -1;
Map<byte[], List<Path>> storeFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR); Map<byte[], List<Path>> storeFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR);
Map<String, Long> storeFilesSizes = new HashMap<>(); Map<String, Long> storeFilesSizes = new HashMap<>();
@ -6282,9 +6281,9 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
this.writeRequestsCount.increment(); this.writeRequestsCount.increment();
// There possibly was a split that happened between when the split keys // There possibly was a split that happened between when the split keys
// were gathered and before the HRegion's write lock was taken. We need // were gathered and before the HRegion's write lock was taken. We need
// to validate the HFile region before attempting to bulk load all of them // to validate the HFile region before attempting to bulk load all of them
List<IOException> ioes = new ArrayList<>(); IOException ioException = null;
List<Pair<byte[], String>> failures = new ArrayList<>(); List<Pair<byte[], String>> failures = new ArrayList<>();
for (Pair<byte[], String> p : familyPaths) { for (Pair<byte[], String> p : familyPaths) {
byte[] familyName = p.getFirst(); byte[] familyName = p.getFirst();
@ -6292,9 +6291,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
HStore store = getStore(familyName); HStore store = getStore(familyName);
if (store == null) { if (store == null) {
IOException ioe = new org.apache.hadoop.hbase.DoNotRetryIOException( ioException = new org.apache.hadoop.hbase.DoNotRetryIOException(
"No such column family " + Bytes.toStringBinary(familyName)); "No such column family " + Bytes.toStringBinary(familyName));
ioes.add(ioe);
} else { } else {
try { try {
store.assertBulkLoadHFileOk(new Path(path)); store.assertBulkLoadHFileOk(new Path(path));
@ -6303,18 +6301,16 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
failures.add(p); failures.add(p);
} catch (IOException ioe) { } catch (IOException ioe) {
// unrecoverable (hdfs problem) // unrecoverable (hdfs problem)
ioes.add(ioe); ioException = ioe;
} }
} }
}
// validation failed because of some sort of IO problem. // validation failed because of some sort of IO problem.
if (ioes.size() != 0) { if (ioException != null) {
IOException e = MultipleIOException.createIOException(ioes); LOG.error("There was IO error when checking if the bulk load is ok.", ioException);
LOG.error("There were one or more IO errors when checking if the bulk load is ok.", e); throw ioException;
throw e; }
} }
// validation failed, bail out before doing anything permanent. // validation failed, bail out before doing anything permanent.
if (failures.size() != 0) { if (failures.size() != 0) {
StringBuilder list = new StringBuilder(); StringBuilder list = new StringBuilder();

View File

@ -93,6 +93,7 @@ public class TestBulkLoad {
private final byte[] randomBytes = new byte[100]; private final byte[] randomBytes = new byte[100];
private final byte[] family1 = Bytes.toBytes("family1"); private final byte[] family1 = Bytes.toBytes("family1");
private final byte[] family2 = Bytes.toBytes("family2"); private final byte[] family2 = Bytes.toBytes("family2");
private final byte[] family3 = Bytes.toBytes("family3");
@Rule @Rule
public TestName name = new TestName(); public TestName name = new TestName();
@ -202,6 +203,13 @@ public class TestBulkLoad {
null); null);
} }
// after HBASE-24021 will throw DoNotRetryIOException, not MultipleIOException
@Test(expected = DoNotRetryIOException.class)
public void shouldCrashIfBulkLoadMultiFamiliesNotInTable() throws IOException {
testRegionWithFamilies(family1).bulkLoadHFiles(withFamilyPathsFor(family1, family2, family3),
false, null);
}
@Test(expected = DoNotRetryIOException.class) @Test(expected = DoNotRetryIOException.class)
public void bulkHLogShouldThrowErrorWhenFamilySpecifiedAndHFileExistsButNotInTableDescriptor() public void bulkHLogShouldThrowErrorWhenFamilySpecifiedAndHFileExistsButNotInTableDescriptor()
throws IOException { throws IOException {
@ -221,6 +229,15 @@ public class TestBulkLoad {
testRegionWithFamilies(family1).bulkLoadHFiles(list, false, null); testRegionWithFamilies(family1).bulkLoadHFiles(list, false, null);
} }
// after HBASE-24021 will throw FileNotFoundException, not MultipleIOException
@Test(expected = FileNotFoundException.class)
public void shouldThrowErrorIfMultiHFileDoesNotExist() throws IOException {
List<Pair<byte[], String>> list = new ArrayList<>();
list.addAll(asList(withMissingHFileForFamily(family1)));
list.addAll(asList(withMissingHFileForFamily(family2)));
testRegionWithFamilies(family1, family2).bulkLoadHFiles(list, false, null);
}
private Pair<byte[], String> withMissingHFileForFamily(byte[] family) { private Pair<byte[], String> withMissingHFileForFamily(byte[] family) {
return new Pair<>(family, getNotExistFilePath()); return new Pair<>(family, getNotExistFilePath());
} }