use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class CheckPointerIntegrationTest method checkPointInTxLog.
private boolean checkPointInTxLog(GraphDatabaseService db) throws IOException {
LogFile logFile = ((GraphDatabaseAPI) db).getDependencyResolver().resolveDependency(LogFile.class);
try (ReadableLogChannel reader = logFile.getReader(new LogPosition(0, LOG_HEADER_SIZE))) {
LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader = new VersionAwareLogEntryReader<>();
LogEntry entry = null;
while ((entry = logEntryReader.readLogEntry(reader)) != null) {
if (entry instanceof CheckPoint) {
return true;
}
}
return false;
}
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class LogEntryParserDispatcherV6Test method shouldParseCheckPointEntry.
@Test
public void shouldParseCheckPointEntry() throws IOException {
// given
final CheckPoint checkPoint = new CheckPoint(new LogPosition(43, 44));
final InMemoryClosableChannel channel = new InMemoryClosableChannel();
channel.putLong(checkPoint.getLogPosition().getLogVersion());
channel.putLong(checkPoint.getLogPosition().getByteOffset());
channel.getCurrentPosition(marker);
// when
final LogEntryParser parser = version.entryParser(LogEntryByteCodes.CHECK_POINT);
final LogEntry logEntry = parser.parse(version, channel, marker, commandReader);
// then
assertEquals(checkPoint, logEntry);
assertFalse(parser.skip());
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class VersionAwareLogEntryReaderTest method shouldReadAStartLogEntry.
@Test
public void shouldReadAStartLogEntry() throws IOException {
// given
LogEntryVersion version = LogEntryVersion.CURRENT;
final LogEntryStart start = new LogEntryStart(version, 1, 2, 3, 4, new byte[] { 5 }, new LogPosition(0, 31));
final InMemoryClosableChannel channel = new InMemoryClosableChannel();
// version
channel.put(version.byteCode());
// type
channel.put(LogEntryByteCodes.TX_START);
channel.putInt(start.getMasterId());
channel.putInt(start.getLocalId());
channel.putLong(start.getTimeWritten());
channel.putLong(start.getLastCommittedTxWhenTransactionStarted());
channel.putInt(start.getAdditionalHeader().length);
channel.put(start.getAdditionalHeader(), start.getAdditionalHeader().length);
// when
final LogEntry logEntry = logEntryReader.readLogEntry(channel);
// then
assertEquals(start, logEntry);
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition 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.LogPosition in project neo4j by neo4j.
the class StoreCopyClient method writeTransactionsToActiveLogFile.
private void writeTransactionsToActiveLogFile(File tempStoreDir, Response<?> response) throws Exception {
LifeSupport life = new LifeSupport();
try {
// Start the log and appender
PhysicalLogFiles logFiles = new PhysicalLogFiles(tempStoreDir, fs);
LogHeaderCache logHeaderCache = new LogHeaderCache(10);
ReadOnlyLogVersionRepository logVersionRepository = new ReadOnlyLogVersionRepository(pageCache, tempStoreDir);
ReadOnlyTransactionIdStore readOnlyTransactionIdStore = new ReadOnlyTransactionIdStore(pageCache, tempStoreDir);
LogFile logFile = life.add(new PhysicalLogFile(fs, logFiles, Long.MAX_VALUE, /*don't rotate*/
readOnlyTransactionIdStore::getLastCommittedTransactionId, logVersionRepository, new Monitors().newMonitor(PhysicalLogFile.Monitor.class), logHeaderCache));
life.start();
// Just write all transactions to the active log version. Remember that this is after a store copy
// where there are no logs, and the transaction stream we're about to write will probably contain
// transactions that goes some time back, before the last committed transaction id. So we cannot
// use a TransactionAppender, since it has checks for which transactions one can append.
FlushableChannel channel = logFile.getWriter();
final TransactionLogWriter writer = new TransactionLogWriter(new LogEntryWriter(channel));
final AtomicLong firstTxId = new AtomicLong(BASE_TX_ID);
response.accept(new Response.Handler() {
@Override
public void obligation(long txId) throws IOException {
throw new UnsupportedOperationException("Shouldn't be called");
}
@Override
public Visitor<CommittedTransactionRepresentation, Exception> transactions() {
return transaction -> {
long txId = transaction.getCommitEntry().getTxId();
if (firstTxId.compareAndSet(BASE_TX_ID, txId)) {
monitor.startReceivingTransactions(txId);
}
writer.append(transaction.getTransactionRepresentation(), txId);
return false;
};
}
});
long endTxId = firstTxId.get();
if (endTxId != BASE_TX_ID) {
monitor.finishReceivingTransactions(endTxId);
}
long currentLogVersion = logVersionRepository.getCurrentLogVersion();
writer.checkPoint(new LogPosition(currentLogVersion, LOG_HEADER_SIZE));
// And since we write this manually we need to set the correct transaction id in the
// header of the log that we just wrote.
File currentLogFile = logFiles.getLogFileForVersion(currentLogVersion);
writeLogHeader(fs, currentLogFile, currentLogVersion, max(BASE_TX_ID, endTxId - 1));
if (!forensics) {
// since we just create new log and put checkpoint into it with offset equals to
// LOG_HEADER_SIZE we need to update last transaction offset to be equal to this newly defined max
// offset otherwise next checkpoint that use last transaction offset will be created for non
// existing offset that is in most of the cases bigger than new log size.
// Recovery will treat that as last checkpoint and will not try to recover store till new
// last closed transaction offset will not overcome old one. Till that happens it will be
// impossible for recovery process to restore the store
File neoStore = new File(tempStoreDir, MetaDataStore.DEFAULT_NAME);
MetaDataStore.setRecord(pageCache, neoStore, MetaDataStore.Position.LAST_CLOSED_TRANSACTION_LOG_BYTE_OFFSET, LOG_HEADER_SIZE);
}
} finally {
life.shutdown();
}
}
Aggregations