use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class CorruptedLogsTruncatorTest method pruneAndArchiveLastLog.
@Test
void pruneAndArchiveLastLog() throws IOException {
life.start();
generateTransactionLogFiles(logFiles);
var logFile = logFiles.getLogFile();
long highestLogVersion = logFile.getHighestLogVersion();
Path highestLogFile = logFile.getHighestLogFile();
long fileSizeBeforePrune = Files.size(highestLogFile);
int bytesToPrune = 5;
long byteOffset = fileSizeBeforePrune - bytesToPrune;
LogPosition prunePosition = new LogPosition(highestLogVersion, byteOffset);
logPruner.truncate(prunePosition);
assertEquals(TOTAL_NUMBER_OF_LOG_FILES, logFiles.logFiles().length);
assertEquals(byteOffset, Files.size(highestLogFile));
Path corruptedLogsDirectory = databaseDirectory.resolve(CORRUPTED_TX_LOGS_BASE_NAME);
assertTrue(Files.exists(corruptedLogsDirectory));
File[] files = corruptedLogsDirectory.toFile().listFiles();
assertNotNull(files);
assertEquals(1, files.length);
File corruptedLogsArchive = files[0];
checkArchiveName(highestLogVersion, byteOffset, corruptedLogsArchive);
try (ZipFile zipFile = new ZipFile(corruptedLogsArchive)) {
assertEquals(1, zipFile.size());
checkEntryNameAndSize(zipFile, highestLogFile.getFileName().toString(), bytesToPrune);
}
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class CorruptedLogsTruncatorTest method truncateLogWithCorruptionThatLooksLikePreAllocatedZeros.
@Test
void truncateLogWithCorruptionThatLooksLikePreAllocatedZeros() throws IOException {
life.start();
generateTransactionLogFiles(logFiles);
var logFile = logFiles.getLogFile();
long highestLogVersion = logFile.getHighestLogVersion();
long fileSizeBeforeAppend = Files.size(logFile.getHighestLogFile());
LogPosition endOfLogsPosition = new LogPosition(highestLogVersion, fileSizeBeforeAppend);
FlushablePositionAwareChecksumChannel channel = logFile.getTransactionLogWriter().getChannel();
for (int i = 0; i < RandomUtils.nextInt(100, 10240); i++) {
channel.putLong(0);
}
// corruption byte
channel.put((byte) 7);
for (int i = 0; i < RandomUtils.nextInt(10, 1024); i++) {
channel.putLong(0);
}
channel.prepareForFlush().flush();
long fileAfterZeroAppend = Files.size(logFile.getHighestLogFile());
assertNotEquals(fileSizeBeforeAppend, fileAfterZeroAppend);
logPruner.truncate(endOfLogsPosition);
assertEquals(TOTAL_NUMBER_OF_LOG_FILES, logFiles.logFiles().length);
assertEquals(fileSizeBeforeAppend, Files.size(logFile.getHighestLogFile()));
Path corruptedLogsDirectory = databaseDirectory.resolve(CORRUPTED_TX_LOGS_BASE_NAME);
assertTrue(Files.exists(corruptedLogsDirectory));
File[] files = corruptedLogsDirectory.toFile().listFiles();
assertNotNull(files);
assertEquals(1, files.length);
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class RecoveryStartInformationProviderTest method shouldRecoverFromStartOfLogZeroIfThereAreNoCheckPointAndOldestLogIsVersionZero.
@Test
void shouldRecoverFromStartOfLogZeroIfThereAreNoCheckPointAndOldestLogIsVersionZero() {
// given
when(logFiles.getTailInformation()).thenReturn(new LogTailInformation(true, 10L, false, currentLogVersion, LATEST.version()));
// when
RecoveryStartInformation recoveryStartInformation = new RecoveryStartInformationProvider(logFiles, monitor).get();
// then
verify(monitor).noCheckPointFound();
assertEquals(new LogPosition(0, CURRENT_FORMAT_LOG_HEADER_SIZE), recoveryStartInformation.getTransactionLogPosition());
assertEquals(new LogPosition(0, CURRENT_FORMAT_LOG_HEADER_SIZE), recoveryStartInformation.getCheckpointPosition());
assertEquals(10L, recoveryStartInformation.getFirstTxIdAfterLastCheckPoint());
assertTrue(recoveryStartInformation.isRecoveryRequired());
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class TransactionLogsRecoveryTest method shouldTruncateInvalidCheckpointAndAllCorruptTransactions.
@Test
void shouldTruncateInvalidCheckpointAndAllCorruptTransactions() throws IOException {
Path file = logFiles.getLogFile().getLogFileForVersion(logVersion);
LogPositionMarker marker = new LogPositionMarker();
writeSomeData(file, pair -> {
LogEntryWriter writer = pair.first();
writer.writeStartEntry(1L, 1L, BASE_TX_CHECKSUM, ArrayUtils.EMPTY_BYTE_ARRAY);
writer.writeCommitEntry(1L, 2L);
Consumer<LogPositionMarker> other = pair.other();
other.accept(marker);
var checkpointFile = logFiles.getCheckpointFile();
var checkpointAppender = checkpointFile.getCheckpointAppender();
checkpointAppender.checkPoint(LogCheckPointEvent.NULL, marker.newPosition(), Instant.now(), "valid checkpoint");
checkpointAppender.checkPoint(LogCheckPointEvent.NULL, new LogPosition(marker.getLogVersion() + 1, marker.getByteOffset()), Instant.now(), "invalid checkpoint");
// incomplete tx
writer.writeStartEntry(5L, 4L, 0, new byte[0]);
return true;
});
assertTrue(recover(storeDir, logFiles));
assertEquals(marker.getByteOffset(), Files.size(file));
assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE + 192, /* one checkpoint */
Files.size(logFiles.getCheckpointFile().getCurrentFile()));
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class LogEntryParserDispatcherV6Test method parseLegacyCheckPointEntry.
@Test
void parseLegacyCheckPointEntry() throws IOException {
// given
final LogEntryInlinedCheckPoint checkPoint = new LogEntryInlinedCheckPoint(KernelVersion.V4_0, new LogPosition(43, 44));
final InMemoryClosableChannel channel = new InMemoryClosableChannel();
channel.putLong(checkPoint.getLogPosition().getLogVersion());
channel.putLong(checkPoint.getLogPosition().getByteOffset());
channel.putChecksum();
channel.getCurrentPosition(marker);
// when
final LogEntryParser parser = new LogEntryParserSetV4_0().select(LEGACY_CHECK_POINT);
final LogEntry logEntry = parser.parse(KernelVersion.V4_0, channel, marker, commandReader);
// then
assertEquals(checkPoint, logEntry);
}
Aggregations