Commit 76f6b6d8 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-34515: Reduce context switching in purge

Before this patch, the InnoDB purge coordinator task submitted
innodb_purge_threads-1 tasks even if there was not sufficient amount
of work for all of them. For example, if there are undo log records
only for 1 table, only 1 task can be employed, and that task had better
be the purge coordinator.

srv_purge_worker_task_low(): Split from purge_worker_callback().

trx_purge_attach_undo_recs(): Remove the parameter n_purge_threads,
and add the parameter n_work_items, to keep track of the amount of
work.

trx_purge(): Launch purge worker tasks only if necessary. The work of
one thread will be executed by this purge coordinator thread.

que_fork_scheduler_round_robin(): Merged to trx_purge().

Thanks to Vladislav Vaintroub for supplying a prototype of this.

Reviewed by: Debarun Banerjee
parent b7b9f3ce
...@@ -209,17 +209,6 @@ que_eval_sql( ...@@ -209,17 +209,6 @@ que_eval_sql(
const char* sql, /*!< in: SQL string */ const char* sql, /*!< in: SQL string */
trx_t* trx); /*!< in: trx */ trx_t* trx); /*!< in: trx */
/**********************************************************************//**
Round robin scheduler.
@return a query thread of the graph moved to QUE_THR_RUNNING state, or
NULL; the query thread should be executed by que_run_threads by the
caller */
que_thr_t*
que_fork_scheduler_round_robin(
/*===========================*/
que_fork_t* fork, /*!< in: a query fork */
que_thr_t* thr); /*!< in: current pos */
/** Query thread states */ /** Query thread states */
enum que_thr_state_t { enum que_thr_state_t {
/** in selects this means that the thread is at the end of its /** in selects this means that the thread is at the end of its
......
...@@ -624,6 +624,15 @@ Complete the shutdown tasks such as background DROP TABLE, ...@@ -624,6 +624,15 @@ Complete the shutdown tasks such as background DROP TABLE,
and optionally change buffer merge (on innodb_fast_shutdown=0). */ and optionally change buffer merge (on innodb_fast_shutdown=0). */
void srv_shutdown(bool ibuf_merge); void srv_shutdown(bool ibuf_merge);
/**
Fetches and executes tasks from the purge work queue,
until this queue is empty.
This is main part of purge worker task, but also
executed in coordinator.
@note needs current_thd to be set beforehand.
*/
void srv_purge_worker_task_low();
} /* extern "C" */ } /* extern "C" */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
......
...@@ -166,40 +166,6 @@ que_thr_init_command( ...@@ -166,40 +166,6 @@ que_thr_init_command(
thr->state = QUE_THR_RUNNING; thr->state = QUE_THR_RUNNING;
} }
/**********************************************************************//**
Round robin scheduler.
@return a query thread of the graph moved to QUE_THR_RUNNING state, or
NULL; the query thread should be executed by que_run_threads by the
caller */
que_thr_t*
que_fork_scheduler_round_robin(
/*===========================*/
que_fork_t* fork, /*!< in: a query fork */
que_thr_t* thr) /*!< in: current pos */
{
fork->trx->mutex_lock();
/* If no current, start first available. */
if (thr == NULL) {
thr = UT_LIST_GET_FIRST(fork->thrs);
} else {
thr = UT_LIST_GET_NEXT(thrs, thr);
}
if (thr) {
fork->state = QUE_FORK_ACTIVE;
fork->last_sel_node = NULL;
ut_ad(thr->state == QUE_THR_COMPLETED);
que_thr_init_command(thr);
}
fork->trx->mutex_unlock();
return(thr);
}
/**********************************************************************//** /**********************************************************************//**
Starts execution of a command in a query fork. Picks a query thread which Starts execution of a command in a query fork. Picks a query thread which
is not in the QUE_THR_RUNNING state and moves it to that state. If none is not in the QUE_THR_RUNNING state and moves it to that state. If none
......
...@@ -1556,7 +1556,6 @@ static bool srv_purge_should_exit(size_t old_history_size) ...@@ -1556,7 +1556,6 @@ static bool srv_purge_should_exit(size_t old_history_size)
/*********************************************************************//** /*********************************************************************//**
Fetch and execute a task from the work queue. Fetch and execute a task from the work queue.
@param [in,out] slot purge worker thread slot
@return true if a task was executed */ @return true if a task was executed */
static bool srv_task_execute() static bool srv_task_execute()
{ {
...@@ -1696,6 +1695,13 @@ static void release_thd(THD *thd, void *ctx) ...@@ -1696,6 +1695,13 @@ static void release_thd(THD *thd, void *ctx)
set_current_thd(0); set_current_thd(0);
} }
void srv_purge_worker_task_low()
{
ut_ad(current_thd);
while (srv_task_execute())
ut_ad(purge_sys.running());
}
static void purge_worker_callback(void*) static void purge_worker_callback(void*)
{ {
ut_ad(!current_thd); ut_ad(!current_thd);
...@@ -1703,8 +1709,7 @@ static void purge_worker_callback(void*) ...@@ -1703,8 +1709,7 @@ static void purge_worker_callback(void*)
ut_ad(srv_force_recovery < SRV_FORCE_NO_BACKGROUND); ut_ad(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
void *ctx; void *ctx;
THD *thd= acquire_thd(&ctx); THD *thd= acquire_thd(&ctx);
while (srv_task_execute()) srv_purge_worker_task_low();
ut_ad(purge_sys.running());
release_thd(thd,ctx); release_thd(thd,ctx);
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment