Search in sources :

Example 6 with TransactionIdStore

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

the class InternalTransactionCommitProcessTest method shouldCloseTransactionRegardlessOfWhetherOrNotItAppliedCorrectly.

@Test
void shouldCloseTransactionRegardlessOfWhetherOrNotItAppliedCorrectly() throws Exception {
    // GIVEN
    TransactionIdStore transactionIdStore = mock(TransactionIdStore.class);
    TransactionAppender appender = new TestableTransactionAppender(transactionIdStore);
    long txId = 11;
    when(transactionIdStore.nextCommittingTransactionId()).thenReturn(txId);
    IOException rootCause = new IOException("Mock exception");
    StorageEngine storageEngine = mock(StorageEngine.class);
    doThrow(new IOException(rootCause)).when(storageEngine).apply(any(TransactionToApply.class), any(TransactionApplicationMode.class));
    TransactionCommitProcess commitProcess = new InternalTransactionCommitProcess(appender, storageEngine);
    TransactionToApply transaction = mockedTransaction();
    // WHEN
    TransactionFailureException exception = assertThrows(TransactionFailureException.class, () -> commitProcess.commit(transaction, commitEvent, INTERNAL));
    assertThat(exception.getMessage()).contains("Could not apply the transaction to the store");
    assertTrue(contains(exception, rootCause.getMessage(), rootCause.getClass()));
    // THEN
    // we can't verify transactionCommitted since that's part of the TransactionAppender, which we have mocked
    verify(transactionIdStore).transactionClosed(eq(txId), anyLong(), anyLong(), any(CursorContext.class));
}
Also used : TransactionFailureException(org.neo4j.internal.kernel.api.exceptions.TransactionFailureException) TransactionIdStore(org.neo4j.storageengine.api.TransactionIdStore) TestableTransactionAppender(org.neo4j.kernel.impl.transaction.log.TestableTransactionAppender) TestableTransactionAppender(org.neo4j.kernel.impl.transaction.log.TestableTransactionAppender) TransactionAppender(org.neo4j.kernel.impl.transaction.log.TransactionAppender) TransactionApplicationMode(org.neo4j.storageengine.api.TransactionApplicationMode) IOException(java.io.IOException) CursorContext(org.neo4j.io.pagecache.context.CursorContext) StorageEngine(org.neo4j.storageengine.api.StorageEngine) Test(org.junit.jupiter.api.Test)

Example 7 with TransactionIdStore

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

the class RecoveryCorruptedTransactionLogIT method recoverNotAFirstCorruptedTransactionSingleFileNoCheckpoint.

@ParameterizedTest(name = "[{index}] ({0})")
@MethodSource("corruptedLogEntryWriters")
void recoverNotAFirstCorruptedTransactionSingleFileNoCheckpoint(String testName, LogEntryWriterWrapper logEntryWriterWrapper) throws IOException {
    DatabaseManagementService managementService = databaseFactory.build();
    GraphDatabaseAPI database = (GraphDatabaseAPI) managementService.database(DEFAULT_DATABASE_NAME);
    logFiles = buildDefaultLogFiles(getStoreId(database));
    TransactionIdStore transactionIdStore = getTransactionIdStore(database);
    long lastClosedTransactionBeforeStart = transactionIdStore.getLastClosedTransactionId();
    for (int i = 0; i < 10; i++) {
        generateTransaction(database);
    }
    long numberOfTransactions = transactionIdStore.getLastClosedTransactionId() - lastClosedTransactionBeforeStart;
    managementService.shutdown();
    Path highestLogFile = logFiles.getLogFile().getHighestLogFile();
    long originalFileLength = getLastReadablePosition(highestLogFile).getByteOffset();
    removeLastCheckpointRecordFromLastLogFile();
    addCorruptedCommandsToLastLogFile(logEntryWriterWrapper);
    long modifiedFileLength = fileSystem.getFileSize(highestLogFile);
    assertThat(modifiedFileLength).isGreaterThan(originalFileLength);
    startStopDbRecoveryOfCorruptedLogs();
    assertThat(logProvider).containsMessages("Fail to read transaction log version 0.", "Recovery required from position LogPosition{logVersion=0, byteOffset=" + txOffsetAfterStart + "}", "Fail to recover all transactions.", "Any later transaction after LogPosition{logVersion=0, byteOffset=" + (6117 + txOffsetAfterStart) + "} are unreadable and will be truncated.");
    assertEquals(0, logFiles.getLogFile().getHighestLogVersion());
    assertEquals(numberOfTransactions, recoveryMonitor.getNumberOfRecoveredTransactions());
    assertEquals(originalFileLength, fileSystem.getFileSize(highestLogFile));
    // 2 shutdowns will create a checkpoint and recovery that will be triggered by removing tx logs for default db
    // during the setup and starting db as part of the test
    assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE + 3 * 192, Files.size(logFiles.getCheckpointFile().getCurrentFile()));
}
Also used : Path(java.nio.file.Path) TransactionIdStore(org.neo4j.storageengine.api.TransactionIdStore) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) DatabaseManagementService(org.neo4j.dbms.api.DatabaseManagementService) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 8 with TransactionIdStore

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

the class Runner method call.

@Override
public Long call() throws Exception {
    long lastCommittedTransactionId;
    try (FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
        Lifespan life = new Lifespan()) {
        TransactionIdStore transactionIdStore = new SimpleTransactionIdStore();
        TransactionMetadataCache transactionMetadataCache = new TransactionMetadataCache();
        LogFiles logFiles = life.add(createLogFiles(transactionIdStore, fileSystem));
        TransactionAppender transactionAppender = life.add(createBatchingTransactionAppender(transactionIdStore, transactionMetadataCache, logFiles));
        ExecutorService executorService = Executors.newFixedThreadPool(threads);
        try {
            List<Future<?>> handlers = new ArrayList<>(threads);
            for (int i = 0; i < threads; i++) {
                TransactionRepresentationFactory factory = new TransactionRepresentationFactory();
                Worker task = new Worker(transactionAppender, factory, condition);
                handlers.add(executorService.submit(task));
            }
            // wait for all the workers to complete
            Futures.getAll(handlers);
        } finally {
            executorService.shutdown();
        }
        lastCommittedTransactionId = transactionIdStore.getLastCommittedTransactionId();
    }
    return lastCommittedTransactionId;
}
Also used : DefaultFileSystemAbstraction(org.neo4j.io.fs.DefaultFileSystemAbstraction) FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) DefaultFileSystemAbstraction(org.neo4j.io.fs.DefaultFileSystemAbstraction) TransactionIdStore(org.neo4j.storageengine.api.TransactionIdStore) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) TransactionAppender(org.neo4j.kernel.impl.transaction.log.TransactionAppender) BatchingTransactionAppender(org.neo4j.kernel.impl.transaction.log.BatchingTransactionAppender) LogFiles(org.neo4j.kernel.impl.transaction.log.files.LogFiles) ArrayList(java.util.ArrayList) TransactionMetadataCache(org.neo4j.kernel.impl.transaction.log.TransactionMetadataCache) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) Lifespan(org.neo4j.kernel.lifecycle.Lifespan)

Example 9 with TransactionIdStore

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

the class RecoveryCorruptedTransactionLogIT method truncateNewerTransactionLogFileWhenForced.

@Test
void truncateNewerTransactionLogFileWhenForced() throws IOException {
    DatabaseManagementService managementService = databaseFactory.build();
    GraphDatabaseAPI database = (GraphDatabaseAPI) managementService.database(DEFAULT_DATABASE_NAME);
    TransactionIdStore transactionIdStore = getTransactionIdStore(database);
    long numberOfClosedTransactionsAfterStartup = transactionIdStore.getLastClosedTransactionId();
    logFiles = buildDefaultLogFiles(getStoreId(database));
    for (int i = 0; i < 10; i++) {
        generateTransaction(database);
    }
    long numberOfTransactionsToRecover = transactionIdStore.getLastClosedTransactionId() - numberOfClosedTransactionsAfterStartup;
    managementService.shutdown();
    removeLastCheckpointRecordFromLastLogFile();
    Supplier<Byte> randomBytesSupplier = this::randomInvalidVersionsBytes;
    BytesCaptureSupplier capturingSupplier = new BytesCaptureSupplier(randomBytesSupplier);
    addRandomBytesToLastLogFile(capturingSupplier);
    assertFalse(recoveryMonitor.wasRecoveryRequired());
    startStopDbRecoveryOfCorruptedLogs();
    try {
        assertEquals(numberOfTransactionsToRecover, recoveryMonitor.getNumberOfRecoveredTransactions());
        assertTrue(recoveryMonitor.wasRecoveryRequired());
        assertThat(logProvider).containsMessages("Fail to read transaction log version 0.", "Fail to read transaction log version 0. Last valid transaction start offset is: " + (5548 + txOffsetAfterStart) + ".");
    } catch (Throwable t) {
        throw new RuntimeException("Generated random bytes: " + capturingSupplier.getCapturedBytes(), t);
    }
}
Also used : TransactionIdStore(org.neo4j.storageengine.api.TransactionIdStore) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) DatabaseManagementService(org.neo4j.dbms.api.DatabaseManagementService) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 10 with TransactionIdStore

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

the class RecoveryCorruptedTransactionLogIT method recoverNotAFirstCorruptedTransactionMultipleFilesNoCheckpoints.

@ParameterizedTest(name = "[{index}] ({0})")
@MethodSource("corruptedLogEntryWriters")
void recoverNotAFirstCorruptedTransactionMultipleFilesNoCheckpoints(String testName, LogEntryWriterWrapper logEntryWriterWrapper) throws IOException {
    DatabaseManagementService managementService = databaseFactory.build();
    GraphDatabaseAPI database = (GraphDatabaseAPI) managementService.database(DEFAULT_DATABASE_NAME);
    logFiles = buildDefaultLogFiles(getStoreId(database));
    TransactionIdStore transactionIdStore = getTransactionIdStore(database);
    long lastClosedTransactionBeforeStart = transactionIdStore.getLastClosedTransactionId();
    generateTransactionsAndRotate(database, 3);
    for (int i = 0; i < 7; i++) {
        generateTransaction(database);
    }
    long numberOfTransactions = transactionIdStore.getLastClosedTransactionId() - lastClosedTransactionBeforeStart;
    managementService.shutdown();
    Path highestLogFile = logFiles.getLogFile().getHighestLogFile();
    long originalFileLength = getLastReadablePosition(highestLogFile).getByteOffset();
    removeLastCheckpointRecordFromLastLogFile();
    addCorruptedCommandsToLastLogFile(logEntryWriterWrapper);
    long modifiedFileLength = fileSystem.getFileSize(highestLogFile);
    assertThat(modifiedFileLength).isGreaterThan(originalFileLength);
    startStopDbRecoveryOfCorruptedLogs();
    assertThat(logProvider).containsMessages("Fail to read transaction log version 3.", "Recovery required from position LogPosition{logVersion=0, byteOffset=" + txOffsetAfterStart + "}", "Fail to recover all transactions.", "Any later transaction after LogPosition{logVersion=3, byteOffset=" + (4552 + HEADER_OFFSET) + "} are unreadable and will be truncated.");
    assertEquals(3, logFiles.getLogFile().getHighestLogVersion());
    assertEquals(numberOfTransactions, recoveryMonitor.getNumberOfRecoveredTransactions());
    assertEquals(originalFileLength, fileSystem.getFileSize(highestLogFile));
    // 2 shutdowns will create a checkpoint and recovery that will be triggered by removing tx logs for default db
    // during the setup and starting db as part of the test
    assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE + 3 * 192, Files.size(logFiles.getCheckpointFile().getCurrentFile()));
}
Also used : Path(java.nio.file.Path) TransactionIdStore(org.neo4j.storageengine.api.TransactionIdStore) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) DatabaseManagementService(org.neo4j.dbms.api.DatabaseManagementService) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

TransactionIdStore (org.neo4j.storageengine.api.TransactionIdStore)22 Test (org.junit.jupiter.api.Test)12 SimpleTransactionIdStore (org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore)10 LogFiles (org.neo4j.kernel.impl.transaction.log.files.LogFiles)6 GraphDatabaseAPI (org.neo4j.kernel.internal.GraphDatabaseAPI)5 LifeSupport (org.neo4j.kernel.lifecycle.LifeSupport)5 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 DatabaseManagementService (org.neo4j.dbms.api.DatabaseManagementService)4 IOException (java.io.IOException)3 TransactionAppender (org.neo4j.kernel.impl.transaction.log.TransactionAppender)3 Path (java.nio.file.Path)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 MethodSource (org.junit.jupiter.params.provider.MethodSource)2 BookmarkWithPrefix (org.neo4j.bolt.v3.runtime.bookmarking.BookmarkWithPrefix)2 DependencyResolver (org.neo4j.common.DependencyResolver)2 CursorContext (org.neo4j.io.pagecache.context.CursorContext)2 TransactionToApply (org.neo4j.kernel.impl.api.TransactionToApply)2 TestableTransactionAppender (org.neo4j.kernel.impl.transaction.log.TestableTransactionAppender)2 StorageEngine (org.neo4j.storageengine.api.StorageEngine)2 TransactionId (org.neo4j.storageengine.api.TransactionId)2