use of org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository in project neo4j by neo4j.
the class VersionAwareLogEntryReaderIT method correctlyResetPositionOfObservedZeroWhenChannelSwitchOnExactlyCheckedByte.
@Test
void correctlyResetPositionOfObservedZeroWhenChannelSwitchOnExactlyCheckedByte() throws IOException {
LogFiles logFiles = LogFilesBuilder.builder(databaseLayout, fs).withLogEntryReader(entryReader).withLogVersionRepository(new SimpleLogVersionRepository()).withTransactionIdStore(new SimpleTransactionIdStore()).withStoreId(StoreId.UNKNOWN).withKernelVersionProvider(() -> KernelVersion.V4_0).build();
try (Lifespan lifespan = new Lifespan(logFiles)) {
LogPositionMarker positionMarker = new LogPositionMarker();
LogFile logFile = logFiles.getLogFile();
long initialPosition = getLastReadablePosition(logFiles);
long checkpointsEndDataOffset = DEFAULT_READ_AHEAD_SIZE + initialPosition;
TransactionLogWriter logWriter = logFile.getTransactionLogWriter();
do {
logWriter.legacyCheckPoint(new LogPosition(4, 5));
logWriter.getCurrentPosition(positionMarker);
} while (positionMarker.getByteOffset() <= checkpointsEndDataOffset);
logFile.flush();
logFiles.getLogFile().rotate();
fs.truncate(logFiles.getLogFile().getLogFileForVersion(0), checkpointsEndDataOffset);
try (StoreChannel storeChannel = fs.write(logFiles.getLogFile().getLogFileForVersion(1))) {
storeChannel.position(CURRENT_FORMAT_LOG_HEADER_SIZE);
storeChannel.writeAll(ByteBuffer.wrap(new byte[] { 0 }));
}
try (ReadableLogChannel logChannel = logFiles.getLogFile().getReader(new LogPosition(0, initialPosition))) {
LogEntry logEntry = entryReader.readLogEntry(logChannel);
// we reading expected checkpoint records
assertThat(logEntry).isInstanceOf(LogEntryInlinedCheckPoint.class);
LogEntryInlinedCheckPoint checkPoint = (LogEntryInlinedCheckPoint) logEntry;
LogPosition logPosition = checkPoint.getLogPosition();
assertEquals(4, logPosition.getLogVersion());
assertEquals(5, logPosition.getByteOffset());
// set position to the end of the buffer to cause channel switch on next byte read
((PositionableChannel) logChannel).setCurrentPosition(checkpointsEndDataOffset);
while (entryReader.readLogEntry(logChannel) != null) {
// read to the end
}
// channel should be switched now and position should be just after the header
LogPosition position = entryReader.lastPosition();
assertEquals(CURRENT_FORMAT_LOG_HEADER_SIZE, position.getByteOffset());
assertEquals(1, position.getLogVersion());
}
}
}
use of org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository in project neo4j by neo4j.
the class LogFilesBuilderTest method buildActiveFilesOnlyContext.
@Test
void buildActiveFilesOnlyContext() throws IOException {
TransactionLogFilesContext context = activeFilesBuilder(databaseLayout, fileSystem, pageCache).withLogEntryReader(logEntryReader()).withLogVersionRepository(new SimpleLogVersionRepository()).withTransactionIdStore(new SimpleTransactionIdStore()).buildContext();
assertEquals(fileSystem, context.getFileSystem());
assertNotNull(context.getLogEntryReader());
assertEquals(Long.MAX_VALUE, context.getRotationThreshold().get());
assertEquals(TransactionIdStore.BASE_TX_ID, context.getLastCommittedTransactionId());
assertEquals(0, context.getLogVersionRepository().getCurrentLogVersion());
}
use of org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository in project neo4j by neo4j.
the class LogFilesBuilderTest method buildContextWithRotationThreshold.
@Test
void buildContextWithRotationThreshold() throws IOException {
TransactionLogFilesContext context = builder(databaseLayout, fileSystem).withLogVersionRepository(new SimpleLogVersionRepository(2)).withTransactionIdStore(new SimpleTransactionIdStore()).withLogEntryReader(logEntryReader()).withRotationThreshold(ByteUnit.mebiBytes(1)).buildContext();
assertEquals(fileSystem, context.getFileSystem());
assertNotNull(context.getLogEntryReader());
assertEquals(ByteUnit.mebiBytes(1), context.getRotationThreshold().get());
assertEquals(1, context.getLastCommittedTransactionId());
assertEquals(2, context.getLogVersionRepository().getCurrentLogVersion());
}
use of org.neo4j.kernel.impl.transaction.SimpleLogVersionRepository 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.SimpleLogVersionRepository in project neo4j by neo4j.
the class LogPruningIT method pruningStrategyShouldBeDynamic.
@Test
void pruningStrategyShouldBeDynamic() throws IOException {
LogFiles logFiles = LogFilesBuilder.builder(db.databaseLayout(), fs).withLogVersionRepository(new SimpleLogVersionRepository()).withLastCommittedTransactionIdSupplier(() -> 1).withCommandReaderFactory(db.getDependencyResolver().resolveDependency(StorageEngineFactory.class).commandReaderFactory()).withTransactionIdStore(new SimpleTransactionIdStore()).build();
// Force transaction log rotation
writeTransactionsAndRotateTwice();
// Checkpoint to make sure strategy is evaluated
checkPointer.forceCheckPoint(triggerInfo);
// Make sure file is still there since we have disable pruning. 3 transaction logs and 1 separate checkpoint file.
assertThat(countTransactionLogs(logFiles)).isEqualTo(4);
// Change pruning to true
config.setDynamic(keep_logical_logs, FALSE, "LogPruningIT");
// Checkpoint to make sure strategy is evaluated
checkPointer.forceCheckPoint(triggerInfo);
// Make sure file is removed
assertThat(countTransactionLogs(logFiles)).isEqualTo(3);
}
Aggregations