@ -64,7 +64,8 @@ ulint srv_fatal_semaphore_wait_threshold = 600;
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_lock_timeout_active = FALSE ;
ibool srv_monitor_active = FALSE ;
ibool srv_error_monitor_active = FALSE ;
const char * srv_main_thread_op_info = " " ;
@ -122,6 +123,16 @@ ulint srv_log_file_size = ULINT_MAX; /* size in database pages */
ulint srv_log_buffer_size = ULINT_MAX ; /* size in database pages */
ulong srv_flush_log_at_trx_commit = 1 ;
/* Maximum number of times allowed to conditionally acquire
mutex before switching to blocking wait on the mutex */
# define MAX_MUTEX_NOWAIT 20
/* Check whether the number of failed nonblocking mutex
acquisition attempts exceeds maximum allowed value . If so ,
srv_printf_innodb_monitor ( ) will request mutex acquisition
with mutex_enter ( ) , which will wait until it gets the mutex . */
# define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
byte srv_latin1_ordering [ 256 ] /* The sort order table of the latin1
character set . The following table is
the MySQL order as of Feb 10 th , 2002 */
@ -1626,10 +1637,13 @@ srv_refresh_innodb_monitor_stats(void)
/**********************************************************************
Outputs to a file the output of the InnoDB Monitor . */
void
ibool
srv_printf_innodb_monitor (
/*======================*/
/* out: FALSE if not all information printed
due to failure to obtain necessary mutex */
FILE * file , /* in: output stream */
ibool nowait , /* in: whether to wait for the mutex. */
ulint * trx_start , /* out: file position of the start of
the list of active transactions */
ulint * trx_end ) /* out: file position of the end of
@ -1638,6 +1652,7 @@ srv_printf_innodb_monitor(
double time_elapsed ;
time_t current_time ;
ulint n_reserved ;
ibool ret ;
mutex_enter ( & srv_innodb_monitor_mutex ) ;
@ -1682,24 +1697,31 @@ srv_printf_innodb_monitor(
mutex_exit ( & dict_foreign_err_mutex ) ;
lock_print_info_summary ( file ) ;
if ( trx_start ) {
long t = ftell ( file ) ;
if ( t < 0 ) {
* trx_start = ULINT_UNDEFINED ;
} else {
* trx_start = ( ulint ) t ;
/* Only if lock_print_info_summary proceeds correctly,
before we call the lock_print_info_all_transactions
to print all the lock information . */
ret = lock_print_info_summary ( file , nowait ) ;
if ( ret ) {
if ( trx_start ) {
long t = ftell ( file ) ;
if ( t < 0 ) {
* trx_start = ULINT_UNDEFINED ;
} else {
* trx_start = ( ulint ) t ;
}
}
}
lock_print_info_all_transactions ( file ) ;
if ( trx_end ) {
long t = ftell ( file ) ;
if ( t < 0 ) {
* trx_end = ULINT_UNDEFINED ;
} else {
* trx_end = ( ulint ) t ;
lock_print_info_all_transactions ( file ) ;
if ( trx_end ) {
long t = ftell ( file ) ;
if ( t < 0 ) {
* trx_end = ULINT_UNDEFINED ;
} else {
* trx_end = ( ulint ) t ;
}
}
}
fputs ( " -------- \n "
" FILE I/O \n "
" -------- \n " , file ) ;
@ -1804,6 +1826,8 @@ srv_printf_innodb_monitor(
" ============================ \n " , file ) ;
mutex_exit ( & srv_innodb_monitor_mutex ) ;
fflush ( file ) ;
return ( ret ) ;
}
/**********************************************************************
@ -1883,26 +1907,23 @@ srv_export_innodb_status(void)
}
/*************************************************************************
A thread which wakes up threads whose lock wait may have lasted too long .
This also prints the info output by various InnoDB monitors . */
A thread prints the info output by various InnoDB monitors . */
os_thread_ret_t
srv_lock_timeout_and_ monitor_thread (
/*================================ */
srv_monitor_thread (
/*===============*/
/* out: a dummy parameter */
void * arg __attribute__ ( ( unused ) ) )
/* in: a dummy parameter required by
os_thread_create */
{
srv_slot_t * slot ;
double time_elapsed ;
time_t current_time ;
time_t last_table_monitor_time ;
time_t last_tablespace_monitor_time ;
time_t last_monitor_time ;
ibool some_waits ;
double wait_time ;
ulint i ;
ulint mutex_skipped ;
ibool last_srv_print_monitor ;
# ifdef UNIV_DEBUG_THREAD_CREATION
fprintf ( stderr , " Lock timeout thread starts, id %lu \n " ,
@ -1913,13 +1934,15 @@ srv_lock_timeout_and_monitor_thread(
last_table_monitor_time = time ( NULL ) ;
last_tablespace_monitor_time = time ( NULL ) ;
last_monitor_time = time ( NULL ) ;
mutex_skipped = 0 ;
last_srv_print_monitor = srv_print_innodb_monitor ;
loop :
srv_lock_timeout_and_monitor_active = TRUE ;
srv_monitor_active = TRUE ;
/* When someone is waiting for a lock, we wake up every second
and check if a timeout has passed for a lock wait */
/* Wake up every 5 seconds to see if we need to print
monitor information . */
os_thread_sleep ( 1 000000) ;
os_thread_sleep ( 5 000000) ;
current_time = time ( NULL ) ;
@ -1929,14 +1952,40 @@ loop:
last_monitor_time = time ( NULL ) ;
if ( srv_print_innodb_monitor ) {
srv_printf_innodb_monitor ( stderr , NULL , NULL ) ;
/* Reset mutex_skipped counter everytime
srv_print_innodb_monitor changes . This is to
ensure we will not be blocked by kernel_mutex
for short duration information printing ,
such as requested by sync_array_print_long_waits ( ) */
if ( ! last_srv_print_monitor ) {
mutex_skipped = 0 ;
last_srv_print_monitor = TRUE ;
}
if ( ! srv_printf_innodb_monitor ( stderr ,
MUTEX_NOWAIT ( mutex_skipped ) ,
NULL , NULL ) ) {
mutex_skipped + + ;
} else {
/* Reset the counter */
mutex_skipped = 0 ;
}
} else {
last_srv_print_monitor = FALSE ;
}
if ( srv_innodb_status ) {
mutex_enter ( & srv_monitor_file_mutex ) ;
rewind ( srv_monitor_file ) ;
srv_printf_innodb_monitor ( srv_monitor_file , NULL ,
NULL ) ;
if ( ! srv_printf_innodb_monitor ( srv_monitor_file ,
MUTEX_NOWAIT ( mutex_skipped ) ,
NULL , NULL ) ) {
mutex_skipped + + ;
} else {
mutex_skipped = 0 ;
}
os_file_set_eof ( srv_monitor_file ) ;
mutex_exit ( & srv_monitor_file_mutex ) ;
}
@ -1989,6 +2038,56 @@ loop:
}
}
if ( srv_shutdown_state > = SRV_SHUTDOWN_CLEANUP ) {
goto exit_func ;
}
if ( srv_print_innodb_monitor
| | srv_print_innodb_lock_monitor
| | srv_print_innodb_tablespace_monitor
| | srv_print_innodb_table_monitor ) {
goto loop ;
}
srv_monitor_active = FALSE ;
goto loop ;
exit_func :
srv_monitor_active = FALSE ;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return ( ) to exit . */
os_thread_exit ( NULL ) ;
OS_THREAD_DUMMY_RETURN ;
}
/*************************************************************************
A thread which wakes up threads whose lock wait may have lasted too long . */
os_thread_ret_t
srv_lock_timeout_thread (
/*====================*/
/* out: a dummy parameter */
void * arg __attribute__ ( ( unused ) ) )
/* in: a dummy parameter required by
os_thread_create */
{
srv_slot_t * slot ;
ibool some_waits ;
double wait_time ;
ulint i ;
loop :
/* When someone is waiting for a lock, we wake up every second
and check if a timeout has passed for a lock wait */
os_thread_sleep ( 1000000 ) ;
srv_lock_timeout_active = TRUE ;
mutex_enter ( & kernel_mutex ) ;
some_waits = FALSE ;
@ -2033,17 +2132,11 @@ loop:
goto exit_func ;
}
if ( some_waits | | srv_print_innodb_monitor
| | srv_print_innodb_lock_monitor
| | srv_print_innodb_tablespace_monitor
| | srv_print_innodb_table_monitor ) {
if ( some_waits ) {
goto loop ;
}
/* No one was waiting for a lock and no monitor was active:
suspend this thread */
srv_lock_timeout_and_monitor_active = FALSE ;
srv_lock_timeout_active = FALSE ;
#if 0
/* The following synchronisation is disabled, since
@ -2053,7 +2146,7 @@ loop:
goto loop ;
exit_func :
srv_lock_timeout_and_monitor_a ctive = FALSE ;
srv_lock_timeout_active = FALSE ;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return ( ) to exit . */