use of org.neo4j.dbms.database.DatabaseStartAbortedException in project neo4j by neo4j.
the class TransactionLogsRecovery method init.
@Override
public void init() throws Exception {
RecoveryStartInformation recoveryStartInformation = recoveryService.getRecoveryStartInformation();
if (!recoveryStartInformation.isRecoveryRequired()) {
schemaLife.init();
return;
}
Stopwatch recoveryStartTime = Stopwatch.start();
LogPosition recoveryStartPosition = recoveryStartInformation.getTransactionLogPosition();
monitor.recoveryRequired(recoveryStartPosition);
LogPosition recoveryToPosition = recoveryStartPosition;
LogPosition lastTransactionPosition = recoveryStartPosition;
CommittedTransactionRepresentation lastTransaction = null;
CommittedTransactionRepresentation lastReversedTransaction = null;
if (!recoveryStartInformation.isMissingLogs()) {
try {
long lowestRecoveredTxId = TransactionIdStore.BASE_TX_ID;
try (var transactionsToRecover = recoveryService.getTransactionsInReverseOrder(recoveryStartPosition);
var recoveryVisitor = recoveryService.getRecoveryApplier(REVERSE_RECOVERY, pageCacheTracer, REVERSE_RECOVERY_TAG)) {
while (transactionsToRecover.next()) {
recoveryStartupChecker.checkIfCanceled();
CommittedTransactionRepresentation transaction = transactionsToRecover.get();
if (lastReversedTransaction == null) {
lastReversedTransaction = transaction;
initProgressReporter(recoveryStartInformation, lastReversedTransaction);
}
recoveryVisitor.visit(transaction);
lowestRecoveredTxId = transaction.getCommitEntry().getTxId();
reportProgress();
}
}
monitor.reverseStoreRecoveryCompleted(lowestRecoveredTxId);
// We cannot initialise the schema (tokens, schema cache, indexing service, etc.) until we have returned the store to a consistent state.
// We need to be able to read the store before we can even figure out what indexes, tokens, etc. we have. Hence we defer the initialisation
// of the schema life until after we've done the reverse recovery.
schemaLife.init();
try (var transactionsToRecover = recoveryService.getTransactions(recoveryStartPosition);
var recoveryVisitor = recoveryService.getRecoveryApplier(RECOVERY, pageCacheTracer, RECOVERY_TAG)) {
while (transactionsToRecover.next()) {
recoveryStartupChecker.checkIfCanceled();
lastTransaction = transactionsToRecover.get();
long txId = lastTransaction.getCommitEntry().getTxId();
recoveryVisitor.visit(lastTransaction);
monitor.transactionRecovered(txId);
numberOfRecoveredTransactions++;
lastTransactionPosition = transactionsToRecover.position();
recoveryToPosition = lastTransactionPosition;
reportProgress();
}
recoveryToPosition = transactionsToRecover.position();
}
} catch (Error | ClosedByInterruptException | DatabaseStartAbortedException e) {
// the users are able to workaround this if truncations is really needed.
throw e;
} catch (Throwable t) {
if (failOnCorruptedLogFiles) {
throwUnableToCleanRecover(t);
}
if (lastTransaction != null) {
LogEntryCommit commitEntry = lastTransaction.getCommitEntry();
monitor.failToRecoverTransactionsAfterCommit(t, commitEntry, recoveryToPosition);
} else {
monitor.failToRecoverTransactionsAfterPosition(t, recoveryStartPosition);
}
}
progressReporter.completed();
logsTruncator.truncate(recoveryToPosition);
}
try (var cursorContext = new CursorContext(pageCacheTracer.createPageCursorTracer(RECOVERY_COMPLETED_TAG))) {
final boolean missingLogs = recoveryStartInformation.isMissingLogs();
recoveryService.transactionsRecovered(lastTransaction, lastTransactionPosition, recoveryToPosition, recoveryStartInformation.getCheckpointPosition(), missingLogs, cursorContext);
}
monitor.recoveryCompleted(numberOfRecoveredTransactions, recoveryStartTime.elapsed(MILLISECONDS));
}
Aggregations