summaryrefslogtreecommitdiff
path: root/src/txn/txn_recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/txn/txn_recover.c')
-rw-r--r--src/txn/txn_recover.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/txn/txn_recover.c b/src/txn/txn_recover.c
index e6bd8a8d755..1ea4dba1152 100644
--- a/src/txn/txn_recover.c
+++ b/src/txn/txn_recover.c
@@ -88,11 +88,11 @@ __recovery_cursor(WT_SESSION_IMPL *session, WT_RECOVERY *r,
* Helper to a cursor if this operation is to be applied during recovery.
*/
#define GET_RECOVERY_CURSOR(session, r, lsnp, fileid, cp) \
- WT_ERR(__recovery_cursor( \
- (session), (r), (lsnp), (fileid), false, (cp))); \
- WT_ERR(__wt_verbose((session), WT_VERB_RECOVERY, \
- "%s op %d to file %d at LSN %u/%u", \
- (cursor == NULL) ? "Skipping" : "Applying", \
+ WT_ERR(__recovery_cursor(session, r, lsnp, fileid, false, cp)); \
+ WT_ERR(__wt_verbose(session, WT_VERB_RECOVERY, \
+ "%s op %" PRIu32 " to file %" PRIu32 " at LSN %" PRIu32 \
+ "/%" PRIu32, \
+ cursor == NULL ? "Skipping" : "Applying", \
optype, fileid, lsnp->l.file, lsnp->l.offset)); \
if (cursor == NULL) \
break
@@ -334,7 +334,7 @@ __recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config)
r->files[fileid].ckpt_lsn = lsn;
WT_RET(__wt_verbose(r->session, WT_VERB_RECOVERY,
- "Recovering %s with id %u @ (%" PRIu32 ", %" PRIu32 ")",
+ "Recovering %s with id %" PRIu32 " @ (%" PRIu32 ", %" PRIu32 ")",
uri, fileid, lsn.l.file, lsn.l.offset));
return (0);
@@ -449,6 +449,18 @@ __wt_txn_recover(WT_SESSION_IMPL *session)
*/
if (!was_backup) {
r.metadata_only = true;
+ /*
+ * If this is a read-only connection, check if the checkpoint
+ * LSN in the metadata file is up to date, indicating a clean
+ * shutdown.
+ */
+ if (F_ISSET(conn, WT_CONN_READONLY)) {
+ WT_ERR(__wt_log_needs_recovery(
+ session, &metafile->ckpt_lsn, &needs_rec));
+ if (needs_rec)
+ WT_ERR_MSG(session, WT_RUN_RECOVERY,
+ "Read-only database needs recovery");
+ }
if (WT_IS_INIT_LSN(&metafile->ckpt_lsn))
WT_ERR(__wt_log_scan(session,
NULL, WT_LOGSCAN_FIRST, __txn_log_recover, &r));
@@ -484,7 +496,7 @@ __wt_txn_recover(WT_SESSION_IMPL *session)
*/
r.metadata_only = false;
WT_ERR(__wt_verbose(session, WT_VERB_RECOVERY,
- "Main recovery loop: starting at %u/%u",
+ "Main recovery loop: starting at %" PRIu32 "/%" PRIu32,
r.ckpt_lsn.l.file, r.ckpt_lsn.l.offset));
WT_ERR(__wt_log_needs_recovery(session, &r.ckpt_lsn, &needs_rec));
/*
@@ -492,8 +504,17 @@ __wt_txn_recover(WT_SESSION_IMPL *session)
* return an error if the user does not want automatic
* recovery.
*/
- if (needs_rec && FLD_ISSET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR))
+ if (needs_rec &&
+ (FLD_ISSET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR) ||
+ F_ISSET(conn, WT_CONN_READONLY))) {
+ if (F_ISSET(conn, WT_CONN_READONLY))
+ WT_ERR_MSG(session, WT_RUN_RECOVERY,
+ "Read-only database needs recovery");
WT_ERR(WT_RUN_RECOVERY);
+ }
+
+ if (F_ISSET(conn, WT_CONN_READONLY))
+ goto done;
/*
* Recovery can touch more data than fits in cache, so it relies on
@@ -504,7 +525,8 @@ __wt_txn_recover(WT_SESSION_IMPL *session)
eviction_started = true;
/*
- * Always run recovery even if it was a clean shutdown.
+ * Always run recovery even if it was a clean shutdown only if
+ * this is not a read-only connection.
* We can consider skipping it in the future.
*/
if (WT_IS_INIT_LSN(&r.ckpt_lsn))