Search in sources :

Example 16 with VersionAwareLogEntryReader

use of org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader in project neo4j by neo4j.

the class TransactionLogFileRotateAndReadRaceIT method shouldNotSeeEmptyLogFileWhenReadingTransactionStream.

@Test
void shouldNotSeeEmptyLogFileWhenReadingTransactionStream() throws Exception {
    // GIVEN
    LogVersionRepository logVersionRepository = new SimpleLogVersionRepository();
    Config cfg = Config.newBuilder().set(GraphDatabaseSettings.neo4j_home, databaseLayout.getNeo4jLayout().homeDirectory()).set(GraphDatabaseSettings.preallocate_logical_logs, false).set(GraphDatabaseSettings.logical_log_rotation_threshold, ByteUnit.kibiBytes(128)).build();
    LogFiles logFiles = LogFilesBuilder.builder(databaseLayout, fs).withLogVersionRepository(logVersionRepository).withTransactionIdStore(new SimpleTransactionIdStore()).withLogEntryReader(new VersionAwareLogEntryReader(new TestCommandReaderFactory())).withConfig(cfg).withStoreId(StoreId.UNKNOWN).build();
    life.add(logFiles);
    LogFile logFile = logFiles.getLogFile();
    var writer = logFile.getTransactionLogWriter();
    LogPositionMarker startPosition = new LogPositionMarker();
    writer.getCurrentPosition(startPosition);
    // WHEN
    AtomicBoolean end = new AtomicBoolean();
    byte[] dataChunk = new byte[100];
    // one thread constantly writing to and rotating the channel
    CountDownLatch startSignal = new CountDownLatch(1);
    Future<Void> writeFuture = t2.execute(() -> {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        startSignal.countDown();
        int rotations = 0;
        while (!end.get()) {
            int bytesToWrite = random.nextInt(1, dataChunk.length);
            writer.getChannel().put(dataChunk, bytesToWrite);
            if (logFile.rotationNeeded()) {
                logFile.rotate();
                // Let's just close the gap to the reader so that it gets closer to the "hot zone"
                // where the rotation happens.
                writer.getCurrentPosition(startPosition);
                if (++rotations > LIMIT_ROTATIONS) {
                    end.set(true);
                }
            }
        }
        return null;
    });
    assertTrue(startSignal.await(10, SECONDS));
    // one thread reading through the channel
    try {
        int reads = 0;
        while (!end.get()) {
            try (ReadableLogChannel reader = logFile.getReader(startPosition.newPosition())) {
                deplete(reader);
            }
            if (++reads > LIMIT_READS) {
                end.set(true);
            }
        }
    } finally {
        writeFuture.get();
    }
// THEN simply getting here means this was successful
}
Also used : SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) Config(org.neo4j.configuration.Config) LogFiles(org.neo4j.kernel.impl.transaction.log.files.LogFiles) SimpleLogVersionRepository(org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository) TestCommandReaderFactory(org.neo4j.kernel.impl.api.TestCommandReaderFactory) CountDownLatch(java.util.concurrent.CountDownLatch) LogVersionRepository(org.neo4j.storageengine.api.LogVersionRepository) SimpleLogVersionRepository(org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository) LogFile(org.neo4j.kernel.impl.transaction.log.files.LogFile) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Test(org.junit.jupiter.api.Test)

Example 17 with VersionAwareLogEntryReader

use of org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader in project neo4j by neo4j.

the class RecoverIndexDropIT method appendDropTransactionToTransactionLog.

private void appendDropTransactionToTransactionLog(Path transactionLogsDirectory, CommittedTransactionRepresentation dropTransaction, StorageEngineFactory storageEngineFactory) throws IOException {
    LogFiles logFiles = LogFilesBuilder.logFilesBasedOnlyBuilder(transactionLogsDirectory, fs).withCommandReaderFactory(storageEngineFactory.commandReaderFactory()).build();
    LogFile logFile = logFiles.getLogFile();
    try (ReadableLogChannel reader = logFile.getReader(logFile.extractHeader(0).getStartPosition())) {
        LogEntryReader logEntryReader = new VersionAwareLogEntryReader(storageEngineFactory.commandReaderFactory());
        while (logEntryReader.readLogEntry(reader) != null) {
        }
        LogPosition position = logEntryReader.lastPosition();
        StoreChannel storeChannel = fs.write(logFile.getLogFileForVersion(logFile.getHighestLogVersion()));
        storeChannel.position(position.getByteOffset());
        try (PhysicalFlushableChecksumChannel writeChannel = new PhysicalFlushableChecksumChannel(storeChannel, new HeapScopedBuffer(100, INSTANCE))) {
            new LogEntryWriter<>(writeChannel, KernelVersion.LATEST).serialize(dropTransaction);
        }
    }
}
Also used : LogFile(org.neo4j.kernel.impl.transaction.log.files.LogFile) HeapScopedBuffer(org.neo4j.io.memory.HeapScopedBuffer) ReadableLogChannel(org.neo4j.kernel.impl.transaction.log.ReadableLogChannel) PhysicalFlushableChecksumChannel(org.neo4j.io.fs.PhysicalFlushableChecksumChannel) StoreChannel(org.neo4j.io.fs.StoreChannel) LogFiles(org.neo4j.kernel.impl.transaction.log.files.LogFiles) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) LogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) LogPosition(org.neo4j.kernel.impl.transaction.log.LogPosition)

Example 18 with VersionAwareLogEntryReader

use of org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader in project neo4j by neo4j.

the class LogFilesBuilder method buildContext.

TransactionLogFilesContext buildContext() throws IOException {
    if (logEntryReader == null) {
        requireNonNull(commandReaderFactory);
        logEntryReader = new VersionAwareLogEntryReader(commandReaderFactory);
    }
    if (config == null) {
        config = Config.defaults();
    }
    requireNonNull(fileSystem);
    Supplier<StoreId> storeIdSupplier = getStoreId();
    Supplier<LogVersionRepository> logVersionRepositorySupplier = getLogVersionRepositorySupplier();
    LongSupplier lastCommittedIdSupplier = lastCommittedIdSupplier();
    LongSupplier committingTransactionIdSupplier = committingIdSupplier();
    Supplier<LogPosition> lastClosedTransactionPositionSupplier = closePositionSupplier();
    // Register listener for rotation threshold
    AtomicLong rotationThreshold = getRotationThresholdAndRegisterForUpdates();
    AtomicBoolean tryPreallocateTransactionLogs = getTryToPreallocateTransactionLogs();
    var nativeAccess = getNativeAccess();
    var monitors = getMonitors();
    var health = getDatabaseHealth();
    var clock = getClock();
    // Or the latest version if we can't find the system db version.
    if (kernelVersionRepository == null) {
        kernelVersionRepository = () -> KernelVersion.LATEST;
        if (dependencies != null) {
            try {
                this.kernelVersionRepository = dependencies.resolveDependency(KernelVersionRepository.class);
            } catch (UnsatisfiedDependencyException e) {
            // Use latest version if can't find version repository.
            }
        }
    }
    return new TransactionLogFilesContext(rotationThreshold, tryPreallocateTransactionLogs, logEntryReader, lastCommittedIdSupplier, committingTransactionIdSupplier, lastClosedTransactionPositionSupplier, logVersionRepositorySupplier, fileSystem, logProvider, databaseTracers, storeIdSupplier, nativeAccess, memoryTracker, monitors, config.get(fail_on_corrupted_log_files), health, kernelVersionRepository, clock, config);
}
Also used : LogVersionRepository(org.neo4j.storageengine.api.LogVersionRepository) KernelVersionRepository(org.neo4j.storageengine.api.KernelVersionRepository) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) UnsatisfiedDependencyException(org.neo4j.exceptions.UnsatisfiedDependencyException) StoreId(org.neo4j.storageengine.api.StoreId) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) LongSupplier(java.util.function.LongSupplier) LogPosition(org.neo4j.kernel.impl.transaction.log.LogPosition)

Example 19 with VersionAwareLogEntryReader

use of org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader in project neo4j by neo4j.

the class TransactionLogInitializer method initializeExistingLogFiles.

/**
 * Make sure that any existing log files in the given transaction logs directory are initialised.
 * This is done when we migrate 3.x stores into a 4.x world.
 */
public void initializeExistingLogFiles(DatabaseLayout layout, Path transactionLogsDirectory, String checkpointReason) throws Exception {
    try (LogFilesSpan span = buildLogFiles(layout, transactionLogsDirectory)) {
        LogFiles logFiles = span.getLogFiles();
        LogFile logFile = logFiles.getLogFile();
        LogHeader logHeader = logFile.extractHeader(logFile.getLowestLogVersion());
        VersionAwareLogEntryReader entryReader = new VersionAwareLogEntryReader(commandReaderFactory, false);
        try (var readableChannel = logFile.getReader(logHeader.getStartPosition());
            var cursor = new LogEntryCursor(entryReader, readableChannel)) {
            while (cursor.next()) {
                LogEntry entry = cursor.get();
                if (entry.getType() == LogEntryTypeCodes.TX_COMMIT) {
                    // The log files already contain a transaction, so we can only append checkpoint for the end of the log files.
                    appendCheckpoint(logFiles, checkpointReason, logFile.getTransactionLogWriter().getCurrentPosition());
                    return;
                }
            }
        }
        appendEmptyTransactionAndCheckPoint(logFiles, checkpointReason);
    }
}
Also used : VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) LogEntryCursor(org.neo4j.kernel.impl.transaction.log.LogEntryCursor) LogHeader(org.neo4j.kernel.impl.transaction.log.entry.LogHeader) LogEntry(org.neo4j.kernel.impl.transaction.log.entry.LogEntry)

Example 20 with VersionAwareLogEntryReader

use of org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader in project neo4j by neo4j.

the class RecoveryRequiredChecker method isRecoveryRequiredAt.

public boolean isRecoveryRequiredAt(DatabaseLayout databaseLayout, MemoryTracker memoryTracker) throws IOException {
    LogEntryReader reader = new VersionAwareLogEntryReader(storageEngineFactory.commandReaderFactory());
    LogFiles logFiles = buildLogFiles(databaseLayout, reader, memoryTracker);
    return isRecoveryRequiredAt(databaseLayout, logFiles);
}
Also used : LogFiles(org.neo4j.kernel.impl.transaction.log.files.LogFiles) LogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader) VersionAwareLogEntryReader(org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader)

Aggregations

VersionAwareLogEntryReader (org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader)39 ReadableClosablePositionAwareChannel (org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel)18 ReadableLogChannel (org.neo4j.kernel.impl.transaction.log.ReadableLogChannel)9 LogFiles (org.neo4j.kernel.impl.transaction.log.files.LogFiles)9 IOException (java.io.IOException)8 ReadAheadLogChannel (org.neo4j.kernel.impl.transaction.log.ReadAheadLogChannel)8 LogEntry (org.neo4j.kernel.impl.transaction.log.entry.LogEntry)8 LifeSupport (org.neo4j.kernel.lifecycle.LifeSupport)8 File (java.io.File)7 Test (org.junit.Test)7 LogPosition (org.neo4j.kernel.impl.transaction.log.LogPosition)7 PhysicalLogFiles (org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles)7 LatestCheckPointFinder (org.neo4j.kernel.recovery.LatestCheckPointFinder)7 LogEntryCursor (org.neo4j.kernel.impl.transaction.log.LogEntryCursor)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 CommittedTransactionRepresentation (org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation)5 LogEntryReader (org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader)5 LogFile (org.neo4j.kernel.impl.transaction.log.files.LogFile)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 StoreChannel (org.neo4j.io.fs.StoreChannel)4