Ejemplo n.º 1
0
 private HRegionInfo nextRegion() throws IOException {
   try {
     Result results = getMetaRow();
     if (results == null) {
       return null;
     }
     byte[] regionInfoValue =
         results.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
     if (regionInfoValue == null || regionInfoValue.length == 0) {
       throw new NoSuchElementException(
           "meta region entry missing "
               + Bytes.toString(HConstants.CATALOG_FAMILY)
               + ":"
               + Bytes.toString(HConstants.REGIONINFO_QUALIFIER));
     }
     HRegionInfo region = Writables.getHRegionInfo(regionInfoValue);
     if (!Bytes.equals(region.getTableName(), this.tableName)) {
       return null;
     }
     return region;
   } catch (IOException e) {
     e = RemoteExceptionHandler.checkIOException(e);
     LOG.error("meta scanner error", e);
     metaScanner.close();
     throw e;
   }
 }
Ejemplo n.º 2
0
 /** Apply column family options such as Bloom filters, compression, and data block encoding. */
 protected void applyColumnFamilyOptions(byte[] tableName, byte[][] columnFamilies)
     throws IOException {
   HBaseAdmin admin = new HBaseAdmin(conf);
   HTableDescriptor tableDesc = admin.getTableDescriptor(tableName);
   LOG.info("Disabling table " + Bytes.toString(tableName));
   admin.disableTable(tableName);
   for (byte[] cf : columnFamilies) {
     HColumnDescriptor columnDesc = tableDesc.getFamily(cf);
     boolean isNewCf = columnDesc == null;
     if (isNewCf) {
       columnDesc = new HColumnDescriptor(cf);
     }
     if (bloomType != null) {
       columnDesc.setBloomFilterType(bloomType);
     }
     if (compressAlgo != null) {
       columnDesc.setCompressionType(compressAlgo);
     }
     if (dataBlockEncodingAlgo != null) {
       columnDesc.setDataBlockEncoding(dataBlockEncodingAlgo);
       columnDesc.setEncodeOnDisk(!encodeInCacheOnly);
     }
     if (inMemoryCF) {
       columnDesc.setInMemory(inMemoryCF);
     }
     if (isNewCf) {
       admin.addColumn(tableName, columnDesc);
     } else {
       admin.modifyColumn(tableName, columnDesc);
     }
   }
   LOG.info("Enabling table " + Bytes.toString(tableName));
   admin.enableTable(tableName);
 }
 /**
  * Get HTD from HDFS.
  *
  * @param fs
  * @param hbaseRootDir
  * @param tableName
  * @return Descriptor or null if none found.
  * @throws IOException
  */
 public static HTableDescriptor getTableDescriptor(
     FileSystem fs, Path hbaseRootDir, byte[] tableName) throws IOException {
   HTableDescriptor htd = null;
   try {
     TableDescriptorModtime tdmt =
         getTableDescriptorModtime(fs, hbaseRootDir, Bytes.toString(tableName));
     htd = tdmt == null ? null : tdmt.getTableDescriptor();
   } catch (NullPointerException e) {
     LOG.debug(
         "Exception during readTableDecriptor. Current table name = " + Bytes.toString(tableName),
         e);
   }
   return htd;
 }
 /*
  * @param number Number to use as suffix.
  * @return Returns zero-prefixed 5-byte wide decimal version of passed
  * number (Does absolute in case number is negative).
  */
 static String formatTableInfoSequenceId(final int number) {
   byte[] b = new byte[WIDTH_OF_SEQUENCE_ID];
   int d = Math.abs(number);
   for (int i = b.length - 1; i >= 0; i--) {
     b[i] = (byte) ((d % 10) + '0');
     d /= 10;
   }
   return Bytes.toString(b);
 }
Ejemplo n.º 5
0
 /**
  * A lower level API, return ID integer from raw value bytes. In case of not found
  *
  * <p>- if roundingFlag=0, throw IllegalArgumentException; <br>
  * - if roundingFlag<0, the closest smaller ID integer if exist; <br>
  * - if roundingFlag>0, the closest bigger ID integer if exist. <br>
  *
  * <p>Bypassing the cache layer, this could be significantly slower than getIdFromValue(T value).
  *
  * @throws IllegalArgumentException if value is not found in dictionary and rounding is off; or if
  *     rounding cannot find a smaller or bigger ID
  */
 public final int getIdFromValueBytes(byte[] value, int offset, int len, int roundingFlag)
     throws IllegalArgumentException {
   if (isNullByteForm(value, offset, len)) return nullId();
   else {
     int id = getIdFromValueBytesImpl(value, offset, len, roundingFlag);
     if (id == -1)
       throw new IllegalArgumentException(
           "Value '"
               + Bytes.toString(value, offset, len)
               + "' ("
               + Bytes.toStringBinary(value, offset, len)
               + ") not exists!");
     return id;
   }
 }
Ejemplo n.º 6
0
 // Parse mutate info into a map of <column name> => <update action>
 private Map<String, MutationType> parseMutateInfo(byte[] mutateInfo) {
   Map<String, MutationType> mi = new HashMap<String, MutationType>();
   if (mutateInfo != null) {
     String mutateInfoStr = Bytes.toString(mutateInfo);
     String[] mutations = mutateInfoStr.split("#");
     for (String mutation : mutations) {
       if (mutation.isEmpty()) continue;
       Preconditions.checkArgument(mutation.contains(":"), "Invalid mutation info " + mutation);
       int p = mutation.indexOf(":");
       String column = mutation.substring(0, p);
       MutationType type = MutationType.valueOf(Integer.parseInt(mutation.substring(p + 1)));
       mi.put(column, type);
     }
   }
   return mi;
 }
Ejemplo n.º 7
0
    protected Merger(Configuration conf, FileSystem fs, final byte[] tableName) throws IOException {
      this.conf = conf;
      this.fs = fs;
      this.maxFilesize =
          conf.getLong("hbase.hregion.max.filesize", HConstants.DEFAULT_MAX_FILE_SIZE);

      this.tabledir =
          new Path(
              fs.makeQualified(new Path(conf.get(HConstants.HBASE_DIR))),
              Bytes.toString(tableName));
      this.htd = FSTableDescriptors.getTableDescriptor(this.fs, this.tabledir);
      Path logdir =
          new Path(
              tabledir, "merge_" + System.currentTimeMillis() + HConstants.HREGION_LOGDIR_NAME);
      Path oldLogDir = new Path(tabledir, HConstants.HREGION_OLDLOGDIR_NAME);
      this.hlog = new HLog(fs, logdir, oldLogDir, conf);
    }
Ejemplo n.º 8
0
 private void printLocations(Result r) {
   RegionLocations rl = null;
   if (r == null) {
     LOG.info("FAILED FOR null Result");
     return;
   }
   LOG.info("FAILED FOR " + resultToString(r) + " Stale " + r.isStale());
   if (r.getRow() == null) {
     return;
   }
   try {
     rl = ((ClusterConnection) connection).locateRegion(tableName, r.getRow(), true, true);
   } catch (IOException e) {
     LOG.warn("Couldn't get locations for row " + Bytes.toString(r.getRow()));
   }
   HRegionLocation locations[] = rl.getRegionLocations();
   for (HRegionLocation h : locations) {
     LOG.info("LOCATION " + h);
   }
 }
Ejemplo n.º 9
0
  /**
   * Verifies the result from get or scan using the dataGenerator (that was presumably also used to
   * generate said result).
   *
   * @param verifyValues verify that values in the result make sense for row/cf/column combination
   * @param verifyCfAndColumnIntegrity verify that cf/column set in the result is complete. Note
   *     that to use this multiPut should be used, or verification has to happen after writes,
   *     otherwise there can be races.
   * @return
   */
  public boolean verifyResultAgainstDataGenerator(
      Result result, boolean verifyValues, boolean verifyCfAndColumnIntegrity) {
    String rowKeyStr = Bytes.toString(result.getRow());
    // See if we have any data at all.
    if (result.isEmpty()) {
      LOG.error("Error checking data for key [" + rowKeyStr + "], no data returned");
      printLocations(result);
      return false;
    }

    if (!verifyValues && !verifyCfAndColumnIntegrity) {
      return true; // as long as we have something, we are good.
    }

    // See if we have all the CFs.
    byte[][] expectedCfs = dataGenerator.getColumnFamilies();
    if (verifyCfAndColumnIntegrity && (expectedCfs.length != result.getMap().size())) {
      LOG.error(
          "Error checking data for key ["
              + rowKeyStr
              + "], bad family count: "
              + result.getMap().size());
      printLocations(result);
      return false;
    }

    // Verify each column family from get in the result.
    for (byte[] cf : result.getMap().keySet()) {
      String cfStr = Bytes.toString(cf);
      Map<byte[], byte[]> columnValues = result.getFamilyMap(cf);
      if (columnValues == null) {
        LOG.error(
            "Error checking data for key [" + rowKeyStr + "], no data for family [" + cfStr + "]]");
        printLocations(result);
        return false;
      }

      Map<String, MutationType> mutateInfo = null;
      if (verifyCfAndColumnIntegrity || verifyValues) {
        if (!columnValues.containsKey(MUTATE_INFO)) {
          LOG.error(
              "Error checking data for key ["
                  + rowKeyStr
                  + "], column family ["
                  + cfStr
                  + "], column ["
                  + Bytes.toString(MUTATE_INFO)
                  + "]; value is not found");
          printLocations(result);
          return false;
        }

        long cfHash = Arrays.hashCode(cf);
        // Verify deleted columns, and make up column counts if deleted
        byte[] mutateInfoValue = columnValues.remove(MUTATE_INFO);
        mutateInfo = parseMutateInfo(mutateInfoValue);
        for (Map.Entry<String, MutationType> mutate : mutateInfo.entrySet()) {
          if (mutate.getValue() == MutationType.DELETE) {
            byte[] column = Bytes.toBytes(mutate.getKey());
            long columnHash = Arrays.hashCode(column);
            long hashCode = cfHash + columnHash;
            if (hashCode % 2 == 0) {
              if (columnValues.containsKey(column)) {
                LOG.error(
                    "Error checking data for key ["
                        + rowKeyStr
                        + "], column family ["
                        + cfStr
                        + "], column ["
                        + mutate.getKey()
                        + "]; should be deleted");
                printLocations(result);
                return false;
              }
              byte[] hashCodeBytes = Bytes.toBytes(hashCode);
              columnValues.put(column, hashCodeBytes);
            }
          }
        }

        // Verify increment
        if (!columnValues.containsKey(INCREMENT)) {
          LOG.error(
              "Error checking data for key ["
                  + rowKeyStr
                  + "], column family ["
                  + cfStr
                  + "], column ["
                  + Bytes.toString(INCREMENT)
                  + "]; value is not found");
          printLocations(result);
          return false;
        }
        long currentValue = Bytes.toLong(columnValues.remove(INCREMENT));
        if (verifyValues) {
          long amount = mutateInfo.isEmpty() ? 0 : cfHash;
          long originalValue = Arrays.hashCode(result.getRow());
          long extra = currentValue - originalValue;
          if (extra != 0 && (amount == 0 || extra % amount != 0)) {
            LOG.error(
                "Error checking data for key ["
                    + rowKeyStr
                    + "], column family ["
                    + cfStr
                    + "], column [increment], extra ["
                    + extra
                    + "], amount ["
                    + amount
                    + "]");
            printLocations(result);
            return false;
          }
          if (amount != 0 && extra != amount) {
            LOG.warn(
                "Warning checking data for key ["
                    + rowKeyStr
                    + "], column family ["
                    + cfStr
                    + "], column [increment], incremented ["
                    + (extra / amount)
                    + "] times");
          }
        }

        // See if we have correct columns.
        if (verifyCfAndColumnIntegrity
            && !dataGenerator.verify(result.getRow(), cf, columnValues.keySet())) {
          String colsStr = "";
          for (byte[] col : columnValues.keySet()) {
            if (colsStr.length() > 0) {
              colsStr += ", ";
            }
            colsStr += "[" + Bytes.toString(col) + "]";
          }
          LOG.error(
              "Error checking data for key ["
                  + rowKeyStr
                  + "], bad columns for family ["
                  + cfStr
                  + "]: "
                  + colsStr);
          printLocations(result);
          return false;
        }
        // See if values check out.
        if (verifyValues) {
          for (Map.Entry<byte[], byte[]> kv : columnValues.entrySet()) {
            String column = Bytes.toString(kv.getKey());
            MutationType mutation = mutateInfo.get(column);
            boolean verificationNeeded = true;
            byte[] bytes = kv.getValue();
            if (mutation != null) {
              boolean mutationVerified = true;
              long columnHash = Arrays.hashCode(kv.getKey());
              long hashCode = cfHash + columnHash;
              byte[] hashCodeBytes = Bytes.toBytes(hashCode);
              if (mutation == MutationType.APPEND) {
                int offset = bytes.length - hashCodeBytes.length;
                mutationVerified =
                    offset > 0
                        && Bytes.equals(
                            hashCodeBytes,
                            0,
                            hashCodeBytes.length,
                            bytes,
                            offset,
                            hashCodeBytes.length);
                if (mutationVerified) {
                  int n = 1;
                  while (true) {
                    int newOffset = offset - hashCodeBytes.length;
                    if (newOffset < 0
                        || !Bytes.equals(
                            hashCodeBytes,
                            0,
                            hashCodeBytes.length,
                            bytes,
                            newOffset,
                            hashCodeBytes.length)) {
                      break;
                    }
                    offset = newOffset;
                    n++;
                  }
                  if (n > 1) {
                    LOG.warn(
                        "Warning checking data for key ["
                            + rowKeyStr
                            + "], column family ["
                            + cfStr
                            + "], column ["
                            + column
                            + "], appended ["
                            + n
                            + "] times");
                  }
                  byte[] dest = new byte[offset];
                  System.arraycopy(bytes, 0, dest, 0, offset);
                  bytes = dest;
                }
              } else if (hashCode % 2 == 0) { // checkAndPut
                mutationVerified = Bytes.equals(bytes, hashCodeBytes);
                verificationNeeded = false;
              }
              if (!mutationVerified) {
                LOG.error(
                    "Error checking data for key ["
                        + rowKeyStr
                        + "], mutation checking failed for column family ["
                        + cfStr
                        + "], column ["
                        + column
                        + "]; mutation ["
                        + mutation
                        + "], hashCode ["
                        + hashCode
                        + "], verificationNeeded ["
                        + verificationNeeded
                        + "]");
                printLocations(result);
                return false;
              }
            } // end of mutation checking
            if (verificationNeeded
                && !dataGenerator.verify(result.getRow(), cf, kv.getKey(), bytes)) {
              LOG.error(
                  "Error checking data for key ["
                      + rowKeyStr
                      + "], column family ["
                      + cfStr
                      + "], column ["
                      + column
                      + "], mutation ["
                      + mutation
                      + "]; value of length "
                      + bytes.length);
              printLocations(result);
              return false;
            }
          }
        }
      }
    }
    return true;
  }
 /* (non-Javadoc)
  * @see org.apache.hadoop.hbase.TableDescriptors#getHTableDescriptor(java.lang.String)
  */
 @Override
 public HTableDescriptor get(final byte[] tablename) throws IOException {
   return get(Bytes.toString(tablename));
 }