Example #1
0
/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
void
trx_purge_sys_create(
/*=================*/
	ib_bh_t*	ib_bh)	/*!< in, own: UNDO log min binary heap */
{
	ut_ad(mutex_own(&kernel_mutex));

	purge_sys = mem_zalloc(sizeof(trx_purge_t));

	/* Take ownership of ib_bh, we are responsible for freeing it. */
	purge_sys->ib_bh = ib_bh;
	purge_sys->state = TRX_STOP_PURGE;

	purge_sys->n_pages_handled = 0;

	purge_sys->purge_trx_no = 0;
	purge_sys->purge_undo_no = 0;
	purge_sys->next_stored = FALSE;
	ut_d(purge_sys->done_trx_no = 0);

	rw_lock_create(trx_purge_latch_key,
		       &purge_sys->latch, SYNC_PURGE_LATCH);

	mutex_create(
		purge_sys_bh_mutex_key, &purge_sys->bh_mutex,
		SYNC_PURGE_QUEUE);

	purge_sys->heap = mem_heap_create(256);

	purge_sys->arr = trx_undo_arr_create();

	purge_sys->sess = sess_open();

	purge_sys->trx = purge_sys->sess->trx;

	purge_sys->trx->is_purge = 1;

	ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));

	purge_sys->query = trx_purge_graph_build();

	purge_sys->prebuilt_view =
		read_view_oldest_copy_or_open_new(0, NULL);
	purge_sys->view = purge_sys->prebuilt_view;
}
Example #2
0
/********************************************************************//**
Creates the global purge system control structure and inits the history
mutex. */
UNIV_INTERN
void
trx_purge_sys_create(void)
/*======================*/
{
	ut_ad(mutex_own(&kernel_mutex));

	purge_sys = mem_alloc(sizeof(trx_purge_t));

	purge_sys->state = TRX_STOP_PURGE;

	purge_sys->n_pages_handled = 0;

	purge_sys->purge_trx_no = ut_dulint_zero;
	purge_sys->purge_undo_no = ut_dulint_zero;
	purge_sys->next_stored = FALSE;
	ut_d(purge_sys->done_trx_no = ut_dulint_zero);

	rw_lock_create(&purge_sys->latch, SYNC_PURGE_LATCH);

	mutex_create(&purge_sys->mutex, SYNC_PURGE_SYS);

	purge_sys->heap = mem_heap_create(256);

	purge_sys->arr = trx_undo_arr_create();

	purge_sys->sess = sess_open();

	purge_sys->trx = purge_sys->sess->trx;

	purge_sys->trx->is_purge = 1;

	ut_a(trx_start_low(purge_sys->trx, ULINT_UNDEFINED));

	purge_sys->query = trx_purge_graph_build();

	purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
							    purge_sys->heap);
}
/*******************************************************************//**
This function runs a purge batch.
@return	number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(
    /*======*/
    ulint	limit)		/*!< in: the maximum number of records to
				purge in one batch */
{
    que_thr_t*	thr;
    ulint		old_pages_handled;

    if (srv_fake_write)
        return(0);

    ut_a(purge_sys->trx->n_active_thrs == 0);

    rw_lock_x_lock(&purge_sys->latch);

    mutex_enter(&kernel_mutex);

    /* Close and free the old purge view */

    read_view_close(purge_sys->view);
    purge_sys->view = NULL;
    mem_heap_empty(purge_sys->heap);

    /* Determine how much data manipulation language (DML) statements
    need to be delayed in order to reduce the lagging of the purge
    thread. */
    srv_dml_needed_delay = 0; /* in microseconds; default: no delay */

    /* If we cannot advance the 'purge view' because of an old
    'consistent read view', then the DML statements cannot be delayed.
    Also, srv_max_purge_lag <= 0 means 'infinity'. */
    if (srv_max_purge_lag > 0) {
        float	ratio = (float) trx_sys->rseg_history_len
                        / srv_max_purge_lag;
        if (ratio > ULINT_MAX / 10000) {
            /* Avoid overflow: maximum delay is 4295 seconds */
            srv_dml_needed_delay = ULINT_MAX;
        } else if (ratio > 1) {
            /* If the history list length exceeds the
            innodb_max_purge_lag, the
            data manipulation statements are delayed
            by at least 5000 microseconds. */
            srv_dml_needed_delay = (ulint) ((ratio - .5) * 10000);
        }
    }

    purge_sys->view = read_view_oldest_copy_or_open_new(
                          0, purge_sys->heap);

    mutex_exit(&kernel_mutex);

    rw_lock_x_unlock(&(purge_sys->latch));

    purge_sys->state = TRX_PURGE_ON;

    purge_sys->handle_limit = purge_sys->n_pages_handled + limit;

    old_pages_handled = purge_sys->n_pages_handled;


    mutex_enter(&kernel_mutex);

    thr = que_fork_start_command(purge_sys->query);

    ut_ad(thr);

    mutex_exit(&kernel_mutex);

    if (srv_print_thread_releases) {

        fputs("Starting purge\n", stderr);
    }

    que_run_threads(thr);

    if (srv_print_thread_releases) {

        fprintf(stderr,
                "Purge ends; pages handled %lu\n",
                (ulong) purge_sys->n_pages_handled);
    }

    return(purge_sys->n_pages_handled - old_pages_handled);
}
Example #4
0
/*******************************************************************//**
This function runs a purge batch.
@return	number of undo log pages handled in the batch */
UNIV_INTERN
ulint
trx_purge(void)
/*===========*/
{
	que_thr_t*	thr;
	/*	que_thr_t*	thr2; */
	ulonglong	old_pages_handled;

	mutex_enter(&(purge_sys->mutex));

	if (purge_sys->trx->n_active_thrs > 0) {

		mutex_exit(&(purge_sys->mutex));

		/* Should not happen */

		ut_error;

		return(0);
	}

	rw_lock_x_lock(&(purge_sys->latch));

	mutex_enter(&kernel_mutex);

	/* Close and free the old purge view */

	read_view_close(purge_sys->view);
	purge_sys->view = NULL;
	mem_heap_empty(purge_sys->heap);

	/* Determine how much data manipulation language (DML) statements
	need to be delayed in order to reduce the lagging of the purge
	thread. */
	srv_dml_needed_delay = 0; /* in microseconds; default: no delay */

	/* If we cannot advance the 'purge view' because of an old
	'consistent read view', then the DML statements cannot be delayed.
	Also, srv_max_purge_lag <= 0 means 'infinity'. */
	if (srv_max_purge_lag > 0
	    && !UT_LIST_GET_LAST(trx_sys->view_list)) {
		float	ratio = (float) trx_sys->rseg_history_len
			/ srv_max_purge_lag;
		if (ratio > ULINT_MAX / 10000) {
			/* Avoid overflow: maximum delay is 4295 seconds */
			srv_dml_needed_delay = ULINT_MAX;
		} else if (ratio > 1) {
			/* If the history list length exceeds the
			innodb_max_purge_lag, the
			data manipulation statements are delayed
			by at least 5000 microseconds. */
			srv_dml_needed_delay = (ulint) ((ratio - .5) * 10000);
		}
	}

	purge_sys->view = read_view_oldest_copy_or_open_new(ut_dulint_zero,
							    purge_sys->heap);
	mutex_exit(&kernel_mutex);

	rw_lock_x_unlock(&(purge_sys->latch));

#ifdef UNIV_DEBUG
	if (srv_purge_view_update_only_debug) {
		mutex_exit(&(purge_sys->mutex));
		return(0);
	}
#endif

	purge_sys->state = TRX_PURGE_ON;

	/* Handle at most 20 undo log pages in one purge batch */

	purge_sys->handle_limit = purge_sys->n_pages_handled + 20;

	old_pages_handled = purge_sys->n_pages_handled;

	mutex_exit(&(purge_sys->mutex));

	mutex_enter(&kernel_mutex);

	thr = que_fork_start_command(purge_sys->query);

	ut_ad(thr);

	/*	thr2 = que_fork_start_command(purge_sys->query);

	ut_ad(thr2); */


	mutex_exit(&kernel_mutex);

	/*	srv_que_task_enqueue(thr2); */

	if (srv_print_thread_releases) {

		fputs("Starting purge\n", stderr);
	}

	que_run_threads(thr);

	if (srv_print_thread_releases) {

		fprintf(stderr,
			"Purge ends; pages handled %lu\n",
			(ulong) purge_sys->n_pages_handled);
	}

	return((ulint) (purge_sys->n_pages_handled - old_pages_handled));
}