void mur_tp_resolve_time(jnl_tm_t max_lvrec_time) { int reg_total; reg_ctl_list *rctl, *rctl_top; jnl_tm_t reg_tp_resolve_time; reg_total = murgbl.reg_total; if (mur_options.forward) { if (!mur_options.verify) { jgbl.mur_tp_resolve_time = mur_ctl[0].lvrec_time; for (rctl = mur_ctl + 1, rctl_top = mur_ctl + reg_total; rctl < rctl_top; rctl++) { if (rctl->lvrec_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = rctl->lvrec_time; } assert(jgbl.mur_tp_resolve_time); } else jgbl.mur_tp_resolve_time = 0; /* verify continues till the beginning of journal file */ return; } mur_sort_files(); jgbl.mur_tp_resolve_time = MAXUINT4; assert(max_lvrec_time == mur_ctl[reg_total - 1].lvrec_time); for (rctl = mur_ctl, rctl_top = mur_ctl + reg_total; rctl < rctl_top; rctl++) { /* Assumption : It is guaranteed to see an EPOCH in every * "rctl->jctl->jfh->epoch_interval + MAX_EPOCH_DELAY" seconds. */ assert(max_lvrec_time >= rctl->jctl->jfh->epoch_interval + MAX_EPOCH_DELAY); reg_tp_resolve_time = max_lvrec_time - rctl->jctl->jfh->epoch_interval - MAX_EPOCH_DELAY; if (rctl->lvrec_time > reg_tp_resolve_time) reg_tp_resolve_time = rctl->lvrec_time; if (reg_tp_resolve_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = reg_tp_resolve_time; assert(!mur_options.update || NULL != rctl->csd); if (mur_options.update && rctl->recov_interrupted && rctl->csd->intrpt_recov_tp_resolve_time && rctl->csd->intrpt_recov_tp_resolve_time < jgbl.mur_tp_resolve_time) /* Previous backward recovery/rollback was interrupted. * Update tp_resolve_time to reflect the minimum of the previous and * current recovery/rollback's turn-around-points. * It is possible that both rctl->csd->intrpt_recov_resync_seqno and * rctl->csd->intrpt_recov_tp_resolve_time are zero in case previous recover * was killed after mur_open_files, (which sets csd->recov_interrupted) * but before mur_back_process() which would have set csd->intrpt_recov_tp_resolve_time */ jgbl.mur_tp_resolve_time = rctl->csd->intrpt_recov_tp_resolve_time; } if (mur_options.since_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = (jnl_tm_t)mur_options.since_time; if (FENCE_NONE == mur_options.fences && !mur_options.since_time_specified && !murgbl.intrpt_recovery) jgbl.mur_tp_resolve_time = max_lvrec_time; }
void mur_tp_resolve_time(jnl_tm_t max_lvrec_time) { int reg_total; reg_ctl_list *rctl, *rctl_top; jnl_tm_t reg_tp_resolve_time; reg_total = murgbl.reg_total; if (mur_options.forward) { if (!mur_options.verify) { jgbl.mur_tp_resolve_time = mur_ctl[0].lvrec_time; for (rctl = mur_ctl + 1, rctl_top = mur_ctl + reg_total; rctl < rctl_top; rctl++) { if (rctl->lvrec_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = rctl->lvrec_time; } assert(jgbl.mur_tp_resolve_time); } else jgbl.mur_tp_resolve_time = 0; /* verify continues till the beginning of journal file */ return; } mur_sort_files(); jgbl.mur_tp_resolve_time = MAXUINT4; assert(max_lvrec_time == mur_ctl[reg_total - 1].lvrec_time); for (rctl = mur_ctl, rctl_top = mur_ctl + reg_total; rctl < rctl_top; rctl++) { /* Assumption : It is guaranteed to see an EPOCH in every * "rctl->jctl->jfh->epoch_interval + MAX_EPOCH_DELAY" seconds. */ assert(max_lvrec_time >= rctl->jctl->jfh->epoch_interval + MAX_EPOCH_DELAY); /* Calculate this region's TP resolve time based on the maximum of the last valid record across regions. If the * region is properly closed (typically this means that the journal file's crash field is FALSE. But, with online * rollback, crash field being TRUE, does not mean the journal file is crashed (as long as the shared memory for * that region existed when the region was opened). So, use jctl->properly_closed to determine whether the journal * file for the region is really crashed. If it is properly closed, the region's TP resolve time is the * max_lvrec_time. If not, we need to go back by an epoch interval in addition to the MAX_EPOCH_DELAY. */ if (!rctl->jctl->properly_closed) reg_tp_resolve_time = max_lvrec_time - rctl->jctl->jfh->epoch_interval - MAX_EPOCH_DELAY; else reg_tp_resolve_time = max_lvrec_time; if (rctl->lvrec_time > reg_tp_resolve_time) reg_tp_resolve_time = rctl->lvrec_time; if (reg_tp_resolve_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = reg_tp_resolve_time; assert(!mur_options.update || NULL != rctl->csd); if (mur_options.update && rctl->recov_interrupted && rctl->csd->intrpt_recov_tp_resolve_time && rctl->csd->intrpt_recov_tp_resolve_time < jgbl.mur_tp_resolve_time) /* Previous backward recovery/rollback was interrupted. * Update tp_resolve_time to reflect the minimum of the previous and * current recovery/rollback's turn-around-points. * It is possible that both rctl->csd->intrpt_recov_resync_seqno and * rctl->csd->intrpt_recov_tp_resolve_time are zero in case previous recover * was killed after mur_open_files, (which sets csd->recov_interrupted) * but before mur_back_process() which would have set csd->intrpt_recov_tp_resolve_time */ jgbl.mur_tp_resolve_time = rctl->csd->intrpt_recov_tp_resolve_time; } if (mur_options.since_time < jgbl.mur_tp_resolve_time) jgbl.mur_tp_resolve_time = (jnl_tm_t)mur_options.since_time; if (FENCE_NONE == mur_options.fences && !mur_options.since_time_specified && !murgbl.intrpt_recovery) jgbl.mur_tp_resolve_time = max_lvrec_time; }