Commit 736bad53 authored by Jimmy Yang's avatar Jimmy Yang

backport Bug #47707 print some progress messages during shutdown of innodb

to mysql-5.5

rb://979 approved by Marko
parent 4f22e1fc
...@@ -4750,34 +4750,32 @@ buf_all_freed(void) ...@@ -4750,34 +4750,32 @@ buf_all_freed(void)
/*********************************************************************//** /*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer Checks that there currently are no pending i/o-operations for the buffer
pool. pool.
@return TRUE if there is no pending i/o */ @return number of pending i/o */
UNIV_INTERN UNIV_INTERN
ibool ulint
buf_pool_check_no_pending_io(void) buf_pool_check_num_pending_io(void)
/*==============================*/ /*===============================*/
{ {
ulint i; ulint i;
ibool ret = TRUE; ulint pending_io = 0;
buf_pool_mutex_enter_all(); buf_pool_mutex_enter_all();
for (i = 0; i < srv_buf_pool_instances && ret; i++) { for (i = 0; i < srv_buf_pool_instances; i++) {
const buf_pool_t* buf_pool; const buf_pool_t* buf_pool;
buf_pool = buf_pool_from_array(i); buf_pool = buf_pool_from_array(i);
if (buf_pool->n_pend_reads pending_io += buf_pool->n_pend_reads
+ buf_pool->n_flush[BUF_FLUSH_LRU] + buf_pool->n_flush[BUF_FLUSH_LRU]
+ buf_pool->n_flush[BUF_FLUSH_LIST] + buf_pool->n_flush[BUF_FLUSH_LIST]
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]) { + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE];
ret = FALSE;
}
} }
buf_pool_mutex_exit_all(); buf_pool_mutex_exit_all();
return(ret); return(pending_io);
} }
#if 0 #if 0
......
...@@ -789,11 +789,11 @@ buf_all_freed(void); ...@@ -789,11 +789,11 @@ buf_all_freed(void);
/*********************************************************************//** /*********************************************************************//**
Checks that there currently are no pending i/o-operations for the buffer Checks that there currently are no pending i/o-operations for the buffer
pool. pool.
@return TRUE if there is no pending i/o */ @return number of pending i/o operations */
UNIV_INTERN UNIV_INTERN
ibool ulint
buf_pool_check_no_pending_io(void); buf_pool_check_num_pending_io(void);
/*==============================*/ /*===============================*/
/*********************************************************************//** /*********************************************************************//**
Invalidates the file pages in the buffer pool when an archive recovery is Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when completed. All the file pages buffered must be in a replaceable state when
......
...@@ -678,12 +678,14 @@ srv_que_task_enqueue_low( ...@@ -678,12 +678,14 @@ srv_que_task_enqueue_low(
que_thr_t* thr); /*!< in: query thread */ que_thr_t* thr); /*!< in: query thread */
/**********************************************************************//** /**********************************************************************//**
Check whether any background thread is active. Check whether any background thread is active. If so, return the thread
@return FALSE if all are are suspended or have exited. */ type.
@return ULINT_UNDEFINED if all are are suspended or have exited, thread
type if any are still active. */
UNIV_INTERN UNIV_INTERN
ibool ulint
srv_is_any_background_thread_active(void); srv_get_active_thread_type(void);
/*======================================*/ /*============================*/
/** Status variables to be passed to MySQL */ /** Status variables to be passed to MySQL */
struct export_var_struct{ struct export_var_struct{
......
...@@ -3076,9 +3076,12 @@ void ...@@ -3076,9 +3076,12 @@ void
logs_empty_and_mark_files_at_shutdown(void) logs_empty_and_mark_files_at_shutdown(void)
/*=======================================*/ /*=======================================*/
{ {
ib_uint64_t lsn; ib_uint64_t lsn;
ulint arch_log_no; ulint arch_log_no;
ibool server_busy; ibool server_busy;
ulint count = 0;
ulint pending_io;
ulint active_thd;
if (srv_print_verbose_log) { if (srv_print_verbose_log) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -3091,6 +3094,8 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3091,6 +3094,8 @@ logs_empty_and_mark_files_at_shutdown(void)
loop: loop:
os_thread_sleep(100000); os_thread_sleep(100000);
count++;
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
/* We need the monitor threads to stop before we proceed with /* We need the monitor threads to stop before we proceed with
...@@ -3099,6 +3104,21 @@ loop: ...@@ -3099,6 +3104,21 @@ loop:
if (srv_error_monitor_active if (srv_error_monitor_active
|| srv_lock_timeout_active || srv_lock_timeout_active
|| srv_monitor_active) { || srv_monitor_active) {
const char* thread_active = NULL;
/* Print a message every 60 seconds if we are waiting
for the monitor thread to exit. Master and worker threads
check will be done later. */
if (srv_print_verbose_log && count > 600) {
if (srv_error_monitor_active) {
thread_active = "srv_error_monitor_thread";
} else if (srv_lock_timeout_active) {
thread_active = "srv_lock_timeout thread";
} else if (srv_monitor_active) {
thread_active = "srv_monitor_thread";
}
}
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
...@@ -3106,6 +3126,13 @@ loop: ...@@ -3106,6 +3126,13 @@ loop:
os_event_set(srv_monitor_event); os_event_set(srv_monitor_event);
os_event_set(srv_timeout_event); os_event_set(srv_timeout_event);
if (thread_active) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %s to exit\n",
thread_active);
count = 0;
}
goto loop; goto loop;
} }
...@@ -3116,9 +3143,54 @@ loop: ...@@ -3116,9 +3143,54 @@ loop:
server_busy = trx_n_mysql_transactions > 0 server_busy = trx_n_mysql_transactions > 0
|| UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared; || UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared;
if (server_busy) {
ulint total_trx = UT_LIST_GET_LEN(trx_sys->trx_list)
+ trx_n_mysql_transactions;
mutex_exit(&kernel_mutex);
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %lu "
"active transactions to finish\n",
(ulong) total_trx);
count = 0;
}
goto loop;
}
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
if (server_busy || srv_is_any_background_thread_active()) { /* Check that the background threads are suspended */
active_thd = srv_get_active_thread_type();
if (active_thd != ULINT_UNDEFINED) {
/* The srv_lock_timeout_thread, srv_error_monitor_thread
and srv_monitor_thread should already exit by now. The
only threads to be suspended are the master threads
and worker threads (purge threads). Print the thread
type if any of such threads not in suspended mode */
if (srv_print_verbose_log && count > 600) {
const char* thread_type = "<null>";
switch (active_thd) {
case SRV_WORKER:
thread_type = "worker threads";
break;
case SRV_MASTER:
thread_type = "master thread";
break;
}
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %s "
"to be suspended\n", thread_type);
count = 0;
}
goto loop; goto loop;
} }
...@@ -3130,10 +3202,35 @@ loop: ...@@ -3130,10 +3202,35 @@ loop:
|| log_sys->n_pending_writes; || log_sys->n_pending_writes;
mutex_exit(&log_sys->mutex); mutex_exit(&log_sys->mutex);
if (server_busy || !buf_pool_check_no_pending_io()) { if (server_busy) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Pending checkpoint_writes: %lu\n"
" InnoDB: Pending log flush writes: %lu\n",
(ulong) log_sys->n_pending_checkpoint_writes,
(ulong) log_sys->n_pending_writes);
count = 0;
}
goto loop; goto loop;
} }
pending_io = buf_pool_check_num_pending_io();
if (pending_io) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for %lu buffer page "
"I/Os to complete\n",
(ulong) pending_io);
count = 0;
}
goto loop;
}
#ifdef UNIV_LOG_ARCHIVE #ifdef UNIV_LOG_ARCHIVE
log_archive_all(); log_archive_all();
#endif /* UNIV_LOG_ARCHIVE */ #endif /* UNIV_LOG_ARCHIVE */
...@@ -3157,7 +3254,7 @@ loop: ...@@ -3157,7 +3254,7 @@ loop:
log_buffer_flush_to_disk(); log_buffer_flush_to_disk();
/* Check that the background threads stay suspended */ /* Check that the background threads stay suspended */
if (srv_is_any_background_thread_active()) { if (srv_get_active_thread_type() != ULINT_UNDEFINED) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Warning: some background thread" "InnoDB: Warning: some background thread"
" woke up during shutdown\n"); " woke up during shutdown\n");
...@@ -3166,7 +3263,7 @@ loop: ...@@ -3166,7 +3263,7 @@ loop:
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
fil_close_all_files(); fil_close_all_files();
ut_a(!srv_is_any_background_thread_active()); ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
return; return;
} }
...@@ -3204,7 +3301,7 @@ loop: ...@@ -3204,7 +3301,7 @@ loop:
mutex_exit(&log_sys->mutex); mutex_exit(&log_sys->mutex);
/* Check that the background threads stay suspended */ /* Check that the background threads stay suspended */
if (srv_is_any_background_thread_active()) { if (srv_get_active_thread_type() != ULINT_UNDEFINED) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Warning: some background thread woke up" "InnoDB: Warning: some background thread woke up"
" during shutdown\n"); " during shutdown\n");
...@@ -3222,13 +3319,20 @@ loop: ...@@ -3222,13 +3319,20 @@ loop:
if (!buf_all_freed()) { if (!buf_all_freed()) {
if (srv_print_verbose_log && count > 600) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for dirty buffer "
"pages to be flushed\n");
count = 0;
}
goto loop; goto loop;
} }
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
/* Make some checks that the server really is quiet */ /* Make some checks that the server really is quiet */
ut_a(!srv_is_any_background_thread_active()); ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
ut_a(buf_all_freed()); ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn); ut_a(lsn == log_sys->lsn);
...@@ -3250,7 +3354,7 @@ loop: ...@@ -3250,7 +3354,7 @@ loop:
fil_close_all_files(); fil_close_all_files();
/* Make some checks that the server really is quiet */ /* Make some checks that the server really is quiet */
ut_a(!srv_is_any_background_thread_active()); ut_a(srv_get_active_thread_type() == ULINT_UNDEFINED);
ut_a(buf_all_freed()); ut_a(buf_all_freed());
ut_a(lsn == log_sys->lsn); ut_a(lsn == log_sys->lsn);
......
...@@ -2485,21 +2485,23 @@ loop: ...@@ -2485,21 +2485,23 @@ loop:
} }
/**********************************************************************//** /**********************************************************************//**
Check whether any background thread is active. Check whether any background thread is active. If so return the thread
@return FALSE if all are are suspended or have exited. */ type
@return ULINT_UNDEFINED if all are suspended or have exited, thread
type if any are still active. */
UNIV_INTERN UNIV_INTERN
ibool ulint
srv_is_any_background_thread_active(void) srv_get_active_thread_type(void)
/*=====================================*/ /*============================*/
{ {
ulint i; ulint i;
ibool ret = FALSE; ibool ret = ULINT_UNDEFINED;
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
for (i = 0; i <= SRV_MASTER; ++i) { for (i = 0; i <= SRV_MASTER; ++i) {
if (srv_n_threads_active[i] != 0) { if (srv_n_threads_active[i] != 0) {
ret = TRUE; ret = i;
break; break;
} }
} }
...@@ -2509,6 +2511,57 @@ srv_is_any_background_thread_active(void) ...@@ -2509,6 +2511,57 @@ srv_is_any_background_thread_active(void)
return(ret); return(ret);
} }
/*********************************************************************//**
This function prints progress message every 60 seconds during server
shutdown, for any activities that master thread is pending on. */
static
void
srv_shutdown_print_master_pending(
/*==============================*/
ib_time_t* last_print_time, /*!< last time the function
print the message */
ulint n_tables_to_drop, /*!< number of tables to
be dropped */
ulint n_bytes_merged, /*!< number of change buffer
just merged */
ulint n_pages_flushed) /*!< number of pages flushed */
{
ib_time_t current_time;
double time_elapsed;
current_time = ut_time();
time_elapsed = ut_difftime(current_time, *last_print_time);
if (time_elapsed > 60) {
*last_print_time = ut_time();
if (n_tables_to_drop) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for "
"%lu table(s) to be dropped\n",
(ulong) n_tables_to_drop);
}
/* Check change buffer merge, we only wait for change buffer
merge if it is a slow shutdown */
if (!srv_fast_shutdown && n_bytes_merged) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for change "
"buffer merge to complete\n"
" InnoDB: number of bytes of change buffer "
"just merged: %lu\n",
n_bytes_merged);
}
if (n_pages_flushed) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Waiting for "
"%lu pages to be flushed\n",
(ulong) n_pages_flushed);
}
}
}
/*******************************************************************//** /*******************************************************************//**
Tells the InnoDB server that there has been activity in the database Tells the InnoDB server that there has been activity in the database
and wakes up the master thread if it is suspended (not sleeping). Used and wakes up the master thread if it is suspended (not sleeping). Used
...@@ -2664,6 +2717,7 @@ srv_master_thread( ...@@ -2664,6 +2717,7 @@ srv_master_thread(
ulint n_pend_ios; ulint n_pend_ios;
ulint next_itr_time; ulint next_itr_time;
ulint i; ulint i;
ib_time_t last_print_time;
#ifdef UNIV_DEBUG_THREAD_CREATION #ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n", fprintf(stderr, "Master thread starts, id %lu\n",
...@@ -2685,6 +2739,7 @@ srv_master_thread( ...@@ -2685,6 +2739,7 @@ srv_master_thread(
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
last_print_time = ut_time();
loop: loop:
/*****************************************************************/ /*****************************************************************/
/* ---- When there is database activity by users, we cycle in this /* ---- When there is database activity by users, we cycle in this
...@@ -3030,6 +3085,14 @@ flush_loop: ...@@ -3030,6 +3085,14 @@ flush_loop:
*/ */
n_bytes_archived = 0; n_bytes_archived = 0;
/* Print progress message every 60 seconds during shutdown */
if (srv_shutdown_state > 0 && srv_print_verbose_log) {
srv_shutdown_print_master_pending(&last_print_time,
n_tables_to_drop,
n_bytes_merged,
n_pages_flushed);
}
/* Keep looping in the background loop if still work to do */ /* Keep looping in the background loop if still work to do */
if (srv_fast_shutdown && srv_shutdown_state > 0) { if (srv_fast_shutdown && srv_shutdown_state > 0) {
...@@ -3048,6 +3111,7 @@ flush_loop: ...@@ -3048,6 +3111,7 @@ flush_loop:
} else if (n_tables_to_drop } else if (n_tables_to_drop
+ n_pages_purged + n_bytes_merged + n_pages_flushed + n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_bytes_archived != 0) { + n_bytes_archived != 0) {
/* In a 'slow' shutdown we run purge and the insert buffer /* In a 'slow' shutdown we run purge and the insert buffer
merge to completion */ merge to completion */
......
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