throws IOException, DatabaseException {
startupTracker.start(Phase.FIND_END_OF_LOG);
startupTracker.setProgress(RecoveryProgress.FIND_END_OF_LOG);
Counter counter = startupTracker.getCounter(Phase.FIND_END_OF_LOG);
LastFileReader reader = new LastFileReader(envImpl, readBufferSize);
/*
* Tell the reader to iterate through the log file until we hit the end
* of the log or an invalid entry. Remember the last seen CkptEnd, and
* the first CkptStart with no following CkptEnd.
*/
while (reader.readNextEntry()) {
counter.incNumRead();
counter.incNumProcessed();
LogEntryType type = reader.getEntryType();
if (LogEntryType.LOG_CKPT_END.equals(type)) {
info.checkpointEndLsn = reader.getLastLsn();
info.partialCheckpointStartLsn = DbLsn.NULL_LSN;
} else if (LogEntryType.LOG_CKPT_START.equals(type)) {
if (info.partialCheckpointStartLsn == DbLsn.NULL_LSN) {
info.partialCheckpointStartLsn = reader.getLastLsn();
}
} else if (LogEntryType.LOG_DBTREE.equals(type)) {
info.useRootLsn = reader.getLastLsn();
}
}
/*
* The last valid LSN should point to the start of the last valid log
* entry, while the end of the log should point to the first byte of
* blank space, so these two should not be the same.
*/
assert (reader.getLastValidLsn() != reader.getEndOfLog()):
"lastUsed=" + DbLsn.getNoFormatString(reader.getLastValidLsn()) +
" end=" + DbLsn.getNoFormatString(reader.getEndOfLog());
/* Now truncate if necessary. */
if (!readOnly) {
reader.setEndOfFile();
}
/* Tell the fileManager where the end of the log is. */
info.lastUsedLsn = reader.getLastValidLsn();
info.nextAvailableLsn = reader.getEndOfLog();
counter.setRepeatIteratorReads(reader.getNRepeatIteratorReads());
envImpl.getFileManager().setLastPosition(info.nextAvailableLsn,
info.lastUsedLsn,
reader.getPrevOffset());
startupTracker.stop(Phase.FIND_END_OF_LOG);
}