static boolean canUpdate(HRegionLocation loc, HRegionLocation oldLoc) { // Do not need to update if no such location, or the location is newer, or the location is not // same with us return oldLoc != null && oldLoc.getSeqNum() <= loc.getSeqNum() && oldLoc.getServerName().equals(loc.getServerName()); }
protected void deleteRegion(Configuration conf, final Table tbl, byte[] startKey, byte[] endKey) throws IOException { LOG.info("Before delete:"); HTableDescriptor htd = tbl.getTableDescriptor(); dumpMeta(htd); List<HRegionLocation> regions; try (RegionLocator rl = connection.getRegionLocator(tbl.getName())) { regions = rl.getAllRegionLocations(); } for (HRegionLocation e : regions) { HRegionInfo hri = e.getRegionInfo(); ServerName hsa = e.getServerName(); if (Bytes.compareTo(hri.getStartKey(), startKey) == 0 && Bytes.compareTo(hri.getEndKey(), endKey) == 0) { LOG.info("RegionName: " + hri.getRegionNameAsString()); byte[] deleteRow = hri.getRegionName(); TEST_UTIL.getHBaseAdmin().unassign(deleteRow, true); LOG.info("deleting hdfs data: " + hri.toString() + hsa.toString()); Path rootDir = FSUtils.getRootDir(conf); FileSystem fs = rootDir.getFileSystem(conf); Path p = new Path(FSUtils.getTableDir(rootDir, htd.getTableName()), hri.getEncodedName()); fs.delete(p, true); try (Table meta = this.connection.getTable(TableName.META_TABLE_NAME)) { Delete delete = new Delete(deleteRow); meta.delete(delete); } } LOG.info(hri.toString() + hsa.toString()); } TEST_UTIL.getMetaTableRows(htd.getTableName()); LOG.info("After delete:"); dumpMeta(htd); }
@Override public int compareTo(HRegionLocation o) { return serverName.compareTo(o.getServerName()); }
@Override public void run() { int failedCount = 0; try { long start = EnvironmentEdgeManager.currentTime(); // drain all the queued puts into the tmp list processingList.clear(); queue.drainTo(processingList); if (processingList.size() == 0) { // Nothing to flush return; } currentProcessingCount.set(processingList.size()); // failedCount is decreased whenever a Put is success or resubmit. failedCount = processingList.size(); List<Action<Row>> retainedActions = new ArrayList<>(processingList.size()); MultiAction<Row> actions = new MultiAction<>(); for (int i = 0; i < processingList.size(); i++) { PutStatus putStatus = processingList.get(i); Action<Row> action = new Action<Row>(putStatus.put, i); actions.add(putStatus.regionInfo.getRegionName(), action); retainedActions.add(action); } // Process this multi-put request List<PutStatus> failed = null; Object[] results = new Object[actions.size()]; ServerName server = addr.getServerName(); Map<ServerName, MultiAction<Row>> actionsByServer = Collections.singletonMap(server, actions); try { AsyncRequestFuture arf = ap.submitMultiActions( null, retainedActions, 0L, null, results, true, null, null, actionsByServer, null); arf.waitUntilDone(); if (arf.hasError()) { // We just log and ignore the exception here since failed Puts will be resubmit again. LOG.debug( "Caught some exceptions when flushing puts to region server " + addr.getHostnamePort(), arf.getErrors()); } } finally { for (int i = 0; i < results.length; i++) { if (results[i] instanceof Result) { failedCount--; } else { if (failed == null) { failed = new ArrayList<PutStatus>(); } failed.add(processingList.get(i)); } } } if (failed != null) { // Resubmit failed puts for (PutStatus putStatus : failed) { if (resubmitFailedPut(putStatus, this.addr)) { failedCount--; } } } long elapsed = EnvironmentEdgeManager.currentTime() - start; // Update latency counters averageLatency.add(elapsed); if (elapsed > maxLatency.get()) { maxLatency.set(elapsed); } // Log some basic info if (LOG.isDebugEnabled()) { LOG.debug( "Processed " + currentProcessingCount + " put requests for " + addr.getHostnamePort() + " and " + failedCount + " failed" + ", latency for this send: " + elapsed); } // Reset the current processing put count currentProcessingCount.set(0); } catch (RuntimeException e) { // To make findbugs happy // Log all the exceptions and move on LOG.debug( "Caught some exceptions " + e + " when flushing puts to region server " + addr.getHostnamePort(), e); } catch (Exception e) { if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } // Log all the exceptions and move on LOG.debug( "Caught some exceptions " + e + " when flushing puts to region server " + addr.getHostnamePort(), e); } finally { // Update the totalFailedCount this.totalFailedPutCount.addAndGet(failedCount); } }
/** * Looking forward to TransactionalRegion-side implementation * * @param transactionState * @param deletes * @throws IOException */ public void delete(final TransactionState transactionState, List<Delete> deletes) throws IOException { long transactionId = transactionState.getTransactionId(); if (LOG.isTraceEnabled()) LOG.trace( "Enter TransactionalTable.delete[] <List> size: " + deletes.size() + ", transid: " + transactionId); // collect all rows from same region final Map<TransactionRegionLocation, List<Delete>> rows = new HashMap<TransactionRegionLocation, List<Delete>>(); HRegionLocation hlocation = null; TransactionRegionLocation location = null; List<Delete> list = null; int size = 0; for (Delete del : deletes) { hlocation = this.getRegionLocation(del.getRow(), false); location = new TransactionRegionLocation(hlocation.getRegionInfo(), hlocation.getServerName()); if (LOG.isTraceEnabled()) LOG.trace( "delete <List> with trRegion [" + location.getRegionInfo().getEncodedName() + "], endKey: " + Hex.encodeHexString(location.getRegionInfo().getEndKey()) + " and transaction [" + transactionId + "], delete number: " + size); if (!rows.containsKey(location)) { if (LOG.isTraceEnabled()) LOG.trace( "delete adding new <List> for region [" + location.getRegionInfo().getRegionNameAsString() + "], endKey: " + Hex.encodeHexString(location.getRegionInfo().getEndKey()) + " and transaction [" + transactionId + "], delete number: " + size); list = new ArrayList<Delete>(); rows.put(location, list); } else { list = rows.get(location); } list.add(del); size++; } final List<Delete> rowsInSameRegion = new ArrayList<Delete>(); for (Map.Entry<TransactionRegionLocation, List<Delete>> entry : rows.entrySet()) { rowsInSameRegion.clear(); rowsInSameRegion.addAll(entry.getValue()); final String regionName = entry.getKey().getRegionInfo().getRegionNameAsString(); Batch.Call<TrxRegionService, DeleteMultipleTransactionalResponse> callable = new Batch.Call<TrxRegionService, DeleteMultipleTransactionalResponse>() { ServerRpcController controller = new ServerRpcController(); BlockingRpcCallback<DeleteMultipleTransactionalResponse> rpcCallback = new BlockingRpcCallback<DeleteMultipleTransactionalResponse>(); @Override public DeleteMultipleTransactionalResponse call(TrxRegionService instance) throws IOException { org.apache.hadoop.hbase.coprocessor.transactional.generated.TrxRegionProtos .DeleteMultipleTransactionalRequest.Builder builder = DeleteMultipleTransactionalRequest.newBuilder(); builder.setTransactionId(transactionState.getTransactionId()); builder.setRegionName(ByteString.copyFromUtf8(regionName)); for (Delete delete : rowsInSameRegion) { MutationProto m1 = ProtobufUtil.toMutation(MutationType.DELETE, delete); builder.addDelete(m1); } instance.deleteMultiple(controller, builder.build(), rpcCallback); return rpcCallback.get(); } }; DeleteMultipleTransactionalResponse result = null; try { int retryCount = 0; boolean retry = false; do { Iterator<Map.Entry<byte[], DeleteMultipleTransactionalResponse>> it = super.coprocessorService( TrxRegionService.class, entry.getValue().get(0).getRow(), entry.getValue().get(0).getRow(), callable) .entrySet() .iterator(); if (it.hasNext()) { result = it.next().getValue(); retry = false; } if (result == null || result.getException().contains("closing region")) { Thread.sleep(TransactionalTable.delay); retry = true; transactionState.setRetried(true); retryCount++; } } while (retryCount < TransactionalTable.retries && retry == true); } catch (Throwable e) { if (LOG.isErrorEnabled()) LOG.error("ERROR while calling deleteMultipleTransactional ", e); throw new IOException("ERROR while calling deleteMultipleTransactional", e); } if (result == null) throw new IOException(retryErrMsg); else if (result.hasException()) throw new IOException(result.getException()); } }