use of org.neo4j.kernel.impl.transaction.log.entry.LogEntry in project neo4j by neo4j.
the class TransactionLogEntryCursorTest method mockedLogEntry.
private LogEntry mockedLogEntry(byte type) {
LogEntry logEntry = mock(LogEntry.class);
when(logEntry.getType()).thenReturn(type);
return logEntry;
}
use of org.neo4j.kernel.impl.transaction.log.entry.LogEntry 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);
}
use of org.neo4j.kernel.impl.transaction.log.entry.LogEntry in project neo4j by neo4j.
the class LatestCheckPointFinder method extractFirstTxIdAfterPosition.
/**
* Extracts txId from first commit entry, when starting reading at the given {@code position}.
* If no commit entry found in the version, the reader will continue into next version(s) up till
* {@code maxLogVersion} until finding one.
*
* @param initialPosition {@link LogPosition} to start scan from.
* @param maxLogVersion max log version to scan.
* @return txId of closes commit entry to {@code initialPosition}, or {@link LatestCheckPoint#NO_TRANSACTION_ID}
* if not found.
* @throws IOException on I/O error.
*/
private long extractFirstTxIdAfterPosition(LogPosition initialPosition, long maxLogVersion) throws IOException {
LogPosition currentPosition = initialPosition;
while (currentPosition.getLogVersion() <= maxLogVersion) {
LogVersionedStoreChannel storeChannel = PhysicalLogFile.tryOpenForVersion(logFiles, fileSystem, currentPosition.getLogVersion(), false);
if (storeChannel != null) {
try {
storeChannel.position(currentPosition.getByteOffset());
try (ReadAheadLogChannel logChannel = new ReadAheadLogChannel(storeChannel, NO_MORE_CHANNELS);
LogEntryCursor cursor = new LogEntryCursor(logEntryReader, logChannel)) {
while (cursor.next()) {
LogEntry entry = cursor.get();
if (entry instanceof LogEntryCommit) {
return ((LogEntryCommit) entry).getTxId();
}
}
}
} finally {
storeChannel.close();
}
}
currentPosition = LogPosition.start(currentPosition.getLogVersion() + 1);
}
return LatestCheckPoint.NO_TRANSACTION_ID;
}
use of org.neo4j.kernel.impl.transaction.log.entry.LogEntry in project neo4j by neo4j.
the class LogTruncationTest method assertHandlesLogTruncation.
private void assertHandlesLogTruncation(Command cmd) throws IOException {
inMemoryChannel.reset();
writer.serialize(new PhysicalTransactionRepresentation(Arrays.asList(cmd)));
int bytesSuccessfullyWritten = inMemoryChannel.writerPosition();
try {
LogEntry logEntry = logEntryReader.readLogEntry(inMemoryChannel);
StorageCommand command = ((LogEntryCommand) logEntry).getXaCommand();
assertEquals(cmd, command);
} catch (Exception e) {
throw new AssertionError("Failed to deserialize " + cmd.toString() + ", because: ", e);
}
bytesSuccessfullyWritten--;
while (bytesSuccessfullyWritten-- > 0) {
inMemoryChannel.reset();
writer.serialize(new PhysicalTransactionRepresentation(Arrays.asList(cmd)));
inMemoryChannel.truncateTo(bytesSuccessfullyWritten);
LogEntry deserialized = logEntryReader.readLogEntry(inMemoryChannel);
assertNull("Deserialization did not detect log truncation!" + "Record: " + cmd + ", deserialized: " + deserialized, deserialized);
}
}
use of org.neo4j.kernel.impl.transaction.log.entry.LogEntry in project neo4j by neo4j.
the class PhysicalTransactionCursor method next.
@Override
public boolean next() throws IOException {
// Clear the previous deserialized transaction so that it won't have to be kept in heap while deserializing
// the next one. Could be problematic if both are really big.
current = null;
while (true) {
if (!logEntryCursor.next()) {
return false;
}
LogEntry entry = logEntryCursor.get();
if (entry instanceof LogEntryInlinedCheckPoint) {
// this is a good position anyhow
channel.getCurrentPosition(lastGoodPositionMarker);
continue;
}
assert entry instanceof LogEntryStart : "Expected Start entry, read " + entry + " instead";
LogEntryStart startEntry = (LogEntryStart) entry;
LogEntryCommit commitEntry;
List<StorageCommand> entries = new ArrayList<>();
while (true) {
if (!logEntryCursor.next()) {
return false;
}
entry = logEntryCursor.get();
if (entry instanceof LogEntryCommit) {
commitEntry = (LogEntryCommit) entry;
break;
}
LogEntryCommand command = (LogEntryCommand) entry;
entries.add(command.getCommand());
}
PhysicalTransactionRepresentation transaction = new PhysicalTransactionRepresentation(entries);
transaction.setHeader(startEntry.getAdditionalHeader(), startEntry.getTimeWritten(), startEntry.getLastCommittedTxWhenTransactionStarted(), commitEntry.getTimeWritten(), -1, ANONYMOUS);
current = new CommittedTransactionRepresentation(startEntry, transaction, commitEntry);
channel.getCurrentPosition(lastGoodPositionMarker);
return true;
}
}
Aggregations