use of org.neo4j.kernel.impl.transaction.log.files.LogFile in project neo4j by neo4j.
the class MissingStoreFilesRecoveryIT method rotateTransactionLogs.
private static LogFiles rotateTransactionLogs(GraphDatabaseAPI databaseApi) throws IOException {
LogFiles logFiles = databaseApi.getDependencyResolver().resolveDependency(LogFiles.class);
LogFile logFile = logFiles.getLogFile();
logFile.rotate();
return logFiles;
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFile in project neo4j by neo4j.
the class ThresholdBasedPruneStrategyTest method shouldNotDeleteAnythingIfThresholdDoesNotAllow.
@Test
void shouldNotDeleteAnythingIfThresholdDoesNotAllow() throws IOException {
// Given
Path fileName0 = Path.of("logical.log.v0");
Path fileName1 = Path.of("logical.log.v1");
Path fileName2 = Path.of("logical.log.v2");
Path fileName3 = Path.of("logical.log.v3");
Path fileName4 = Path.of("logical.log.v4");
Path fileName5 = Path.of("logical.log.v5");
Path fileName6 = Path.of("logical.log.v6");
when(logFile.getLogFileForVersion(6)).thenReturn(fileName6);
when(logFile.getLogFileForVersion(5)).thenReturn(fileName5);
when(logFile.getLogFileForVersion(4)).thenReturn(fileName4);
when(logFile.getLogFileForVersion(3)).thenReturn(fileName3);
when(logFile.getLogFileForVersion(2)).thenReturn(fileName2);
when(logFile.getLogFileForVersion(1)).thenReturn(fileName1);
when(logFile.getLogFileForVersion(0)).thenReturn(fileName0);
when(logFile.getLowestLogVersion()).thenReturn(0L);
when(fileSystem.fileExists(fileName6)).thenReturn(true);
when(fileSystem.fileExists(fileName5)).thenReturn(true);
when(fileSystem.fileExists(fileName4)).thenReturn(true);
when(fileSystem.fileExists(fileName3)).thenReturn(true);
when(fileSystem.fileExists(fileName2)).thenReturn(true);
when(fileSystem.fileExists(fileName1)).thenReturn(true);
when(fileSystem.fileExists(fileName0)).thenReturn(true);
when(fileSystem.getFileSize(any(Path.class))).thenReturn(CURRENT_FORMAT_LOG_HEADER_SIZE + 1L);
when(threshold.reached(any(), anyLong(), any())).thenReturn(false);
ThresholdBasedPruneStrategy strategy = new ThresholdBasedPruneStrategy(logFile, threshold);
// When
strategy.findLogVersionsToDelete(7L).forEachOrdered(uncheckedLongConsumer(v -> fileSystem.deleteFile(logFile.getLogFileForVersion(v))));
// Then
verify(threshold).init();
verify(fileSystem, never()).deleteFile(any(Path.class));
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFile in project neo4j by neo4j.
the class CorruptedLogsTruncatorTest method pruneAndArchiveMultipleLogs.
@Test
void pruneAndArchiveMultipleLogs() throws IOException {
life.start();
generateTransactionLogFiles(logFiles);
long highestCorrectLogFileIndex = 5;
var logFile = logFiles.getLogFile();
Path highestCorrectLogFile = logFile.getLogFileForVersion(highestCorrectLogFileIndex);
long fileSizeBeforePrune = Files.size(highestCorrectLogFile);
long highestLogFileLength = Files.size(logFile.getHighestLogFile());
int bytesToPrune = 7;
long byteOffset = fileSizeBeforePrune - bytesToPrune;
LogPosition prunePosition = new LogPosition(highestCorrectLogFileIndex, byteOffset);
CheckpointFile checkpointFile = logFiles.getCheckpointFile();
checkpointFile.getCheckpointAppender().checkPoint(LogCheckPointEvent.NULL, new LogPosition(highestCorrectLogFileIndex, byteOffset - 1), Instant.now(), "within okay transactions");
/* Write checkpoints that should be truncated. Write enough to get them get them in two files. */
for (int i = 0; i < 5; i++) {
checkpointFile.getCheckpointAppender().checkPoint(LogCheckPointEvent.NULL, new LogPosition(highestCorrectLogFileIndex, byteOffset + 1), Instant.now(), "in the part being truncated");
}
life.shutdown();
logPruner.truncate(prunePosition);
life.start();
// 6 transaction log files and a checkpoint file
logVersionRepository.setCheckpointLogVersion(0, NULL);
assertEquals(7, logFiles.logFiles().length);
assertEquals(byteOffset, Files.size(highestCorrectLogFile));
assertThat(checkpointFile.getDetachedCheckpointFiles()).hasSize(1);
assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE + 192, /* one checkpoint */
Files.size(checkpointFile.getDetachedCheckpointFiles()[0]));
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(highestCorrectLogFileIndex, byteOffset, corruptedLogsArchive);
try (ZipFile zipFile = new ZipFile(corruptedLogsArchive)) {
assertEquals(9, zipFile.size());
checkEntryNameAndSize(zipFile, highestCorrectLogFile.getFileName().toString(), bytesToPrune);
long nextLogFileIndex = highestCorrectLogFileIndex + 1;
int lastFileIndex = TOTAL_NUMBER_OF_TRANSACTION_LOG_FILES - 1;
for (long index = nextLogFileIndex; index < lastFileIndex; index++) {
checkEntryNameAndSize(zipFile, TransactionLogFilesHelper.DEFAULT_NAME + "." + index, SINGLE_LOG_FILE_SIZE);
}
checkEntryNameAndSize(zipFile, TransactionLogFilesHelper.DEFAULT_NAME + "." + lastFileIndex, highestLogFileLength);
checkEntryNameAndSize(zipFile, TransactionLogFilesHelper.CHECKPOINT_FILE_PREFIX + ".0", 192 * 4);
checkEntryNameAndSize(zipFile, TransactionLogFilesHelper.CHECKPOINT_FILE_PREFIX + ".1", CURRENT_FORMAT_LOG_HEADER_SIZE + 192);
}
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFile 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.files.LogFile 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);
}
Aggregations