* Generate a map of nodeId->List of intermediate LSNs for this node.
* to re-create the transaction chain.
*/
TreeLocation location = new TreeLocation();
Long undoLsn = lastLoggedLsn;
TxnChain chain =
new TxnChain(undoLsn, id, matchpointLsn, undoDatabases, envImpl);
try {
while ((undoLsn != DbLsn.NULL_LSN) &&
DbLsn.compareTo(undoLsn, matchpointLsn) > 0) {
UndoReader undo =
new UndoReader(envImpl, undoLsn, undoDatabases);
RevertInfo revertTo = chain.pop();
logFinest(undoLsn, undo, revertTo);
/*
* When we undo this log entry, we've logically truncated
* it from the log. Remove it from the btree and mark it
* obsolete.
*/
RecoveryManager.rollbackUndo
(logger, Level.FINER, undo, revertTo, location, undoLsn);
countObsoleteInexact(undoLsn, undo);
rollbackLsns.add(undoLsn);
/*
* Move on to the previous log entry for this txn and update
* what is considered to be the end of the transaction chain.
*/
undoLsn = undo.logEntry.getUserTxn().getLastLsn();
lastLoggedLsn = undoLsn;
}
/*
* Correct the fields which hold LSN and VLSN state that may
* now be changed.
*/
lastApplied = chain.getLastValidVLSN();
if (!updateLoggedForTxn()) {
firstLoggedLsn = NULL_LSN;
}
} catch (DatabaseException e) {
LoggerUtils.traceAndLogException(envImpl, "Txn", "undo",
"For LSN=" +
DbLsn.getNoFormatString(undoLsn), e);
throw e;
} catch (RuntimeException e) {
throw EnvironmentFailureException.unexpectedException
("Txn undo for LSN=" + DbLsn.getNoFormatString(undoLsn), e);
}
if (lastLoggedLsn == DbLsn.NULL_LSN) {
/*
* The whole txn is rolled back, and it may not appear again. This
* is the equivalent of an abort. Do any delete processing for an
* abort which is needed.
*
* Set database state for deletes before releasing any write
* locks.
*/
setDeletedDatabaseState(false);
}
/* Clear any write locks that are no longer needed. */
clearWriteLocks(chain.getRemainingLockedNodes());
}