Commit 743597ea authored by unknown's avatar unknown
Browse files

Backport innodb_max_purge_lag from 4.1


innobase/include/srv0srv.h:
  Add configuration parameter srv_max_purge_lag.
  Add global variable srv_dml_needed_delay.
innobase/include/trx0sys.h:
  Add trx_sys->rseg_history_len
innobase/row/row0mysql.c:
  Add row_mysql_delay_if_needed() for delaying INSERTs, UPDATEs and
  DELETEs for srv_dml_needed_delay microseconds.
innobase/srv/srv0srv.c:
  Define global variable srv_dml_needed_delay.
  Define configuration parameter srv_max_purge_lag.
innobase/trx/trx0purge.c:
  Update trx_sys->rseg_history_len.
  trx_purge(): Compute srv_dml_needed_delay from srv_max_purge_lag
  and trx_sys->rseg_history_len.
innobase/trx/trx0rseg.c:
  Initialize trx_sys->rseg_history_len at InnoDB start-up.
sql/ha_innodb.h:
  Add configuration parameter srv_max_purge_lag.
sql/mysqld.cc:
  Add startup option innodb_max_purge_lag,
  with default value 0 (meaning infinite, disabling the feature).
sql/set_var.cc:
  Add global variable innodb_max_purge_lag.
parent 9abe7d27
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ extern ibool srv_use_doublewrite_buf;
extern ibool    srv_set_thread_priorities;
extern int      srv_query_thread_priority;

extern ulint	srv_max_purge_lag;
/*-------------------------------------------*/

extern ulint	srv_n_rows_inserted;
@@ -152,6 +153,7 @@ extern ulint srv_test_array_size;

extern ulint	srv_activity_count;
extern ulint	srv_fatal_semaphore_wait_threshold;
extern ulint	srv_dml_needed_delay;

extern mutex_t*	kernel_mutex_temp;/* mutex protecting the server, trx structs,
				query threads, and lock table: we allocate
+4 −0
Original line number Diff line number Diff line
@@ -419,6 +419,10 @@ struct trx_sys_struct{
	trx_rseg_t*	rseg_array[TRX_SYS_N_RSEGS];
					/* Pointer array to rollback segments;
					NULL if slot not in use */
	ulint		rseg_history_len;/* Length of the TRX_RSEG_HISTORY
					list (update undo logs for committed
					transactions), protected by
					rseg->mutex */
	UT_LIST_BASE_NODE_T(read_view_t) view_list;
					/* List of read views sorted on trx no,
					biggest first */
+17 −0
Original line number Diff line number Diff line
@@ -89,6 +89,19 @@ row_mysql_is_system_table(
	    || 0 == strcmp(name + 6, "user")
	    || 0 == strcmp(name + 6, "db"));
}

/***********************************************************************
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
static
void
row_mysql_delay_if_needed(void)
/*===========================*/
{
	if (srv_dml_needed_delay) {
		os_thread_sleep(srv_dml_needed_delay);
	}
}

/***********************************************************************
Reads a MySQL format variable-length field (like VARCHAR) length and
returns pointer to the field data. */
@@ -856,6 +869,8 @@ row_insert_for_mysql(

	trx->op_info = (char *) "inserting";

	row_mysql_delay_if_needed();

	trx_start_if_not_started(trx);

	if (node == NULL) {
@@ -1071,6 +1086,8 @@ row_update_for_mysql(

	trx->op_info = (char *) "updating or deleting";

	row_mysql_delay_if_needed();

	trx_start_if_not_started(trx);

	node = prebuilt->upd_node;
+6 −0
Original line number Diff line number Diff line
@@ -58,6 +58,10 @@ ulint srv_activity_count = 0;
/* The following is the maximum allowed duration of a lock wait. */
ulint	srv_fatal_semaphore_wait_threshold = 600;

/* How much data manipulation language (DML) statements need to be delayed,
in microseconds, in order to reduce the lagging of the purge thread. */
ulint	srv_dml_needed_delay = 0;

ibool	srv_lock_timeout_and_monitor_active = FALSE;
ibool	srv_error_monitor_active = FALSE;

@@ -841,6 +845,8 @@ srv_general_init(void)

/*======================= InnoDB Server FIFO queue =======================*/

/* Maximum allowable purge history length.  <=0 means 'infinite'. */
ulint	srv_max_purge_lag		= 0;

/*************************************************************************
Puts an OS thread to wait if there are too many concurrent threads
+38 −0
Original line number Diff line number Diff line
@@ -295,6 +295,9 @@ trx_purge_add_update_undo_to_history(
	/* 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);
@@ -386,6 +389,12 @@ trx_purge_free_segment(

	flst_cut_end(rseg_hdr + TRX_RSEG_HISTORY,
			log_hdr + TRX_UNDO_HISTORY_NODE, n_removed_logs, &mtr);

	mutex_enter(&kernel_mutex);
	ut_ad(trx_sys->rseg_history_len >= n_removed_logs);
	trx_sys->rseg_history_len -= n_removed_logs;
	mutex_exit(&kernel_mutex);

	freed = FALSE;

	while (!freed) {
@@ -470,6 +479,11 @@ trx_purge_truncate_rseg_history(
	}

	if (cmp >= 0) {
		mutex_enter(&kernel_mutex);
		ut_a(trx_sys->rseg_history_len >= n_removed_logs);
		trx_sys->rseg_history_len -= n_removed_logs;
		mutex_exit(&kernel_mutex);

		flst_truncate_end(rseg_hdr + TRX_RSEG_HISTORY,
	    			log_hdr + TRX_UNDO_HISTORY_NODE,
				n_removed_logs, &mtr);
@@ -1031,6 +1045,30 @@ trx_purge(void)
	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(NULL,
							purge_sys->heap);
	mutex_exit(&kernel_mutex);	
Loading