Barry Oglesby created GEODE-333:
-----------------------------------

             Summary: Indexes sometimes are no longer used after a rebalance
                 Key: GEODE-333
                 URL: https://issues.apache.org/jira/browse/GEODE-333
             Project: Geode
          Issue Type: Bug
          Components: querying
            Reporter: Barry Oglesby
            Assignee: Barry Oglesby


My test defines the following index:
{noformat}
<index name="customer_displayName" from-clause="/customer" 
expression="displayName"/>
{noformat}
And the following query:
{noformat}
select * from /customer where displayName='some-display-name'
{noformat}
Query execution uses the index during execution before a rebalance takes place. 
In some cases (see below) the index is no longer used after a rebalance.

When the issue occurs, the {{IndexManager getBestMatchIndex}} method returns no 
indexes for the {{index_iter1.displayName}} expression even though there is one.

Here is some debugging that shows null being returned:
{noformat}
IndexManager getBestMatchIndex FUNCTIONAL index for index_iter1.displayName 
found null from [Index [ Name=customer_displayName Type =FUNCTIONAL 
IdxExp=displayName From=/customer Proj=*]imports : null]
{noformat}
This is due to this clause in the getBestMatchIndex method:
{noformat}
index = prIndex.getBucketIndex();
if (index == null) {
        continue;
}
{noformat}
The {{getBucketIndex}} method asks the first value in the {{bucketIndexes}} Map 
for its indexes. If the first value is empty, null is returned.

In this case, the first value is empty because the index at that bucket 
({{\_B__customer_47}}) was removed during the rebalance.

Here is some debugging that shows it. The first value in the {{bucketIndexes}} 
Map is for {{\_B__customer_47}}. This bucket is removed during the rebalance, 
so its List of indexes initially contains an index, then it doesn't. This 
causes {{getBucketIndex}} to return null and causes {{getBestMatchIndex}} to 
short-circuit.
{noformat}
PartitionedIndex Bucket Indexes size=113; first 
entry=BucketRegion[path='/__PR/_B__customer_47;serial=149;primary=false;indexUpdater=null]=[Index
 [ Name=customer_displayName Type =FUNCTIONAL IdxExp=displayName From=/customer 
Proj=*]]

PartitionedIndex removeFromBucketIndexes /__PR/_B__customer_47->Index [ 
Name=customer_displayName Type =FUNCTIONAL IdxExp=displayName From=/customer 
Proj=*]

PartitionedIndex Bucket Indexes size=113; first 
entry=BucketRegion[path='/__PR/_B__customer_47;serial=149;primary=false;indexUpdater=null]=[]
{noformat}
A potential fix is to remove any entries from the {{bucketIndexes}} Map that 
are empty in the {{removeFromBucketIndexes}} method like:
{noformat}
public void removeFromBucketIndexes(Region r, Index index)
{
        synchronized(this.bucketIndexes) {
                List<Index> indexes = this.bucketIndexes.get(r);
                if(indexes != null) {
                        indexes.remove(index);
                        if (indexes.isEmpty()) {
                                this.bucketIndexes.remove(r);
                        }
                }
        }
}
{noformat}
Here is some debugging that shows the first value in the {{bucketIndexes}} Map 
is initially for {{\_B\_\_customer_68}}. Then {{\_B\_\_customer_68}} is removed 
and {{\_B\_\_customer\_46}} takes over as first in the value in the 
{{bucketIndexes}} Map.
{noformat}
PartitionedIndex Bucket Indexes size=113; first 
entry=BucketRegion[path='/__PR/_B__customer_68;serial=209;primary=true;indexUpdater=null]=[Index
 [ Name=customer_displayName Type =FUNCTIONAL IdxExp=displayName From=/customer 
Proj=*]]

PartitionedIndex removeFromBucketIndexes removing entry for 
/__PR/_B__customer_68

PartitionedIndex Bucket Indexes size=95; first 
entry=BucketRegion[path='/__PR/_B__customer_46;serial=229;primary=false;indexUpdater=null]=[Index
 [ Name=customer_displayName Type =FUNCTIONAL IdxExp=displayName From=/customer 
Proj=*]]
{noformat}




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to