/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998
* Sleepycat Software. All rights reserved.
*/
#include "config.h"
#ifndef lint
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <errno.h>
#include <string.h>
#endif
#include "db_int.h"
#include "shqueue.h"
#include "log.h"
#include "txn.h"
#include "common_ext.h"
/*
* __log_findckp --
*
* Looks for the most recent checkpoint that occurs before the most recent
* checkpoint LSN, subject to the constraint that there must be at least two
* checkpoints. The reason you need two checkpoints is that you might have
* crashed during the most recent one and may not have a copy of all the
* open files. This is the point from which recovery can start and the
* point up to which archival/truncation can take place. Checkpoints in
* the log look like:
*
* -------------------------------------------------------------------
* | ckp A, ckplsn 100 | .... record .... | ckp B, ckplsn 600 | ...
* -------------------------------------------------------------------
* LSN 500 LSN 1000
*
* If we read what log returns from using the DB_CKP parameter to logput,
* we'll get the record at LSN 1000. The checkpoint LSN there is 600.
* Now we have to scan backwards looking for a checkpoint before LSN 600.
* We find one at 500. This means that we can truncate the log before
* 500 or run recovery beginning at 500.
*
* Returns 0 if we find a suitable checkpoint or we retrieved the
* first record in the log from which to start.
* Returns DB_NOTFOUND if there are no log records.
* Returns errno on error.
*
* PUBLIC: int __log_findckp __P((DB_LOG *, DB_LSN *));
*/
int
{
/*
* Need to find the appropriate point from which to begin
* recovery.
*/
goto get_first;
else
return (ret);
do {
return (ret);
return (ret);
}
if (IS_ZERO_LSN(ckp_lsn))
if (verbose) {
}
/*
* Keep looping until either you 1) run out of checkpoints,
* 2) you've found a checkpoint before the most recent
* checkpoint's LSN and you have at least 2 checkpoints.
*/
} while (!IS_ZERO_LSN(next_lsn) &&
/*
* At this point, either, next_lsn is ZERO or ckp_lsn is the
* checkpoint lsn and last_ckp is the LSN of the last checkpoint
* before ckp_lsn. If the compare in the loop is still true, then
* next_lsn must be 0 and we need to roll forward from the
* beginning of the log.
*/
return (ret);
}
}