Search in sources :

Example 16 with StorageCommand

use of org.neo4j.storageengine.api.StorageCommand in project neo4j by neo4j.

the class LogTruncationTest method assertHandlesLogTruncation.

private void assertHandlesLogTruncation(Command cmd) throws IOException {
    inMemoryChannel.reset();
    writer.serialize(new PhysicalTransactionRepresentation(Arrays.asList(cmd)));
    int bytesSuccessfullyWritten = inMemoryChannel.writerPosition();
    try {
        LogEntry logEntry = logEntryReader.readLogEntry(inMemoryChannel);
        StorageCommand command = ((LogEntryCommand) logEntry).getXaCommand();
        assertEquals(cmd, command);
    } catch (Exception e) {
        throw new AssertionError("Failed to deserialize " + cmd.toString() + ", because: ", e);
    }
    bytesSuccessfullyWritten--;
    while (bytesSuccessfullyWritten-- > 0) {
        inMemoryChannel.reset();
        writer.serialize(new PhysicalTransactionRepresentation(Arrays.asList(cmd)));
        inMemoryChannel.truncateTo(bytesSuccessfullyWritten);
        LogEntry deserialized = logEntryReader.readLogEntry(inMemoryChannel);
        assertNull("Deserialization did not detect log truncation!" + "Record: " + cmd + ", deserialized: " + deserialized, deserialized);
    }
}
Also used : LogEntryCommand(org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand) StorageCommand(org.neo4j.storageengine.api.StorageCommand) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) LogEntry(org.neo4j.kernel.impl.transaction.log.entry.LogEntry) IOException(java.io.IOException)

Example 17 with StorageCommand

use of org.neo4j.storageengine.api.StorageCommand in project neo4j by neo4j.

the class MadeUpServerImplementation method transaction.

private TransactionRepresentation transaction(long txId) {
    Collection<StorageCommand> commands = new ArrayList<>();
    NodeRecord node = new NodeRecord(txId);
    node.setInUse(true);
    commands.add(new NodeCommand(new NodeRecord(txId), node));
    PhysicalTransactionRepresentation transaction = new PhysicalTransactionRepresentation(commands);
    transaction.setHeader(new byte[0], 0, 0, 0, 0, 0, 0);
    return transaction;
}
Also used : NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) StorageCommand(org.neo4j.storageengine.api.StorageCommand) ArrayList(java.util.ArrayList) NodeCommand(org.neo4j.kernel.impl.transaction.command.Command.NodeCommand) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation)

Example 18 with StorageCommand

use of org.neo4j.storageengine.api.StorageCommand in project neo4j by neo4j.

the class LabelAndIndexUpdateBatchingIT method findCutoffIndex.

private static int findCutoffIndex(Collection<TransactionRepresentation> transactions) throws IOException {
    Iterator<TransactionRepresentation> iterator = transactions.iterator();
    for (int i = 0; iterator.hasNext(); i++) {
        TransactionRepresentation tx = iterator.next();
        CommandExtractor extractor = new CommandExtractor();
        tx.accept(extractor);
        List<StorageCommand> nodeCommands = extractor.commands.stream().filter(command -> command instanceof NodeCommand).collect(toList());
        if (nodeCommands.size() == 1) {
            return i;
        }
    }
    throw new AssertionError("Couldn't find the transaction which would be the cut-off point");
}
Also used : Visitor(org.neo4j.internal.helpers.collection.Visitor) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Label(org.neo4j.graphdb.Label) NodeCommand(org.neo4j.internal.recordstorage.Command.NodeCommand) LogicalTransactionStore(org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore) CursorContext(org.neo4j.io.pagecache.context.CursorContext) TransactionToApply(org.neo4j.kernel.impl.api.TransactionToApply) ArrayList(java.util.ArrayList) StorageCommand(org.neo4j.storageengine.api.StorageCommand) Iterators.singleOrNull(org.neo4j.internal.helpers.collection.Iterators.singleOrNull) DEFAULT_DATABASE_NAME(org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME) TestDatabaseManagementServiceBuilder(org.neo4j.test.TestDatabaseManagementServiceBuilder) EXTERNAL(org.neo4j.storageengine.api.TransactionApplicationMode.EXTERNAL) Transaction(org.neo4j.graphdb.Transaction) Iterator(java.util.Iterator) TransactionRepresentation(org.neo4j.kernel.impl.transaction.TransactionRepresentation) Collection(java.util.Collection) IOException(java.io.IOException) GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) Test(org.junit.jupiter.api.Test) MetadataProvider(org.neo4j.storageengine.api.MetadataProvider) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) TransactionCommitProcess(org.neo4j.kernel.impl.api.TransactionCommitProcess) TransactionCursor(org.neo4j.kernel.impl.transaction.log.TransactionCursor) CommitEvent(org.neo4j.kernel.impl.transaction.tracing.CommitEvent) DatabaseManagementService(org.neo4j.dbms.api.DatabaseManagementService) TransactionRepresentation(org.neo4j.kernel.impl.transaction.TransactionRepresentation) StorageCommand(org.neo4j.storageengine.api.StorageCommand) NodeCommand(org.neo4j.internal.recordstorage.Command.NodeCommand)

Example 19 with StorageCommand

use of org.neo4j.storageengine.api.StorageCommand in project neo4j by neo4j.

the class PhysicalTransactionCursor method next.

@Override
public boolean next() throws IOException {
    // Clear the previous deserialized transaction so that it won't have to be kept in heap while deserializing
    // the next one. Could be problematic if both are really big.
    current = null;
    while (true) {
        if (!logEntryCursor.next()) {
            return false;
        }
        LogEntry entry = logEntryCursor.get();
        if (entry instanceof LogEntryInlinedCheckPoint) {
            // this is a good position anyhow
            channel.getCurrentPosition(lastGoodPositionMarker);
            continue;
        }
        assert entry instanceof LogEntryStart : "Expected Start entry, read " + entry + " instead";
        LogEntryStart startEntry = (LogEntryStart) entry;
        LogEntryCommit commitEntry;
        List<StorageCommand> entries = new ArrayList<>();
        while (true) {
            if (!logEntryCursor.next()) {
                return false;
            }
            entry = logEntryCursor.get();
            if (entry instanceof LogEntryCommit) {
                commitEntry = (LogEntryCommit) entry;
                break;
            }
            LogEntryCommand command = (LogEntryCommand) entry;
            entries.add(command.getCommand());
        }
        PhysicalTransactionRepresentation transaction = new PhysicalTransactionRepresentation(entries);
        transaction.setHeader(startEntry.getAdditionalHeader(), startEntry.getTimeWritten(), startEntry.getLastCommittedTxWhenTransactionStarted(), commitEntry.getTimeWritten(), -1, ANONYMOUS);
        current = new CommittedTransactionRepresentation(startEntry, transaction, commitEntry);
        channel.getCurrentPosition(lastGoodPositionMarker);
        return true;
    }
}
Also used : LogEntryStart(org.neo4j.kernel.impl.transaction.log.entry.LogEntryStart) CommittedTransactionRepresentation(org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation) LogEntryCommand(org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand) LogEntryCommit(org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommit) StorageCommand(org.neo4j.storageengine.api.StorageCommand) ArrayList(java.util.ArrayList) LogEntryInlinedCheckPoint(org.neo4j.kernel.impl.transaction.log.entry.LogEntryInlinedCheckPoint) LogEntry(org.neo4j.kernel.impl.transaction.log.entry.LogEntry)

Example 20 with StorageCommand

use of org.neo4j.storageengine.api.StorageCommand in project neo4j by neo4j.

the class KernelTransactionImplementation method commitTransaction.

private long commitTransaction() throws KernelException {
    boolean success = false;
    long txId = READ_ONLY_ID;
    TransactionListenersState listenersState = null;
    try (CommitEvent commitEvent = transactionEvent.beginCommitEvent()) {
        listenersState = eventListeners.beforeCommit(txState, this, storageReader);
        if (listenersState != null && listenersState.isFailed()) {
            Throwable cause = listenersState.failure();
            if (cause instanceof TransientFailureException) {
                throw (TransientFailureException) cause;
            }
            if (cause instanceof Status.HasStatus) {
                throw new TransactionFailureException(((Status.HasStatus) cause).status(), cause, cause.getMessage());
            }
            throw new TransactionFailureException(Status.Transaction.TransactionHookFailed, cause, cause.getMessage());
        }
        // Convert changes into commands and commit
        if (hasChanges()) {
            forceThawLocks();
            lockClient.prepareForCommit();
            // Gather up commands from the various sources
            HeapTrackingArrayList<StorageCommand> extractedCommands = HeapTrackingCollections.newArrayList(memoryTracker);
            storageEngine.createCommands(extractedCommands, txState, storageReader, commandCreationContext, lockClient, lockTracer(), lastTransactionIdWhenStarted, this::enforceConstraints, cursorContext, memoryTracker);
            /* Here's the deal: we track a quick-to-access hasChanges in transaction state which is true
                 * if there are any changes imposed by this transaction. Some changes made inside a transaction undo
                 * previously made changes in that same transaction, and so at some point a transaction may have
                 * changes and at another point, after more changes seemingly,
                 * the transaction may not have any changes.
                 * However, to track that "undoing" of the changes is a bit tedious, intrusive and hard to maintain
                 * and get right.... So to really make sure the transaction has changes we re-check by looking if we
                 * have produced any commands to add to the logical log.
                 */
            if (!extractedCommands.isEmpty()) {
                // Finish up the whole transaction representation
                PhysicalTransactionRepresentation transactionRepresentation = new PhysicalTransactionRepresentation(extractedCommands);
                long timeCommitted = clocks.systemClock().millis();
                transactionRepresentation.setHeader(EMPTY_BYTE_ARRAY, startTimeMillis, lastTransactionIdWhenStarted, timeCommitted, leaseClient.leaseId(), securityContext.subject());
                // Commit the transaction
                success = true;
                TransactionToApply batch = new TransactionToApply(transactionRepresentation, cursorContext);
                kernelTransactionMonitor.beforeApply();
                txId = commitProcess.commit(batch, commitEvent, INTERNAL);
                commitTime = timeCommitted;
            }
        }
        success = true;
        return txId;
    } catch (ConstraintValidationException | CreateConstraintFailureException e) {
        throw new ConstraintViolationTransactionFailureException(e.getUserMessage(tokenRead()), e);
    } finally {
        if (!success) {
            rollback(listenersState);
        } else {
            transactionId = txId;
            afterCommit(listenersState);
        }
        transactionMonitor.addHeapTransactionSize(memoryTracker.heapHighWaterMark());
        transactionMonitor.addNativeTransactionSize(memoryTracker.usedNativeMemory());
    }
}
Also used : Status(org.neo4j.kernel.api.exceptions.Status) ConstraintViolationTransactionFailureException(org.neo4j.internal.kernel.api.exceptions.ConstraintViolationTransactionFailureException) TransientFailureException(org.neo4j.graphdb.TransientFailureException) StorageCommand(org.neo4j.storageengine.api.StorageCommand) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) TransactionFailureException(org.neo4j.internal.kernel.api.exceptions.TransactionFailureException) ConstraintViolationTransactionFailureException(org.neo4j.internal.kernel.api.exceptions.ConstraintViolationTransactionFailureException) CommitEvent(org.neo4j.kernel.impl.transaction.tracing.CommitEvent) TransactionListenersState(org.neo4j.kernel.internal.event.TransactionListenersState) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) CreateConstraintFailureException(org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException)

Aggregations

StorageCommand (org.neo4j.storageengine.api.StorageCommand)77 ArrayList (java.util.ArrayList)39 Test (org.junit.jupiter.api.Test)34 CommandReader (org.neo4j.storageengine.api.CommandReader)23 InMemoryClosableChannel (org.neo4j.kernel.impl.transaction.log.InMemoryClosableChannel)22 RepeatedTest (org.junit.jupiter.api.RepeatedTest)19 PhysicalTransactionRepresentation (org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation)14 LongArrayList (org.eclipse.collections.impl.list.mutable.primitive.LongArrayList)10 Test (org.junit.Test)10 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)9 RelationshipGroupRecord (org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)9 PropertyRecord (org.neo4j.kernel.impl.store.record.PropertyRecord)8 Command (org.neo4j.kernel.impl.transaction.command.Command)7 NodeCommand (org.neo4j.kernel.impl.transaction.command.Command.NodeCommand)7 LogEntryCommand (org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand)7 SchemaRuleCommand (org.neo4j.internal.recordstorage.Command.SchemaRuleCommand)6 NeoStores (org.neo4j.kernel.impl.store.NeoStores)6 IOException (java.io.IOException)5 PropertyCommand (org.neo4j.internal.recordstorage.Command.PropertyCommand)5 IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)5