phoenix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ankit Singhal (JIRA)" <>
Subject [jira] [Commented] (PHOENIX-3986) UngroupedAggregateRegionObserver.commitBatch() should set the index metadata as an attribute on every mutation
Date Tue, 04 Jul 2017 11:21:00 GMT


Ankit Singhal commented on PHOENIX-3986:

[~tdsilva], I think you are right. MiniBatchOperationInProgress#getOperation returns the first
operation from the mini batch(getAbsoluteIndex()) and there is no public API to access all
the operations contained in it.
  public T getOperation(int index) {
    return operations[getAbsoluteIndex(index)];

As we will be in the same JVM, we should be ok to set it for every mutation.

bq. Also, the code flow you mentioned is very different 
yes [~giacomotaylor],  as we are running Delete and UPSERT SELECT on the server we are sending
IndexMetadata as part of the scan and using it while committing.

> UngroupedAggregateRegionObserver.commitBatch() should set the index metadata as an attribute
on every mutation
> --------------------------------------------------------------------------------------------------------------
>                 Key: PHOENIX-3986
>                 URL:
>             Project: Phoenix
>          Issue Type: Bug
>    Affects Versions: 4.9.0
>            Reporter: Thomas D'Silva
>            Assignee: Thomas D'Silva
>             Fix For: 4.12.0, 4.11.1
> We are seeing "unable to find cached index metadata" exceptions  in production while
running UPSERT SELECT queries on a table that has mutable indexes. These exceptions should
not happen because PHOENIX-2935 changed the code to set the index metadata as an attribute.

> {code}
> ERROR 2008 (INT10): ERROR 2008 (INT10): Unable to find cached index metadata.  key={}
region={}.host={} Index update failed
>  		at org.apache.phoenix.util.ServerUtil.createIOException(
>  		at org.apache.phoenix.util.ServerUtil.throwIOException(
>  		at org.apache.phoenix.index.PhoenixIndexMetaData.getIndexMetaData(
>  		at org.apache.phoenix.index.PhoenixIndexMetaData.<init>(
>  		at org.apache.phoenix.index.PhoenixIndexBuilder.getIndexMetaData(
>  		at org.apache.phoenix.hbase.index.builder.IndexBuildManager.getIndexUpdate(
>  		at org.apache.phoenix.hbase.index.Indexer.preBatchMutateWithExceptions(
>  		at org.apache.phoenix.hbase.index.Indexer.preBatchMutate(
>  		at org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost$
>  		at org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost$
>  		at org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost.execOperation(
>  		at org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost.execOperation(
>  		at org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost.preBatchMutate(
>  		at org.apache.hadoop.hbase.regionserver.HRegion.doMiniBatchMutation(
>  		at org.apache.hadoop.hbase.regionserver.HRegion.batchMutate(
>  		at org.apache.hadoop.hbase.regionserver.HRegion.batchMutate(
>  		at org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver.commitBatch(
>  		at org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver.commit(
>  		at org.apache.phoenix.coprocessor.UngroupedAggregateRegionObserver.doPostScannerOpen(
>  		at org.apache.phoenix.coprocessor.BaseScannerRegionObserver$RegionScannerHolder.overrideDelegate(
>  		at org.apache.phoenix.coprocessor.BaseScannerRegionObserver$RegionScannerHolder.nextRaw(
>  		at org.apache.hadoop.hbase.regionserver.HRegionServer.scan(
>  		at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(
>  		at
>  		at
>  		at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(
>  		at org.apache.hadoop.hbase.ipc.RpcExecutor$
>  		at
> {code} 
> This is what I think is happening : 
> In UngroupedAggregateRegionObserver.doPostScannerOpen we commit batches of mutations.

> In commitBatch() since the mutations are for the same region we only set the index maintainer
as an attribute on the first mutation of the batch. We then call HRegion.batchMutate() which
ends up calling HRegion.doMiniBatchMutation() in a loop. 
> doMiniBatchMutation()  loops throught the mutations one at a time and tries to acquire
the each mutation's lock. If it cannot acquire a lock it processes the mutations for which
it has acquired locks so far and then calls coprocessorHost.preBatchMutate which eventually
ends up calling PhoenixIndexBuilder.getIndexMetaData() which set the index metadata using
the attribute map of the first mutation in the mini batch. 
> It then processes the next set of mutations for which it has acquired locks. The index
metadata is not set as an attribute for this next mini batch, so we try and look it up in
the cache which fails 
> In PhoenixIndexBuilder
> {code}
> @Override
>     public IndexMetaData getIndexMetaData(MiniBatchOperationInProgress<Mutation>
miniBatchOp) throws IOException {
>         return new PhoenixIndexMetaData(env, miniBatchOp.getOperation(0).getAttributesMap());
>     }
> {code}
> In MiniBatchOperationInProgress
> {code}
> /**
>    * @param index
>    * @return The operation(Mutation) at the specified position.
>    */
>   public T getOperation(int index) {
>     return operations[getAbsoluteIndex(index)];
>   }
> private int getAbsoluteIndex(int index) {
>     if (index < 0 || this.firstIndex + index >= this.lastIndexExclusive) {
>       throw new ArrayIndexOutOfBoundsException(index);
>     }
>     return this.firstIndex + index;
>   }
> {code}
> [~ankit.singhal] [~jamestaylor] Does this make sense?

This message was sent by Atlassian JIRA

View raw message