📄 srv0srv.c
字号:
slot = srv_mysql_table + i; while (slot->in_use) { i++; if (i >= OS_THREAD_MAX_N) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: There appear to be %lu MySQL threads currently waiting\n""InnoDB: inside InnoDB, which is the upper limit. Cannot continue operation.\n""InnoDB: We intentionally generate a seg fault to print a stack trace\n""InnoDB: on Linux. But first we print a list of waiting threads.\n", (ulong) i); for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_mysql_table + i; fprintf(stderr,"Slot %lu: thread id %lu, type %lu, in use %lu, susp %lu, time %lu\n", (ulong) i, (ulong) os_thread_pf(slot->id), (ulong) slot->type, (ulong) slot->in_use, (ulong) slot->suspended, (ulong) difftime(ut_time(), slot->suspend_time)); } ut_error; } slot = srv_mysql_table + i; } ut_a(slot->in_use == FALSE); slot->in_use = TRUE; slot->id = os_thread_get_curr_id(); slot->handle = os_thread_get_curr(); return(slot);}#endif /* !UNIV_HOTBACKUP *//*******************************************************************Puts a MySQL OS thread to wait for a lock to be released. If an erroroccurs during the wait trx->error_state associated with thr is!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCKare possible errors. DB_DEADLOCK is returned if selective deadlockresolution chose this transaction as a victim. */voidsrv_suspend_mysql_thread(/*=====================*/ que_thr_t* thr) /* in: query thread associated with the MySQL OS thread */{#ifndef UNIV_HOTBACKUP srv_slot_t* slot; os_event_t event; double wait_time; trx_t* trx; ibool had_dict_lock = FALSE; ibool was_declared_inside_innodb = FALSE; ib_longlong start_time = 0; ib_longlong finish_time; ulint diff_time; ulint sec; ulint ms;#ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); os_event_set(srv_lock_timeout_thread_event); mutex_enter(&kernel_mutex); trx->error_state = DB_SUCCESS; if (thr->state == QUE_THR_RUNNING) { ut_ad(thr->is_active == TRUE); /* The lock has already been released or this transaction was chosen as a deadlock victim: no need to suspend */ if (trx->was_chosen_as_deadlock_victim) { trx->error_state = DB_DEADLOCK; trx->was_chosen_as_deadlock_victim = FALSE; } mutex_exit(&kernel_mutex); return; } ut_ad(thr->is_active == FALSE); slot = srv_table_reserve_slot_for_mysql(); event = slot->event; slot->thr = thr; os_event_reset(event); slot->suspend_time = ut_time(); if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_n_lock_wait_count++; srv_n_lock_wait_current_count++; ut_usectime(&sec, &ms); start_time = (ib_longlong)sec * 1000000 + ms; } /* Wake the lock timeout monitor thread, if it is suspended */ os_event_set(srv_lock_timeout_thread_event); mutex_exit(&kernel_mutex); if (trx->declared_to_be_inside_innodb) { was_declared_inside_innodb = TRUE; /* We must declare this OS thread to exit InnoDB, since a possible other thread holding a lock which this thread waits for must be allowed to enter, sooner or later */ srv_conc_force_exit_innodb(trx); } /* Release possible foreign key check latch */ if (trx->dict_operation_lock_mode == RW_S_LATCH) { had_dict_lock = TRUE; row_mysql_unfreeze_data_dictionary(trx); } ut_a(trx->dict_operation_lock_mode == 0); /* Wait for the release */ os_event_wait(event); if (had_dict_lock) { row_mysql_freeze_data_dictionary(trx); } if (was_declared_inside_innodb) { /* Return back inside InnoDB */ srv_conc_force_enter_innodb(trx); } mutex_enter(&kernel_mutex); /* Release the slot for others to use */ slot->in_use = FALSE; wait_time = ut_difftime(ut_time(), slot->suspend_time); if (thr->lock_state == QUE_THR_LOCK_ROW) { ut_usectime(&sec, &ms); finish_time = (ib_longlong)sec * 1000000 + ms; diff_time = (ulint) (finish_time - start_time); srv_n_lock_wait_current_count--; srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time; if (diff_time > srv_n_lock_max_wait_time) { srv_n_lock_max_wait_time = diff_time; } } if (trx->was_chosen_as_deadlock_victim) { trx->error_state = DB_DEADLOCK; trx->was_chosen_as_deadlock_victim = FALSE; } mutex_exit(&kernel_mutex); if (srv_lock_wait_timeout < 100000000 && wait_time > (double)srv_lock_wait_timeout) { trx->error_state = DB_LOCK_WAIT_TIMEOUT; }#else /* UNIV_HOTBACKUP */ /* This function depends on MySQL code that is not included in InnoDB Hot Backup builds. Besides, this function should never be called in InnoDB Hot Backup. */ ut_error;#endif /* UNIV_HOTBACKUP */}/************************************************************************Releases a MySQL OS thread waiting for a lock to be released, if thethread is already suspended. */voidsrv_release_mysql_thread_if_suspended(/*==================================*/ que_thr_t* thr) /* in: query thread associated with the MySQL OS thread */{#ifndef UNIV_HOTBACKUP srv_slot_t* slot; ulint i; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex));#endif /* UNIV_SYNC_DEBUG */ for (i = 0; i < OS_THREAD_MAX_N; i++) { slot = srv_mysql_table + i; if (slot->in_use && slot->thr == thr) { /* Found */ os_event_set(slot->event); return; } } /* not found */#else /* UNIV_HOTBACKUP */ /* This function depends on MySQL code that is not included in InnoDB Hot Backup builds. Besides, this function should never be called in InnoDB Hot Backup. */ ut_error;#endif /* UNIV_HOTBACKUP */}#ifndef UNIV_HOTBACKUP/**********************************************************************Refreshes the values used to calculate per-second averages. */staticvoidsrv_refresh_innodb_monitor_stats(void)/*==================================*/{ mutex_enter(&srv_innodb_monitor_mutex); srv_last_monitor_time = time(NULL); os_aio_refresh_stats(); btr_cur_n_sea_old = btr_cur_n_sea; btr_cur_n_non_sea_old = btr_cur_n_non_sea; log_refresh_stats(); buf_refresh_io_stats(); srv_n_rows_inserted_old = srv_n_rows_inserted; srv_n_rows_updated_old = srv_n_rows_updated; srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; mutex_exit(&srv_innodb_monitor_mutex);}/**********************************************************************Outputs to a file the output of the InnoDB Monitor. */voidsrv_printf_innodb_monitor(/*======================*/ FILE* file, /* in: output stream */ 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 the list of active transactions */{ double time_elapsed; time_t current_time; ulint n_reserved; mutex_enter(&srv_innodb_monitor_mutex); current_time = time(NULL); /* We add 0.001 seconds to time_elapsed to prevent division by zero if two users happen to call SHOW INNODB STATUS at the same time */ time_elapsed = difftime(current_time, srv_last_monitor_time) + 0.001; srv_last_monitor_time = time(NULL); fputs("\n=====================================\n", file); ut_print_timestamp(file); fprintf(file, " INNODB MONITOR OUTPUT\n" "=====================================\n" "Per second averages calculated from the last %lu seconds\n", (ulong)time_elapsed); fputs("----------\n" "SEMAPHORES\n" "----------\n", file); sync_print(file); /* Conceptually, srv_innodb_monitor_mutex has a very high latching order level in sync0sync.h, while dict_foreign_err_mutex has a very low level 135. Therefore we can reserve the latter mutex here without a danger of a deadlock of threads. */ mutex_enter(&dict_foreign_err_mutex); if (ftell(dict_foreign_err_file) != 0L) { fputs("------------------------\n" "LATEST FOREIGN KEY ERROR\n" "------------------------\n", file); ut_copy_file(file, dict_foreign_err_file); } 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; } } 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); os_aio_print(file); fputs("-------------------------------------\n" "INSERT BUFFER AND ADAPTIVE HASH INDEX\n" "-------------------------------------\n", file); ibuf_print(file); ha_print_info(file, btr_search_sys->hash_index); fprintf(file, "%.2f hash searches/s, %.2f non-hash searches/s\n", (btr_cur_n_sea - btr_cur_n_sea_old) / time_elapsed, (btr_cur_n_non_sea - btr_cur_n_non_sea_old) / time_elapsed); btr_cur_n_sea_old = btr_cur_n_sea; btr_cur_n_non_sea_old = btr_cur_n_non_sea; fputs("---\n" "LOG\n" "---\n", file); log_print(file); fputs("----------------------\n" "BUFFER POOL AND MEMORY\n" "----------------------\n", file); fprintf(file, "Total memory allocated " ULINTPF "; in additional pool allocated " ULINTPF "\n", ut_total_allocated_memory, mem_pool_get_reserved(mem_comm_pool)); if (srv_use_awe) { fprintf(file, "In addition to that %lu MB of AWE memory allocated\n", (ulong) (srv_pool_size / ((1024 * 1024) / UNIV_PAGE_SIZE))); } buf_print_io(file); fputs("--------------\n" "ROW OPERATIONS\n" "--------------\n", file); fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n", (long) srv_conc_n_threads, (ulong) srv_conc_n_waiting_threads); fprintf(file, "%lu read views open inside InnoDB\n", UT_LIST_GET_LEN(trx_sys->view_list)); n_reserved = fil_space_get_n_reserved_extents(0); if (n_reserved > 0) { fprintf(file, "%lu tablespace extents now reserved for B-tree split operations\n", (ulong) n_reserved); }#ifdef UNIV_LINUX fprintf(file, "Main thread process no. %lu, id %lu, state: %s\n", (ulong) srv_main_thread_process_no, (ulong) srv_main_thread_id, srv_main_thread_op_info);#else fprintf(file, "Main thread id %lu, state: %s\n", (ulong) srv_main_thread_id, srv_main_thread_op_info);#endif fprintf(file, "Number of rows inserted " ULINTPF ", updated " ULINTPF ", deleted " ULINTPF ", read " ULINTPF "\n", srv_n_rows_inserted, srv_n_rows_updated, srv_n_rows_deleted, srv_n_rows_read); fprintf(file, "%.2f inserts/s, %.2f updates/s, %.2f deletes/s, %.2f reads/s\n", (srv_n_rows_inserted - srv_n_rows_inserted_old) / time_elapsed, (srv_n_rows_updated - srv_n_rows_updated_old) / time_elapsed, (srv_n_rows_deleted - srv_n_rows_deleted_old) / time_elapsed, (srv_n_rows_read - srv_n_rows_read_old) / time_elapsed); srv_n_rows_inserted_old = srv_n_rows_inserted; srv_n_rows_updated_old = srv_n_rows_updated; srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; fputs("----------------------------\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -