Uploaded image for project: 'HBase'
  1. HBase
  2. HBASE-27580

Reverse scan over rows with tags throw exceptions when using DataBlockEncoding

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • None
    • 2.6.0, 3.0.0-alpha-4, 2.4.17, 2.5.4
    • None
    • None

    Description

      This is easily reproducible, see test below. All you need to do is create a table with a DBE, write some puts with setTTL, then do a reverse scan. All 3 compressing DBE's fail. 

      PREFIX throws an exception:

      Caused by: java.lang.IndexOutOfBoundsException: index (0) must be less than size (0)
          at org.apache.hbase.thirdparty.com.google.common.base.Preconditions.checkElementIndex(Preconditions.java:1355)
          at org.apache.hbase.thirdparty.com.google.common.base.Preconditions.checkElementIndex(Preconditions.java:1337)
          at org.apache.hadoop.hbase.io.util.LRUDictionary$BidirectionalLRUMap.get(LRUDictionary.java:153)
          at org.apache.hadoop.hbase.io.util.LRUDictionary$BidirectionalLRUMap.access$000(LRUDictionary.java:79)
          at org.apache.hadoop.hbase.io.util.LRUDictionary.getEntry(LRUDictionary.java:43)
          at org.apache.hadoop.hbase.io.TagCompressionContext.uncompressTags(TagCompressionContext.java:152)
          at org.apache.hadoop.hbase.io.encoding.BufferedDataBlockEncoder$BufferedEncodedSeeker.decodeTags(BufferedDataBlockEncoder.java:819)
          at org.apache.hadoop.hbase.io.encoding.PrefixKeyDeltaEncoder$SeekerStateBufferedEncodedSeeker.decodeNext(PrefixKeyDeltaEncoder.java:209)
          at org.apache.hadoop.hbase.io.encoding.BufferedDataBlockEncoder$BufferedEncodedSeeker.seekToKeyInBlock(BufferedDataBlockEncoder.java:920) 

       

      DIFF throws an exception:

      Caused by: java.lang.ArrayIndexOutOfBoundsException: arraycopy: length -22 is negative
          at java.base/java.lang.System.arraycopy(Native Method)
          at org.apache.hadoop.hbase.util.ByteBufferUtils.copyFromBufferToArray(ByteBufferUtils.java:1140)
          at org.apache.hadoop.hbase.nio.SingleByteBuff.get(SingleByteBuff.java:213)
          at org.apache.hadoop.hbase.io.encoding.DiffKeyDeltaEncoder$DiffSeekerStateBufferedEncodedSeeker.decode(DiffKeyDeltaEncoder.java:431)
          at org.apache.hadoop.hbase.io.encoding.DiffKeyDeltaEncoder$DiffSeekerStateBufferedEncodedSeeker.decodeNext(DiffKeyDeltaEncoder.java:502)
          at org.apache.hadoop.hbase.io.encoding.BufferedDataBlockEncoder$BufferedEncodedSeeker.seekToKeyInBlock(BufferedDataBlockEncoder.java:920) 

       

      FAST_DIFF throws a similar exception:

      Caused by: java.lang.ArrayIndexOutOfBoundsException: arraycopy: length -22 is negative
          at java.base/java.lang.System.arraycopy(Native Method)
          at org.apache.hadoop.hbase.util.ByteBufferUtils.copyFromBufferToArray(ByteBufferUtils.java:1140)
          at org.apache.hadoop.hbase.nio.SingleByteBuff.get(SingleByteBuff.java:213)
          at org.apache.hadoop.hbase.io.encoding.FastDiffDeltaEncoder$FastDiffSeekerStateBufferedEncodedSeeker.decode(FastDiffDeltaEncoder.java:424)
          at org.apache.hadoop.hbase.io.encoding.FastDiffDeltaEncoder$FastDiffSeekerStateBufferedEncodedSeeker.decodeNext(FastDiffDeltaEncoder.java:490)
          at org.apache.hadoop.hbase.io.encoding.BufferedDataBlockEncoder$BufferedEncodedSeeker.seekToKeyInBlock(BufferedDataBlockEncoder.java:920) 

       

      Reproduce with:

      private static final Logger LOG = LoggerFactory.getLogger(TestTags.class);
      @Test
      public void testReverseScanWithDBE() throws IOException {
        byte[] family = Bytes.toBytes("0");
      
        Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
        conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
      
        try (Connection connection = ConnectionFactory.createConnection(conf)) {
      
          for (DataBlockEncoding encoding : DataBlockEncoding.values()) {
            boolean isCompressing = encoding != DataBlockEncoding.NONE && encoding != DataBlockEncoding.ROW_INDEX_V1;
            try {
              testReverseScanWithDBE(connection, encoding, family);
              if (isCompressing) {
                Assert.fail("Expected to throw exception for DBE " + encoding);
              }
            } catch (Exception e) {
              LOG.info("Got exception for DBE {}", encoding, e);
              assertTrue("Only expected compressing encodings to fail, but failed on " + encoding, isCompressing);
            }
          }
        }
      }
      
      private void testReverseScanWithDBE(Connection conn, DataBlockEncoding encoding, byte[] family)
        throws IOException {
        LOG.info("Running test with DBE={}", encoding);
        TableName tableName = TableName.valueOf(TEST_NAME.getMethodName() + "-" + encoding);
        TEST_UTIL.createTable(
          TableDescriptorBuilder.newBuilder(tableName)
            .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(family)
              .setDataBlockEncoding(encoding)
              .build())
            .build(),
          null);
      
        Table table = conn.getTable(tableName);
      
        for (int i = 0; i < 10; i++) {
          table.put(new Put(Bytes.toBytes(i)).addColumn(family, Bytes.toBytes(0), new byte[10]).setTTL(600_000));
        }
      
        TEST_UTIL.flush(table.getName());
      
        Scan scan = new Scan();
        scan.setReversed(true);
      
        try (ResultScanner scanner = table.getScanner(scan)) {
          // should fail for compressing encodings
          scanner.next();
        }
      } 

      Attachments

        Issue Links

          Activity

            People

              bbeaudreault Bryan Beaudreault
              bbeaudreault Bryan Beaudreault
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: