use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class CorruptedLogsTruncatorTest method doNotPruneEmptyLogs.
@Test
void doNotPruneEmptyLogs() throws IOException {
logPruner.truncate(new LogPosition(0, CURRENT_FORMAT_LOG_HEADER_SIZE));
assertTrue(FileSystemUtils.isEmptyOrNonExistingDirectory(fs, databaseDirectory));
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class RecoveryProgressIndicatorTest method reportProgressOnRecovery.
@Test
void reportProgressOnRecovery() throws Throwable {
RecoveryService recoveryService = mock(RecoveryService.class, Answers.RETURNS_MOCKS);
CorruptedLogsTruncator logsTruncator = mock(CorruptedLogsTruncator.class);
RecoveryMonitor recoveryMonitor = mock(RecoveryMonitor.class);
TransactionCursor reverseTransactionCursor = mock(TransactionCursor.class);
TransactionCursor transactionCursor = mock(TransactionCursor.class);
CommittedTransactionRepresentation transactionRepresentation = mock(CommittedTransactionRepresentation.class);
int transactionsToRecover = 5;
int expectedMax = transactionsToRecover * 2;
int lastCommittedTransactionId = 14;
LogPosition transactionLogPosition = new LogPosition(0, CURRENT_FORMAT_LOG_HEADER_SIZE);
LogPosition checkpointLogPosition = new LogPosition(0, CURRENT_FORMAT_LOG_HEADER_SIZE);
int firstTxIdAfterLastCheckPoint = 10;
RecoveryStartInformation startInformation = new RecoveryStartInformation(transactionLogPosition, checkpointLogPosition, firstTxIdAfterLastCheckPoint);
when(reverseTransactionCursor.next()).thenAnswer(new NextTransactionAnswer(transactionsToRecover));
when(transactionCursor.next()).thenAnswer(new NextTransactionAnswer(transactionsToRecover));
when(reverseTransactionCursor.get()).thenReturn(transactionRepresentation);
when(transactionCursor.get()).thenReturn(transactionRepresentation);
when(transactionRepresentation.getCommitEntry()).thenReturn(new LogEntryCommit(lastCommittedTransactionId, 1L, BASE_TX_CHECKSUM));
when(recoveryService.getRecoveryStartInformation()).thenReturn(startInformation);
when(recoveryService.getTransactionsInReverseOrder(transactionLogPosition)).thenReturn(reverseTransactionCursor);
when(recoveryService.getTransactions(transactionLogPosition)).thenReturn(transactionCursor);
AssertableProgressReporter progressReporter = new AssertableProgressReporter(expectedMax);
TransactionLogsRecovery recovery = new TransactionLogsRecovery(recoveryService, logsTruncator, new LifecycleAdapter(), recoveryMonitor, progressReporter, true, EMPTY_CHECKER, PageCacheTracer.NULL);
recovery.init();
progressReporter.verify();
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class TransactionLogFile method accept.
@Override
public void accept(LogHeaderVisitor visitor) throws IOException {
// Start from the where we're currently at and go backwards in time (versions)
long logVersion = getHighestLogVersion();
long highTransactionId = context.getLastCommittedTransactionId();
while (versionExists(logVersion)) {
LogHeader logHeader = extractHeader(logVersion, false);
if (logHeader != null) {
long lowTransactionId = logHeader.getLastCommittedTxId() + 1;
LogPosition position = logHeader.getStartPosition();
if (!visitor.visit(logHeader, position, lowTransactionId, highTransactionId)) {
break;
}
highTransactionId = logHeader.getLastCommittedTxId();
}
logVersion--;
}
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class LogFilesBuilder method closePositionSupplier.
private Supplier<LogPosition> closePositionSupplier() throws IOException {
if (lastClosedPositionSupplier != null) {
return lastClosedPositionSupplier;
}
if (transactionIdStore != null) {
return () -> {
long[] lastClosedTransaction = transactionIdStore.getLastClosedTransaction();
return new LogPosition(lastClosedTransaction[1], lastClosedTransaction[2]);
};
}
if (fileBasedOperationsOnly) {
return () -> {
throw new UnsupportedOperationException("Current version of log files can't perform any " + "operation that require availability of transaction id store. Please build full version of log files " + "to be able to use them.");
};
}
if (readOnly) {
requireNonNull(pageCache, "Read only log files require page cache to be able to read committed " + "transaction info from store store.");
requireNonNull(databaseLayout, "Store directory is required.");
TransactionIdStore transactionIdStore = readOnlyTransactionIdStore();
return () -> {
long[] lastClosedTransaction = transactionIdStore.getLastClosedTransaction();
return new LogPosition(lastClosedTransaction[1], lastClosedTransaction[2]);
};
} else {
requireNonNull(dependencies, TransactionIdStore.class.getSimpleName() + " is required. " + "Please provide an instance or a dependencies where it can be found.");
return () -> {
long[] lastClosedTransaction = resolveDependency(TransactionIdStore.class).getLastClosedTransaction();
return new LogPosition(lastClosedTransaction[1], lastClosedTransaction[2]);
};
}
}
use of org.neo4j.kernel.impl.transaction.log.LogPosition in project neo4j by neo4j.
the class DetachedLogTailScanner method getFirstTransactionIdAfterCheckpoint.
private StartCommitEntries getFirstTransactionIdAfterCheckpoint(LogFile logFile, LogPosition logPosition) throws IOException {
boolean corruptedTransactionLogs = false;
LogEntryStart start = null;
LogEntryCommit commit = null;
LogPosition lookupPosition = null;
long logVersion = logPosition.getLogVersion();
try {
while (logFile.versionExists(logVersion)) {
lookupPosition = lookupPosition == null ? logPosition : logFile.extractHeader(logVersion).getStartPosition();
try (var reader = logFile.getReader(lookupPosition, NO_MORE_CHANNELS);
var cursor = new LogEntryCursor(logEntryReader, reader)) {
LogEntry entry;
while ((start == null || commit == null) && cursor.next()) {
entry = cursor.get();
if (commit == null && entry instanceof LogEntryCommit) {
commit = (LogEntryCommit) entry;
} else if (start == null && entry instanceof LogEntryStart) {
start = (LogEntryStart) entry;
}
}
}
if ((start != null) && (commit != null)) {
return new StartCommitEntries(start, commit);
}
verifyReaderPosition(logVersion, logEntryReader.lastPosition());
logVersion++;
}
} catch (Error | ClosedByInterruptException e) {
// These should not be parsing errors
throw e;
} catch (Throwable t) {
monitor.corruptedLogFile(logVersion, t);
if (failOnCorruptedLogFiles) {
throwUnableToCleanRecover(t);
}
corruptedTransactionLogs = true;
}
return new StartCommitEntries(start, commit, corruptedTransactionLogs);
}
Aggregations