diff options
Diffstat (limited to 'src/env/env_recover.c')
-rw-r--r-- | src/env/env_recover.c | 130 |
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); +} |