Search in sources :

Example 56 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class IndexingService method init.

/**
 * Called while the database starts up, before recovery.
 */
@Override
public void init() throws IOException {
    validateDefaultProviderExisting();
    try (var cursorContext = new CursorContext(pageCacheTracer.createPageCursorTracer(INIT_TAG))) {
        indexMapRef.modify(indexMap -> {
            Map<InternalIndexState, List<IndexLogRecord>> indexStates = new EnumMap<>(InternalIndexState.class);
            for (IndexDescriptor descriptor : indexDescriptors) {
                // No index (except NLI) is allowed to have the name generated for NLI.
                if (descriptor.getName().equals(IndexDescriptor.NLI_GENERATED_NAME) && !(descriptor.schema().isAnyTokenSchemaDescriptor() && descriptor.schema().entityType() == NODE)) {
                    throw new IllegalStateException("Index '" + descriptor.userDescription(tokenNameLookup) + "' is using a reserved name: '" + IndexDescriptor.NLI_GENERATED_NAME + "'. This index must be removed on an earlier version " + "to be able to use binaries for version 4.3 or newer.");
                }
                IndexProxy indexProxy;
                IndexProviderDescriptor providerDescriptor = descriptor.getIndexProvider();
                IndexProvider provider = providerMap.lookup(providerDescriptor);
                InternalIndexState initialState = provider.getInitialState(descriptor, cursorContext);
                indexStates.computeIfAbsent(initialState, internalIndexState -> new ArrayList<>()).add(new IndexLogRecord(descriptor));
                internalLog.debug(indexStateInfo("init", initialState, descriptor));
                switch(initialState) {
                    case ONLINE:
                        monitor.initialState(databaseName, descriptor, ONLINE);
                        indexProxy = indexProxyCreator.createOnlineIndexProxy(descriptor);
                        break;
                    case POPULATING:
                        // The database was shut down during population, or a crash has occurred, or some other sad thing.
                        monitor.initialState(databaseName, descriptor, POPULATING);
                        indexProxy = indexProxyCreator.createRecoveringIndexProxy(descriptor);
                        break;
                    case FAILED:
                        monitor.initialState(databaseName, descriptor, FAILED);
                        IndexPopulationFailure failure = failure(provider.getPopulationFailure(descriptor, cursorContext));
                        indexProxy = indexProxyCreator.createFailedIndexProxy(descriptor, failure);
                        break;
                    default:
                        throw new IllegalArgumentException("" + initialState);
                }
                indexMap.putIndexProxy(indexProxy);
            }
            logIndexStateSummary("init", indexStates);
            return indexMap;
        });
    }
    indexStatisticsStore.init();
}
Also used : LifecycleAdapter(org.neo4j.kernel.lifecycle.LifecycleAdapter) Arrays(java.util.Arrays) ResourceIterator(org.neo4j.graphdb.ResourceIterator) Log(org.neo4j.logging.Log) CursorContext(org.neo4j.io.pagecache.context.CursorContext) TokenNameLookup(org.neo4j.common.TokenNameLookup) IndexPopulator(org.neo4j.kernel.api.index.IndexPopulator) LongObjectProcedure(org.eclipse.collections.api.block.procedure.primitive.LongObjectProcedure) UnaryOperator(java.util.function.UnaryOperator) Config(org.neo4j.configuration.Config) Value(org.neo4j.values.storable.Value) Preconditions(org.neo4j.util.Preconditions) IndexStatisticsStore(org.neo4j.kernel.impl.api.index.stats.IndexStatisticsStore) UnderlyingStorageException(org.neo4j.exceptions.UnderlyingStorageException) IndexUpdater(org.neo4j.kernel.api.index.IndexUpdater) IndexNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException) IndexPopulationFailedKernelException(org.neo4j.kernel.api.exceptions.index.IndexPopulationFailedKernelException) LongHashSet(org.eclipse.collections.impl.set.mutable.primitive.LongHashSet) Map(java.util.Map) LongIterable(org.eclipse.collections.api.LongIterable) PageCacheTracer(org.neo4j.io.pagecache.tracing.PageCacheTracer) IndexProviderDescriptor(org.neo4j.internal.schema.IndexProviderDescriptor) Path(java.nio.file.Path) EnumMap(java.util.EnumMap) SYSTEM(org.neo4j.common.Subject.SYSTEM) Collection(java.util.Collection) Set(java.util.Set) IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) UncheckedIOException(java.io.UncheckedIOException) List(java.util.List) EntityType(org.neo4j.common.EntityType) IndexPrototype(org.neo4j.internal.schema.IndexPrototype) FAILED(org.neo4j.internal.kernel.api.InternalIndexState.FAILED) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) MutableBoolean(org.apache.commons.lang3.mutable.MutableBoolean) DatabaseReadOnlyChecker(org.neo4j.configuration.helpers.DatabaseReadOnlyChecker) NODE(org.neo4j.common.EntityType.NODE) Iterators.asResourceIterator(org.neo4j.internal.helpers.collection.Iterators.asResourceIterator) GraphDatabaseSettings(org.neo4j.configuration.GraphDatabaseSettings) InternalIndexState(org.neo4j.internal.kernel.api.InternalIndexState) IndexSamplingController(org.neo4j.kernel.impl.api.index.sampling.IndexSamplingController) LogProvider(org.neo4j.logging.LogProvider) HashMap(java.util.HashMap) MutableLongObjectMap(org.eclipse.collections.api.map.primitive.MutableLongObjectMap) Iterators.iterator(org.neo4j.internal.helpers.collection.Iterators.iterator) IndexProvider(org.neo4j.kernel.api.index.IndexProvider) ArrayList(java.util.ArrayList) IndexEntryConflictException(org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException) LongObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.LongObjectHashMap) ThrowingConsumer(org.neo4j.function.ThrowingConsumer) POPULATING(org.neo4j.internal.kernel.api.InternalIndexState.POPULATING) IndexPopulationFailure.failure(org.neo4j.kernel.impl.api.index.IndexPopulationFailure.failure) ONLINE(org.neo4j.internal.kernel.api.InternalIndexState.ONLINE) IndexStoreViewFactory(org.neo4j.kernel.impl.transaction.state.storeview.IndexStoreViewFactory) JobScheduler(org.neo4j.scheduler.JobScheduler) MemoryTracker(org.neo4j.memory.MemoryTracker) NodePropertyAccessor(org.neo4j.storageengine.api.NodePropertyAccessor) IndexUpdateListener(org.neo4j.storageengine.api.IndexUpdateListener) Subject(org.neo4j.common.Subject) Iterators(org.neo4j.internal.helpers.collection.Iterators) IndexSamplingMode(org.neo4j.kernel.impl.api.index.sampling.IndexSamplingMode) Iterables.asList(org.neo4j.internal.helpers.collection.Iterables.asList) IOException(java.io.IOException) IndexActivationFailedKernelException(org.neo4j.kernel.api.exceptions.index.IndexActivationFailedKernelException) RELATIONSHIP(org.neo4j.common.EntityType.RELATIONSHIP) MutableLongSet(org.eclipse.collections.api.set.primitive.MutableLongSet) TimeUnit(java.util.concurrent.TimeUnit) KernelException(org.neo4j.exceptions.KernelException) StringJoiner(java.util.StringJoiner) UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) SchemaState(org.neo4j.internal.schema.SchemaState) LongSet(org.eclipse.collections.api.set.primitive.LongSet) IndexProviderDescriptor(org.neo4j.internal.schema.IndexProviderDescriptor) ArrayList(java.util.ArrayList) CursorContext(org.neo4j.io.pagecache.context.CursorContext) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) IndexProvider(org.neo4j.kernel.api.index.IndexProvider) InternalIndexState(org.neo4j.internal.kernel.api.InternalIndexState) List(java.util.List) ArrayList(java.util.ArrayList) Iterables.asList(org.neo4j.internal.helpers.collection.Iterables.asList) EnumMap(java.util.EnumMap)

Example 57 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class ConstraintIndexCreator method createUniquenessConstraintIndex.

/**
 * You MUST hold a label write lock before you call this method.
 * However the label write lock is temporarily released while populating the index backing the constraint.
 * It goes a little like this:
 * <ol>
 * <li>Prerequisite: Getting here means that there's an open schema transaction which has acquired the
 * LABEL WRITE lock.</li>
 * <li>Index schema rule which is backing the constraint is created in a nested mini-transaction
 * which doesn't acquire any locking, merely adds tx state and commits so that the index rule is applied
 * to the store, which triggers the index population</li>
 * <li>Release the LABEL WRITE lock</li>
 * <li>Await index population to complete</li>
 * <li>Acquire the LABEL WRITE lock (effectively blocking concurrent transactions changing
 * data related to this constraint, and it so happens, most other transactions as well) and verify
 * the uniqueness of the built index</li>
 * <li>Leave this method, knowing that the uniqueness constraint rule will be added to tx state
 * and this tx committed, which will create the uniqueness constraint</li>
 * </ol>
 */
public IndexDescriptor createUniquenessConstraintIndex(KernelTransactionImplementation transaction, IndexBackedConstraintDescriptor constraint, IndexPrototype prototype) throws TransactionFailureException, CreateConstraintFailureException, UniquePropertyValueValidationException, AlreadyConstrainedException {
    String constraintString = constraint.userDescription(transaction.tokenRead());
    log.info("Starting constraint creation: %s.", constraintString);
    IndexDescriptor index;
    SchemaRead schemaRead = transaction.schemaRead();
    try {
        index = checkAndCreateConstraintIndex(schemaRead, transaction.tokenRead(), constraint, prototype);
    } catch (AlreadyConstrainedException e) {
        throw e;
    } catch (KernelException e) {
        throw new CreateConstraintFailureException(constraint, e);
    }
    boolean success = false;
    boolean reacquiredLabelLock = false;
    Client locks = transaction.lockClient();
    ResourceType keyType = constraint.schema().keyType();
    long[] lockingKeys = constraint.schema().lockingKeys();
    try {
        locks.acquireShared(transaction.lockTracer(), keyType, lockingKeys);
        IndexProxy proxy = indexingService.getIndexProxy(index);
        // 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
        locks.releaseExclusive(keyType, lockingKeys);
        awaitConstraintIndexPopulation(constraint, proxy, transaction);
        log.info("Constraint %s populated, starting verification.", constraintString);
        // 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
        // and if everything checks out then it will be held until after the constraint has been
        // created and activated.
        locks.acquireExclusive(transaction.lockTracer(), keyType, lockingKeys);
        reacquiredLabelLock = true;
        try (NodePropertyAccessor propertyAccessor = new DefaultNodePropertyAccessor(transaction.newStorageReader(), transaction.cursorContext(), transaction.memoryTracker())) {
            indexingService.getIndexProxy(index).verifyDeferredConstraints(propertyAccessor);
        }
        log.info("Constraint %s verified.", constraintString);
        success = true;
        return index;
    } catch (IndexNotFoundKernelException e) {
        String indexString = index.userDescription(transaction.tokenRead());
        throw new TransactionFailureException(format("Index (%s) that we just created does not exist.", indexString), e);
    } catch (IndexEntryConflictException e) {
        throw new UniquePropertyValueValidationException(constraint, VERIFICATION, e, transaction.tokenRead());
    } catch (InterruptedException | IOException e) {
        throw new CreateConstraintFailureException(constraint, e);
    } finally {
        if (!success) {
            if (!reacquiredLabelLock) {
                locks.acquireExclusive(transaction.lockTracer(), keyType, lockingKeys);
            }
            if (indexStillExists(schemaRead, index)) {
                dropUniquenessConstraintIndex(index);
            }
        }
    }
}
Also used : UniquePropertyValueValidationException(org.neo4j.kernel.api.exceptions.schema.UniquePropertyValueValidationException) SchemaRead(org.neo4j.internal.kernel.api.SchemaRead) ResourceType(org.neo4j.lock.ResourceType) IndexNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException) IOException(java.io.IOException) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) NodePropertyAccessor(org.neo4j.storageengine.api.NodePropertyAccessor) DefaultNodePropertyAccessor(org.neo4j.kernel.impl.transaction.state.storeview.DefaultNodePropertyAccessor) DefaultNodePropertyAccessor(org.neo4j.kernel.impl.transaction.state.storeview.DefaultNodePropertyAccessor) TransactionFailureException(org.neo4j.internal.kernel.api.exceptions.TransactionFailureException) AlreadyConstrainedException(org.neo4j.kernel.api.exceptions.schema.AlreadyConstrainedException) IndexProxy(org.neo4j.kernel.impl.api.index.IndexProxy) IndexNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException) IndexPopulationFailedKernelException(org.neo4j.kernel.api.exceptions.index.IndexPopulationFailedKernelException) KernelException(org.neo4j.exceptions.KernelException) Client(org.neo4j.kernel.impl.locking.Locks.Client) IndexEntryConflictException(org.neo4j.kernel.api.exceptions.index.IndexEntryConflictException) CreateConstraintFailureException(org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException)

Example 58 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class TxState method accept.

@Override
public void accept(final TxStateVisitor visitor) throws KernelException {
    if (nodes != null) {
        nodes.getAdded().each(visitor::visitCreatedNode);
    }
    if (relationships != null) {
        try (HeapTrackingArrayList<NodeRelationshipIds> sortedNodeRelState = HeapTrackingArrayList.newArrayList(nodeStatesMap.size(), memoryTracker)) {
            nodeStatesMap.forEachValue(nodeState -> {
                if (nodeState.isDeleted() && nodeState.isAddedInThisTx()) {
                    return;
                }
                if (nodeState.hasAddedRelationships() || nodeState.hasRemovedRelationships()) {
                    sortedNodeRelState.add(StateNodeRelationshipIds.createStateNodeRelationshipIds(nodeState, this::relationshipVisit, memoryTracker));
                }
            });
            sortedNodeRelState.sort(Comparator.comparingLong(NodeRelationshipIds::nodeId));
            // Visit relationships, this will grab all the locks needed to do the updates
            visitor.visitRelationshipModifications(new RelationshipModifications() {

                @Override
                public void forEachSplit(IdsVisitor visitor) {
                    sortedNodeRelState.forEach(visitor);
                }

                @Override
                public RelationshipBatch creations() {
                    return idsAsBatch(relationships.getAdded(), TxState.this::relationshipVisit);
                }

                @Override
                public RelationshipBatch deletions() {
                    return idsAsBatch(relationships.getRemoved());
                }
            });
        }
    }
    if (nodes != null) {
        nodes.getRemoved().each(visitor::visitDeletedNode);
    }
    for (NodeState node : modifiedNodes()) {
        if (node.hasPropertyChanges()) {
            visitor.visitNodePropertyChanges(node.getId(), node.addedProperties(), node.changedProperties(), node.removedProperties());
        }
        final LongDiffSets labelDiffSets = node.labelDiffSets();
        if (!labelDiffSets.isEmpty()) {
            visitor.visitNodeLabelChanges(node.getId(), labelDiffSets.getAdded(), labelDiffSets.getRemoved());
        }
    }
    for (RelationshipState rel : modifiedRelationships()) {
        visitor.visitRelPropertyChanges(rel.getId(), rel.addedProperties(), rel.changedProperties(), rel.removedProperties());
    }
    if (indexChanges != null) {
        for (IndexDescriptor indexDescriptor : indexChanges.getAdded()) {
            visitor.visitAddedIndex(indexDescriptor);
        }
        indexChanges.getRemoved().forEach(visitor::visitRemovedIndex);
    }
    if (constraintsChanges != null) {
        for (ConstraintDescriptor added : constraintsChanges.getAdded()) {
            visitor.visitAddedConstraint(added);
        }
        constraintsChanges.getRemoved().forEach(visitor::visitRemovedConstraint);
    }
    if (createdLabelTokens != null) {
        createdLabelTokens.forEachKeyValue((id, token) -> visitor.visitCreatedLabelToken(id, token.name, token.internal));
    }
    if (createdPropertyKeyTokens != null) {
        createdPropertyKeyTokens.forEachKeyValue((id, token) -> visitor.visitCreatedPropertyKeyToken(id, token.name, token.internal));
    }
    if (createdRelationshipTypeTokens != null) {
        createdRelationshipTypeTokens.forEachKeyValue((id, token) -> visitor.visitCreatedRelationshipTypeToken(id, token.name, token.internal));
    }
}
Also used : NodeRelationshipIds(org.neo4j.storageengine.api.txstate.RelationshipModifications.NodeRelationshipIds) RelationshipModifications(org.neo4j.storageengine.api.txstate.RelationshipModifications) NodeState(org.neo4j.storageengine.api.txstate.NodeState) ConstraintDescriptor(org.neo4j.internal.schema.ConstraintDescriptor) IndexBackedConstraintDescriptor(org.neo4j.internal.schema.constraints.IndexBackedConstraintDescriptor) RelationshipState(org.neo4j.storageengine.api.txstate.RelationshipState) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) TrackableDiffSets.newMutableLongDiffSets(org.neo4j.kernel.impl.util.diffsets.TrackableDiffSets.newMutableLongDiffSets) MutableLongDiffSets(org.neo4j.kernel.impl.util.diffsets.MutableLongDiffSets) LongDiffSets(org.neo4j.storageengine.api.txstate.LongDiffSets)

Example 59 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class IndexSamplingController method recoverIndexSamples.

public void recoverIndexSamples() {
    samplingLock.lock();
    try {
        IndexMap indexMap = indexMapSnapshotProvider.indexMapSnapshot();
        final LongIterator indexIds = indexMap.indexIds();
        List<IndexSamplingJobHandle> asyncSamplingJobs = Lists.mutable.of();
        while (indexIds.hasNext()) {
            long indexId = indexIds.next();
            IndexDescriptor descriptor = indexMap.getIndexProxy(indexId).getDescriptor();
            if (indexRecoveryCondition.test(descriptor) && descriptor.getIndexType() != IndexType.LOOKUP) {
                if (logRecoverIndexSamples) {
                    log.info("Index requires sampling, id=%d, name=%s.", indexId, descriptor.getName());
                }
                if (asyncRecoverIndexSamples) {
                    asyncSamplingJobs.add(sampleIndexOnTracker(indexMap, indexId));
                } else {
                    sampleIndexOnCurrentThread(indexMap, indexId);
                }
            } else {
                if (logRecoverIndexSamples) {
                    log.info("Index does not require sampling, id=%d, name=%s.", indexId, descriptor.getName());
                }
            }
        }
        if (asyncRecoverIndexSamplesWait) {
            waitForAsyncIndexSamples(asyncSamplingJobs);
        }
    } finally {
        samplingLock.unlock();
    }
}
Also used : IndexMap(org.neo4j.kernel.impl.api.index.IndexMap) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) LongIterator(org.eclipse.collections.api.iterator.LongIterator)

Example 60 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class IndexSamplingControllerFactory method createIndexRecoveryCondition.

private RecoveryCondition createIndexRecoveryCondition(final LogProvider logProvider, final TokenNameLookup tokenNameLookup) {
    return new RecoveryCondition() {

        private final Log log = logProvider.getLog(IndexSamplingController.class);

        @Override
        public boolean test(IndexDescriptor descriptor) {
            IndexSample indexSample = indexStatisticsStore.indexSample(descriptor.getId());
            long samples = indexSample.sampleSize();
            long size = indexSample.indexSize();
            boolean empty = (samples == 0) || (size == 0);
            if (empty) {
                log.debug("Recovering index sampling for index %s", descriptor.schema().userDescription(tokenNameLookup));
            }
            return empty;
        }
    };
}
Also used : IndexSample(org.neo4j.kernel.api.index.IndexSample) Log(org.neo4j.logging.Log) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor)

Aggregations

IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)404 Test (org.junit.jupiter.api.Test)231 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)81 Value (org.neo4j.values.storable.Value)43 ConstraintDescriptor (org.neo4j.internal.schema.ConstraintDescriptor)33 ArrayList (java.util.ArrayList)31 Transaction (org.neo4j.graphdb.Transaction)31 SchemaDescriptor (org.neo4j.internal.schema.SchemaDescriptor)31 IndexPrototype (org.neo4j.internal.schema.IndexPrototype)30 InternalTransaction (org.neo4j.kernel.impl.coreapi.InternalTransaction)30 TokenRead (org.neo4j.internal.kernel.api.TokenRead)29 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)26 SchemaRead (org.neo4j.internal.kernel.api.SchemaRead)26 IndexUpdater (org.neo4j.kernel.api.index.IndexUpdater)25 IndexProxy (org.neo4j.kernel.impl.api.index.IndexProxy)25 IndexReadSession (org.neo4j.internal.kernel.api.IndexReadSession)23 IndexNotFoundKernelException (org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException)23 LabelSchemaDescriptor (org.neo4j.internal.schema.LabelSchemaDescriptor)23 IndexProviderDescriptor (org.neo4j.internal.schema.IndexProviderDescriptor)22 KernelException (org.neo4j.exceptions.KernelException)20