diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursor.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursor.java index 9b862c64d08dc..14f7661329eec 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursor.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursor.java @@ -74,6 +74,7 @@ private long[] sketchOutTransactionStartOffsets() throws IOException long[] offsets = new long[10_000]; int offsetCursor = 0; + long logVersion = channel.getVersion(); long startOffset = channel.position(); while ( transactionCursor.next() ) { @@ -82,11 +83,15 @@ private long[] sketchOutTransactionStartOffsets() throws IOException offsets = Arrays.copyOf( offsets, offsetCursor * 2 ); } offsets[offsetCursor++] = startOffset; - long nextStartOffset = channel.position(); - assert nextStartOffset > startOffset : "It looks like this channel moved over to another version"; startOffset = channel.position(); } + if ( channel.getVersion() != logVersion ) + { + throw new IllegalArgumentException( "The channel which was passed in bridged multiple log versions, it started at version " + + logVersion + ", but continued through to version " + channel.getVersion() + ". This isn't supported" ); + } + offsetsLength = offsetCursor; chunkStartOffsetIndex = offsetCursor; totalSize = channel.position(); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursorTest.java index 7c85f65aa0078..a95ad1209800a 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/ReversedSingleFileTransactionCursorTest.java @@ -41,7 +41,11 @@ import org.neo4j.test.rule.TestDirectory; import org.neo4j.test.rule.fs.DefaultFileSystemRule; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + import static org.neo4j.io.ByteUnit.mebiBytes; import static org.neo4j.kernel.impl.store.record.Record.NO_LABELS_FIELD; import static org.neo4j.kernel.impl.transaction.log.GivenTransactionCursor.exhaust; @@ -121,6 +125,27 @@ public void shouldHandleEmptyLog() throws Exception assertEquals( 0, readTransactions.length ); } + @Test + public void shouldDetectAndPreventChannelReadingMultipleLogVersions() throws Exception + { + // given + writeTransactions( 1, 1, 1 ); + logFile.rotate(); + writeTransactions( 1, 1, 1 ); + + // when + try ( ReadAheadLogChannel channel = (ReadAheadLogChannel) logFile.getReader( start( 0 ) ) ) + { + new ReversedSingleFileTransactionCursor( channel, new VersionAwareLogEntryReader<>() ); + fail( "Should've failed" ); + } + catch ( IllegalArgumentException e ) + { + // then good + assertThat( e.getMessage(), containsString( "multiple log versions" ) ); + } + } + private CommittedTransactionRepresentation[] readAllFromReversedCursor() throws IOException { try ( ReversedSingleFileTransactionCursor cursor = txCursor() )