* to worry about entries that are in log buffers when constructing
* the rollback information.
*/
LogManager logManager = repImpl.getLogManager();
LogEntry rollbackStart =
new SingleItemEntry(LogEntryType.LOG_ROLLBACK_START,
new RollbackStart(matchpointVLSN,
matchpointLsn,
activeTxns.keySet()));
long rollbackStartLsn =
logManager.logForceFlush(rollbackStart,
true, // fsyncRequired,
ReplicationContext.NO_REPLICATE);
rollbackStatus = RBSTATUS_LOG_RBSTART;
/*
* 2. Do rollback in memory. Undo any operations that were logged
* after the matchpointLsn, and save the LSNs for those log
* entries.. There should be something to undo, because we checked
* earlier that there were log entries after the matchpoint.
*/
List<Long> rollbackLsns = new ArrayList<Long>();
for (ReplayTxn replayTxn : activeTxns.values()) {
Collection<Long> txnRollbackLsns =
replayTxn.rollback(matchpointLsn);
/*
* Txns that were entirely rolled back should have been removed
* from the activeTxns map.
*/
assert checkRemoved(replayTxn) :
"Should have removed " + replayTxn;
rollbackLsns.addAll(txnRollbackLsns);
}
rollbackStatus = RBSTATUS_MEM_ROLLBACK;
assert rollbackLsns.size() != 0;
/*
* 3 & 4 - Mark the rolled back log entries as invisible. After all
* are done, fsync the set of files. By waiting, some may have made
* it out on their own.
*/
RollbackTracker.makeInvisible(repImpl, rollbackLsns);
rollbackStatus = RBSTATUS_INVISIBLE;
/*
* 5. Log RollbackEnd. Flush it so that we can use it to optimize
* recoveries later on. If the RollbackEnd exists, we can skip the
* step of re-making LNs invisible.
*/
logManager.logForceFlush
(new SingleItemEntry(LogEntryType.LOG_ROLLBACK_END,
new RollbackEnd(matchpointLsn,
rollbackStartLsn)),
true, // fsyncRequired
ReplicationContext.NO_REPLICATE);