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);
  }
Exemple #3
0
 @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());
    }
  }