use of org.neo4j.kernel.impl.transaction.log.files.LogFiles in project neo4j by neo4j.
the class TransactionLogFileTest method shouldSuppressFailureToCloseChannelInFailedAttemptToReadHeaderAfterOpen.
@Test
void shouldSuppressFailureToCloseChannelInFailedAttemptToReadHeaderAfterOpen() throws Exception {
// GIVEN a file which returns 1/2 log header size worth of bytes
FileSystemAbstraction fs = mock(FileSystemAbstraction.class);
LogFiles logFiles = LogFilesBuilder.builder(databaseLayout, fs).withTransactionIdStore(transactionIdStore).withLogVersionRepository(logVersionRepository).withLogEntryReader(logEntryReader()).build();
int logVersion = 0;
Path logFile = logFiles.getLogFile().getLogFileForVersion(logVersion);
StoreChannel channel = mock(StoreChannel.class);
when(channel.read(any(ByteBuffer.class))).thenReturn(CURRENT_FORMAT_LOG_HEADER_SIZE / 2);
when(fs.fileExists(logFile)).thenReturn(true);
when(fs.read(eq(logFile))).thenReturn(channel);
doThrow(IOException.class).when(channel).close();
// WHEN
IncompleteLogHeaderException exception = assertThrows(IncompleteLogHeaderException.class, () -> logFiles.getLogFile().openForVersion(logVersion));
verify(channel).close();
assertEquals(1, exception.getSuppressed().length);
assertTrue(exception.getSuppressed()[0] instanceof IOException);
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFiles in project neo4j by neo4j.
the class PhysicalLogicalTransactionStoreTest method shouldOpenCleanStore.
@Test
void shouldOpenCleanStore() throws Exception {
// GIVEN
TransactionIdStore transactionIdStore = new SimpleTransactionIdStore();
TransactionMetadataCache positionCache = new TransactionMetadataCache();
LifeSupport life = new LifeSupport();
final LogFiles logFiles = buildLogFiles(transactionIdStore);
life.add(logFiles);
life.add(new BatchingTransactionAppender(logFiles, NO_ROTATION, positionCache, transactionIdStore, DATABASE_HEALTH));
try {
// WHEN
life.start();
} finally {
life.shutdown();
}
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFiles in project neo4j by neo4j.
the class TransactionLogFileRotateAndReadRaceIT method shouldNotSeeEmptyLogFileWhenReadingTransactionStream.
@Test
void shouldNotSeeEmptyLogFileWhenReadingTransactionStream() throws Exception {
// GIVEN
LogVersionRepository logVersionRepository = new SimpleLogVersionRepository();
Config cfg = Config.newBuilder().set(GraphDatabaseSettings.neo4j_home, databaseLayout.getNeo4jLayout().homeDirectory()).set(GraphDatabaseSettings.preallocate_logical_logs, false).set(GraphDatabaseSettings.logical_log_rotation_threshold, ByteUnit.kibiBytes(128)).build();
LogFiles logFiles = LogFilesBuilder.builder(databaseLayout, fs).withLogVersionRepository(logVersionRepository).withTransactionIdStore(new SimpleTransactionIdStore()).withLogEntryReader(new VersionAwareLogEntryReader(new TestCommandReaderFactory())).withConfig(cfg).withStoreId(StoreId.UNKNOWN).build();
life.add(logFiles);
LogFile logFile = logFiles.getLogFile();
var writer = logFile.getTransactionLogWriter();
LogPositionMarker startPosition = new LogPositionMarker();
writer.getCurrentPosition(startPosition);
// WHEN
AtomicBoolean end = new AtomicBoolean();
byte[] dataChunk = new byte[100];
// one thread constantly writing to and rotating the channel
CountDownLatch startSignal = new CountDownLatch(1);
Future<Void> writeFuture = t2.execute(() -> {
ThreadLocalRandom random = ThreadLocalRandom.current();
startSignal.countDown();
int rotations = 0;
while (!end.get()) {
int bytesToWrite = random.nextInt(1, dataChunk.length);
writer.getChannel().put(dataChunk, bytesToWrite);
if (logFile.rotationNeeded()) {
logFile.rotate();
// Let's just close the gap to the reader so that it gets closer to the "hot zone"
// where the rotation happens.
writer.getCurrentPosition(startPosition);
if (++rotations > LIMIT_ROTATIONS) {
end.set(true);
}
}
}
return null;
});
assertTrue(startSignal.await(10, SECONDS));
// one thread reading through the channel
try {
int reads = 0;
while (!end.get()) {
try (ReadableLogChannel reader = logFile.getReader(startPosition.newPosition())) {
deplete(reader);
}
if (++reads > LIMIT_READS) {
end.set(true);
}
}
} finally {
writeFuture.get();
}
// THEN simply getting here means this was successful
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFiles in project neo4j by neo4j.
the class RelationshipTypeIndexIT method removeLastCheckpointRecordFromLastLogFile.
private void removeLastCheckpointRecordFromLastLogFile() {
try {
LogFiles logFiles = buildLogFiles();
Optional<CheckpointInfo> latestCheckpoint = logFiles.getCheckpointFile().findLatestCheckpoint();
if (latestCheckpoint.isPresent()) {
try (StoreChannel storeChannel = fs.write(logFiles.getCheckpointFile().getCurrentFile())) {
storeChannel.truncate(latestCheckpoint.get().getCheckpointEntryPosition().getByteOffset());
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of org.neo4j.kernel.impl.transaction.log.files.LogFiles in project neo4j by neo4j.
the class RecoverIndexDropIT method appendDropTransactionToTransactionLog.
private void appendDropTransactionToTransactionLog(Path transactionLogsDirectory, CommittedTransactionRepresentation dropTransaction, StorageEngineFactory storageEngineFactory) throws IOException {
LogFiles logFiles = LogFilesBuilder.logFilesBasedOnlyBuilder(transactionLogsDirectory, fs).withCommandReaderFactory(storageEngineFactory.commandReaderFactory()).build();
LogFile logFile = logFiles.getLogFile();
try (ReadableLogChannel reader = logFile.getReader(logFile.extractHeader(0).getStartPosition())) {
LogEntryReader logEntryReader = new VersionAwareLogEntryReader(storageEngineFactory.commandReaderFactory());
while (logEntryReader.readLogEntry(reader) != null) {
}
LogPosition position = logEntryReader.lastPosition();
StoreChannel storeChannel = fs.write(logFile.getLogFileForVersion(logFile.getHighestLogVersion()));
storeChannel.position(position.getByteOffset());
try (PhysicalFlushableChecksumChannel writeChannel = new PhysicalFlushableChecksumChannel(storeChannel, new HeapScopedBuffer(100, INSTANCE))) {
new LogEntryWriter<>(writeChannel, KernelVersion.LATEST).serialize(dropTransaction);
}
}
}
Aggregations