/********************************************************************//** Fetches the next undo log record from the history list to purge. It must be released with the corresponding release function. @return copy of an undo log record or pointer to trx_purge_dummy_rec, if the whole undo log can skipped in purge; NULL if none left */ UNIV_INTERN trx_undo_rec_t* trx_purge_fetch_next_rec( /*=====================*/ roll_ptr_t* roll_ptr,/*!< out: roll pointer to undo record */ trx_undo_inf_t** cell, /*!< out: storage cell for the record in the purge array */ mem_heap_t* heap) /*!< in: memory heap where copied */ { trx_undo_rec_t* undo_rec; if (purge_sys->state == TRX_STOP_PURGE) { trx_purge_truncate_if_arr_empty(); return(NULL); } else if (!purge_sys->next_stored) { trx_purge_choose_next_log(); if (!purge_sys->next_stored) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); if (srv_print_thread_releases) { fprintf(stderr, "Purge: No logs left in the" " history list; pages handled %lu\n", (ulong) purge_sys->n_pages_handled); } return(NULL); } } if (purge_sys->n_pages_handled >= purge_sys->handle_limit) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); return(NULL); } else if (purge_sys->purge_trx_no >= purge_sys->view->low_limit_no) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); return(NULL); } /* fprintf(stderr, "Thread %lu purging trx %llu undo record %llu\n", os_thread_get_curr_id(), (ullint) purge_sys->purge_trx_no, (ullint) purge_sys->purge_undo_no); */ *roll_ptr = trx_undo_build_roll_ptr( FALSE, (purge_sys->rseg)->id, purge_sys->page_no, purge_sys->offset); *cell = trx_purge_arr_store_info( purge_sys->purge_trx_no, purge_sys->purge_undo_no); ut_ad(purge_sys->purge_trx_no < purge_sys->view->low_limit_no); /* The following call will advance the stored values of purge_trx_no and purge_undo_no, therefore we had to store them first */ undo_rec = trx_purge_get_next_rec(heap); return(undo_rec); }
trx_undo_rec_t* trx_purge_fetch_next_rec( /*=====================*/ /* out: copy of an undo log record or pointer to the dummy undo log record &trx_purge_dummy_rec, if the whole undo log can skipped in purge; NULL if none left */ dulint* roll_ptr,/* out: roll pointer to undo record */ trx_undo_inf_t** cell, /* out: storage cell for the record in the purge array */ mem_heap_t* heap) /* in: memory heap where copied */ { trx_undo_rec_t* undo_rec; mutex_enter(&(purge_sys->mutex)); if (purge_sys->state == TRX_STOP_PURGE) { trx_purge_truncate_if_arr_empty(); mutex_exit(&(purge_sys->mutex)); return(NULL); } if (!purge_sys->next_stored) { trx_purge_choose_next_log(); if (!purge_sys->next_stored) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); if (srv_print_thread_releases) { fprintf(stderr, "Purge: No logs left in the" " history list; pages handled %lu\n", (ulong) purge_sys->n_pages_handled); } mutex_exit(&(purge_sys->mutex)); return(NULL); } } if (purge_sys->n_pages_handled >= purge_sys->handle_limit) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); mutex_exit(&(purge_sys->mutex)); return(NULL); } if (ut_dulint_cmp(purge_sys->purge_trx_no, purge_sys->view->low_limit_no) >= 0) { purge_sys->state = TRX_STOP_PURGE; trx_purge_truncate_if_arr_empty(); mutex_exit(&(purge_sys->mutex)); return(NULL); } /* fprintf(stderr, "Thread %lu purging trx %lu undo record %lu\n", os_thread_get_curr_id(), ut_dulint_get_low(purge_sys->purge_trx_no), ut_dulint_get_low(purge_sys->purge_undo_no)); */ *roll_ptr = trx_undo_build_roll_ptr(FALSE, (purge_sys->rseg)->id, purge_sys->page_no, purge_sys->offset); *cell = trx_purge_arr_store_info(purge_sys->purge_trx_no, purge_sys->purge_undo_no); ut_ad(ut_dulint_cmp(purge_sys->purge_trx_no, (purge_sys->view)->low_limit_no) < 0); /* The following call will advance the stored values of purge_trx_no and purge_undo_no, therefore we had to store them first */ undo_rec = trx_purge_get_next_rec(heap); mutex_exit(&(purge_sys->mutex)); return(undo_rec); }