/********************************************************************//**
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
    /*=================================*/
    trx_t*	trx,		/*!< in: transaction */
    page_t*	undo_page,	/*!< in: update undo log header page,
				x-latched */
    mtr_t*	mtr)		/*!< in: mtr */
{
    trx_undo_t*	undo;
    trx_rsegf_t*	rseg_header;
    trx_ulogf_t*	undo_header;

    undo = trx->update_undo;

    ut_ad(undo);

    ut_ad(mutex_own(&undo->rseg->mutex));

    rseg_header = trx_rsegf_get(
                      undo->rseg->space, undo->rseg->zip_size, undo->rseg->page_no,
                      mtr);

    undo_header = undo_page + undo->hdr_offset;
    /* Add the log as the first in the history list */

    if (undo->state != TRX_UNDO_CACHED) {
        ulint		hist_size;
#ifdef UNIV_DEBUG
        trx_usegf_t*	seg_header = undo_page + TRX_UNDO_SEG_HDR;
#endif /* UNIV_DEBUG */

        /* The undo log segment will not be reused */

        if (UNIV_UNLIKELY(undo->id >= TRX_RSEG_N_SLOTS)) {
            fprintf(stderr,
                    "InnoDB: Error: undo->id is %lu\n",
                    (ulong) undo->id);
            ut_error;
        }

        trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr);

        hist_size = mtr_read_ulint(
                        rseg_header + TRX_RSEG_HISTORY_SIZE, MLOG_4BYTES, mtr);

        ut_ad(undo->size == flst_get_len(
                  seg_header + TRX_UNDO_PAGE_LIST, mtr));

        mlog_write_ulint(
            rseg_header + TRX_RSEG_HISTORY_SIZE,
            hist_size + undo->size, MLOG_4BYTES, mtr);
    }

    flst_add_first(
        rseg_header + TRX_RSEG_HISTORY,
        undo_header + TRX_UNDO_HISTORY_NODE, mtr);

    /* Write the trx number to the undo log header */

    mlog_write_ull(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr);

    /* Write information about delete markings to the undo log header */

    if (!undo->del_marks) {
        mlog_write_ulint(
            undo_header + TRX_UNDO_DEL_MARKS, FALSE,
            MLOG_2BYTES, mtr);
    }

    if (undo->rseg->last_page_no == FIL_NULL) {
        undo->rseg->last_trx_no = trx->no;
        undo->rseg->last_offset = undo->hdr_offset;
        undo->rseg->last_page_no = undo->hdr_page_no;
        undo->rseg->last_del_marks = undo->del_marks;

        /* FIXME: Add a bin heap validate function to check that
        the rseg exists. */
    }

    mutex_enter(&kernel_mutex);
    trx_sys->rseg_history_len++;
    mutex_exit(&kernel_mutex);

//	if (!(trx_sys->rseg_history_len % srv_purge_batch_size)) { /*should wake up always*/
    /* Inform the purge thread that there is work to do. */
    srv_wake_purge_thread_if_not_active();
//	}
}
Beispiel #2
0
/********************************************************************//**
Adds the update undo log as the first log in the history list. Removes the
update undo log segment from the rseg slot if it is too big for reuse. */
UNIV_INTERN
void
trx_purge_add_update_undo_to_history(
/*=================================*/
	trx_t*	trx,		/*!< in: transaction */
	page_t*	undo_page,	/*!< in: update undo log header page,
				x-latched */
	mtr_t*	mtr)		/*!< in: mtr */
{
	trx_undo_t*	undo;
	trx_rseg_t*	rseg;
	trx_rsegf_t*	rseg_header;
#ifdef UNIV_DEBUG
	trx_usegf_t*	seg_header;
#endif /* UNIV_DEBUG */
	trx_ulogf_t*	undo_header;
	ulint		hist_size;

	undo = trx->update_undo;

	ut_ad(undo);

	rseg = undo->rseg;

	ut_ad(mutex_own(&(rseg->mutex)));

	rseg_header = trx_rsegf_get(rseg->space, rseg->zip_size,
				    rseg->page_no, mtr);

	undo_header = undo_page + undo->hdr_offset;
#ifdef UNIV_DEBUG
	seg_header  = undo_page + TRX_UNDO_SEG_HDR;
#endif /* UNIV_DEBUG */

	if (undo->state != TRX_UNDO_CACHED) {
		/* The undo log segment will not be reused */

		if (undo->id >= TRX_RSEG_N_SLOTS) {
			fprintf(stderr,
				"InnoDB: Error: undo->id is %lu\n",
				(ulong) undo->id);
			ut_error;
		}

		trx_rsegf_set_nth_undo(rseg_header, undo->id, FIL_NULL, mtr);

		hist_size = mtr_read_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
					   MLOG_4BYTES, mtr);
		ut_ad(undo->size == flst_get_len(
			      seg_header + TRX_UNDO_PAGE_LIST, mtr));

		mlog_write_ulint(rseg_header + TRX_RSEG_HISTORY_SIZE,
				 hist_size + undo->size, MLOG_4BYTES, mtr);
	}

	/* Add the log as the first in the history list */
	flst_add_first(rseg_header + TRX_RSEG_HISTORY,
		       undo_header + TRX_UNDO_HISTORY_NODE, mtr);
	mutex_enter(&kernel_mutex);
	trx_sys->rseg_history_len++;
	mutex_exit(&kernel_mutex);

	/* Write the trx number to the undo log header */
	mlog_write_dulint(undo_header + TRX_UNDO_TRX_NO, trx->no, mtr);
	/* Write information about delete markings to the undo log header */

	if (!undo->del_marks) {
		mlog_write_ulint(undo_header + TRX_UNDO_DEL_MARKS, FALSE,
				 MLOG_2BYTES, mtr);
	}

	if (rseg->last_page_no == FIL_NULL) {

		rseg->last_page_no = undo->hdr_page_no;
		rseg->last_offset = undo->hdr_offset;
		rseg->last_trx_no = trx->no;
		rseg->last_del_marks = undo->del_marks;
	}
}