summaryrefslogtreecommitdiff
path: root/src/env/env_recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/env/env_recover.c')
-rw-r--r--src/env/env_recover.c130
1 files changed, 119 insertions, 11 deletions
diff --git a/src/env/env_recover.c b/src/env/env_recover.c
index 9636554a..fb7ddee7 100644
--- a/src/env/env_recover.c
+++ b/src/env/env_recover.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -18,17 +18,15 @@
#include "dbinc/qam.h"
#include "dbinc/txn.h"
-#ifndef lint
-static const char copyright[] =
- "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n";
-#endif
-
static int __db_log_corrupt __P((ENV *, DB_LSN *));
static int __env_init_rec_42 __P((ENV *));
static int __env_init_rec_43 __P((ENV *));
static int __env_init_rec_46 __P((ENV *));
static int __env_init_rec_47 __P((ENV *));
static int __env_init_rec_48 __P((ENV *));
+static int __env_init_rec_53 __P((ENV *));
+static int __env_init_rec_60 __P((ENV *));
+static int __env_init_rec_60p1 __P((ENV *));
static int __log_earliest __P((ENV *, DB_LOGC *, int32_t *, DB_LSN *));
static double __lsn_diff __P((DB_LSN *, DB_LSN *, DB_LSN *, u_int32_t, int));
@@ -632,6 +630,12 @@ err: if (logc != NULL && (t_ret = __logc_close(logc)) != 0 && ret == 0)
dbenv->tx_timestamp = 0;
+ /*
+ * Failure means that the env has panicked. Disable locking so that the
+ * env can close without its mutexes calls causing additional panics.
+ */
+ if (ret != 0)
+ F_SET(env->dbenv, DB_ENV_NOLOCKING);
F_CLR(env->lg_handle, DBLOG_RECOVER);
F_CLR(region, TXN_IN_RECOVERY);
@@ -690,7 +694,8 @@ __lsn_diff(low, high, current, max, is_forward)
* is trying to sync up with a master whose max LSN is less than this
* client's max lsn; we want to roll back everything after that.
*
- * Find the latest checkpoint whose ckp_lsn is less than the max lsn.
+ * Find the latest checkpoint less than or equal to max lsn and
+ * return the ckp_lsn from that checkpoint.
*/
static int
__log_backup(env, logc, max_lsn, start_lsn)
@@ -713,10 +718,11 @@ __log_backup(env, logc, max_lsn, start_lsn)
return (ret);
/*
* Follow checkpoints through the log until
- * we find one with a ckp_lsn less than
- * or equal max_lsn.
+ * we find one less than or equal max_lsn.
+ * Then return the ckp_lsn from that checkpoint as it
+ * is our earliest outstanding txn needed.
*/
- if (LOG_COMPARE(&ckp_args->ckp_lsn, max_lsn) <= 0) {
+ if (LOG_COMPARE(&lsn, max_lsn) <= 0) {
*start_lsn = ckp_args->ckp_lsn;
break;
}
@@ -727,7 +733,7 @@ __log_backup(env, logc, max_lsn, start_lsn)
* done. Break with DB_NOTFOUND.
*/
if (IS_ZERO_LSN(lsn)) {
- ret = DB_NOTFOUND;
+ ret = USR_ERR(env, DB_NOTFOUND);
break;
}
__os_free(env, ckp_args);
@@ -880,6 +886,9 @@ __db_log_corrupt(env, lsnp)
/*
* __env_init_rec --
*
+ * Install recover functions in the environment. Whenever this is updated,
+ * corresponding changes are needed by db_printlog's env_init_print().
+ *
* PUBLIC: int __env_init_rec __P((ENV *, u_int32_t));
*/
int
@@ -924,6 +933,29 @@ __env_init_rec(env, version)
* oldest revision that applies must be used. Therefore we override
* the recovery functions in reverse log version order.
*/
+ if (version == DB_LOGVERSION)
+ goto done;
+
+ /* DB_LOGVERSION_61 add the blob file id to the dbreg logs. */
+ if (version > DB_LOGVERSION_60p1)
+ goto done;
+ if ((ret = __env_init_rec_60p1(env)) != 0)
+ goto err;
+
+ /*
+ * DB_LOGVERSION_60p1 changed the two u_int32_t offset fields in the
+ * log for fop_write_file into a single int64.
+ */
+ if (version > DB_LOGVERSION_60)
+ goto done;
+ if ((ret = __env_init_rec_60(env)) != 0)
+ goto err;
+
+ /* DB_LOGVERSION_53 changed the heap addrem log record. */
+ if (version > DB_LOGVERSION_53)
+ goto done;
+ if ((ret = __env_init_rec_53(env)) != 0)
+ goto err;
/*
* DB_LOGVERSION_53 is a strict superset of DB_LOGVERSION_50.
* So, only check > DB_LOGVERSION_48p2. If/When log records are
@@ -931,6 +963,8 @@ __env_init_rec(env, version)
*/
if (version > DB_LOGVERSION_48p2)
goto done;
+ if (version >= DB_LOGVERSION_50)
+ goto done;
if ((ret = __env_init_rec_48(env)) != 0)
goto err;
/*
@@ -1091,3 +1125,77 @@ __env_init_rec_48(env)
err:
return (ret);
}
+
+static int
+__env_init_rec_53(env)
+ ENV *env;
+{
+ int ret;
+
+#ifdef HAVE_HEAP
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __heap_addrem_50_recover, DB___heap_addrem_50)) != 0)
+ goto err;
+#else
+ COMPQUIET(env, NULL);
+ COMPQUIET(ret, 0);
+ goto err;
+#endif
+err:
+ return (ret);
+}
+
+static int
+__env_init_rec_60(env)
+ ENV *env;
+{
+ int ret;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_create_60_recover, DB___fop_create_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_remove_60_recover, DB___fop_remove_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_rename_60_recover, DB___fop_rename_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_rename_noundo_60_recover, DB___fop_rename_noundo_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_file_remove_60_recover, DB___fop_file_remove_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_write_60_recover, DB___fop_write_60)) != 0)
+ goto err;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __fop_write_file_60_recover, DB___fop_write_file_60)) != 0)
+ goto err;
+err:
+ return (ret);
+}
+
+static int
+__env_init_rec_60p1(env)
+ ENV *env;
+{
+ int ret;
+
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __dbreg_register_42_recover, DB___dbreg_register_42)) != 0)
+ goto err;
+#ifdef HAVE_HEAP
+ if ((ret = __db_add_recovery_int(env, &env->recover_dtab,
+ __heap_addrem_60_recover, DB___heap_addrem_60)) != 0)
+ goto err;
+#endif
+err:
+ return (ret);
+}