private void findLastCheckpoint()
throws IOException, DatabaseException {
startupTracker.start(Phase.FIND_LAST_CKPT);
startupTracker.setProgress(RecoveryProgress.FIND_LAST_CKPT);
Counter counter = startupTracker.getCounter(Phase.FIND_LAST_CKPT);
/*
* The checkpointLsn might have been already found when establishing
* the end of the log. If it was found, then partialCheckpointStartLsn
* was also found. If it was not found, search backwards for it now
* and also set partialCheckpointStartLsn.
*/
if (info.checkpointEndLsn == DbLsn.NULL_LSN) {
/*
* Search backwards though the log for a checkpoint end entry and a
* root entry.
*/
CheckpointFileReader searcher =
new CheckpointFileReader(envImpl, readBufferSize, false,
info.lastUsedLsn, DbLsn.NULL_LSN,
info.nextAvailableLsn);
while (searcher.readNextEntry()) {
counter.incNumRead();
counter.incNumProcessed();
/*
* Continue iterating until we find a checkpoint end entry.
* While we're at it, remember the last root seen in case we
* don't find a checkpoint end entry.
*/
if (searcher.isCheckpointEnd()) {
/*
* We're done, the checkpoint end will tell us where the
* root is.
*/
info.checkpointEndLsn = searcher.getLastLsn();
break;
} else if (searcher.isCheckpointStart()) {
/*
* Remember the first CkptStart following the CkptEnd.
*/
info.partialCheckpointStartLsn = searcher.getLastLsn();
} else if (searcher.isDbTree()) {
/*
* Save the last root that was found in the log in case we
* don't see a checkpoint.
*/
if (info.useRootLsn == DbLsn.NULL_LSN) {
info.useRootLsn = searcher.getLastLsn();
}
}
}
counter.setRepeatIteratorReads(searcher.getNRepeatIteratorReads());
}
/*
* If we haven't found a checkpoint, we'll have to recover without
* one. At a minimium, we must have found a root.