Search in sources :

Example 56 with RelationshipRecord

use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.

the class LogCommandSerializationV3_0_10 method readRelationshipRecord.

private static RelationshipRecord readRelationshipRecord(long id, ReadableChannel channel) throws IOException {
    byte flags = channel.get();
    boolean inUse = bitFlag(flags, Record.IN_USE.byteValue());
    boolean requiresSecondaryUnit = bitFlag(flags, Record.REQUIRE_SECONDARY_UNIT);
    boolean hasSecondaryUnit = bitFlag(flags, Record.HAS_SECONDARY_UNIT);
    boolean usesFixedReferenceFormat = bitFlag(flags, Record.USES_FIXED_REFERENCE_FORMAT);
    RelationshipRecord record;
    if (inUse) {
        record = new RelationshipRecord(id);
        record.setLinks(channel.getLong(), channel.getLong(), channel.getInt());
        record.setInUse(true);
        record.setRequiresSecondaryUnit(requiresSecondaryUnit);
        record.setFirstPrevRel(channel.getLong());
        record.setFirstNextRel(channel.getLong());
        record.setSecondPrevRel(channel.getLong());
        record.setSecondNextRel(channel.getLong());
        record.setNextProp(channel.getLong());
        byte extraByte = channel.get();
        record.setFirstInFirstChain((extraByte & 0x1) > 0);
        record.setFirstInSecondChain((extraByte & 0x2) > 0);
        if (hasSecondaryUnit) {
            record.setSecondaryUnitIdOnLoad(channel.getLong());
        }
        record.setUseFixedReferences(usesFixedReferenceFormat);
    } else {
        record = new RelationshipRecord(id);
        record.setLinks(-1, -1, channel.getInt());
        record.setInUse(false);
    }
    if (bitFlag(flags, Record.CREATED_IN_TX)) {
        record.setCreated();
    }
    return record;
}
Also used : RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord)

Example 57 with RelationshipRecord

use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.

the class LogCommandSerializationV3_0_10 method readRelationshipCommand.

@Override
protected Command readRelationshipCommand(ReadableChannel channel) throws IOException {
    long id = channel.getLong();
    RelationshipRecord before = readRelationshipRecord(id, channel);
    if (before == null) {
        return null;
    }
    RelationshipRecord after = readRelationshipRecord(id, channel);
    if (after == null) {
        return null;
    }
    if (!before.inUse() && after.inUse()) {
        after.setCreated();
    }
    return new Command.RelationshipCommand(this, before, after);
}
Also used : RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) AddRelationshipCommand(org.neo4j.internal.recordstorage.legacy.IndexCommand.AddRelationshipCommand)

Example 58 with RelationshipRecord

use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.

the class FulltextIndexConsistencyCheckIT method mustDiscoverRelationshipInIndexMissingFromStore.

@Disabled("Turns out that this is not something that the consistency checker actually looks for, currently. " + "The test is disabled until the consistency checker is extended with checks that will discover this sort of inconsistency.")
@Test
void mustDiscoverRelationshipInIndexMissingFromStore() throws Exception {
    GraphDatabaseService db = createDatabase();
    try (Transaction tx = db.beginTx()) {
        tx.execute(format(RELATIONSHIP_CREATE, "rels", asStrList("REL"), asStrList("prop"))).close();
        tx.commit();
    }
    long relId;
    try (Transaction tx = db.beginTx()) {
        tx.schema().awaitIndexesOnline(2, TimeUnit.MINUTES);
        Node node = tx.createNode();
        Relationship rel = node.createRelationshipTo(node, RelationshipType.withName("REL"));
        relId = rel.getId();
        rel.setProperty("prop", "value");
        tx.commit();
    }
    NeoStores stores = getNeoStores(db);
    RelationshipRecord record = stores.getRelationshipStore().newRecord();
    record = stores.getRelationshipStore().getRecord(relId, record, RecordLoad.NORMAL, NULL);
    long propId = record.getNextProp();
    record.setNextProp(AbstractBaseRecord.NO_ID);
    stores.getRelationshipStore().updateRecord(record, NULL);
    PropertyRecord propRecord = stores.getPropertyStore().getRecord(propId, stores.getPropertyStore().newRecord(), RecordLoad.NORMAL, NULL);
    propRecord.setInUse(false);
    stores.getPropertyStore().updateRecord(propRecord, NULL);
    managementService.shutdown();
    ConsistencyCheckService.Result result = checkConsistency();
    assertFalse(result.isSuccessful());
}
Also used : GraphDatabaseService(org.neo4j.graphdb.GraphDatabaseService) PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) Transaction(org.neo4j.graphdb.Transaction) Node(org.neo4j.graphdb.Node) Relationship(org.neo4j.graphdb.Relationship) NeoStores(org.neo4j.kernel.impl.store.NeoStores) RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) ConsistencyCheckService(org.neo4j.consistency.ConsistencyCheckService) Test(org.junit.jupiter.api.Test) Disabled(org.junit.jupiter.api.Disabled)

Example 59 with RelationshipRecord

use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.

the class RelationshipChecker method check.

private void check(LongRange nodeIdRange, boolean firstRound, long fromRelationshipId, long toRelationshipId, boolean checkToEndOfIndex) throws Exception {
    RelationshipCounter counter = observedCounts.instantiateRelationshipCounter();
    long[] typeHolder = new long[1];
    try (var cursorContext = new CursorContext(context.pageCacheTracer.createPageCursorTracer(RELATIONSHIP_RANGE_CHECKER_TAG));
        RecordReader<RelationshipRecord> relationshipReader = new RecordReader<>(context.neoStores.getRelationshipStore(), true, cursorContext);
        BoundedIterable<EntityTokenRange> relationshipTypeReader = getRelationshipTypeIndexReader(fromRelationshipId, toRelationshipId, checkToEndOfIndex, cursorContext);
        SafePropertyChainReader property = new SafePropertyChainReader(context, cursorContext);
        SchemaComplianceChecker schemaComplianceChecker = new SchemaComplianceChecker(context, mandatoryProperties, indexes, cursorContext, context.memoryTracker)) {
        ProgressListener localProgress = progress.threadLocalReporter();
        CacheAccess.Client client = cacheAccess.client();
        MutableIntObjectMap<Value> propertyValues = new IntObjectHashMap<>();
        Iterator<EntityTokenRange> relationshipTypeRangeIterator = relationshipTypeReader.iterator();
        EntityTokenIndexCheckState typeIndexState = new EntityTokenIndexCheckState(null, fromRelationshipId - 1);
        for (long relationshipId = fromRelationshipId; relationshipId < toRelationshipId && !context.isCancelled(); relationshipId++) {
            localProgress.add(1);
            RelationshipRecord relationshipRecord = relationshipReader.read(relationshipId);
            if (!relationshipRecord.inUse()) {
                continue;
            }
            // Start/end nodes
            long startNode = relationshipRecord.getFirstNode();
            boolean startNodeIsWithinRange = nodeIdRange.isWithinRangeExclusiveTo(startNode);
            boolean startNodeIsNegativeOnFirstRound = startNode < 0 && firstRound;
            if (startNodeIsWithinRange || startNodeIsNegativeOnFirstRound) {
                checkRelationshipVsNode(client, relationshipRecord, startNode, relationshipRecord.isFirstInFirstChain(), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeNotInUse(node), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeDoesNotReferenceBack(node), (relationship, node) -> reporter.forNode(node).relationshipNotFirstInSourceChain(relationship), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeHasNoRelationships(node), relationship -> reporter.forRelationship(relationship).illegalSourceNode(), cursorContext);
            }
            long endNode = relationshipRecord.getSecondNode();
            boolean endNodeIsWithinRange = nodeIdRange.isWithinRangeExclusiveTo(endNode);
            boolean endNodeIsNegativeOnFirstRound = endNode < 0 && firstRound;
            if (endNodeIsWithinRange || endNodeIsNegativeOnFirstRound) {
                checkRelationshipVsNode(client, relationshipRecord, endNode, relationshipRecord.isFirstInSecondChain(), (relationship, node) -> reporter.forRelationship(relationship).targetNodeNotInUse(node), (relationship, node) -> reporter.forRelationship(relationship).targetNodeDoesNotReferenceBack(node), (relationship, node) -> reporter.forNode(node).relationshipNotFirstInTargetChain(relationship), (relationship, node) -> reporter.forRelationship(relationship).targetNodeHasNoRelationships(node), relationship -> reporter.forRelationship(relationship).illegalTargetNode(), cursorContext);
            }
            if (firstRound) {
                if (startNode >= context.highNodeId) {
                    reporter.forRelationship(relationshipRecord).sourceNodeNotInUse(context.recordLoader.node(startNode, cursorContext));
                }
                if (endNode >= context.highNodeId) {
                    reporter.forRelationship(relationshipRecord).targetNodeNotInUse(context.recordLoader.node(endNode, cursorContext));
                }
                // Properties
                typeHolder[0] = relationshipRecord.getType();
                lightClear(propertyValues);
                boolean propertyChainIsOk = property.read(propertyValues, relationshipRecord, reporter::forRelationship, cursorContext);
                if (propertyChainIsOk) {
                    schemaComplianceChecker.checkContainsMandatoryProperties(relationshipRecord, typeHolder, propertyValues, reporter::forRelationship);
                    // gets checked this way, larger indexes will be checked in IndexChecker
                    if (context.consistencyFlags.isCheckIndexes()) {
                        schemaComplianceChecker.checkCorrectlyIndexed((RelationshipRecord) relationshipRecord, typeHolder, propertyValues, reporter::forRelationship);
                    }
                }
                // Type and count
                checkValidToken(relationshipRecord, relationshipRecord.getType(), tokenHolders.relationshipTypeTokens(), neoStores.getRelationshipTypeTokenStore(), (rel, token) -> reporter.forRelationship(rel).illegalRelationshipType(), (rel, token) -> reporter.forRelationship(rel).relationshipTypeNotInUse(token), cursorContext);
                observedCounts.incrementRelationshipTypeCounts(counter, relationshipRecord);
                // Relationship type index
                if (relationshipTypeReader.maxCount() != 0) {
                    checkRelationshipVsRelationshipTypeIndex(relationshipRecord, relationshipTypeRangeIterator, typeIndexState, relationshipId, relationshipRecord.getType(), fromRelationshipId, cursorContext);
                }
            }
            observedCounts.incrementRelationshipNodeCounts(counter, relationshipRecord, startNodeIsWithinRange, endNodeIsWithinRange);
        }
        if (firstRound && !context.isCancelled() && relationshipTypeReader.maxCount() != 0) {
            reportRemainingRelationshipTypeIndexEntries(relationshipTypeRangeIterator, typeIndexState, checkToEndOfIndex ? Long.MAX_VALUE : toRelationshipId, cursorContext);
        }
        localProgress.done();
    }
}
Also used : IntObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap) CacheAccess(org.neo4j.consistency.checking.cache.CacheAccess) RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) CursorContext(org.neo4j.io.pagecache.context.CursorContext) EntityTokenRange(org.neo4j.kernel.impl.index.schema.EntityTokenRange) RelationshipCounter(org.neo4j.internal.recordstorage.RelationshipCounter) ProgressListener(org.neo4j.internal.helpers.progress.ProgressListener) Value(org.neo4j.values.storable.Value)

Example 60 with RelationshipRecord

use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.

the class PageCachePrefetchingTest method scanningWithPreFetchMustGiveScannerFewerPageFaultsWhenScannerIsSlow.

@Test
void scanningWithPreFetchMustGiveScannerFewerPageFaultsWhenScannerIsSlow() throws Exception {
    RecordFormat<RelationshipRecord> format = Standard.LATEST_RECORD_FORMATS.relationship();
    RelationshipRecord record = format.newRecord();
    int recordSize = format.getRecordSize(NoStoreHeader.NO_STORE_HEADER);
    int recordsPerPage = PageCache.PAGE_SIZE / recordSize;
    SplittableRandom rng = new SplittableRandom(13);
    // This scanner is a bit on the slow side:
    scanner = cursor -> {
        for (int j = 0; j < recordsPerPage; j++) {
            try {
                record.initialize(rng.nextBoolean(), rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextInt() & 0xFFFF, rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextBoolean(), rng.nextBoolean());
                format.write(record, cursor, recordSize, recordsPerPage);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
    };
    runScan(file, cursorContext, "Warmup", PF_READ_AHEAD);
    long faultsWithPreFetch = runScan(file, cursorContext, "Scanner With Prefetch", PF_READ_AHEAD);
    long faultsWithoutPreFetch = runScan(file, cursorContext, "Scanner Without Prefetch", 0);
    assertThat(faultsWithPreFetch).as("faults").isLessThan(faultsWithoutPreFetch);
}
Also used : RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) SplittableRandom(java.util.SplittableRandom) Test(org.junit.jupiter.api.Test)

Aggregations

RelationshipRecord (org.neo4j.kernel.impl.store.record.RelationshipRecord)207 Test (org.junit.Test)73 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)69 ConsistencyReport (org.neo4j.consistency.report.ConsistencyReport)43 Test (org.junit.jupiter.api.Test)34 RelationshipTypeTokenRecord (org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord)30 PropertyRecord (org.neo4j.kernel.impl.store.record.PropertyRecord)19 RelationshipGroupRecord (org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)19 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)15 RelationshipStore (org.neo4j.kernel.impl.store.RelationshipStore)14 GraphStoreFixture (org.neo4j.consistency.checking.GraphStoreFixture)12 IdGenerator (org.neo4j.consistency.checking.GraphStoreFixture.IdGenerator)12 ConsistencySummaryStatistics (org.neo4j.consistency.report.ConsistencySummaryStatistics)12 TransactionDataBuilder (org.neo4j.consistency.checking.GraphStoreFixture.TransactionDataBuilder)11 InMemoryClosableChannel (org.neo4j.kernel.impl.transaction.log.InMemoryClosableChannel)11 RecordAccessStub (org.neo4j.consistency.store.RecordAccessStub)9 InputRelationship (org.neo4j.unsafe.impl.batchimport.input.InputRelationship)8 RepeatedTest (org.junit.jupiter.api.RepeatedTest)7 IOException (java.io.IOException)6 CursorContext (org.neo4j.io.pagecache.context.CursorContext)6