29 #include "trx0purge.ic"
54 #ifdef UNIV_PFS_RWLOCK
56 UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
61 UNIV_INTERN mysql_pfs_key_t purge_sys_mutex_key;
76 #ifdef UNIV_SYNC_DEBUG
95 trx_purge_arr_store_info(
126 trx_purge_arr_remove_info(
145 trx_purge_arr_get_biggest(
170 if ((cell->
trx_no > pair_trx_no)
171 || ((cell->
trx_no == pair_trx_no)
172 && cell->
undo_no >= pair_undo_no)) {
174 pair_trx_no = cell->
trx_no;
184 *trx_no = pair_trx_no;
185 *undo_no = pair_undo_no;
194 trx_purge_graph_build(
void)
225 ut_ad(mutex_own(&kernel_mutex));
240 mutex_create(purge_sys_mutex_key,
268 ut_ad(!mutex_own(&kernel_mutex));
280 mutex_enter(&kernel_mutex);
285 mutex_exit(&kernel_mutex);
338 if (undo->
state != TRX_UNDO_CACHED) {
341 if (undo->
id >= TRX_RSEG_N_SLOTS) {
343 "InnoDB: Error: undo->id is %lu\n",
360 flst_add_first(rseg_header + TRX_RSEG_HISTORY,
362 mutex_enter(&kernel_mutex);
364 mutex_exit(&kernel_mutex);
394 trx_purge_free_segment(
398 ulint n_removed_logs)
409 ibool marked = FALSE;
417 mutex_enter(&(rseg->
mutex));
420 rseg->page_no, &mtr);
423 hdr_addr.
page, &mtr);
425 log_hdr = undo_page + hdr_addr.
boffset;
442 mutex_exit(&(rseg->
mutex));
459 flst_cut_end(rseg_hdr + TRX_RSEG_HISTORY,
462 mutex_enter(&kernel_mutex);
465 mutex_exit(&kernel_mutex);
481 ut_ad(hist_size >= seg_size);
486 ut_ad(rseg->curr_size >= seg_size);
488 rseg->curr_size -= seg_size;
490 mutex_exit(&(rseg->
mutex));
499 trx_purge_truncate_rseg_history(
514 ulint n_removed_logs = 0;
521 mutex_enter(&(rseg->
mutex));
524 rseg->page_no, &mtr);
531 mutex_exit(&(rseg->
mutex));
539 hdr_addr.
page, &mtr);
541 log_hdr = undo_page + hdr_addr.
boffset;
544 if (undo_trx_no >= limit_trx_no) {
545 if (undo_trx_no == limit_trx_no) {
552 mutex_enter(&kernel_mutex);
555 mutex_exit(&kernel_mutex);
557 flst_truncate_end(rseg_hdr + TRX_RSEG_HISTORY,
559 n_removed_logs, &mtr);
561 mutex_exit(&(rseg->
mutex));
578 mutex_exit(&(rseg->
mutex));
581 trx_purge_free_segment(rseg, hdr_addr, n_removed_logs);
585 mutex_exit(&(rseg->
mutex));
590 mutex_enter(&(rseg->
mutex));
593 rseg->page_no, &mtr);
595 hdr_addr = prev_hdr_addr;
605 trx_purge_truncate_history(
void)
614 trx_purge_arr_get_biggest(
purge_sys->
arr, &limit_trx_no,
617 if (limit_trx_no == 0) {
631 ut_ad(limit_trx_no <= purge_sys->view->low_limit_no);
636 trx_purge_truncate_rseg_history(rseg, limit_trx_no,
648 trx_purge_truncate_if_arr_empty(
void)
655 trx_purge_truncate_history();
668 trx_purge_rseg_get_next_history_log(
681 mutex_enter(&(rseg->
mutex));
706 mutex_exit(&(rseg->
mutex));
709 mutex_enter(&kernel_mutex);
722 " InnoDB: Warning: purge reached the"
723 " head of the history list,\n"
724 "InnoDB: but its length is still"
725 " reported as %lu! Make a detailed bug\n"
726 "InnoDB: report, and submit it"
727 " to http://bugs.mysql.com\n",
731 mutex_exit(&kernel_mutex);
736 mutex_exit(&(rseg->
mutex));
743 prev_log_addr.
page, &mtr)
752 mutex_enter(&(rseg->
mutex));
759 mutex_exit(&(rseg->
mutex));
769 trx_purge_choose_next_log(
void)
787 min_trx_no = IB_ULONGLONG_MAX;
792 mutex_enter(&(rseg->
mutex));
802 zip_size = rseg->zip_size;
811 mutex_exit(&(rseg->
mutex));
816 if (min_rseg == NULL) {
845 if (rec == &trx_purge_dummy_rec) {
865 trx_purge_get_next_rec(
899 trx_purge_choose_next_log();
901 return(&trx_purge_dummy_rec);
908 rec = undo_page + offset;
919 if (next_rec == NULL) {
930 if (type == TRX_UNDO_DEL_MARK_REC) {
941 if ((type == TRX_UNDO_UPD_EXIST_REC)
942 && !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
954 trx_purge_choose_next_log();
961 rec = undo_page + offset;
969 if (undo_page != page) {
1001 trx_purge_truncate_if_arr_empty();
1009 trx_purge_choose_next_log();
1014 trx_purge_truncate_if_arr_empty();
1016 if (srv_print_thread_releases) {
1018 "Purge: No logs left in the"
1019 " history list; pages handled %lu\n",
1033 trx_purge_truncate_if_arr_empty();
1043 trx_purge_truncate_if_arr_empty();
1067 undo_rec = trx_purge_get_next_rec(heap);
1084 trx_purge_arr_remove_info(cell);
1101 ulint old_pages_handled;
1121 mutex_enter(&kernel_mutex);
1132 srv_dml_needed_delay = 0;
1137 if (srv_max_purge_lag > 0
1140 / srv_max_purge_lag;
1141 if (ratio > ULINT_MAX / 10000) {
1143 srv_dml_needed_delay = ULINT_MAX;
1144 }
else if (ratio > 1) {
1149 srv_dml_needed_delay = (ulint) ((ratio - .5) * 10000);
1155 mutex_exit(&kernel_mutex);
1167 mutex_enter(&kernel_mutex);
1178 mutex_exit(&kernel_mutex);
1182 if (srv_print_thread_releases) {
1184 fputs(
"Starting purge\n", stderr);
1189 if (srv_print_thread_releases) {
1192 "Purge ends; pages handled %lu\n",
1206 fprintf(stderr,
"InnoDB: Purge system view:\n");
1209 fprintf(stderr,
"InnoDB: Purge trx n:o " TRX_ID_FMT
1214 "InnoDB: Purge next stored %lu, page_no %lu, offset %lu,\n"
1215 "InnoDB: Purge hdr_page_no %lu, hdr_offset %lu\n",