diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java index 3b90ccc50fa31..e22209313416b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -102,6 +102,7 @@ import org.neo4j.kernel.impl.transaction.log.LogFileInformation; import org.neo4j.kernel.impl.transaction.log.LogHeaderCache; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.LogVersionRepository; import org.neo4j.kernel.impl.transaction.log.LoggingLogFileMonitor; import org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore; @@ -148,7 +149,6 @@ import org.neo4j.kernel.monitoring.Monitors; import org.neo4j.kernel.monitoring.tracing.Tracers; import org.neo4j.kernel.recovery.DefaultRecoverySPI; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.kernel.recovery.PositionToRecoverFrom; import org.neo4j.kernel.recovery.Recovery; import org.neo4j.kernel.spi.legacyindex.IndexImplementation; @@ -691,11 +691,11 @@ private void buildRecovery( LogEntryReader logEntryReader, LogicalTransactionStore logicalTransactionStore ) { - final LatestCheckPointFinder checkPointFinder = - new LatestCheckPointFinder( logFiles, fileSystemAbstraction, logEntryReader ); + final LogTailScanner logTailScanner = + new LogTailScanner( logFiles, fileSystemAbstraction, logEntryReader ); Recovery.SPI spi = new DefaultRecoverySPI( storageEngine, logFiles, fileSystemAbstraction, logVersionRepository, - checkPointFinder, transactionIdStore, logicalTransactionStore, positionMonitor ); + logTailScanner, transactionIdStore, logicalTransactionStore, positionMonitor ); Recovery recovery = new Recovery( spi, recoveryMonitor ); monitors.addMonitorListener( new Recovery.Monitor() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/recovery/RecoveryRequiredChecker.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/recovery/RecoveryRequiredChecker.java index 5d8b8552d4538..5c816c92e6fd9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/recovery/RecoveryRequiredChecker.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/recovery/RecoveryRequiredChecker.java @@ -27,11 +27,11 @@ import org.neo4j.kernel.impl.store.MetaDataStore; import org.neo4j.kernel.impl.store.NeoStores; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.kernel.recovery.PositionToRecoverFrom; import static org.neo4j.kernel.recovery.PositionToRecoverFrom.NO_MONITOR; @@ -67,7 +67,7 @@ public boolean isRecoveryRequiredAt( File dataDir ) throws IOException LogEntryReader reader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fs, reader ); + LogTailScanner finder = new LogTailScanner( logFiles, fs, reader ); return new PositionToRecoverFrom( finder, NO_MONITOR ).apply( logVersion ) != LogPosition.UNSPECIFIED; } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java index 130253d748d33..84ee4aea4082b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/UpgradableDatabase.java @@ -34,12 +34,11 @@ import org.neo4j.kernel.impl.storemigration.StoreUpgrader.UpgradingStoreVersionNotFoundException; import org.neo4j.kernel.impl.storemigration.StoreVersionCheck.Result; import org.neo4j.kernel.impl.storemigration.StoreVersionCheck.Result.Outcome; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; -import org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint; /** * Logic to check whether a database version is upgradable to the current version. It looks at the @@ -139,12 +138,12 @@ private Result checkCleanShutDownByCheckPoint( File storeDirectory ) // check version PhysicalLogFiles logFiles = new PhysicalLogFiles( storeDirectory, fs ); LogEntryReader logEntryReader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder latestCheckPointFinder = - new LatestCheckPointFinder( logFiles, fs, logEntryReader ); + LogTailScanner logTailScanner = + new LogTailScanner( logFiles, fs, logEntryReader ); try { - LatestCheckPoint latestCheckPoint = latestCheckPointFinder.find( logFiles.getHighestLogVersion() ); - if ( !latestCheckPoint.commitsAfterCheckPoint ) + LogTailScanner.LogTailInformation logTailInformation = logTailScanner.find( logFiles.getHighestLogVersion() ); + if ( !logTailInformation.commitsAfterLastCheckPoint ) { return new Result( Result.Outcome.ok, null, null ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/recovery/LatestCheckPointFinder.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogTailScanner.java similarity index 70% rename from community/kernel/src/main/java/org/neo4j/kernel/recovery/LatestCheckPointFinder.java rename to community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogTailScanner.java index 09d1156ce021d..12bafc1b6adb8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/recovery/LatestCheckPointFinder.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/transaction/log/LogTailScanner.java @@ -17,35 +17,36 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.kernel.recovery; +package org.neo4j.kernel.impl.transaction.log; import java.io.IOException; import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.kernel.impl.transaction.log.LogEntryCursor; -import org.neo4j.kernel.impl.transaction.log.LogPosition; -import org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel; -import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile; -import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; -import org.neo4j.kernel.impl.transaction.log.ReadAheadLogChannel; -import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel; -import org.neo4j.kernel.impl.transaction.log.ReadableLogChannel; import org.neo4j.kernel.impl.transaction.log.entry.CheckPoint; import org.neo4j.kernel.impl.transaction.log.entry.LogEntry; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommit; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryStart; +import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion; import static org.neo4j.kernel.impl.transaction.log.LogVersionBridge.NO_MORE_CHANNELS; import static org.neo4j.kernel.impl.transaction.log.LogVersionRepository.INITIAL_LOG_VERSION; -public class LatestCheckPointFinder +/** + * This class collects information about the latest entries in the transaction log. Since the only way we have to collect + * said information is to scan the transaction log from beginning to end, which is costly, we do this once and save the + * result for others to consume. + *

+ * Due to the nature of transaction logs and log rotation, a single transaction log file has to be scanned forward, and + * if the required data is not found we search backwards through log file versions. + */ +public class LogTailScanner { private final PhysicalLogFiles logFiles; private final FileSystemAbstraction fileSystem; private final LogEntryReader logEntryReader; - public LatestCheckPointFinder( PhysicalLogFiles logFiles, FileSystemAbstraction fileSystem, + public LogTailScanner( PhysicalLogFiles logFiles, FileSystemAbstraction fileSystem, LogEntryReader logEntryReader ) { this.logFiles = logFiles; @@ -53,13 +54,15 @@ public LatestCheckPointFinder( PhysicalLogFiles logFiles, FileSystemAbstraction this.logEntryReader = logEntryReader; } - public LatestCheckPoint find( long fromVersionBackwards ) throws IOException + public LogTailInformation find( long fromVersionBackwards ) throws IOException { long version = fromVersionBackwards; long versionToSearchForCommits = fromVersionBackwards; LogEntryStart latestStartEntry = null; LogEntryStart oldestStartEntry = null; long oldestVersionFound = -1; + LogEntryVersion latestLogEntryVersion = null; + while ( version >= INITIAL_LOG_VERSION ) { LogVersionedStoreChannel channel = @@ -82,10 +85,14 @@ public LatestCheckPoint find( long fromVersionBackwards ) throws IOException while ( cursor.next() ) { entry = cursor.get(); + + // Collect data about latest checkpoint if ( entry instanceof CheckPoint ) { latestCheckPoint = entry.as(); } + + // Collect data about latest commits if ( entry instanceof LogEntryStart ) { LogEntryStart startEntry = entry.as(); @@ -102,13 +109,19 @@ public LatestCheckPoint find( long fromVersionBackwards ) throws IOException firstStartEntry = false; } } + + // Collect data about latest entry version + if ( latestLogEntryVersion == null || version == versionToSearchForCommits ) + { + latestLogEntryVersion = entry.getVersion(); + } } } if ( latestCheckPoint != null ) { return latestCheckPoint( fromVersionBackwards, version, latestStartEntry, oldestVersionFound, - latestCheckPoint ); + latestCheckPoint, latestLogEntryVersion ); } version--; @@ -123,14 +136,15 @@ public LatestCheckPoint find( long fromVersionBackwards ) throws IOException boolean commitsAfterCheckPoint = oldestStartEntry != null; long firstTxAfterPosition = commitsAfterCheckPoint ? extractFirstTxIdAfterPosition( oldestStartEntry.getStartPosition(), fromVersionBackwards ) - : LatestCheckPoint.NO_TRANSACTION_ID; + : LogTailInformation.NO_TRANSACTION_ID; - return new LatestCheckPoint( null, commitsAfterCheckPoint, firstTxAfterPosition, oldestVersionFound ); + return new LogTailInformation( null, commitsAfterCheckPoint, firstTxAfterPosition, oldestVersionFound, + latestLogEntryVersion ); } - protected LatestCheckPoint latestCheckPoint( long fromVersionBackwards, long version, LogEntryStart - latestStartEntry, - long oldestVersionFound, CheckPoint latestCheckPoint ) throws IOException + protected LogTailInformation latestCheckPoint( long fromVersionBackwards, long version, + LogEntryStart latestStartEntry, long oldestVersionFound, CheckPoint latestCheckPoint, + LogEntryVersion latestLogEntryVersion ) throws IOException { // Is the latest start entry in this log file version later than what the latest check point targets? LogPosition target = latestCheckPoint.getLogPosition(); @@ -143,7 +157,7 @@ protected LatestCheckPoint latestCheckPoint( long fromVersionBackwards, long ver // This check point entry targets a previous log file. // Go there and see if there's a transaction. Reader is capped to that log version. startEntryAfterCheckPoint = extractFirstTxIdAfterPosition( target, version ) != - LatestCheckPoint.NO_TRANSACTION_ID; + LogTailInformation.NO_TRANSACTION_ID; } } @@ -151,9 +165,9 @@ protected LatestCheckPoint latestCheckPoint( long fromVersionBackwards, long ver // Reader may continue into log files after the initial version. long firstTxIdAfterCheckPoint = startEntryAfterCheckPoint ? extractFirstTxIdAfterPosition( target, fromVersionBackwards ) - : LatestCheckPoint.NO_TRANSACTION_ID; - return new LatestCheckPoint( latestCheckPoint, startEntryAfterCheckPoint, - firstTxIdAfterCheckPoint, oldestVersionFound ); + : LogTailInformation.NO_TRANSACTION_ID; + return new LogTailInformation( latestCheckPoint, startEntryAfterCheckPoint, + firstTxIdAfterCheckPoint, oldestVersionFound, latestLogEntryVersion ); } /** @@ -163,7 +177,7 @@ protected LatestCheckPoint latestCheckPoint( long fromVersionBackwards, long ver * * @param initialPosition {@link LogPosition} to start scan from. * @param maxLogVersion max log version to scan. - * @return txId of closes commit entry to {@code initialPosition}, or {@link LatestCheckPoint#NO_TRANSACTION_ID} + * @return txId of closes commit entry to {@code initialPosition}, or {@link LogTailInformation#NO_TRANSACTION_ID} * if not found. * @throws IOException on I/O error. */ @@ -200,25 +214,27 @@ protected long extractFirstTxIdAfterPosition( LogPosition initialPosition, long currentPosition = LogPosition.start( currentPosition.getLogVersion() + 1 ); } - return LatestCheckPoint.NO_TRANSACTION_ID; + return LogTailInformation.NO_TRANSACTION_ID; } - public static class LatestCheckPoint + public static class LogTailInformation { public static long NO_TRANSACTION_ID = -1; - public final CheckPoint checkPoint; - public final boolean commitsAfterCheckPoint; + public final CheckPoint lastCheckPoint; + public final boolean commitsAfterLastCheckPoint; public final long firstTxIdAfterLastCheckPoint; public final long oldestLogVersionFound; + public final LogEntryVersion latestLogEntryVersion; - public LatestCheckPoint( CheckPoint checkPoint, boolean commitsAfterCheckPoint, - long firstTxIdAfterLastCheckPoint, long oldestLogVersionFound ) + public LogTailInformation( CheckPoint lastCheckPoint, boolean commitsAfterLastCheckPoint, + long firstTxIdAfterLastCheckPoint, long oldestLogVersionFound, LogEntryVersion latestLogEntryVersion ) { - this.checkPoint = checkPoint; - this.commitsAfterCheckPoint = commitsAfterCheckPoint; + this.lastCheckPoint = lastCheckPoint; + this.commitsAfterLastCheckPoint = commitsAfterLastCheckPoint; this.firstTxIdAfterLastCheckPoint = firstTxIdAfterLastCheckPoint; this.oldestLogVersionFound = oldestLogVersionFound; + this.latestLogEntryVersion = latestLogEntryVersion; } @Override @@ -233,34 +249,37 @@ public boolean equals( Object o ) return false; } - LatestCheckPoint that = (LatestCheckPoint) o; + LogTailInformation that = (LogTailInformation) o; - return commitsAfterCheckPoint == that.commitsAfterCheckPoint && + return commitsAfterLastCheckPoint == that.commitsAfterLastCheckPoint && firstTxIdAfterLastCheckPoint == that.firstTxIdAfterLastCheckPoint && oldestLogVersionFound == that.oldestLogVersionFound && - (checkPoint == null ? that.checkPoint == null : checkPoint.equals( that.checkPoint )); + (lastCheckPoint == null ? that.lastCheckPoint == null : lastCheckPoint + .equals( that.lastCheckPoint )) && + latestLogEntryVersion.equals( that.latestLogEntryVersion ); } @Override public int hashCode() { - int result = checkPoint != null ? checkPoint.hashCode() : 0; - result = 31 * result + (commitsAfterCheckPoint ? 1 : 0); - if ( commitsAfterCheckPoint ) + int result = lastCheckPoint != null ? lastCheckPoint.hashCode() : 0; + result = 31 * result + (commitsAfterLastCheckPoint ? 1 : 0); + if ( commitsAfterLastCheckPoint ) { result = 31 * result + Long.hashCode( firstTxIdAfterLastCheckPoint ); } result = 31 * result + Long.hashCode( oldestLogVersionFound ); + result = 31 * result + latestLogEntryVersion.hashCode(); return result; } @Override public String toString() { - return "LatestCheckPoint{" + - "checkPoint=" + checkPoint + - ", commitsAfterCheckPoint=" + commitsAfterCheckPoint + - (commitsAfterCheckPoint ? ", firstTxIdAfterLastCheckPoint=" + firstTxIdAfterLastCheckPoint : "") + + return "LogTailInformation{" + + "lastCheckPoint=" + lastCheckPoint + + ", commitsAfterLastCheckPoint=" + commitsAfterLastCheckPoint + + (commitsAfterLastCheckPoint ? ", firstTxIdAfterLastCheckPoint=" + firstTxIdAfterLastCheckPoint : "") + ", oldestLogVersionFound=" + oldestLogVersionFound + '}'; } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/recovery/DefaultRecoverySPI.java b/community/kernel/src/main/java/org/neo4j/kernel/recovery/DefaultRecoverySPI.java index 0648558716f76..1b1bcb8ebf12f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/recovery/DefaultRecoverySPI.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/recovery/DefaultRecoverySPI.java @@ -27,6 +27,7 @@ import org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation; import org.neo4j.kernel.impl.transaction.TransactionRepresentation; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.LogVersionRepository; import org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; @@ -52,7 +53,7 @@ public class DefaultRecoverySPI implements Recovery.SPI public DefaultRecoverySPI( StorageEngine storageEngine, PhysicalLogFiles logFiles, FileSystemAbstraction fs, - LogVersionRepository logVersionRepository, LatestCheckPointFinder checkPointFinder, + LogVersionRepository logVersionRepository, LogTailScanner logTailScanner, TransactionIdStore transactionIdStore, LogicalTransactionStore logicalTransactionStore, PositionToRecoverFrom.Monitor monitor ) { @@ -62,7 +63,7 @@ public DefaultRecoverySPI( this.logVersionRepository = logVersionRepository; this.transactionIdStore = transactionIdStore; this.logicalTransactionStore = logicalTransactionStore; - this.positionToRecoverFrom = new PositionToRecoverFrom( checkPointFinder, monitor ); + this.positionToRecoverFrom = new PositionToRecoverFrom( logTailScanner, monitor ); } @Override diff --git a/community/kernel/src/main/java/org/neo4j/kernel/recovery/PositionToRecoverFrom.java b/community/kernel/src/main/java/org/neo4j/kernel/recovery/PositionToRecoverFrom.java index db2c26132cd78..d678a1ed2d01b 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/recovery/PositionToRecoverFrom.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/recovery/PositionToRecoverFrom.java @@ -24,6 +24,7 @@ import org.neo4j.function.ThrowingLongFunction; import org.neo4j.kernel.impl.store.UnderlyingStorageException; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import static org.neo4j.kernel.impl.transaction.log.LogVersionRepository.INITIAL_LOG_VERSION; @@ -66,12 +67,12 @@ default void noCheckPointFound() { }; - private final LatestCheckPointFinder checkPointFinder; + private final LogTailScanner logTailScanner; private final Monitor monitor; - public PositionToRecoverFrom( LatestCheckPointFinder checkPointFinder, Monitor monitor ) + public PositionToRecoverFrom( LogTailScanner logTailScanner, Monitor monitor ) { - this.checkPointFinder = checkPointFinder; + this.logTailScanner = logTailScanner; this.monitor = monitor; } @@ -86,25 +87,25 @@ public PositionToRecoverFrom( LatestCheckPointFinder checkPointFinder, Monitor m @Override public LogPosition apply( long currentLogVersion ) throws IOException { - LatestCheckPointFinder.LatestCheckPoint latestCheckPoint = checkPointFinder.find( currentLogVersion ); - if ( !latestCheckPoint.commitsAfterCheckPoint ) + LogTailScanner.LogTailInformation logTailInformation = logTailScanner.find( currentLogVersion ); + if ( !logTailInformation.commitsAfterLastCheckPoint ) { monitor.noCommitsAfterLastCheckPoint( - latestCheckPoint.checkPoint != null ? latestCheckPoint.checkPoint.getLogPosition() : null ); + logTailInformation.lastCheckPoint != null ? logTailInformation.lastCheckPoint.getLogPosition() : null ); return LogPosition.UNSPECIFIED; } - if ( latestCheckPoint.checkPoint != null ) + if ( logTailInformation.lastCheckPoint != null ) { - monitor.commitsAfterLastCheckPoint( latestCheckPoint.checkPoint.getLogPosition(), - latestCheckPoint.firstTxIdAfterLastCheckPoint ); - return latestCheckPoint.checkPoint.getLogPosition(); + monitor.commitsAfterLastCheckPoint( logTailInformation.lastCheckPoint.getLogPosition(), + logTailInformation.firstTxIdAfterLastCheckPoint ); + return logTailInformation.lastCheckPoint.getLogPosition(); } else { - if ( latestCheckPoint.oldestLogVersionFound != INITIAL_LOG_VERSION ) + if ( logTailInformation.oldestLogVersionFound != INITIAL_LOG_VERSION ) { - long fromLogVersion = Math.max( INITIAL_LOG_VERSION, latestCheckPoint.oldestLogVersionFound ); + long fromLogVersion = Math.max( INITIAL_LOG_VERSION, logTailInformation.oldestLogVersionFound ); throw new UnderlyingStorageException( "No check point found in any log file from version " + fromLogVersion + " to " + currentLogVersion ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/RecoveryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/RecoveryTest.java index 156414eafd808..139b5db4c6a41 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/RecoveryTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/RecoveryTest.java @@ -37,6 +37,7 @@ import org.neo4j.kernel.impl.transaction.log.LogHeaderCache; import org.neo4j.kernel.impl.transaction.log.LogPosition; import org.neo4j.kernel.impl.transaction.log.LogPositionMarker; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.LogVersionRepository; import org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel; import org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore; @@ -57,7 +58,6 @@ import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; import org.neo4j.kernel.lifecycle.LifeSupport; import org.neo4j.kernel.recovery.DefaultRecoverySPI; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.kernel.recovery.Recovery; import org.neo4j.kernel.recovery.Recovery.RecoveryApplier; import org.neo4j.storageengine.api.StorageEngine; @@ -138,7 +138,7 @@ public void shouldRecoverExistingData() throws Exception { StorageEngine storageEngine = mock( StorageEngine.class ); final LogEntryReader reader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fileSystemRule.get(), reader ); + LogTailScanner finder = new LogTailScanner( logFiles, fileSystemRule.get(), reader ); LogHeaderCache logHeaderCache = new LogHeaderCache( 10 ); TransactionMetadataCache metadataCache = new TransactionMetadataCache( 100 ); @@ -241,7 +241,7 @@ public void shouldSeeThatACleanDatabaseShouldNotRequireRecovery() throws Excepti { StorageEngine storageEngine = mock( StorageEngine.class ); final LogEntryReader reader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fileSystemRule.get(), reader ); + LogTailScanner finder = new LogTailScanner( logFiles, fileSystemRule.get(), reader ); TransactionMetadataCache metadataCache = new TransactionMetadataCache( 100 ); LogHeaderCache logHeaderCache = new LogHeaderCache( 10 ); @@ -379,7 +379,7 @@ private boolean recover( PhysicalLogFiles logFiles ) { StorageEngine storageEngine = mock( StorageEngine.class ); final LogEntryReader reader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fileSystemRule.get(), reader ); + LogTailScanner finder = new LogTailScanner( logFiles, fileSystemRule.get(), reader ); TransactionMetadataCache metadataCache = new TransactionMetadataCache( 100 ); LogHeaderCache logHeaderCache = new LogHeaderCache( 10 ); diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java index 883294250b516..38c9b65507a39 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/storemigration/MigrationTestUtils.java @@ -34,11 +34,11 @@ import org.neo4j.kernel.impl.storemigration.legacystore.v23.Legacy23Store; import org.neo4j.kernel.impl.storemigration.legacystore.v30.Legacy30Store; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.string.UTF8; import org.neo4j.test.Unzip; @@ -184,19 +184,19 @@ public static void removeCheckPointFromTxLog( FileSystemAbstraction fileSystem, { PhysicalLogFiles logFiles = new PhysicalLogFiles( workingDirectory, fileSystem ); LogEntryReader logEntryReader = new VersionAwareLogEntryReader<>(); - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fileSystem, logEntryReader ); - LatestCheckPointFinder.LatestCheckPoint latestCheckPoint = finder.find( logFiles.getHighestLogVersion() ); + LogTailScanner finder = new LogTailScanner( logFiles, fileSystem, logEntryReader ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( logFiles.getHighestLogVersion() ); - if ( latestCheckPoint.commitsAfterCheckPoint ) + if ( logTailInformation.commitsAfterLastCheckPoint ) { // done already return; } // let's assume there is at least a checkpoint - assertNotNull( latestCheckPoint.checkPoint ); + assertNotNull( logTailInformation.lastCheckPoint ); - LogPosition logPosition = latestCheckPoint.checkPoint.getLogPosition(); + LogPosition logPosition = logTailInformation.lastCheckPoint.getLogPosition(); File logFile = logFiles.getLogFileForVersion( logPosition.getLogVersion() ); fileSystem.truncate( logFile, logPosition.getByteOffset() ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/recovery/LatestCheckPointFinderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/LogTailScannerTest.java similarity index 79% rename from community/kernel/src/test/java/org/neo4j/kernel/recovery/LatestCheckPointFinderTest.java rename to community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/LogTailScannerTest.java index 745e74c7f8f67..0b8cb99a9ae98 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/recovery/LatestCheckPointFinderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/transaction/log/LogTailScannerTest.java @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.kernel.recovery; +package org.neo4j.kernel.impl.transaction.log; import org.junit.Before; import org.junit.Rule; @@ -37,41 +37,35 @@ import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.kernel.impl.transaction.DeadSimpleLogVersionRepository; -import org.neo4j.kernel.impl.transaction.log.FlushablePositionAwareChannel; -import org.neo4j.kernel.impl.transaction.log.LogHeaderCache; -import org.neo4j.kernel.impl.transaction.log.LogPosition; -import org.neo4j.kernel.impl.transaction.log.LogPositionMarker; -import org.neo4j.kernel.impl.transaction.log.LogVersionRepository; -import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile; -import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles; -import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner.LogTailInformation; import org.neo4j.kernel.impl.transaction.log.entry.CheckPoint; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryStart; +import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion; import org.neo4j.kernel.impl.transaction.log.entry.LogEntryWriter; import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; import org.neo4j.kernel.lifecycle.LifeSupport; -import org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint; import org.neo4j.test.rule.fs.EphemeralFileSystemRule; import static org.junit.Assert.assertEquals; import static org.neo4j.io.ByteUnit.mebiBytes; +import static org.neo4j.kernel.impl.transaction.log.LogTailScanner.LogTailInformation.NO_TRANSACTION_ID; import static org.neo4j.kernel.impl.transaction.log.PhysicalLogFile.NO_MONITOR; -import static org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint.NO_TRANSACTION_ID; @RunWith( Parameterized.class ) -public class LatestCheckPointFinderTest +public class LogTailScannerTest { @Rule public final EphemeralFileSystemRule fsRule = new EphemeralFileSystemRule(); private final File directory = new File( "/somewhere" ); private final LogEntryReader reader = new VersionAwareLogEntryReader<>(); - private LatestCheckPointFinder finder; + private LogTailScanner finder; private PhysicalLogFiles logFiles; private final int startLogVersion; private final int endLogVersion; + private final LogEntryVersion latestLogEntryVersion = LogEntryVersion.CURRENT; - public LatestCheckPointFinderTest( Integer startLogVersion, Integer endLogVersion ) + public LogTailScannerTest( Integer startLogVersion, Integer endLogVersion ) { this.startLogVersion = startLogVersion; this.endLogVersion = endLogVersion; @@ -88,7 +82,7 @@ public void setUp() { fsRule.get().mkdirs( directory ); logFiles = new PhysicalLogFiles( directory, fsRule.get() ); - finder = new LatestCheckPointFinder( logFiles, fsRule.get(), reader ); + finder = new LogTailScanner( logFiles, fsRule.get(), reader ); } @Test @@ -97,13 +91,13 @@ public void noLogFilesFound() throws Throwable // given no files setupLogFiles(); int logVersion = startLogVersion; - LatestCheckPointFinder finder = new LatestCheckPointFinder( logFiles, fsRule.get(), reader ); + LogTailScanner finder = new LogTailScanner( logFiles, fsRule.get(), reader ); // when - LatestCheckPoint latestCheckPoint = finder.find( logVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( logVersion ); // then - assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, -1, latestCheckPoint ); + assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, -1, logTailInformation ); } @Test @@ -114,10 +108,10 @@ public void oneLogFileNoCheckPoints() throws Throwable setupLogFiles( logFile() ); // when - LatestCheckPoint latestCheckPoint = finder.find( logVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( logVersion ); // then - assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, logVersion, latestCheckPoint ); + assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, logVersion, logTailInformation ); } @Test @@ -129,10 +123,10 @@ public void oneLogFileNoCheckPointsOneStart() throws Throwable setupLogFiles( logFile( start(), commit( txId ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( logVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( logVersion ); // then - assertLatestCheckPoint( false, true, txId, logVersion, latestCheckPoint ); + assertLatestCheckPoint( false, true, txId, logVersion, logTailInformation ); } @Test @@ -142,10 +136,10 @@ public void twoLogFilesNoCheckPoints() throws Throwable setupLogFiles( logFile(), logFile() ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( false, false, NO_TRANSACTION_ID, startLogVersion, logTailInformation ); } @Test @@ -156,10 +150,10 @@ public void twoLogFilesNoCheckPointsOneStart() throws Throwable setupLogFiles( logFile(), logFile( start(), commit( txId ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( false, true, txId, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( false, true, txId, startLogVersion, logTailInformation ); } @Test @@ -169,10 +163,10 @@ public void twoLogFilesNoCheckPointsOneStartWithoutCommit() throws Throwable setupLogFiles( logFile(), logFile( start() ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( false, true, NO_TRANSACTION_ID, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( false, true, NO_TRANSACTION_ID, startLogVersion, logTailInformation ); } @Test @@ -183,10 +177,10 @@ public void twoLogFilesNoCheckPointsTwoCommits() throws Throwable setupLogFiles( logFile(), logFile( start(), commit( txId ), start(), commit( txId + 1 ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( false, true, txId, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( false, true, txId, startLogVersion, logTailInformation ); } @Test @@ -201,10 +195,10 @@ public void twoLogFilesCheckPointTargetsPrevious() throws Exception logFile( checkPoint( position ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, endLogVersion, logTailInformation ); } @Test @@ -214,10 +208,10 @@ public void latestLogFileContainingACheckPointOnly() throws Throwable setupLogFiles( logFile( checkPoint() ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -227,10 +221,10 @@ public void latestLogFileContainingACheckPointAndAStartBefore() throws Throwable setupLogFiles( logFile( start(), checkPoint() ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -238,16 +232,16 @@ public void bigFileLatestCheckpointFindsStartAfter() throws Throwable { long firstTxAfterCheckpoint = Integer.MAX_VALUE + 4L; - LatestCheckPointFinder checkPointFinder = + LogTailScanner checkPointFinder = new FirstTxIdConfigurableCheckpointFinder( firstTxAfterCheckpoint, logFiles, fsRule.get(), reader ); LogEntryStart startEntry = new LogEntryStart( 1, 2, 3L, 4L, new byte[]{5, 6}, new LogPosition( endLogVersion, Integer.MAX_VALUE + 17L ) ); CheckPoint checkPoint = new CheckPoint( new LogPosition( endLogVersion, 16L ) ); - LatestCheckPoint latestCheckPoint = checkPointFinder.latestCheckPoint( endLogVersion, endLogVersion, startEntry, - endLogVersion, checkPoint ); + LogTailInformation + logTailInformation = checkPointFinder.latestCheckPoint( endLogVersion, endLogVersion, startEntry, + endLogVersion, checkPoint, latestLogEntryVersion ); - assertLatestCheckPoint( true, true, firstTxAfterCheckpoint, endLogVersion, - latestCheckPoint ); + assertLatestCheckPoint( true, true, firstTxAfterCheckpoint, endLogVersion, logTailInformation ); } @Test @@ -259,10 +253,10 @@ public void latestLogFileContainingACheckPointAndAStartAfter() throws Throwable setupLogFiles( logFile( start, commit( txId ), checkPoint( start ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, endLogVersion, logTailInformation ); } @Test @@ -273,10 +267,10 @@ public void latestLogFileContainingACheckPointAndAStartWithoutCommitAfter() thro setupLogFiles( logFile( start, checkPoint( start ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -286,10 +280,10 @@ public void latestLogFileContainingMultipleCheckPointsOneStartInBetween() throws setupLogFiles( logFile( checkPoint(), start(), checkPoint() ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -300,10 +294,10 @@ public void latestLogFileContainingMultipleCheckPointsOneStartAfterBoth() throws setupLogFiles( logFile( checkPoint(), checkPoint(), start(), commit( txId ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, endLogVersion, logTailInformation ); } @Test @@ -315,10 +309,10 @@ public void olderLogFileContainingACheckPointAndNewerFileContainingAStart() thro setupLogFiles( logFile( checkPoint() ), logFile( start, commit( txId ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, startLogVersion, logTailInformation ); } @Test @@ -329,10 +323,10 @@ public void olderLogFileContainingACheckPointAndNewerFileIsEmpty() throws Throwa setupLogFiles( logFile( start, checkPoint() ), logFile() ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, startLogVersion, logTailInformation ); } @Test @@ -344,10 +338,10 @@ public void olderLogFileContainingAStartAndNewerFileContainingACheckPointPointin setupLogFiles( logFile( start, commit( txId ) ), logFile( checkPoint( start ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, endLogVersion, logTailInformation ); } @Test @@ -359,10 +353,10 @@ public void olderLogFileContainingAStartAndNewerFileContainingACheckPointPointin setupLogFiles( logFile( start ), logFile( checkPoint( start ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -373,10 +367,10 @@ public void olderLogFileContainingAStartAndNewerFileContainingACheckPointPointin setupLogFiles( logFile( start(), commit( 3 ), position ), logFile( checkPoint( position ) ) ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, false, NO_TRANSACTION_ID, endLogVersion, logTailInformation ); } @Test @@ -387,10 +381,10 @@ public void latestLogEmptyStartEntryBeforeAndAfterCheckPointInTheLastButOneLog() setupLogFiles( logFile( start(), checkPoint(), start(), commit( txId ) ), logFile() ); // when - LatestCheckPoint latestCheckPoint = finder.find( endLogVersion ); + LogTailScanner.LogTailInformation logTailInformation = finder.find( endLogVersion ); // then - assertLatestCheckPoint( true, true, txId, startLogVersion, latestCheckPoint ); + assertLatestCheckPoint( true, true, txId, startLogVersion, logTailInformation ); } // === Below is code for helping the tests above === @@ -534,18 +528,18 @@ private static class PositionEntry implements Entry } private void assertLatestCheckPoint( boolean hasCheckPointEntry, boolean commitsAfterLastCheckPoint, - long firstTxIdAfterLastCheckPoint, long logVersion, LatestCheckPoint latestCheckPoint ) + long firstTxIdAfterLastCheckPoint, long logVersion, LogTailScanner.LogTailInformation logTailInformation ) { - assertEquals( hasCheckPointEntry, latestCheckPoint.checkPoint != null ); - assertEquals( commitsAfterLastCheckPoint, latestCheckPoint.commitsAfterCheckPoint ); + assertEquals( hasCheckPointEntry, logTailInformation.lastCheckPoint != null ); + assertEquals( commitsAfterLastCheckPoint, logTailInformation.commitsAfterLastCheckPoint ); if ( commitsAfterLastCheckPoint ) { - assertEquals( firstTxIdAfterLastCheckPoint, latestCheckPoint.firstTxIdAfterLastCheckPoint ); + assertEquals( firstTxIdAfterLastCheckPoint, logTailInformation.firstTxIdAfterLastCheckPoint ); } - assertEquals( logVersion, latestCheckPoint.oldestLogVersionFound ); + assertEquals( logVersion, logTailInformation.oldestLogVersionFound ); } - private static class FirstTxIdConfigurableCheckpointFinder extends LatestCheckPointFinder + private static class FirstTxIdConfigurableCheckpointFinder extends LogTailScanner { private final long txId; @@ -558,12 +552,13 @@ private static class FirstTxIdConfigurableCheckpointFinder extends LatestCheckPo } @Override - public LatestCheckPoint latestCheckPoint( long fromVersionBackwards, long version, - LogEntryStart latestStartEntry, long oldestVersionFound, CheckPoint latestCheckPoint ) + public LogTailInformation latestCheckPoint( long fromVersionBackwards, long version, + LogEntryStart latestStartEntry, long oldestVersionFound, CheckPoint latestCheckPoint, + LogEntryVersion latestLogEntryVersion ) throws IOException { return super.latestCheckPoint( fromVersionBackwards, version, latestStartEntry, oldestVersionFound, - latestCheckPoint ); + latestCheckPoint, latestLogEntryVersion ); } @Override diff --git a/community/kernel/src/test/java/org/neo4j/kernel/recovery/PositionToRecoverFromTest.java b/community/kernel/src/test/java/org/neo4j/kernel/recovery/PositionToRecoverFromTest.java index e8747d3d7f33c..81b70796fad97 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/recovery/PositionToRecoverFromTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/recovery/PositionToRecoverFromTest.java @@ -23,28 +23,31 @@ import org.neo4j.kernel.impl.store.UnderlyingStorageException; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner.LogTailInformation; import org.neo4j.kernel.impl.transaction.log.entry.CheckPoint; -import org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint; +import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion; import org.neo4j.kernel.recovery.PositionToRecoverFrom.Monitor; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.neo4j.kernel.impl.transaction.log.LogTailScanner.LogTailInformation.NO_TRANSACTION_ID; import static org.neo4j.kernel.impl.transaction.log.LogVersionRepository.INITIAL_LOG_VERSION; -import static org.neo4j.kernel.recovery.LatestCheckPointFinder.LatestCheckPoint.NO_TRANSACTION_ID; public class PositionToRecoverFromTest { private final long logVersion = 2L; - private final LatestCheckPointFinder finder = mock( LatestCheckPointFinder.class ); + private final LogTailScanner finder = mock( LogTailScanner.class ); private final Monitor monitor = mock( Monitor.class ); @Test public void shouldReturnUnspecifiedIfThereIsNoNeedForRecovery() throws Throwable { // given - when( finder.find( logVersion ) ).thenReturn( new LatestCheckPoint( null, false, NO_TRANSACTION_ID, logVersion ) ); + when( finder.find( logVersion ) ).thenReturn( new LogTailScanner.LogTailInformation( null, false, NO_TRANSACTION_ID, logVersion, + LogEntryVersion.CURRENT ) ); // when LogPosition logPosition = new PositionToRecoverFrom( finder, monitor ).apply( logVersion ); @@ -60,7 +63,8 @@ public void shouldReturnLogPositionToRecoverFromIfNeeded() throws Throwable // given LogPosition checkPointLogPosition = new LogPosition( 1L, 4242 ); when( finder.find( logVersion ) ) - .thenReturn( new LatestCheckPoint( new CheckPoint( checkPointLogPosition ), true, 10L, logVersion ) ); + .thenReturn( new LogTailInformation( new CheckPoint( checkPointLogPosition ), true, 10L, logVersion, + LogEntryVersion.CURRENT ) ); // when LogPosition logPosition = new PositionToRecoverFrom( finder, monitor ).apply( logVersion ); @@ -74,7 +78,8 @@ public void shouldReturnLogPositionToRecoverFromIfNeeded() throws Throwable public void shouldRecoverFromStartOfLogZeroIfThereAreNoCheckPointAndOldestLogIsVersionZero() throws Throwable { // given - when( finder.find( logVersion ) ).thenReturn( new LatestCheckPoint( null, true, 10L, INITIAL_LOG_VERSION ) ); + when( finder.find( logVersion ) ).thenReturn( new LogTailInformation( null, true, 10L, INITIAL_LOG_VERSION, + LogEntryVersion.CURRENT ) ); // when LogPosition logPosition = new PositionToRecoverFrom( finder, monitor ).apply( logVersion ); @@ -89,7 +94,8 @@ public void shouldFailIfThereAreNoCheckPointsAndOldestLogVersionInNotZero() thro { // given long oldestLogVersionFound = 1L; - when( finder.find( logVersion ) ).thenReturn( new LatestCheckPoint( null, true, 10L, oldestLogVersionFound ) ); + when( finder.find( logVersion ) ).thenReturn( new LogTailScanner.LogTailInformation( null, true, 10L, oldestLogVersionFound, + LogEntryVersion.CURRENT ) ); // when try diff --git a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/catchup/tx/TransactionLogCatchUpWriterTest.java b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/catchup/tx/TransactionLogCatchUpWriterTest.java index 478e3410c0a19..4a9cf9c96325e 100644 --- a/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/catchup/tx/TransactionLogCatchUpWriterTest.java +++ b/enterprise/causal-clustering/src/test/java/org/neo4j/causalclustering/catchup/tx/TransactionLogCatchUpWriterTest.java @@ -34,6 +34,7 @@ import org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation; import org.neo4j.kernel.impl.transaction.command.Commands; import org.neo4j.kernel.impl.transaction.log.LogPosition; +import org.neo4j.kernel.impl.transaction.log.LogTailScanner; import org.neo4j.kernel.impl.transaction.log.LogVersionBridge; import org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel; import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile; @@ -48,7 +49,6 @@ import org.neo4j.kernel.impl.transaction.log.entry.OnePhaseCommit; import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader; import org.neo4j.kernel.lifecycle.Lifespan; -import org.neo4j.kernel.recovery.LatestCheckPointFinder; import org.neo4j.logging.NullLogProvider; import org.neo4j.test.rule.NeoStoreDataSourceRule; import org.neo4j.test.rule.PageCacheRule; @@ -119,12 +119,12 @@ private void verifyCheckpointInLog() throws IOException LogEntryReader logEntryReader = new VersionAwareLogEntryReader<>( new RecordStorageCommandReaderFactory(), InvalidLogEntryHandler.STRICT ); PhysicalLogFiles logFiles = new PhysicalLogFiles( storeDir, fs ); - final LatestCheckPointFinder checkPointFinder = - new LatestCheckPointFinder( logFiles, fs, logEntryReader ); + final LogTailScanner logTailScanner = + new LogTailScanner( logFiles, fs, logEntryReader ); - LatestCheckPointFinder.LatestCheckPoint checkPoint = checkPointFinder.find( 0 ); - assertNotNull( checkPoint.checkPoint ); - assertTrue( checkPoint.commitsAfterCheckPoint ); + LogTailScanner.LogTailInformation checkPoint = logTailScanner.find( 0 ); + assertNotNull( checkPoint.lastCheckPoint ); + assertTrue( checkPoint.commitsAfterLastCheckPoint ); } private void verifyTransactionsInLog( long fromTxId, long endTxId ) throws IOException