Search in sources :

Example 1 with PositionableChannel

use of org.neo4j.io.fs.PositionableChannel in project neo4j by neo4j.

the class VersionAwareLogEntryReaderIT method correctlyResetPositionOfObservedZeroWhenChannelSwitchOnExactlyCheckedByte.

@Test
void correctlyResetPositionOfObservedZeroWhenChannelSwitchOnExactlyCheckedByte() throws IOException {
    LogFiles logFiles = LogFilesBuilder.builder(databaseLayout, fs).withLogEntryReader(entryReader).withLogVersionRepository(new SimpleLogVersionRepository()).withTransactionIdStore(new SimpleTransactionIdStore()).withStoreId(StoreId.UNKNOWN).withKernelVersionProvider(() -> KernelVersion.V4_0).build();
    try (Lifespan lifespan = new Lifespan(logFiles)) {
        LogPositionMarker positionMarker = new LogPositionMarker();
        LogFile logFile = logFiles.getLogFile();
        long initialPosition = getLastReadablePosition(logFiles);
        long checkpointsEndDataOffset = DEFAULT_READ_AHEAD_SIZE + initialPosition;
        TransactionLogWriter logWriter = logFile.getTransactionLogWriter();
        do {
            logWriter.legacyCheckPoint(new LogPosition(4, 5));
            logWriter.getCurrentPosition(positionMarker);
        } while (positionMarker.getByteOffset() <= checkpointsEndDataOffset);
        logFile.flush();
        logFiles.getLogFile().rotate();
        fs.truncate(logFiles.getLogFile().getLogFileForVersion(0), checkpointsEndDataOffset);
        try (StoreChannel storeChannel = fs.write(logFiles.getLogFile().getLogFileForVersion(1))) {
            storeChannel.position(CURRENT_FORMAT_LOG_HEADER_SIZE);
            storeChannel.writeAll(ByteBuffer.wrap(new byte[] { 0 }));
        }
        try (ReadableLogChannel logChannel = logFiles.getLogFile().getReader(new LogPosition(0, initialPosition))) {
            LogEntry logEntry = entryReader.readLogEntry(logChannel);
            // we reading expected checkpoint records
            assertThat(logEntry).isInstanceOf(LogEntryInlinedCheckPoint.class);
            LogEntryInlinedCheckPoint checkPoint = (LogEntryInlinedCheckPoint) logEntry;
            LogPosition logPosition = checkPoint.getLogPosition();
            assertEquals(4, logPosition.getLogVersion());
            assertEquals(5, logPosition.getByteOffset());
            // set position to the end of the buffer to cause channel switch on next byte read
            ((PositionableChannel) logChannel).setCurrentPosition(checkpointsEndDataOffset);
            while (entryReader.readLogEntry(logChannel) != null) {
            // read to the end
            }
            // channel should be switched now and position should be just after the header
            LogPosition position = entryReader.lastPosition();
            assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE, position.getByteOffset());
            assertEquals(1, position.getLogVersion());
        }
    }
}
Also used : ReadableLogChannel(org.neo4j.kernel.impl.transaction.log.ReadableLogChannel) SimpleTransactionIdStore(org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore) StoreChannel(org.neo4j.io.fs.StoreChannel) LogFiles(org.neo4j.kernel.impl.transaction.log.files.LogFiles) SimpleLogVersionRepository(org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository) PositionableChannel(org.neo4j.io.fs.PositionableChannel) LogPositionMarker(org.neo4j.kernel.impl.transaction.log.LogPositionMarker) LogFile(org.neo4j.kernel.impl.transaction.log.files.LogFile) TransactionLogWriter(org.neo4j.kernel.impl.transaction.log.TransactionLogWriter) Lifespan(org.neo4j.kernel.lifecycle.Lifespan) LogPosition(org.neo4j.kernel.impl.transaction.log.LogPosition) Test(org.junit.jupiter.api.Test)

Example 2 with PositionableChannel

use of org.neo4j.io.fs.PositionableChannel in project neo4j by neo4j.

the class VersionAwareLogEntryReader method resetChannelPosition.

private void resetChannelPosition(ReadableClosablePositionAwareChecksumChannel channel) throws IOException {
    // take current position
    channel.getCurrentPosition(positionMarker);
    PositionableChannel positionableChannel = (PositionableChannel) channel;
    positionableChannel.setCurrentPosition(positionMarker.getByteOffset() - 1);
    // refresh with reset position
    channel.getCurrentPosition(positionMarker);
}
Also used : PositionableChannel(org.neo4j.io.fs.PositionableChannel)

Example 3 with PositionableChannel

use of org.neo4j.io.fs.PositionableChannel in project neo4j by neo4j.

the class VersionAwareLogEntryReader method readLogEntry.

@Override
public LogEntry readLogEntry(ReadableClosablePositionAwareChecksumChannel channel) throws IOException {
    try {
        while (true) {
            channel.getCurrentPosition(positionMarker);
            byte versionCode = channel.get();
            if (versionCode == 0) {
                // and we report that we reach end of record stream from our point of view
                if (channel instanceof PositionableChannel) {
                    resetChannelPosition(channel);
                } else {
                    throw new IllegalStateException("Log reader expects positionable channel to be able to reset offset. Current channel: " + channel);
                }
                return null;
            }
            if (parserSet == null || parserSet.getIntroductionVersion().version() != versionCode) {
                try {
                    parserSet = LogEntryParserSets.parserSet(KernelVersion.getForVersion(versionCode));
                } catch (IllegalArgumentException e) {
                    throw new UnsupportedLogVersionException(String.format("Log file contains entries with prefix %d, and the lowest supported prefix is %s. This " + "indicates that the log files originates from an older version of neo4j, which we don't support " + "migrations from.", versionCode, KernelVersion.V2_3));
                }
                // a new checksum segment if we change version parser.
                if (channel instanceof PositionableChannel) {
                    resetChannelPosition(channel);
                    channel.beginChecksum();
                    channel.get();
                }
            }
            byte typeCode = channel.get();
            LogEntryParser entryReader;
            LogEntry entry;
            try {
                entryReader = parserSet.select(typeCode);
                entry = entryReader.parse(parserSet.getIntroductionVersion(), channel, positionMarker, commandReaderFactory);
            } catch (ReadPastEndException e) {
                // Make these exceptions slip by straight out to the outer handler
                throw e;
            } catch (Exception e) {
                // Tag all other exceptions with log position and other useful information
                LogPosition position = positionMarker.newPosition();
                withMessage(e, e.getMessage() + ". At position " + position + " and entry version " + versionCode);
                throwIfInstanceOf(e, UnsupportedLogVersionException.class);
                throw new IOException(e);
            }
            verifyChecksumChain(entry);
            return entry;
        }
    } catch (ReadPastEndException e) {
        return null;
    }
}
Also used : PositionableChannel(org.neo4j.io.fs.PositionableChannel) IOException(java.io.IOException) ReadPastEndException(org.neo4j.io.fs.ReadPastEndException) IOException(java.io.IOException) ReadPastEndException(org.neo4j.io.fs.ReadPastEndException) LogPosition(org.neo4j.kernel.impl.transaction.log.LogPosition)

Aggregations

PositionableChannel (org.neo4j.io.fs.PositionableChannel)3 LogPosition (org.neo4j.kernel.impl.transaction.log.LogPosition)2 IOException (java.io.IOException)1 Test (org.junit.jupiter.api.Test)1 ReadPastEndException (org.neo4j.io.fs.ReadPastEndException)1 StoreChannel (org.neo4j.io.fs.StoreChannel)1 SimpleLogVersionRepository (org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository)1 SimpleTransactionIdStore (org.neo4j.kernel.impl.transaction.SimpleTransactionIdStore)1 LogPositionMarker (org.neo4j.kernel.impl.transaction.log.LogPositionMarker)1 ReadableLogChannel (org.neo4j.kernel.impl.transaction.log.ReadableLogChannel)1 TransactionLogWriter (org.neo4j.kernel.impl.transaction.log.TransactionLogWriter)1 LogFile (org.neo4j.kernel.impl.transaction.log.files.LogFile)1 LogFiles (org.neo4j.kernel.impl.transaction.log.files.LogFiles)1 Lifespan (org.neo4j.kernel.lifecycle.Lifespan)1