logFactory.openForwardsScan(
undoInstant,(LogInstant)null);
}
else
{
undoScan.resetPosition(new LogCounter(undoInstant));
}
// undoScan now positioned at the beginning of the log
// record was rolled back by this CLR.
// The scan is a forward one so getNextRecord will get
// the log record that needs to be rolled back.
// reuse the buffer in logIn and logIn since CLR
// has no optional data and has no use for them anymore
logIn.clearLimit();
LogRecord undoRecord =
undoScan.getNextRecord(logIn, null, 0);
Undoable undoOp = undoRecord.getUndoable();
if (SanityManager.DEBUG)
{
SanityManager.DEBUG(
LogToFile.DBG_FLAG,
"Redoing CLR: undoInstant = " +
LogCounter.toDebugString(undoInstant) +
" clrinstant = " +
LogCounter.toDebugString(instant));
SanityManager.ASSERT(
undoRecord.getTransactionId().equals(tranId));
SanityManager.ASSERT(undoOp != null);
}
((Compensation)op).setUndoOp(undoOp);
}
// at this point, logIn points to the optional
// data of the loggable that is to be redone or to be
// rolled back
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
{
SanityManager.DEBUG(
LogToFile.DBG_FLAG,
"redoing " + op +
" instant = " +
LogCounter.toDebugString(instant));
}
}
int dataLength = logIn.readInt();
logIn.setLimit(dataLength);
// even though the log has already been written, we need to
// tie the page to the log stream so that if redo failed
// for some reasons, the log factory's corruption will stop
// the corrupt page from flushing to disk.
op.doMe(
recoveryTransaction,
new LogCounter(instant), logIn);
op.releaseResource(recoveryTransaction);
op = null;
}