Skip to content

Commit

Permalink
Get IndexProxy for constraint creation under lock
Browse files Browse the repository at this point in the history
Prevents an unexpected exception thrown from a very rare race for small index populations
with concurrent deletion of said index by retrieving the IndexProxy before releasing
the label lock when creating constraint.

ConcurrentCreateDropIndexIT#concurrentCreatingUniquenessConstraintOnNonUniqueData
failed some times because of it
  • Loading branch information
tinwelint committed Jan 3, 2018
1 parent 4321ae3 commit 77b7cef
Showing 1 changed file with 5 additions and 8 deletions.
Expand Up @@ -46,6 +46,7 @@
import org.neo4j.kernel.api.schema.index.IndexDescriptor.Type;
import org.neo4j.kernel.api.schema.index.IndexDescriptorFactory;
import org.neo4j.kernel.impl.api.KernelStatement;
import org.neo4j.kernel.impl.api.index.IndexProxy;
import org.neo4j.kernel.impl.api.index.IndexingService;
import org.neo4j.kernel.impl.api.operations.SchemaReadOperations;
import org.neo4j.kernel.impl.locking.Locks.Client;
Expand Down Expand Up @@ -114,14 +115,15 @@ public long createUniquenessConstraintIndex(
try
{
long indexId = schemaOps.indexGetCommittedId( state, index );
IndexProxy proxy = indexingService.getIndexProxy( indexId );

// Release the LABEL WRITE lock during index population.
// At this point the integrity of the constraint to be created was checked
// while holding the lock and the index rule backing the soon-to-be-created constraint
// has been created. Now it's just the population left, which can take a long time
releaseLabelLock( locks, descriptor.getLabelId() );

awaitConstrainIndexPopulation( constraint, indexId );
awaitConstrainIndexPopulation( constraint, proxy );

// Index population was successful, but at this point we don't know if the uniqueness constraint holds.
// Acquire LABEL WRITE lock and verify the constraints here in this user transaction
Expand Down Expand Up @@ -200,17 +202,12 @@ public void dropUniquenessConstraintIndex( IndexDescriptor descriptor )
}
}

private void awaitConstrainIndexPopulation( UniquenessConstraintDescriptor constraint, long indexId )
private void awaitConstrainIndexPopulation( UniquenessConstraintDescriptor constraint, IndexProxy proxy )
throws InterruptedException, UniquePropertyValueValidationException
{
try
{
indexingService.getIndexProxy( indexId ).awaitStoreScanCompleted();
}
catch ( IndexNotFoundKernelException e )
{
throw new IllegalStateException(
String.format( "Index (indexId=%d) that we just created does not exist.", indexId ) );
proxy.awaitStoreScanCompleted();
}
catch ( IndexPopulationFailedKernelException e )
{
Expand Down

0 comments on commit 77b7cef

Please sign in to comment.