下面列出了org.apache.hadoop.hbase.client.coprocessor.Batch.Callback#org.apache.hadoop.hbase.DoNotRetryIOException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Make sure that SYSTEM.CATALOG cannot be split if QueryServices.SYSTEM_CATALOG_SPLITTABLE is false
*/
@Test
public void testSystemTableSplit() throws Exception {
testUtil = getUtility();
for (int i=0; i<10; i++) {
createTable("schema"+i+".table_"+i);
}
TableName systemCatalog = TableName.valueOf("SYSTEM.CATALOG");
RegionLocator rl = testUtil.getConnection().getRegionLocator(systemCatalog);
assertEquals(rl.getAllRegionLocations().size(), 1);
try {
// now attempt to split SYSTEM.CATALOG
testUtil.getAdmin().split(systemCatalog);
// make sure the split finishes (there's no synchronous splitting before HBase 2.x)
testUtil.getAdmin().disableTable(systemCatalog);
testUtil.getAdmin().enableTable(systemCatalog);
} catch (DoNotRetryIOException e) {
// table is not splittable
assert (e.getMessage().contains("NOT splittable"));
}
// test again... Must still be exactly one region.
rl = testUtil.getConnection().getRegionLocator(systemCatalog);
assertEquals(1, rl.getAllRegionLocations().size());
}
/**
* Make sure that the transaction is within the max valid transaction lifetime.
* @param env {@link RegionCoprocessorEnvironment} of the Region to which the coprocessor is
* associated
* @param op {@link OperationWithAttributes} HBase operation to access its attributes if required
* @param tx {@link Transaction} supplied by the
* @throws DoNotRetryIOException thrown if the transaction is older than the max lifetime of a
* transaction IOException throw if the value of max lifetime of transaction is
* unavailable
*/
protected void ensureValidTxLifetime(RegionCoprocessorEnvironment env,
@SuppressWarnings("unused") OperationWithAttributes op, @Nullable Transaction tx)
throws IOException {
if (tx == null) {
return;
}
boolean validLifetime =
(TxUtils.getTimestamp(tx.getTransactionId()) + txMaxLifetimeMillis) > System
.currentTimeMillis();
if (!validLifetime) {
throw new DoNotRetryIOException(
String.format("Transaction %s has exceeded max lifetime %s ms", tx.getTransactionId(),
txMaxLifetimeMillis));
}
}
@Test
public void testSanityCheckBlockingStoreFiles() throws IOException {
error.expect(DoNotRetryIOException.class);
error.expectMessage("Blocking file count 'hbase.hstore.blockingStoreFiles'");
error.expectMessage("is below recommended minimum of 1000 for column family");
TableName tableName = TableName.valueOf(getClass().getSimpleName() + "-BlockingStoreFiles");
TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
.setValue(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY,
FIFOCompactionPolicy.class.getName())
.setValue(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
DisabledRegionSplitPolicy.class.getName())
.setValue(HStore.BLOCKING_STOREFILES_KEY, "10")
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(family).setTimeToLive(1).build())
.build();
TEST_UTIL.getAdmin().createTable(desc);
}
private static void throwIfScanOutOfRegion(Scan scan, HRegion region) throws DoNotRetryIOException {
boolean isLocalIndex = ScanUtil.isLocalIndex(scan);
byte[] lowerInclusiveScanKey = scan.getStartRow();
byte[] upperExclusiveScanKey = scan.getStopRow();
byte[] lowerInclusiveRegionKey = region.getStartKey();
byte[] upperExclusiveRegionKey = region.getEndKey();
boolean isStaleRegionBoundaries;
if (isLocalIndex) {
byte[] expectedUpperRegionKey = scan.getAttribute(EXPECTED_UPPER_REGION_KEY);
isStaleRegionBoundaries = expectedUpperRegionKey != null &&
Bytes.compareTo(upperExclusiveRegionKey, expectedUpperRegionKey) != 0;
} else {
isStaleRegionBoundaries = Bytes.compareTo(lowerInclusiveScanKey, lowerInclusiveRegionKey) < 0 ||
( Bytes.compareTo(upperExclusiveScanKey, upperExclusiveRegionKey) > 0 && upperExclusiveRegionKey.length != 0);
}
if (isStaleRegionBoundaries) {
Exception cause = new StaleRegionBoundaryCacheException(region.getRegionInfo().getTable().getNameAsString());
throw new DoNotRetryIOException(cause.getMessage(), cause);
}
}
public static Map<String, Integer> classifyExs(List<Throwable> ths) {
Map<String, Integer> cls = new HashMap<>();
for (Throwable t : ths) {
if (t == null) continue;
String name = "";
if (t instanceof DoNotRetryIOException ||
t instanceof RegionTooBusyException) {
// If RegionTooBusyException, print message since it has Region name in it.
// RegionTooBusyException message was edited to remove variance. Has regionname, server,
// and why the exception; no longer has duration it waited on lock nor current memsize.
name = t.getMessage();
} else {
name = t.getClass().getSimpleName();
}
Integer i = cls.get(name);
if (i == null) {
i = 0;
}
i += 1;
cls.put(name, i);
}
return cls;
}
@Test
public void testDeleteWithReadOnly() throws Exception {
ThriftHBaseServiceHandler handler = createHandler();
byte[] rowName = Bytes.toBytes("testDelete");
ByteBuffer table = wrap(tableAname);
TDelete delete = new TDelete(wrap(rowName));
boolean exceptionCaught = false;
try {
handler.deleteSingle(table, delete);
} catch (TIOError e) {
exceptionCaught = true;
assertTrue(e.getCause() instanceof DoNotRetryIOException);
assertEquals("Thrift Server is in Read-only mode.", e.getMessage());
} finally {
assertTrue(exceptionCaught);
}
}
/**
* Convert a protocol buffer Filter to a client Filter
*
* @param proto the protocol buffer Filter to convert
* @return the converted Filter
*/
@SuppressWarnings("unchecked")
public static Filter toFilter(FilterProtos.Filter proto) throws IOException {
String type = proto.getName();
final byte [] value = proto.getSerializedFilter().toByteArray();
String funcName = "parseFrom";
try {
Class<?> c = Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER);
Method parseFrom = c.getMethod(funcName, byte[].class);
if (parseFrom == null) {
throw new IOException("Unable to locate function: " + funcName + " in type: " + type);
}
return (Filter)parseFrom.invoke(c, value);
} catch (Exception e) {
// Either we couldn't instantiate the method object, or "parseFrom" failed.
// In either case, let's not retry.
throw new DoNotRetryIOException(e);
}
}
@Test
public void testIncrementWithReadOnly() throws Exception {
ThriftHBaseServiceHandler handler = createHandler();
byte[] rowName = Bytes.toBytes("testIncrement");
ByteBuffer table = wrap(tableAname);
List<TColumnIncrement> incrementColumns = new ArrayList<>(1);
incrementColumns.add(new TColumnIncrement(wrap(familyAname), wrap(qualifierAname)));
TIncrement increment = new TIncrement(wrap(rowName), incrementColumns);
boolean exceptionCaught = false;
try {
handler.increment(table, increment);
} catch (TIOError e) {
exceptionCaught = true;
assertTrue(e.getCause() instanceof DoNotRetryIOException);
assertEquals("Thrift Server is in Read-only mode.", e.getMessage());
} finally {
assertTrue(exceptionCaught);
}
}
private static void applyDeleteOnPut(Delete del, Put put) throws IOException {
for (List<Cell> cells : del.getFamilyCellMap().values()) {
for (Cell cell : cells) {
switch ((KeyValue.Type.codeToType(cell.getTypeByte()))) {
case DeleteFamily:
put.getFamilyCellMap().remove(CellUtil.cloneFamily(cell));
break;
case DeleteColumn:
removeColumn(put, cell);
break;
default:
// We do not expect this can happen
throw new DoNotRetryIOException("Single version delete marker in data mutation " +
del);
}
}
}
}
@Test
public void preStoreScannerOpenPartitionMiss() throws Exception {
MemstoreAwareObserver mao = new MemstoreAwareObserver();
// env and scan do not share same start and end keys (partition miss)
ObserverContext<RegionCoprocessorEnvironment> fakeCtx = mockRegionEnv(createByteArray(13), createByteArray(24));
RegionScanner preScanner = mock(RegionScanner.class);
try {
mao.postScannerOpen(fakeCtx, mockScan(createByteArray(14), createByteArray(25)), preScanner);
fail("Expected DoNotRetryIOException");
} catch (IOException e) {
// expected
assertTrue(e instanceof DoNotRetryIOException);
}
}
private void checkQuotaSupport() throws IOException {
if (!QuotaUtil.isQuotaEnabled(masterServices.getConfiguration())) {
throw new DoNotRetryIOException(
new UnsupportedOperationException("quota support disabled"));
}
if (!initialized) {
long maxWaitTime = masterServices.getConfiguration().getLong(
"hbase.master.wait.for.quota.manager.init", 30000); // default is 30 seconds.
long startTime = EnvironmentEdgeManager.currentTime();
do {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
LOG.warn("Interrupted while waiting for Quota Manager to be initialized.");
break;
}
} while (!initialized && (EnvironmentEdgeManager.currentTime() - startTime) < maxWaitTime);
if (!initialized) {
throw new IOException("Quota manager is uninitialized, please retry later.");
}
}
}
private void checkQueuesDeleted(String peerId)
throws ReplicationException, DoNotRetryIOException {
for (ServerName replicator : queueStorage.getListOfReplicators()) {
List<String> queueIds = queueStorage.getAllQueues(replicator);
for (String queueId : queueIds) {
ReplicationQueueInfo queueInfo = new ReplicationQueueInfo(queueId);
if (queueInfo.getPeerId().equals(peerId)) {
throw new DoNotRetryIOException("undeleted queue for peerId: " + peerId +
", replicator: " + replicator + ", queueId: " + queueId);
}
}
}
if (queueStorage.getAllPeersFromHFileRefsQueue().contains(peerId)) {
throw new DoNotRetryIOException("Undeleted queue for peer " + peerId + " in hfile-refs");
}
}
@Override
public void handleFailure(RetryingCallerInterceptorContext context, Throwable t) throws IOException {
if (t instanceof UndeclaredThrowableException) {
t = t.getCause();
}
if (t instanceof RemoteException) {
RemoteException re = (RemoteException)t;
t = re.unwrapRemoteException();
}
if (t instanceof DoNotRetryIOException) {
throw (DoNotRetryIOException)t;
}
if (t instanceof IOException) {
throw (IOException) t;
}
throw new IOException(t);
}
private void processTable(String tableName) throws DoNotRetryIOException {
if (tableName.equals(FAILED_VIEWNAME)) {
// throwing anything other than instances of IOException result
// in this coprocessor being unloaded
// DoNotRetryIOException tells HBase not to retry this mutation
// multiple times
throw new DoNotRetryIOException();
} else if (tableName.startsWith(SLOW_VIEWNAME_PREFIX) || slowDownAddingChildLink) {
// simulate a slow write to SYSTEM.CATALOG or SYSTEM.CHILD_LINK
if (latch1 != null) {
latch1.countDown();
}
if (latch2 != null) {
try {
// wait till the second task is complete before completing the first task
boolean result = latch2.await(2, TimeUnit.MINUTES);
if (!result) {
throw new RuntimeException("Second task took took long to complete");
}
} catch (InterruptedException e) {
}
}
}
}
static void setExceptionResponse(Throwable t, String errorMsg,
ResponseHeader.Builder headerBuilder) {
ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder();
exceptionBuilder.setExceptionClassName(t.getClass().getName());
exceptionBuilder.setStackTrace(errorMsg);
exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException);
if (t instanceof RegionMovedException) {
// Special casing for this exception. This is only one carrying a payload.
// Do this instead of build a generic system for allowing exceptions carry
// any kind of payload.
RegionMovedException rme = (RegionMovedException)t;
exceptionBuilder.setHostname(rme.getHostname());
exceptionBuilder.setPort(rme.getPort());
}
// Set the exception as the result of the method invocation.
headerBuilder.setException(exceptionBuilder.build());
}
private void checkShouldRejectReplicationRequest(List<WALEntry> entries) throws IOException {
ReplicationSourceService replicationSource = regionServer.getReplicationSourceService();
if (replicationSource == null || entries.isEmpty()) {
return;
}
// We can ensure that all entries are for one peer, so only need to check one entry's
// table name. if the table hit sync replication at peer side and the peer cluster
// is (or is transiting to) state ACTIVE or DOWNGRADE_ACTIVE, we should reject to apply
// those entries according to the design doc.
TableName table = TableName.valueOf(entries.get(0).getKey().getTableName().toByteArray());
if (replicationSource.getSyncReplicationPeerInfoProvider().checkState(table,
RejectReplicationRequestStateChecker.get())) {
throw new DoNotRetryIOException(
"Reject to apply to sink cluster because sync replication state of sink cluster "
+ "is ACTIVE or DOWNGRADE_ACTIVE, table: " + table);
}
}
@Test(expected = DoNotRetryIOException.class)
public void testScanOnCorruptHFile() throws IOException {
TableName tableName = TableName.valueOf(name.getMethodName());
TableDescriptorBuilder.ModifyableTableDescriptor tableDescriptor =
new TableDescriptorBuilder.ModifyableTableDescriptor(tableName);
tableDescriptor.setCoprocessor(CorruptHFileCoprocessor.class.getName());
tableDescriptor.setColumnFamily(
new ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor(FAMILY_NAME));
Table table = TEST_UTIL.createTable(tableDescriptor, null);
try {
loadTable(table, 1);
scan(table);
} finally {
table.close();
}
}
@Override
protected void complete(MasterProcedureEnv env, Throwable error) {
if (error == null) {
try {
env.getMasterServices().getSplitWALManager().deleteSplitWAL(walPath);
} catch (IOException e) {
LOG.warn("Failed split of {}; ignore...", walPath, e);
}
succ = true;
} else {
if (error instanceof DoNotRetryIOException) {
LOG.warn("Sent {} to wrong server {}, try another", walPath, targetServer, error);
succ = true;
} else {
LOG.warn("Failed split of {}, retry...", walPath, error);
succ = false;
}
}
}
@Test
public void testInvalidReplicationEndpoint() throws InterruptedException {
try {
admin.addReplicationPeer(ID_ONE,
ReplicationPeerConfig.newBuilder().setReplicationEndpointImpl("whatever").build()).get();
fail();
} catch (ExecutionException e) {
assertThat(e.getCause(), instanceOf(DoNotRetryIOException.class));
assertThat(e.getCause().getMessage(), startsWith("Can not instantiate"));
}
}
/**
* Make sure that the transaction is within the max valid transaction lifetime.
*
* @param env {@link RegionCoprocessorEnvironment} of the Region to which the coprocessor is associated
* @param op {@link OperationWithAttributes} HBase operation to access its attributes if required
* @param tx {@link Transaction} supplied by the
* @throws DoNotRetryIOException thrown if the transaction is older than the max lifetime of a transaction
* IOException throw if the value of max lifetime of transaction is unavailable
*/
protected void ensureValidTxLifetime(RegionCoprocessorEnvironment env,
@SuppressWarnings("unused") OperationWithAttributes op,
@Nullable Transaction tx) throws IOException {
if (tx == null) {
return;
}
boolean validLifetime =
(TxUtils.getTimestamp(tx.getTransactionId()) + txMaxLifetimeMillis) > System.currentTimeMillis();
if (!validLifetime) {
throw new DoNotRetryIOException(String.format("Transaction %s has exceeded max lifetime %s ms",
tx.getTransactionId(), txMaxLifetimeMillis));
}
}
@Override
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
final Put put, final WALEdit edit,
final Durability durability) throws IOException {
if (put.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Put should preserve attributes");
}
if (put.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
@Override
public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
final Delete delete, final WALEdit edit,
final Durability durability) throws IOException {
if (delete.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Delete should preserve attributes");
}
if (delete.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
private void checkOnlineServersOnly(Set<Address> servers) throws IOException {
// This uglyness is because we only have Address, not ServerName.
// Online servers are keyed by ServerName.
Set<Address> onlineServers = new HashSet<>();
for(ServerName server: masterServices.getServerManager().getOnlineServers().keySet()) {
onlineServers.add(server.getAddress());
}
for (Address address: servers) {
if (!onlineServers.contains(address)) {
throw new DoNotRetryIOException("Server " + address +
" is not an online server in 'default' RSGroup.");
}
}
}
private void doPre(ObserverContext<RegionCoprocessorEnvironment> c, BatchMutateContext context,
MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException {
if (ignoreIndexRebuildForTesting && context.rebuild) {
return;
}
long start = EnvironmentEdgeManager.currentTimeMillis();
try {
if (failPreIndexUpdatesForTesting) {
throw new DoNotRetryIOException("Simulating the first (i.e., pre) index table write failure");
}
doIndexWritesWithExceptions(context, false);
metricSource.updatePreIndexUpdateTime(EnvironmentEdgeManager.currentTimeMillis() - start);
return;
} catch (Throwable e) {
metricSource.updatePreIndexUpdateFailureTime(EnvironmentEdgeManager.currentTimeMillis() - start);
metricSource.incrementPreIndexUpdateFailures();
// Remove all locks as they are already unlocked. There is no need to unlock them again later when
// postBatchMutateIndispensably() is called
removePendingRows(context);
context.rowLocks.clear();
if (context.rebuild) {
throw new IOException(String.format("%s for rebuild", e.getMessage()), e);
} else {
rethrowIndexingException(e);
}
}
throw new RuntimeException(
"Somehow didn't complete the index update, but didn't return succesfully either!");
}
@Override
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
final Put put, final WALEdit edit,
final Durability durability) throws IOException {
if (put.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Put should preserve attributes");
}
if (put.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
@Override
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, final Put put,
final WALEdit edit, final Durability durability) throws IOException {
if (put.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Put should preserve attributes");
}
if (put.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
@Override
public void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
final Delete delete, final WALEdit edit, final Durability durability) throws IOException {
if (delete.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Delete should preserve attributes");
}
if (delete.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
@Override
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
final Put put, final WALEdit edit,
final Durability durability) throws IOException {
if (put.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Put should preserve attributes");
}
if (put.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}
/**
* Make sure that the transaction is within the max valid transaction lifetime.
*
* @param env {@link RegionCoprocessorEnvironment} of the Region to which the coprocessor is associated
* @param op {@link OperationWithAttributes} HBase operation to access its attributes if required
* @param tx {@link Transaction} supplied by the
* @throws DoNotRetryIOException thrown if the transaction is older than the max lifetime of a transaction
* IOException throw if the value of max lifetime of transaction is unavailable
*/
protected void ensureValidTxLifetime(RegionCoprocessorEnvironment env,
@SuppressWarnings("unused") OperationWithAttributes op,
@Nullable Transaction tx) throws IOException {
if (tx == null) {
return;
}
boolean validLifetime =
(TxUtils.getTimestamp(tx.getTransactionId()) + txMaxLifetimeMillis) > System.currentTimeMillis();
if (!validLifetime) {
throw new DoNotRetryIOException(String.format("Transaction %s has exceeded max lifetime %s ms",
tx.getTransactionId(), txMaxLifetimeMillis));
}
}
@Override
public void prePut(final ObserverContext<RegionCoprocessorEnvironment> c,
final Put put, final WALEdit edit,
final Durability durability) throws IOException {
if (put.getAttribute(TEST_ATTRIBUTE) == null) {
throw new DoNotRetryIOException("Put should preserve attributes");
}
if (put.getDurability() != Durability.USE_DEFAULT) {
throw new DoNotRetryIOException("Durability is not propagated correctly");
}
}