use of org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel in project neo4j by neo4j.
the class LegacyLogEntryWriterTest method shouldWriteAllTheEntryInACommitToTheFile.
@Test
public void shouldWriteAllTheEntryInACommitToTheFile() throws IOException {
// given
final LogVersionedStoreChannel channel = mock(LogVersionedStoreChannel.class);
final LogEntryWriter logEntryWriter = mock(LogEntryWriter.class);
final LegacyLogEntryWriter writer = new LegacyLogEntryWriter(fs, liftToFactory(logEntryWriter));
final LogEntryStart start = new LogEntryStart(0, 1, 2L, 3L, EMPTY_ADDITIONAL_ARRAY, UNSPECIFIED);
final LogEntryCommand command = new LogEntryCommand(new Command.NodeCommand(nodeRecord, nodeRecord));
final LogEntryCommit commit = new OnePhaseCommit(42L, 43L);
// when
final IOCursor<LogEntry> cursor = mockCursor(start, command, commit);
writer.writeAllLogEntries(channel, cursor);
// then
verify(logEntryWriter, times(1)).writeStartEntry(0, 1, 2L, 3L, EMPTY_ADDITIONAL_ARRAY);
final TransactionRepresentation expected = new PhysicalTransactionRepresentation(Arrays.asList(command.getXaCommand()));
verify(logEntryWriter, times(1)).serialize(eq(expected));
verify(logEntryWriter, times(1)).writeCommitEntry(42L, 43L);
}
use of org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel in project neo4j by neo4j.
the class LegacyLogsTest method shouldRewriteLogFiles.
@Test
public void shouldRewriteLogFiles() throws IOException {
// given
final IOCursor<LogEntry> cursor = mock(IOCursor.class);
final LogVersionedStoreChannel writeChannel = mock(LogVersionedStoreChannel.class);
final LogHeader header = new LogHeader(CURRENT_LOG_VERSION, 1, 42);
when(fs.listFiles(storeDir, versionedLegacyLogFilesFilter)).thenReturn(new File[] { new File(getLegacyLogFilename(1)) });
when(reader.openReadableChannel(new File(getLegacyLogFilename(1)))).thenReturn(Pair.of(header, cursor));
when(writer.openWritableChannel(new File(migrationDir, getLegacyLogFilename(1)))).thenReturn(writeChannel);
// when
new LegacyLogs(fs, reader, writer).migrateLogs(storeDir, migrationDir);
// then
verify(writer, times(1)).writeLogHeader(writeChannel, header);
verify(writer, times(1)).writeAllLogEntries(writeChannel, cursor);
}
use of org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel in project neo4j by neo4j.
the class DumpLogicalLog method dump.
public void dump(String filenameOrDirectory, PrintStream out, Predicate<LogEntry[]> filter, Function<LogEntry, String> serializer) throws IOException {
File file = new File(filenameOrDirectory);
printFile(file, out);
File firstFile;
LogVersionBridge bridge;
if (file.isDirectory()) {
// Use natural log version bridging if a directory is supplied
final PhysicalLogFiles logFiles = new PhysicalLogFiles(file, fileSystem);
bridge = new ReaderLogVersionBridge(fileSystem, logFiles) {
@Override
public LogVersionedStoreChannel next(LogVersionedStoreChannel channel) throws IOException {
LogVersionedStoreChannel next = super.next(channel);
if (next != channel) {
printFile(logFiles.getLogFileForVersion(next.getVersion()), out);
}
return next;
}
};
firstFile = logFiles.getLogFileForVersion(logFiles.getLowestLogVersion());
} else {
// Use no bridging, simple reading this single log file if a file is supplied
firstFile = file;
bridge = NO_MORE_CHANNELS;
}
StoreChannel fileChannel = fileSystem.open(firstFile, "r");
ByteBuffer buffer = ByteBuffer.allocateDirect(LOG_HEADER_SIZE);
LogHeader logHeader;
try {
logHeader = readLogHeader(buffer, fileChannel, false, firstFile);
} catch (IOException ex) {
out.println("Unable to read timestamp information, no records in logical log.");
out.println(ex.getMessage());
fileChannel.close();
throw ex;
}
out.println("Logical log format: " + logHeader.logFormatVersion + " version: " + logHeader.logVersion + " with prev committed tx[" + logHeader.lastCommittedTxId + "]");
PhysicalLogVersionedStoreChannel channel = new PhysicalLogVersionedStoreChannel(fileChannel, logHeader.logVersion, logHeader.logFormatVersion);
ReadableClosablePositionAwareChannel logChannel = new ReadAheadLogChannel(channel, bridge, DEFAULT_READ_AHEAD_SIZE);
LogEntryReader<ReadableClosablePositionAwareChannel> entryReader = new VersionAwareLogEntryReader<>();
IOCursor<LogEntry> entryCursor = new LogEntryCursor(entryReader, logChannel);
TransactionLogEntryCursor transactionCursor = new TransactionLogEntryCursor(entryCursor);
try (IOCursor<LogEntry[]> cursor = filter == null ? transactionCursor : new FilteringIOCursor<>(transactionCursor, filter)) {
while (cursor.next()) {
for (LogEntry entry : cursor.get()) {
out.println(serializer.apply(entry));
}
}
}
}
use of org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel in project neo4j by neo4j.
the class StoreMigratorCheckPointer method checkPoint.
/**
* Write a check point in the log file with the given version
* <p>
* It will create the file with header containing the log version and lastCommittedTx given as arguments
*
* @param logVersion the log version to open
* @param lastCommittedTx the last committed tx id
*/
public void checkPoint(long logVersion, long lastCommittedTx) throws IOException {
PhysicalLogFiles logFiles = new PhysicalLogFiles(storeDir, fileSystem);
File logFileForVersion = logFiles.getLogFileForVersion(logVersion);
if (!fileSystem.fileExists(logFileForVersion)) {
try (StoreChannel channel = fileSystem.create(logFileForVersion)) {
writeLogHeader(channel, logVersion, lastCommittedTx);
}
}
try (LogVersionedStoreChannel storeChannel = PhysicalLogFile.openForVersion(logFiles, fileSystem, logVersion, true)) {
long offset = storeChannel.size();
storeChannel.position(offset);
try (PositionAwarePhysicalFlushableChannel channel = new PositionAwarePhysicalFlushableChannel(storeChannel)) {
TransactionLogWriter writer = new TransactionLogWriter(new LogEntryWriter(channel));
writer.checkPoint(new LogPosition(logVersion, offset));
}
}
}
use of org.neo4j.kernel.impl.transaction.log.LogVersionedStoreChannel in project neo4j by neo4j.
the class LatestCheckPointFinder method find.
public LatestCheckPoint find(long fromVersionBackwards) throws IOException {
long version = fromVersionBackwards;
long versionToSearchForCommits = fromVersionBackwards;
LogEntryStart latestStartEntry = null;
LogEntryStart oldestStartEntry = null;
long oldestVersionFound = -1;
while (version >= INITIAL_LOG_VERSION) {
LogVersionedStoreChannel channel = PhysicalLogFile.tryOpenForVersion(logFiles, fileSystem, version, false);
if (channel == null) {
break;
}
oldestVersionFound = version;
CheckPoint latestCheckPoint = null;
ReadableLogChannel recoveredDataChannel = new ReadAheadLogChannel(channel, NO_MORE_CHANNELS);
boolean firstStartEntry = true;
try (LogEntryCursor cursor = new LogEntryCursor(logEntryReader, recoveredDataChannel)) {
LogEntry entry;
while (cursor.next()) {
entry = cursor.get();
if (entry instanceof CheckPoint) {
latestCheckPoint = entry.as();
}
if (entry instanceof LogEntryStart) {
LogEntryStart startEntry = entry.as();
if (version == versionToSearchForCommits) {
latestStartEntry = startEntry;
}
// Oldest start entry will be the first in the last log version scanned.
if (firstStartEntry) {
oldestStartEntry = startEntry;
firstStartEntry = false;
}
}
}
}
if (latestCheckPoint != null) {
return latestCheckPoint(fromVersionBackwards, version, latestStartEntry, oldestVersionFound, latestCheckPoint);
}
version--;
// if we have found no commits in the latest log, keep searching in the next one
if (latestStartEntry == null) {
versionToSearchForCommits--;
}
}
boolean commitsAfterCheckPoint = oldestStartEntry != null;
long firstTxAfterPosition = commitsAfterCheckPoint ? extractFirstTxIdAfterPosition(oldestStartEntry.getStartPosition(), fromVersionBackwards) : LatestCheckPoint.NO_TRANSACTION_ID;
return new LatestCheckPoint(null, commitsAfterCheckPoint, firstTxAfterPosition, oldestVersionFound);
}
Aggregations