📄 srv0srv.c
字号:
"END OF INNODB MONITOR OUTPUT\n" "============================\n", file); mutex_exit(&srv_innodb_monitor_mutex); fflush(file);}/**********************************************************************Function to pass InnoDB status variables to MySQL */voidsrv_export_innodb_status(void){ mutex_enter(&srv_innodb_monitor_mutex); export_vars.innodb_data_pending_reads= os_n_pending_reads; export_vars.innodb_data_pending_writes= os_n_pending_writes; export_vars.innodb_data_pending_fsyncs= fil_n_pending_log_flushes + fil_n_pending_tablespace_flushes; export_vars.innodb_data_fsyncs= os_n_fsyncs; export_vars.innodb_data_read= srv_data_read; export_vars.innodb_data_reads= os_n_file_reads; export_vars.innodb_data_writes= os_n_file_writes; export_vars.innodb_data_written= srv_data_written; export_vars.innodb_buffer_pool_read_requests= buf_pool->n_page_gets; export_vars.innodb_buffer_pool_write_requests= srv_buf_pool_write_requests; export_vars.innodb_buffer_pool_wait_free= srv_buf_pool_wait_free; export_vars.innodb_buffer_pool_pages_flushed= srv_buf_pool_flushed; export_vars.innodb_buffer_pool_reads= srv_buf_pool_reads; export_vars.innodb_buffer_pool_read_ahead_rnd= srv_read_ahead_rnd; export_vars.innodb_buffer_pool_read_ahead_seq= srv_read_ahead_seq; export_vars.innodb_buffer_pool_pages_data= UT_LIST_GET_LEN(buf_pool->LRU); export_vars.innodb_buffer_pool_pages_dirty= UT_LIST_GET_LEN(buf_pool->flush_list); export_vars.innodb_buffer_pool_pages_free= UT_LIST_GET_LEN(buf_pool->free); export_vars.innodb_buffer_pool_pages_latched= buf_get_latched_pages_number(); export_vars.innodb_buffer_pool_pages_total= buf_pool->curr_size; export_vars.innodb_buffer_pool_pages_misc= buf_pool->max_size - UT_LIST_GET_LEN(buf_pool->LRU) - UT_LIST_GET_LEN(buf_pool->free); export_vars.innodb_page_size= UNIV_PAGE_SIZE; export_vars.innodb_log_waits= srv_log_waits; export_vars.innodb_os_log_written= srv_os_log_written; export_vars.innodb_os_log_fsyncs= fil_n_log_flushes; export_vars.innodb_os_log_pending_fsyncs= fil_n_pending_log_flushes; export_vars.innodb_os_log_pending_writes= srv_os_log_pending_writes; export_vars.innodb_log_write_requests= srv_log_write_requests; export_vars.innodb_log_writes= srv_log_writes; export_vars.innodb_dblwr_pages_written= srv_dblwr_pages_written; export_vars.innodb_dblwr_writes= srv_dblwr_writes; export_vars.innodb_pages_created= buf_pool->n_pages_created; export_vars.innodb_pages_read= buf_pool->n_pages_read; export_vars.innodb_pages_written= buf_pool->n_pages_written; export_vars.innodb_row_lock_waits= srv_n_lock_wait_count; export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count; export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000; if (srv_n_lock_wait_count > 0) { export_vars.innodb_row_lock_time_avg = (ulint) (srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count); } else { export_vars.innodb_row_lock_time_avg = 0; } export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000; export_vars.innodb_rows_read= srv_n_rows_read; export_vars.innodb_rows_inserted= srv_n_rows_inserted; export_vars.innodb_rows_updated= srv_n_rows_updated; export_vars.innodb_rows_deleted= srv_n_rows_deleted; mutex_exit(&srv_innodb_monitor_mutex);}/*************************************************************************A thread which wakes up threads whose lock wait may have lasted too long.This also prints the info output by various InnoDB monitors. */#ifndef __WIN__void*#elseulint#endifsrv_lock_timeout_and_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_monitor_time; ibool some_waits; double wait_time; ulint i;#ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Lock timeout thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id()));#endif UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); last_monitor_time = time(NULL);loop: srv_lock_timeout_and_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 */ os_thread_sleep(1000000); /* In case mutex_exit is not a memory barrier, it is theoretically possible some threads are left waiting though the semaphore is already released. Wake up those threads: */ sync_arr_wake_threads_if_sema_free(); current_time = time(NULL); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { last_monitor_time = time(NULL); if (srv_print_innodb_monitor) { srv_printf_innodb_monitor(stderr, NULL, NULL); } if (srv_innodb_status) { mutex_enter(&srv_monitor_file_mutex); rewind(srv_monitor_file); srv_printf_innodb_monitor(srv_monitor_file, NULL, NULL); os_file_set_eof(srv_monitor_file); mutex_exit(&srv_monitor_file_mutex); } if (srv_print_innodb_tablespace_monitor && difftime(current_time, last_table_monitor_time) > 60) { last_table_monitor_time = time(NULL); fputs("================================================\n", stderr); ut_print_timestamp(stderr); fputs(" INNODB TABLESPACE MONITOR OUTPUT\n" "================================================\n", stderr); fsp_print(0); fputs("Validating tablespace\n", stderr); fsp_validate(0); fputs("Validation ok\n" "---------------------------------------\n" "END OF INNODB TABLESPACE MONITOR OUTPUT\n" "=======================================\n", stderr); } if (srv_print_innodb_table_monitor && difftime(current_time, last_table_monitor_time) > 60) { last_table_monitor_time = time(NULL); fputs("===========================================\n", stderr); ut_print_timestamp(stderr); fputs(" INNODB TABLE MONITOR OUTPUT\n" "===========================================\n", stderr); dict_print(); fputs("-----------------------------------\n" "END OF INNODB TABLE MONITOR OUTPUT\n" "==================================\n", stderr); } } mutex_enter(&kernel_mutex); some_waits = FALSE; /* Check of all slots if a thread is waiting there, and if it has exceeded the time limit */ for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_mysql_table + i; if (slot->in_use) { some_waits = TRUE; wait_time = ut_difftime(ut_time(), slot->suspend_time); if (srv_lock_wait_timeout < 100000000 && (wait_time > (double) srv_lock_wait_timeout || wait_time < 0)) { /* Timeout exceeded or a wrap-around in system time counter: cancel the lock request queued by the transaction and release possible other transactions waiting behind; it is possible that the lock has already been granted: in that case do nothing */ if (thr_get_trx(slot->thr)->wait_lock) { lock_cancel_waiting_and_release( thr_get_trx(slot->thr)->wait_lock); } } } } os_event_reset(srv_lock_timeout_thread_event); mutex_exit(&kernel_mutex); if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { 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) { goto loop; } /* No one was waiting for a lock and no monitor was active: suspend this thread */ srv_lock_timeout_and_monitor_active = FALSE;#if 0 /* The following synchronisation is disabled, since the InnoDB monitor output is to be updated every 15 seconds. */ os_event_wait(srv_lock_timeout_thread_event);#endif goto loop;exit_func: srv_lock_timeout_and_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);#ifndef __WIN__ return(NULL);#else return(0);#endif}/*************************************************************************A thread which prints warnings about semaphore waits which have lastedtoo long. These can be used to track bugs which cause hangs. */#ifndef __WIN__void*#elseulint#endifsrv_error_monitor_thread(/*=====================*/ /* out: a dummy parameter */ void* arg __attribute__((unused))) /* in: a dummy parameter required by os_thread_create */{ /* number of successive fatal timeouts observed */ ulint fatal_cnt = 0; dulint old_lsn; dulint new_lsn; old_lsn = srv_start_lsn;#ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Error monitor thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id()));#endifloop: srv_error_monitor_active = TRUE; /* Try to track a strange bug reported by Harald Fuchs and others, where the lsn seems to decrease at times */ new_lsn = log_get_lsn(); if (ut_dulint_cmp(new_lsn, old_lsn) < 0) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: old log sequence number %lu %lu was greater\n""InnoDB: than the new log sequence number %lu %lu!\n""InnoDB: Please send a bug report to mysql@lists.mysql.com\n", (ulong) ut_dulint_get_high(old_lsn), (ulong) ut_dulint_get_low(old_lsn), (ulong) ut_dulint_get_high(new_lsn), (ulong) ut_dulint_get_low(new_lsn)); } old_lsn = new_lsn; if (difftime(time(NULL), srv_last_monitor_time) > 60) { /* We referesh InnoDB Monitor values so that averages are printed from at most 60 last seconds */ srv_refresh_innodb_monitor_stats(); } if (sync_array_print_long_waits()) { fatal_cnt++; if (fatal_cnt > 5) { fprintf(stderr,"InnoDB: Error: semaphore wait has lasted > %lu seconds\n""InnoDB: We intentionally crash the server, because it appears to be hung.\n", srv_fatal_semaphore_wait_threshold); ut_error; } } else { fatal_cnt = 0; } /* Flush stderr so that a database user gets the output to possible MySQL error file */ fflush(stderr); os_thread_sleep(2000000); if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { goto loop; } srv_error_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);#ifndef __WIN__ return(NULL);#else return(0);#endif}/***********************************************************************Tells the InnoDB server that there has been activity in the databaseand wakes up the master thread if it is suspended (not sleeping). Usedin the MySQL interface. Note that there is a small chance that the masterthread stays suspended (we do not protect our operation with the kernelmutex, for performace reasons). */voidsrv_active_wake_master_thread(void)/*===============================*/{ srv_activity_count++; if (srv_n_threads_active[SRV_MASTER] == 0) { mutex_enter(&kernel_mutex); srv_release_threads(SRV_MASTER, 1); mutex_exit(&kernel_mutex); }}/***********************************************************************Wakes up the master thread if it is suspended or being suspended. */voidsrv_wake_master_thread(void)/*========================*/{ srv_activity_count++; mutex_enter(&kernel_mutex); srv_release_threads(SRV_MASTER, 1); mutex_exit(&kernel_mutex);}/*************************************************************************The master thread controlling the server. */#ifndef __WIN__void*#elseulint#endifsrv_master_thread(/*==============*/ /* out: a dummy parameter */ void* arg __attribute__((unused))) /* in: a dummy parameter required by os_thread_create */{ os_event_t event; time_t last_flush_time; time_t current_time; ulint old_activity_count; ulint n_pages_purged; ulint n_bytes_merged; ulint n_pages_flushed; ulint n_bytes_archived; ulint n_tables_to_drop; ulint n_ios; ulint n_ios_old; ulint n_ios_very_old; ulint n_pend_ios; ibool skip_sleep = FALSE; ulint i; #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Master thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id()));#endif srv_main_thread_process_no = os_proc_get_number(); srv_main_thread_id = os_thread_pf(os_thread_get_curr_id()); srv_table_reserve_slot(SRV_MASTER); mutex_enter(&kernel_mutex); srv_n_threads_active[SRV_MASTER]++; mutex_exit(&kernel_mutex); os_event_set(srv_sys->operational);loo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -