diff options
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r-- | sql/mysqld.cc | 1673 |
1 files changed, 977 insertions, 696 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0f5087c6ccf..53f7cfe944f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2009-2011 Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -50,6 +51,8 @@ #include "derror.h" // init_errmessage #include "des_key_file.h" // load_des_key_file #include "sql_manager.h" // stop_handle_manager, start_handle_manager +#include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit + #include <m_ctype.h> #include <my_dir.h> #include <my_bit.h> @@ -57,6 +60,7 @@ #include "rpl_mi.h" #include "sql_repl.h" #include "rpl_filter.h" +#include "client_settings.h" #include "repl_failsafe.h" #include <sql_common.h> #include <my_stacktrace.h> @@ -66,6 +70,7 @@ #include "sql_audit.h" #include "probes_mysql.h" #include "scheduler.h" +#include <waiting_threads.h> #include "debug_sync.h" #include "sql_callback.h" @@ -98,9 +103,9 @@ #define mysqld_charset &my_charset_latin1 -/* We have HAVE_purify below as this speeds up the shutdown of MySQL */ +/* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */ -#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__) +#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_valgrind) && defined(__linux__) #define HAVE_CLOSE_SERVER_SOCK 1 #endif @@ -189,6 +194,10 @@ typedef fp_except fp_except_t; # endif #endif +#ifndef HAVE_FCNTL +#define fcntl(X,Y,Z) 0 +#endif + extern "C" my_bool reopen_fstreams(const char *filename, FILE *outstream, FILE *errstream); @@ -289,14 +298,15 @@ static my_bool opt_autocommit; ///< for --autocommit command-line option /* Used with --help for detailed option */ -static my_bool opt_help= 0, opt_verbose= 0; +static my_bool opt_verbose= 0; -arg_cmp_func Arg_comparator::comparator_matrix[5][2] = +arg_cmp_func Arg_comparator::comparator_matrix[6][2] = {{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string}, {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real}, {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int}, {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row}, - {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}}; + {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}, + {&Arg_comparator::compare_datetime, &Arg_comparator::compare_e_datetime}}; /* static variables */ @@ -323,16 +333,17 @@ static PSI_rwlock_key key_rwlock_openssl; #endif #endif /* HAVE_PSI_INTERFACE */ +#undef SAFEMALLOC + /* the default log output is log tables */ static bool lower_case_table_names_used= 0; static bool max_long_data_size_used= false; static bool volatile select_thread_in_use, signal_thread_in_use; -/* See Bug#56666 and Bug#56760 */; -volatile bool ready_to_exit; +static volatile bool ready_to_exit; static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0; static my_bool opt_short_log_format= 0; +static my_bool opt_sync= 0; static uint kill_cached_threads, wake_thread; -static ulong killed_threads; static ulong max_used_connections; static volatile ulong cached_thread_count= 0; static char *mysqld_user, *mysqld_chroot; @@ -346,16 +357,15 @@ char *default_storage_engine; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static I_List<THD> thread_cache; static bool binlog_format_used= false; - LEX_STRING opt_init_connect, opt_init_slave; - static mysql_cond_t COND_thread_cache, COND_flush_thread_cache; /* Global variables */ bool opt_bin_log, opt_ignore_builtin_innodb= 0; -my_bool opt_log, opt_slow_log; +my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0; ulonglong log_output_options; +my_bool opt_userstat_running, opt_thread_alarm; my_bool opt_log_queries_not_using_indexes= 0; bool opt_error_log= IF_WIN(1,0); bool opt_disable_networking=0, opt_skip_show_db=0; @@ -367,6 +377,7 @@ my_bool locked_in_memory; bool opt_using_transactions; bool volatile abort_loop; bool volatile shutdown_in_progress; +uint volatile global_disable_checkpoint; /* True if the bootstrap thread is running. Protected by LOCK_thread_count, just like thread_count. @@ -386,7 +397,7 @@ bool in_bootstrap= FALSE; @brief 'grant_option' is used to indicate if privileges needs to be checked, in which case the lock, LOCK_grant, is used to protect access to the grant table. - @note This flag is dropped in 5.1 + @note This flag is dropped in 5.1 @see grant_init() */ bool volatile grant_option; @@ -398,14 +409,9 @@ my_bool opt_local_infile, opt_slave_compressed_protocol; my_bool opt_safe_user_create = 0; my_bool opt_show_slave_auth_info; my_bool opt_log_slave_updates= 0; +my_bool opt_replicate_annotate_rows_events= 0; char *opt_slave_skip_errors; -/** - compatibility option: - - index usage hints (USE INDEX without a FOR clause) behave as in 5.0 -*/ -my_bool old_mode; - /* Legacy global handlerton. These will be removed (please do not add more). */ @@ -421,6 +427,7 @@ my_bool opt_secure_auth= 0; char* opt_secure_file_priv; my_bool opt_log_slow_admin_statements= 0; my_bool opt_log_slow_slave_statements= 0; +my_bool opt_query_cache_strip_comments = 0; my_bool lower_case_file_system= 0; my_bool opt_large_pages= 0; my_bool opt_super_large_pages= 0; @@ -440,11 +447,14 @@ my_bool opt_noacl; my_bool sp_automatic_privileges= 1; ulong opt_binlog_rows_event_max_size; +my_bool opt_master_verify_checksum= 0; +my_bool opt_slave_sql_verify_checksum= 1; const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS}; #ifdef HAVE_INITGROUPS static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */ #endif uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; +uint mysqld_extra_port; uint mysqld_port_timeout; ulong delay_key_write_options; uint protocol_version; @@ -480,11 +490,16 @@ ulong specialflag=0; ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0; ulong max_connections, max_connect_errors; +ulong extra_max_connections; +ulonglong denied_connections; +my_decimal decimal_zero; + /* Maximum length of parameter value which can be set through mysql_send_long_data() call. */ ulong max_long_data_size; + /** Limit of the total number of prepared statements in the server. Is necessary to protect the server against out-of-memory attacks. @@ -545,9 +560,8 @@ const double log_10[] = { time_t server_start_time, flush_status_time; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; -char default_logfile_name[FN_REFLEN]; char *default_tz_name; -char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN]; +char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN], *opt_log_basename; char mysql_real_data_home[FN_REFLEN], lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], @@ -575,7 +589,6 @@ const char *in_left_expr_name= "<left expr>"; const char *in_additional_cond= "<IN COND>"; const char *in_having_cond= "<IN HAVING>"; -my_decimal decimal_zero; /* classes for comparation parsing/processing */ Eq_creator eq_creator; Ne_creator ne_creator; @@ -617,12 +630,16 @@ pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); mysql_mutex_t LOCK_thread_count; mysql_mutex_t - LOCK_status, LOCK_error_log, LOCK_uuid_generator, + LOCK_status, LOCK_error_log, LOCK_short_uuid_generator, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, LOCK_connection_count, LOCK_error_messages; + +mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats, + LOCK_global_table_stats, LOCK_global_index_stats; + /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -657,10 +674,11 @@ char *opt_logname, *opt_slow_logname; /* Static variables */ static bool kill_in_progress, segfaulted; +static my_bool opt_stack_trace; static my_bool opt_bootstrap, opt_myisam_log; static int cleanup_done; static ulong opt_specialflag; -static char *opt_update_logname, *opt_binlog_index_name; +static char *opt_binlog_index_name; char *mysql_home_ptr, *pidfile_name_ptr; /** Initial command line arguments (count), after load_defaults().*/ static int defaults_argc; @@ -682,6 +700,269 @@ static char *opt_bin_logname; int orig_argc; char **orig_argv; +#ifdef HAVE_PSI_INTERFACE +#ifdef HAVE_MMAP +PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool; +#endif /* HAVE_MMAP */ + +#ifdef HAVE_OPENSSL +PSI_mutex_key key_LOCK_des_key_file; +#endif /* HAVE_OPENSSL */ + +PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, + key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, + key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, + key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, + key_LOCK_gdl, key_LOCK_global_system_variables, + key_LOCK_manager, + key_LOCK_prepared_stmt_count, + key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, + key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data, + key_LOCK_user_conn, key_LOCK_uuid_short_generator, key_LOG_LOCK_log, + key_master_info_data_lock, key_master_info_run_lock, + key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, + key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, + key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, + key_PARTITION_LOCK_auto_inc; +PSI_mutex_key key_RELAYLOG_LOCK_index; + +PSI_mutex_key key_LOCK_stats, + key_LOCK_global_user_client_stats, key_LOCK_global_table_stats, + key_LOCK_global_index_stats, + key_LOCK_wakeup_ready; + +PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered; + +static PSI_mutex_info all_server_mutexes[]= +{ +#ifdef HAVE_MMAP + { &key_PAGE_lock, "PAGE::lock", 0}, + { &key_LOCK_sync, "TC_LOG_MMAP::LOCK_sync", 0}, + { &key_LOCK_active, "TC_LOG_MMAP::LOCK_active", 0}, + { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pool", 0}, +#endif /* HAVE_MMAP */ + +#ifdef HAVE_OPENSSL + { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL}, +#endif /* HAVE_OPENSSL */ + + { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0}, + { &key_BINLOG_LOCK_prep_xids, "MYSQL_BIN_LOG::LOCK_prep_xids", 0}, + { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0}, + { &key_delayed_insert_mutex, "Delayed_insert::mutex", 0}, + { &key_hash_filo_lock, "hash_filo::lock", 0}, + { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL}, + { &key_LOCK_connection_count, "LOCK_connection_count", PSI_FLAG_GLOBAL}, + { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL}, + { &key_LOCK_delayed_create, "LOCK_delayed_create", PSI_FLAG_GLOBAL}, + { &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL}, + { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL}, + { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL}, + { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL}, + { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL}, + { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL}, + { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL}, + { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL}, + { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL}, + { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL}, + { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL}, + { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL}, + { &key_LOCK_stats, "LOCK_stats", PSI_FLAG_GLOBAL}, + { &key_LOCK_global_user_client_stats, "LOCK_global_user_client_stats", PSI_FLAG_GLOBAL}, + { &key_LOCK_global_table_stats, "LOCK_global_table_stats", PSI_FLAG_GLOBAL}, + { &key_LOCK_global_index_stats, "LOCK_global_index_stats", PSI_FLAG_GLOBAL}, + { &key_LOCK_wakeup_ready, "THD::LOCK_wakeup_ready", 0}, + { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0}, + { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL}, + { &key_LOCK_uuid_short_generator, "LOCK_uuid_short_generator", PSI_FLAG_GLOBAL}, + { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, + { &key_master_info_data_lock, "Master_info::data_lock", 0}, + { &key_master_info_run_lock, "Master_info::run_lock", 0}, + { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, + { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0}, + { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0}, + { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0}, + { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0}, + { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0}, + { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL}, + { &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL}, + { &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL}, + { &key_LOG_INFO_lock, "LOG_INFO::lock", 0}, + { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL}, + { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0} +}; + +PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger, + key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave, + key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock; + +static PSI_rwlock_info all_server_rwlocks[]= +{ +#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL) + { &key_rwlock_openssl, "CRYPTO_dynlock_value::lock", 0}, +#endif + { &key_rwlock_LOCK_grant, "LOCK_grant", PSI_FLAG_GLOBAL}, + { &key_rwlock_LOCK_logger, "LOGGER::LOCK_logger", 0}, + { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL}, + { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL}, + { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL}, + { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0} +}; + +#ifdef HAVE_MMAP +PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool, key_COND_queue_busy; +#endif /* HAVE_MMAP */ + +PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, + key_COND_cache_status_changed, key_COND_manager, + key_COND_rpl_status, key_COND_server_started, + key_delayed_insert_cond, key_delayed_insert_cond_client, + key_item_func_sleep_cond, key_master_info_data_cond, + key_master_info_start_cond, key_master_info_stop_cond, + key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, + key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_TABLE_SHARE_cond, key_user_level_lock_cond, + key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; +PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready; + +static PSI_cond_info all_server_conds[]= +{ +#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) + { &key_COND_handler_count, "COND_handler_count", PSI_FLAG_GLOBAL}, +#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ +#ifdef HAVE_MMAP + { &key_PAGE_cond, "PAGE::cond", 0}, + { &key_COND_active, "TC_LOG_MMAP::COND_active", 0}, + { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0}, +#endif /* HAVE_MMAP */ + { &key_BINLOG_COND_prep_xids, "MYSQL_BIN_LOG::COND_prep_xids", 0}, + { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0}, + { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0}, + { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0}, + { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0}, + { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL}, + { &key_COND_rpl_status, "COND_rpl_status", PSI_FLAG_GLOBAL}, + { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL}, + { &key_delayed_insert_cond, "Delayed_insert::cond", 0}, + { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0}, + { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0}, + { &key_master_info_data_cond, "Master_info::data_cond", 0}, + { &key_master_info_start_cond, "Master_info::start_cond", 0}, + { &key_master_info_stop_cond, "Master_info::stop_cond", 0}, + { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0}, + { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0}, + { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0}, + { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0}, + { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0}, + { &key_user_level_lock_cond, "User_level_lock::cond", 0}, + { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL}, + { &key_COND_thread_cache, "COND_thread_cache", PSI_FLAG_GLOBAL}, + { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL} +}; + +PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert, + key_thread_handle_manager, key_thread_main, + key_thread_one_connection, key_thread_signal_hand; + +static PSI_thread_info all_server_threads[]= +{ +#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) + { &key_thread_handle_con_namedpipes, "con_named_pipes", PSI_FLAG_GLOBAL}, +#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ + +#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY) + { &key_thread_handle_con_sharedmem, "con_shared_mem", PSI_FLAG_GLOBAL}, +#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */ + +#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) + { &key_thread_handle_con_sockets, "con_sockets", PSI_FLAG_GLOBAL}, +#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ + +#ifdef __WIN__ + { &key_thread_handle_shutdown, "shutdown", PSI_FLAG_GLOBAL}, +#endif /* __WIN__ */ + + { &key_thread_bootstrap, "bootstrap", PSI_FLAG_GLOBAL}, + { &key_thread_delayed_insert, "delayed_insert", 0}, + { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL}, + { &key_thread_main, "main", PSI_FLAG_GLOBAL}, + { &key_thread_one_connection, "one_connection", 0}, + { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL} +}; + +PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, + key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, + key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, + key_file_loadfile, key_file_log_event_data, key_file_log_event_info, + key_file_master_info, key_file_misc, key_file_partition, + key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog, + key_file_trg, key_file_trn, key_file_init; +PSI_file_key key_file_query_log, key_file_slow_log; +PSI_file_key key_file_relaylog, key_file_relaylog_index; + +static PSI_file_info all_server_files[]= +{ + { &key_file_binlog, "binlog", 0}, + { &key_file_binlog_index, "binlog_index", 0}, + { &key_file_relaylog, "relaylog", 0}, + { &key_file_relaylog_index, "relaylog_index", 0}, + { &key_file_casetest, "casetest", 0}, + { &key_file_dbopt, "dbopt", 0}, + { &key_file_des_key_file, "des_key_file", 0}, + { &key_file_ERRMSG, "ERRMSG", 0}, + { &key_select_to_file, "select_to_file", 0}, + { &key_file_fileparser, "file_parser", 0}, + { &key_file_frm, "FRM", 0}, + { &key_file_global_ddl_log, "global_ddl_log", 0}, + { &key_file_load, "load", 0}, + { &key_file_loadfile, "LOAD_FILE", 0}, + { &key_file_log_event_data, "log_event_data", 0}, + { &key_file_log_event_info, "log_event_info", 0}, + { &key_file_master_info, "master_info", 0}, + { &key_file_misc, "misc", 0}, + { &key_file_partition, "partition", 0}, + { &key_file_pid, "pid", 0}, + { &key_file_query_log, "query_log", 0}, + { &key_file_relay_log_info, "relay_log_info", 0}, + { &key_file_send_file, "send_file", 0}, + { &key_file_slow_log, "slow_log", 0}, + { &key_file_tclog, "tclog", 0}, + { &key_file_trg, "trigger_name", 0}, + { &key_file_trn, "trigger", 0}, + { &key_file_init, "init", 0} +}; + +/** + Initialise all the performance schema instrumentation points + used by the server. +*/ +void init_server_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_server_mutexes); + PSI_server->register_mutex(category, all_server_mutexes, count); + + count= array_elements(all_server_rwlocks); + PSI_server->register_rwlock(category, all_server_rwlocks, count); + + count= array_elements(all_server_conds); + PSI_server->register_cond(category, all_server_conds, count); + + count= array_elements(all_server_threads); + PSI_server->register_thread(category, all_server_threads, count); + + count= array_elements(all_server_files); + PSI_server->register_file(category, all_server_files, count); +} + +#endif /* HAVE_PSI_INTERFACE */ + /* Since buffered_option_error_reporter is only used currently for parsing performance schema options, this code is not needed @@ -845,13 +1126,12 @@ C_MODE_END #endif /* !EMBEDDED_LIBRARY */ #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ -static my_socket unix_sock,ip_sock; -struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD() +static my_socket unix_sock, base_ip_sock, extra_ip_sock; +struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD() #ifndef EMBEDDED_LIBRARY struct passwd *user_info; static pthread_t select_thread; -static uint thr_kill_signal; #endif /* OS specific variables */ @@ -890,7 +1170,7 @@ bool mysqld_embedded=1; static my_bool plugins_are_initialized= FALSE; #ifndef DBUG_OFF -static const char* default_dbug_option; +static const char* default_dbug_option, *current_dbug_option; #endif #ifdef HAVE_LIBWRAP const char *libwrapName= NULL; @@ -911,6 +1191,10 @@ my_bool opt_use_ssl = 0; char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL, *opt_ssl_cipher= NULL, *opt_ssl_key= NULL; +static scheduler_functions thread_scheduler_struct, extra_thread_scheduler_struct; +scheduler_functions *thread_scheduler= &thread_scheduler_struct, + *extra_thread_scheduler= &extra_thread_scheduler_struct; + #ifdef HAVE_OPENSSL #include <openssl/crypto.h> #ifndef HAVE_YASSL @@ -936,7 +1220,7 @@ struct st_VioSSLFd *ssl_acceptor_fd; Number of currently active user connections. The variable is protected by LOCK_connection_count. */ -uint connection_count= 0; +uint connection_count= 0, extra_connection_count= 0; /* Function declarations */ @@ -1020,7 +1304,7 @@ static void close_connections(void) break; } #ifdef EXTRA_DEBUG - if (error != 0 && !count++) + if (error != 0 && error != ETIMEDOUT && !count++) sql_print_error("Got error %d from mysql_cond_timedwait", error); #endif close_server_sock(); @@ -1033,11 +1317,17 @@ static void close_connections(void) DBUG_PRINT("quit",("Closing sockets")); if (!opt_disable_networking ) { - if (ip_sock != INVALID_SOCKET) + if (base_ip_sock != INVALID_SOCKET) { - (void) shutdown(ip_sock, SHUT_RDWR); - (void) closesocket(ip_sock); - ip_sock= INVALID_SOCKET; + (void) shutdown(base_ip_sock, SHUT_RDWR); + (void) closesocket(base_ip_sock); + base_ip_sock= INVALID_SOCKET; + } + if (extra_ip_sock != INVALID_SOCKET) + { + (void) shutdown(extra_ip_sock, SHUT_RDWR); + (void) closesocket(extra_ip_sock); + extra_ip_sock= INVALID_SOCKET; } } #ifdef _WIN32 @@ -1102,9 +1392,19 @@ static void close_connections(void) mysql_mutex_lock(&tmp->mysys_var->mutex); if (tmp->mysys_var->current_cond) { - mysql_mutex_lock(tmp->mysys_var->current_mutex); - mysql_cond_broadcast(tmp->mysys_var->current_cond); - mysql_mutex_unlock(tmp->mysys_var->current_mutex); + uint i; + for (i=0; i < 2; i++) + { + int ret= mysql_mutex_trylock(tmp->mysys_var->current_mutex); + mysql_cond_broadcast(tmp->mysys_var->current_cond); + if (!ret) + { + /* Thread has surely got the signal, unlock and abort */ + mysql_mutex_unlock(tmp->mysys_var->current_mutex); + break; + } + sleep(1); + } } mysql_mutex_unlock(&tmp->mysys_var->mutex); } @@ -1115,8 +1415,9 @@ static void close_connections(void) Events::deinit(); end_slave(); - if (thread_count) - sleep(2); // Give threads time to die + /* Give threads time to die. */ + for (int i= 0; thread_count && i < 100; i++) + my_sleep(20000); /* Force remaining threads to die by closing the connection to the client @@ -1158,32 +1459,47 @@ static void close_connections(void) } mysql_mutex_unlock(&LOCK_thread_count); - close_active_mi(); DBUG_PRINT("quit",("close_connections thread")); DBUG_VOID_RETURN; } +#ifdef HAVE_CLOSE_SERVER_SOCK +static void close_socket(my_socket sock, const char *info) +{ + DBUG_ENTER("close_socket"); + + if (sock != INVALID_SOCKET) + { + DBUG_PRINT("info", ("calling shutdown on %s socket", info)); + (void) shutdown(sock, SHUT_RDWR); +#if defined(__NETWARE__) + /* + The following code is disabled for normal systems as it causes MySQL + to hang on AIX 4.3 during shutdown + */ + DBUG_PRINT("info", ("calling closesocket on %s socket", info)); + (void) closesocket(tmp_sock); +#endif + } + DBUG_VOID_RETURN; +} +#endif + + static void close_server_sock() { #ifdef HAVE_CLOSE_SERVER_SOCK DBUG_ENTER("close_server_sock"); - my_socket tmp_sock; - tmp_sock=ip_sock; - if (tmp_sock != INVALID_SOCKET) - { - ip_sock=INVALID_SOCKET; - DBUG_PRINT("info",("calling shutdown on TCP/IP socket")); - (void) shutdown(tmp_sock, SHUT_RDWR); - } - tmp_sock=unix_sock; - if (tmp_sock != INVALID_SOCKET) - { - unix_sock=INVALID_SOCKET; - DBUG_PRINT("info",("calling shutdown on unix socket")); - (void) shutdown(tmp_sock, SHUT_RDWR); + + close_socket(base_ip_sock, "TCP/IP"); + close_socket(extra_ip_sock, "TCP/IP"); + close_socket(unix_sock, "unix/IP"); + + if (unix_sock != INVALID_SOCKET) (void) unlink(mysqld_unix_port); - } + base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET; + DBUG_VOID_RETURN; #endif } @@ -1276,21 +1592,21 @@ static void __cdecl kill_server(int sig_ptr) else sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ -#if defined(HAVE_SMEM) && defined(__WIN__) - /* - Send event to smem_event_connect_request for aborting - */ +#ifdef HAVE_SMEM + /* + Send event to smem_event_connect_request for aborting + */ if (opt_enable_shared_memory) { - if (!SetEvent(smem_event_connect_request)) - { + if (!SetEvent(smem_event_connect_request)) + { DBUG_PRINT("error", ("Got error: %ld from SetEvent of smem_event_connect_request", - GetLastError())); + GetLastError())); } } -#endif - +#endif + close_connections(); if (sig != MYSQL_KILL_SIGNAL && sig != 0) @@ -1402,13 +1718,9 @@ static void mysqld_exit(int exit_code) mysql_audit_finalize(); clean_up_mutexes(); clean_up_error_log_mutex(); -#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE - /* - Bug#56666 needs to be fixed before calling: - shutdown_performance_schema(); - */ -#endif - my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); + my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0) | MY_DONT_FREE_DBUG); + shutdown_performance_schema(); // we do it as late as possible + DBUG_END(); // but this - even later exit(exit_code); /* purecov: inspected */ } @@ -1420,6 +1732,7 @@ void clean_up(bool print_message) if (cleanup_done++) return; /* purecov: inspected */ + close_active_mi(); stop_handle_manager(); release_ddl_log(); @@ -1467,19 +1780,25 @@ void clean_up(bool print_message) table_def_free(); mdl_destroy(); key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache); + wt_end(); multi_keycache_free(); + sp_cache_end(); free_status_vars(); end_thr_alarm(1); /* Free allocated memory */ my_free_open_file_info(); if (defaults_argv) free_defaults(defaults_argv); free_tmpdir(&mysql_tmpdir_list); - my_free(opt_bin_logname); bitmap_free(&temp_pool); free_max_user_conn(); + free_global_user_stats(); + free_global_client_stats(); + free_global_table_stats(); + free_global_index_stats(); #ifdef HAVE_REPLICATION end_slave_list(); #endif + my_uuid_end(); delete binlog_filter; delete rpl_filter; end_ssl(); @@ -1498,12 +1817,13 @@ void clean_up(bool print_message) sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname); cleanup_errmsgs(); MYSQL_CALLBACK(thread_scheduler, end, ()); - mysql_client_plugin_deinit(); + mysql_library_end(); finish_client_errs(); (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs DBUG_PRINT("quit", ("Error messages freed")); /* Tell main we are ready */ logger.cleanup_end(); + sys_var_end(); my_atomic_rwlock_destroy(&global_query_id_lock); my_atomic_rwlock_destroy(&thread_running_lock); mysql_mutex_lock(&LOCK_thread_count); @@ -1512,7 +1832,6 @@ void clean_up(bool print_message) /* do the broadcast inside the lock to ensure that my_end() is not called */ mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); - sys_var_end(); /* The following lines may never be executed as the main thread may have @@ -1537,15 +1856,16 @@ static void wait_for_signal_thread_to_end() */ for (i= 0 ; i < 100 && signal_thread_in_use; i++) { - if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH) + if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) == ESRCH) break; my_sleep(100); // Give it time to die } } - +#endif /*EMBEDDED_LIBRARY*/ static void clean_up_mutexes() { + DBUG_ENTER("clean_up_mutexes"); mysql_rwlock_destroy(&LOCK_grant); mysql_mutex_destroy(&LOCK_thread_count); mysql_mutex_destroy(&LOCK_status); @@ -1556,32 +1876,40 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_crypt); mysql_mutex_destroy(&LOCK_user_conn); mysql_mutex_destroy(&LOCK_connection_count); + mysql_mutex_destroy(&LOCK_stats); + mysql_mutex_destroy(&LOCK_global_user_client_stats); + mysql_mutex_destroy(&LOCK_global_table_stats); + mysql_mutex_destroy(&LOCK_global_index_stats); #ifdef HAVE_OPENSSL mysql_mutex_destroy(&LOCK_des_key_file); #ifndef HAVE_YASSL for (int i= 0; i < CRYPTO_num_locks(); ++i) mysql_rwlock_destroy(&openssl_stdlocks[i].lock); OPENSSL_free(openssl_stdlocks); -#endif -#endif +#endif /* HAVE_YASSL */ +#endif /* HAVE_OPENSSL */ #ifdef HAVE_REPLICATION mysql_mutex_destroy(&LOCK_rpl_status); mysql_cond_destroy(&COND_rpl_status); -#endif +#endif /* HAVE_REPLICATION */ mysql_mutex_destroy(&LOCK_active_mi); mysql_rwlock_destroy(&LOCK_sys_init_connect); mysql_rwlock_destroy(&LOCK_sys_init_slave); mysql_mutex_destroy(&LOCK_global_system_variables); mysql_rwlock_destroy(&LOCK_system_variables_hash); - mysql_mutex_destroy(&LOCK_uuid_generator); + mysql_mutex_destroy(&LOCK_short_uuid_generator); mysql_mutex_destroy(&LOCK_prepared_stmt_count); mysql_mutex_destroy(&LOCK_error_messages); mysql_cond_destroy(&COND_thread_count); mysql_cond_destroy(&COND_thread_cache); mysql_cond_destroy(&COND_flush_thread_cache); mysql_cond_destroy(&COND_manager); + mysql_mutex_destroy(&LOCK_server_started); + mysql_cond_destroy(&COND_server_started); + mysql_mutex_destroy(&LOCK_prepare_ordered); + mysql_mutex_destroy(&LOCK_commit_ordered); + DBUG_VOID_RETURN; } -#endif /*EMBEDDED_LIBRARY*/ /**************************************************************************** @@ -1754,127 +2082,143 @@ static void set_root(const char *path) #endif } +/** + Activate usage of a tcp port +*/ -static void network_init(void) +static my_socket activate_tcp_port(uint port) { -#ifdef HAVE_SYS_UN_H - struct sockaddr_un UNIXaddr; -#endif + struct addrinfo *ai, *a; + struct addrinfo hints; + int error; int arg; - int ret; - uint waited; - uint this_wait; - uint retry; char port_buf[NI_MAXSERV]; - DBUG_ENTER("network_init"); - LINT_INIT(ret); - - if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0)) - unireg_abort(1); /* purecov: inspected */ + my_socket ip_sock= INVALID_SOCKET; + DBUG_ENTER("activate_tcp_port"); + DBUG_PRINT("general",("IP Socket is %d",port)); - set_ports(); + bzero(&hints, sizeof (hints)); + hints.ai_flags= AI_PASSIVE; + hints.ai_socktype= SOCK_STREAM; + hints.ai_family= AF_UNSPEC; - if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap) + my_snprintf(port_buf, NI_MAXSERV, "%d", port); + error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai); + if (error != 0) { - struct addrinfo *ai, *a; - struct addrinfo hints; - int error; - DBUG_PRINT("general",("IP Socket is %d",mysqld_port)); - - bzero(&hints, sizeof (hints)); - hints.ai_flags= AI_PASSIVE; - hints.ai_socktype= SOCK_STREAM; - hints.ai_family= AF_UNSPEC; - - my_snprintf(port_buf, NI_MAXSERV, "%d", mysqld_port); - error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai); - if (error != 0) - { - DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error)); - sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */ - unireg_abort(1); /* purecov: tested */ - } + DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error)); + sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */ + unireg_abort(1); /* purecov: tested */ + } - for (a= ai; a != NULL; a= a->ai_next) - { - ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol); - if (ip_sock != INVALID_SOCKET) - break; - } + for (a= ai; a != NULL; a= a->ai_next) + { + ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol); + if (ip_sock != INVALID_SOCKET) + break; + } - if (ip_sock == INVALID_SOCKET) - { - DBUG_PRINT("error",("Got error: %d from socket()",socket_errno)); - sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */ - unireg_abort(1); /* purecov: tested */ - } + if (ip_sock == INVALID_SOCKET) + { + DBUG_PRINT("error",("Got error: %d from socket()",socket_errno)); + sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */ + unireg_abort(1); /* purecov: tested */ + } #ifndef __WIN__ - /* - We should not use SO_REUSEADDR on windows as this would enable a - user to open two mysqld servers with the same TCP/IP port. - */ - arg= 1; - (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); + /* + We should not use SO_REUSEADDR on windows as this would enable a + user to open two mysqld servers with the same TCP/IP port. + */ + arg= 1; + (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg)); #endif /* __WIN__ */ #ifdef IPV6_V6ONLY - /* - For interoperability with older clients, IPv6 socket should - listen on both IPv6 and IPv4 wildcard addresses. - Turn off IPV6_V6ONLY option. + /* + For interoperability with older clients, IPv6 socket should + listen on both IPv6 and IPv4 wildcard addresses. + Turn off IPV6_V6ONLY option. - NOTE: this will work starting from Windows Vista only. - On Windows XP dual stack is not available, so it will not - listen on the corresponding IPv4-address. - */ - if (a->ai_family == AF_INET6) - { - arg= 0; - (void) setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, - sizeof(arg)); - } + NOTE: this will work starting from Windows Vista only. + On Windows XP dual stack is not available, so it will not + listen on the corresponding IPv4-address. + */ + if (a->ai_family == AF_INET6) + { + arg= 0; + (void) setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, + sizeof(arg)); + } #endif - /* - Sometimes the port is not released fast enough when stopping and - restarting the server. This happens quite often with the test suite - on busy Linux systems. Retry to bind the address at these intervals: - Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ... - Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ... - Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#). - */ - for (waited= 0, retry= 1; ; retry++, waited+= this_wait) - { - if (((ret= bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) || - (socket_errno != SOCKET_EADDRINUSE) || - (waited >= mysqld_port_timeout)) - break; - sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port); - this_wait= retry * retry / 3 + 1; - sleep(this_wait); - } - freeaddrinfo(ai); - if (ret < 0) - { - DBUG_PRINT("error",("Got error: %d from bind",socket_errno)); - sql_perror("Can't start server: Bind on TCP/IP port"); - sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port); - unireg_abort(1); - } - if (listen(ip_sock,(int) back_log) < 0) - { - sql_perror("Can't start server: listen() on TCP/IP port"); - sql_print_error("listen() on TCP/IP failed with error %d", - socket_errno); - unireg_abort(1); - } + /* + Sometimes the port is not released fast enough when stopping and + restarting the server. This happens quite often with the test suite + on busy Linux systems. Retry to bind the address at these intervals: + Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ... + Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ... + Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#). + */ + int ret; + uint waited, retry, this_wait; + for (waited= 0, retry= 1; ; retry++, waited+= this_wait) + { + if (((ret= bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) || + (socket_errno != SOCKET_EADDRINUSE) || + (waited >= mysqld_port_timeout)) + break; + sql_print_information("Retrying bind on TCP/IP port %u", port); + this_wait= retry * retry / 3 + 1; + sleep(this_wait); + } + freeaddrinfo(ai); + if (ret < 0) + { + char buff[100]; + sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d", + (int) socket_errno); + sql_perror(buff); + sql_print_error("Do you already have another mysqld server running on " + "port: %u ?", port); + unireg_abort(1); + } + if (listen(ip_sock,(int) back_log) < 0) + { + sql_perror("Can't start server: listen() on TCP/IP port"); + sql_print_error("listen() on TCP/IP failed with error %d", + socket_errno); + unireg_abort(1); } + DBUG_RETURN(ip_sock); +} -#ifdef _WIN32 +static void network_init(void) +{ +#ifdef HAVE_SYS_UN_H + struct sockaddr_un UNIXaddr; +#endif + int arg; + DBUG_ENTER("network_init"); + + if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0)) + unireg_abort(1); /* purecov: inspected */ + + set_ports(); + + if (!opt_disable_networking && !opt_bootstrap) + { + if (mysqld_port) + base_ip_sock= activate_tcp_port(mysqld_port); + if (mysqld_extra_port) + extra_ip_sock= activate_tcp_port(mysqld_extra_port); + } + +#ifdef __NT__ /* create named pipe */ if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe) { + strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", mysqld_unix_port, NullS); bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity)); @@ -1964,6 +2308,7 @@ static void network_init(void) DBUG_VOID_RETURN; } + #endif /*!EMBEDDED_LIBRARY*/ @@ -1998,17 +2343,14 @@ void close_connection(THD *thd, uint sql_errno) #endif /* EMBEDDED_LIBRARY */ -/** Called when a thread is aborted. */ +/** Called when mysqld is aborted with ^C */ /* ARGSUSED */ -extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) +extern "C" sig_handler end_mysqld_signal(int sig __attribute__((unused))) { - THD *thd=current_thd; - DBUG_ENTER("end_thread_signal"); - if (thd && ! thd->bootstrap) - { - statistic_increment(killed_threads, &LOCK_status); - MYSQL_CALLBACK(thread_scheduler, end_thread, (thd,0)); /* purecov: inspected */ - } + DBUG_ENTER("end_mysqld_signal"); + /* Don't call kill_mysql() if signal thread is not running */ + if (signal_thread_in_use) + kill_mysql(); // Take down mysqld nicely DBUG_VOID_RETURN; /* purecov: deadcode */ } @@ -2033,10 +2375,10 @@ void thd_cleanup(THD *thd) dec_connection_count() */ -void dec_connection_count() +void dec_connection_count(THD *thd) { mysql_mutex_lock(&LOCK_connection_count); - --connection_count; + (*thd->scheduler->connection_count)--; mysql_mutex_unlock(&LOCK_connection_count); } @@ -2073,7 +2415,7 @@ void unlink_thd(THD *thd) DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); thd_cleanup(thd); - dec_connection_count(); + dec_connection_count(thd); mysql_mutex_lock(&LOCK_thread_count); /* Used by binlog_reset_master. It would be cleaner to use @@ -2154,7 +2496,7 @@ static bool cache_thread() this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; - thd->thr_create_utime= my_micro_time(); + thd->thr_create_utime= microsecond_interval_timer(); threads.append(thd); return(1); } @@ -2186,6 +2528,8 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) { DBUG_ENTER("one_thread_per_connection_end"); unlink_thd(thd); + /* Mark that current_thd is not valid anymore */ + my_pthread_setspecific_ptr(THR_THD, 0); if (put_in_cache) put_in_cache= cache_thread(); mysql_mutex_unlock(&LOCK_thread_count); @@ -2283,8 +2627,8 @@ static BOOL WINAPI console_event_handler( DWORD type ) #ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER #define DEBUGGER_ATTACH_TIMEOUT 120 /* - Wait for debugger to attach and break into debugger. If debugger is not attached, - resume after timeout. + Wait for debugger to attach and break into debugger. If debugger is + not attached, resume after timeout. */ static void wait_for_debugger(int timeout_sec) { @@ -2409,11 +2753,15 @@ extern "C" char *my_demangle(const char *mangled_name, int *status) } #endif +extern const char *optimizer_switch_names[]; extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; struct tm tm; +#ifdef HAVE_STACKTRACE + THD *thd=current_thd; +#endif /* Strictly speaking, one needs a mutex here @@ -2432,13 +2780,13 @@ extern "C" sig_handler handle_segfault(int sig) curr_time= my_time(0); localtime_r(&curr_time, &tm); - fprintf(stderr,"\ -%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\ + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ", + tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + fprintf(stderr,"[ERROR] mysqld got " SIGNAL_FMT " ;\n\ This could be because you hit a bug. It is also possible that this binary\n\ or one of the libraries it was linked against is corrupt, improperly built,\n\ or misconfigured. This error can also be caused by malfunctioning hardware.\n", - tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec, sig); fprintf(stderr, "\ We will try our best to scrape up some info that will hopefully help diagnose\n\ @@ -2448,16 +2796,16 @@ and this may fail.\n\n"); (ulong) dflt_key_cache->key_cache_mem_size); fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size); fprintf(stderr, "max_used_connections=%lu\n", max_used_connections); - fprintf(stderr, "max_threads=%u\n", thread_scheduler->max_threads); + fprintf(stderr, "max_threads=%u\n", thread_scheduler->max_threads + + (uint) extra_max_connections); fprintf(stderr, "thread_count=%u\n", thread_count); - fprintf(stderr, "connection_count=%u\n", connection_count); fprintf(stderr, "It is possible that mysqld could use up to \n\ key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\ bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size + (global_system_variables.read_buff_size + global_system_variables.sortbuff_size) * - thread_scheduler->max_threads + - max_connections * sizeof(THD)) / 1024); + (thread_scheduler->max_threads + extra_max_connections) + + (max_connections + extra_max_connections)* sizeof(THD)) / 1024); fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n"); #if defined(HAVE_LINUXTHREADS) @@ -2473,9 +2821,8 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE - THD *thd=current_thd; - if (!(test_flags & TEST_NO_STACKTRACE)) + if (opt_stack_trace) { fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd); fprintf(stderr, "Attempting backtrace. You can use the following " @@ -2508,10 +2855,20 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", fprintf(stderr, "\nTrying to get some variables.\n" "Some pointers may be invalid and cause the dump to abort.\n"); fprintf(stderr, "Query (%p): ", thd->query()); - my_safe_print_str(thd->query(), min(1024, thd->query_length())); - fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id); + my_safe_print_str(thd->query(), min(65536,thd->query_length())); + fprintf(stderr, "\nConnection ID (thread ID): %lu\n", (ulong) thd->thread_id); fprintf(stderr, "Status: %s\n", kreason); - fputc('\n', stderr); + fprintf(stderr, "Optimizer switch: "); + + ulonglong optsw= global_system_variables.optimizer_switch; + for (uint i= 0; optimizer_switch_names[i+1]; i++, optsw >>= 1) + { + if (i) + fputc(',', stderr); + fprintf(stderr, "%s=%s", + optimizer_switch_names[i], optsw & 1 ? "on" : "off"); + } + fprintf(stderr, "\n\n"); } fprintf(stderr, "\ The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\ @@ -2539,7 +2896,7 @@ You should either build a dynamically-linked binary, or force LinuxThreads\n\ to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\ the documentation for your distribution on how to do that.\n"); #endif - + if (locked_in_memory) { fprintf(stderr, "\n\ @@ -2561,8 +2918,11 @@ bugs.\n"); #endif #ifndef __WIN__ - /* On Windows, do not terminate, but pass control to exception filter */ + /* Terminate */ exit(1); +#else + /* On Windows, do not terminate, but pass control to exception filter */ + ; #endif } @@ -2584,7 +2944,7 @@ static void init_signals(void) my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! - if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) + if (opt_stack_trace || (test_flags & TEST_CORE_ON_SIGNAL)) { sa.sa_flags = SA_RESETHAND | SA_NODEFER; sigemptyset(&sa.sa_mask); @@ -2612,7 +2972,7 @@ static void init_signals(void) { /* Change limits so that we will get a core file */ STRUCT_RLIMIT rl; - rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; + rl.rlim_cur = rl.rlim_max = (rlim_t) RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings) sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); } @@ -2641,12 +3001,13 @@ static void init_signals(void) sigaddset(&set,THR_SERVER_ALARM); if (test_flags & TEST_SIGINT) { - my_sigset(thr_kill_signal, end_thread_signal); - // May be SIGINT - sigdelset(&set, thr_kill_signal); + /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ + my_sigset(SIGINT, end_mysqld_signal); + sigdelset(&set, SIGINT); } else sigaddset(&set,SIGINT); + sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; @@ -2705,12 +3066,13 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) This should actually be '+ max_number_of_slaves' instead of +10, but the +10 should be quite safe. */ - init_thr_alarm(thread_scheduler->max_threads + + init_thr_alarm(thread_scheduler->max_threads + extra_max_connections + global_system_variables.max_insert_delayed_threads + 10); - if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT)) + if (test_flags & TEST_SIGINT) { - (void) sigemptyset(&set); // Setup up SIGINT for debug - (void) sigaddset(&set,SIGINT); // For debugging + /* Allow SIGINT to break mysqld. This is for debugging with --gdb */ + (void) sigemptyset(&set); + (void) sigaddset(&set,SIGINT); (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); } (void) sigemptyset(&set); // Setup up SIGINT for debug @@ -2754,8 +3116,8 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) { DBUG_PRINT("quit",("signal_handler: calling my_thread_end()")); my_thread_end(); - signal_thread_in_use= 0; DBUG_LEAVE; // Must match DBUG_ENTER() + signal_thread_in_use= 0; pthread_exit(0); // Safety return 0; // Avoid compiler warnings } @@ -2846,44 +3208,44 @@ extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); void my_message_sql(uint error, const char *str, myf MyFlags) { THD *thd= current_thd; + MYSQL_ERROR::enum_warning_level level; + sql_print_message_func func; + DBUG_ENTER("my_message_sql"); DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); DBUG_ASSERT(str != NULL); - /* - An error should have a valid error number (!= 0), so it can be caught - in stored procedures by SQL exception handlers. - Calling my_error() with error == 0 is a bug. - Remaining known places to fix: - - storage/myisam/mi_create.c, my_printf_error() - TODO: - DBUG_ASSERT(error != 0); - */ + DBUG_ASSERT(error != 0); - if (error == 0) + mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str); + if (MyFlags & ME_JUST_INFO) { - /* At least, prevent new abuse ... */ - DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0); - error= ER_UNKNOWN_ERROR; + level= MYSQL_ERROR::WARN_LEVEL_NOTE; + func= sql_print_information; + } + else if (MyFlags & ME_JUST_WARNING) + { + level= MYSQL_ERROR::WARN_LEVEL_WARN; + func= sql_print_warning; + } + else + { + level= MYSQL_ERROR::WARN_LEVEL_ERROR; + func= sql_print_error; } - - mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str); if (thd) { if (MyFlags & ME_FATALERROR) thd->is_fatal_error= 1; - (void) thd->raise_condition(error, - NULL, - MYSQL_ERROR::WARN_LEVEL_ERROR, - str); + (void) thd->raise_condition(error, NULL, level, str); } /* When simulating OOM, skip writing to error log to avoid mtr errors */ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;); - if (!thd || MyFlags & ME_NOREFRESH) - sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */ + if (!thd || (MyFlags & ME_NOREFRESH)) + (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */ DBUG_VOID_RETURN; } @@ -2926,7 +3288,10 @@ const char *load_default_groups[]= { #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE "mysql_cluster", #endif -"mysqld","server", MYSQL_BASE_VERSION, 0, 0}; +"mysqld", "server", MYSQL_BASE_VERSION, +"mariadb", MARIADB_BASE_VERSION, +"client-server", +0, 0}; #if defined(__WIN__) && !defined(EMBEDDED_LIBRARY) static const int load_default_groups_sz= @@ -3061,6 +3426,7 @@ SHOW_VAR com_status_vars[]= { {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS}, {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS}, {"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS}, + {"show_client_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CLIENT_STATS]), SHOW_LONG_STATUS}, {"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS}, {"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS}, {"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS}, @@ -3082,6 +3448,7 @@ SHOW_VAR com_status_vars[]= { {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS}, {"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS}, {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS}, + {"show_index_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_INDEX_STATS]), SHOW_LONG_STATUS}, {"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS}, {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS}, {"show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS}, @@ -3098,9 +3465,11 @@ SHOW_VAR com_status_vars[]= { {"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS}, {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS}, {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS}, + {"show_table_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATS]), SHOW_LONG_STATUS}, {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS}, {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS}, {"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS}, + {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS}, {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS}, {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS}, {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS}, @@ -3126,23 +3495,11 @@ SHOW_VAR com_status_vars[]= { {NullS, NullS, SHOW_LONG} }; -/** - Create the name of the default general log file - - @param[IN] buff Location for building new string. - @param[IN] log_ext The extension for the file (e.g .log) - @returns Pointer to a new string containing the name -*/ -static inline char *make_default_log_name(char *buff,const char* log_ext) -{ - return make_log_name(buff, default_logfile_name, log_ext); -} - static int init_common_variables() { - char buff[FN_REFLEN]; umask(((~my_umask) & 0666)); my_decimal_set_zero(&decimal_zero); // set decimal_zero constant; + tzset(); // Set tzname max_system_variables.pseudo_thread_id= (ulong)~0; @@ -3206,17 +3563,23 @@ static int init_common_variables() if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0) { + /* + Get hostname of computer (used by 'show variables') and as default + basename for the pid file if --log-basename is not given. + */ strmake(glob_hostname, STRING_WITH_LEN("localhost")); sql_print_warning("gethostname failed, using '%s' as hostname", - glob_hostname); - strmake(default_logfile_name, STRING_WITH_LEN("mysql")); + glob_hostname); + opt_log_basename= const_cast<char *>("mysql"); } else - strmake(default_logfile_name, glob_hostname, - sizeof(default_logfile_name)-5); + opt_log_basename= glob_hostname; - strmake(pidfile_name, default_logfile_name, sizeof(pidfile_name)-5); - strmov(fn_ext(pidfile_name),".pid"); // Add proper extension + if (!*pidfile_name) + { + strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5); + strmov(fn_ext(pidfile_name),".pid"); // Add proper extension + } /* The default-storage-engine entry in my_long_options should have a @@ -3230,7 +3593,7 @@ static int init_common_variables() (except in the embedded server, where the default continues to be MyISAM) */ -#ifdef EMBEDDED_LIBRARY +#ifndef WITH_INNOBASE_STORAGE_ENGINE default_storage_engine= const_cast<char *>("MyISAM"); #else default_storage_engine= const_cast<char *>("InnoDB"); @@ -3357,7 +3720,8 @@ static int init_common_variables() uint files, wanted_files, max_open_files; /* MyISAM requires two file handles per table. */ - wanted_files= 10+max_connections+table_cache_size*2; + wanted_files= (10 + max_connections + extra_max_connections + + table_cache_size*2); /* We are trying to allocate no less than max_connections*5 file handles (i.e. we are trying to set the limit so that they will @@ -3368,7 +3732,8 @@ static int init_common_variables() can't get max_connections*5 but still got no less than was requested (value of wanted_files). */ - max_open_files= max(max(wanted_files, max_connections*5), + max_open_files= max(max(wanted_files, + (max_connections + extra_max_connections)*5), open_files_limit); files= my_set_max_open_files(max_open_files); @@ -3414,7 +3779,7 @@ static int init_common_variables() if (init_errmessage()) /* Read error messages from file */ return 1; init_client_errs(); - mysql_client_plugin_init(); + mysql_library_init(unused,unused,unused); /* for replication */ lex_init(); if (item_create_init()) return 1; @@ -3475,7 +3840,8 @@ static int init_common_variables() global_system_variables.collation_connection= default_charset_info; global_system_variables.character_set_results= default_charset_info; global_system_variables.character_set_client= default_charset_info; - if (!(character_set_filesystem= + + if (!(character_set_filesystem= get_charset_by_csname(character_set_filesystem_name, MY_CS_PRIMARY, MYF(MY_WME)))) return 1; @@ -3490,29 +3856,22 @@ static int init_common_variables() global_system_variables.lc_time_names= my_default_lc_time_names; /* check log options and issue warnings if needed */ - if (opt_log && opt_logname && !(log_output_options & LOG_FILE) && - !(log_output_options & LOG_NONE)) + if (opt_log && opt_logname && *opt_logname && + !(log_output_options & (LOG_FILE | LOG_NONE))) sql_print_warning("Although a path was specified for the " "--log option, log tables are used. " "To enable logging to files use the --log-output option."); - if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE) - && !(log_output_options & LOG_NONE)) + if (opt_slow_log && opt_slow_logname && *opt_slow_logname && + !(log_output_options & (LOG_FILE | LOG_NONE))) sql_print_warning("Although a path was specified for the " "--log-slow-queries option, log tables are used. " "To enable logging to files use the --log-output=file option."); -#define FIX_LOG_VAR(VAR, ALT) \ - if (!VAR || !*VAR) \ - { \ - my_free(VAR); /* it could be an allocated empty string "" */ \ - VAR= my_strdup(ALT, MYF(0)); \ - } - - FIX_LOG_VAR(opt_logname, - make_default_log_name(buff, ".log")); - FIX_LOG_VAR(opt_slow_logname, - make_default_log_name(buff, "-slow.log")); + if (!opt_logname || !*opt_logname) + make_default_log_name(&opt_logname, ".log", false); + if (!opt_slow_logname || !*opt_slow_logname) + make_default_log_name(&opt_slow_logname, "-slow.log", false); #if defined(ENABLED_DEBUG_SYNC) /* Initialize the debug sync facility. See debug_sync.cc. */ @@ -3557,8 +3916,7 @@ You should consider changing lower_case_table_names to 1 or 2", } } else if (lower_case_table_names == 2 && - !(lower_case_file_system= - (test_if_case_insensitive(mysql_real_data_home) == 1))) + !(lower_case_file_system= (lower_case_file_system == 1))) { if (global_system_variables.log_warnings) sql_print_warning("lower_case_table_names was set to 2, even though your " @@ -3569,8 +3927,7 @@ You should consider changing lower_case_table_names to 1 or 2", } else { - lower_case_file_system= - (test_if_case_insensitive(mysql_real_data_home) == 1); + lower_case_file_system= (lower_case_file_system == 1); } /* Reset table_alias_charset, now that lower_case_table_names is set. */ @@ -3605,10 +3962,22 @@ static int init_thread_environment() &LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_error_messages, &LOCK_error_messages, MY_MUTEX_INIT_FAST); - mysql_mutex_init(key_LOCK_uuid_generator, - &LOCK_uuid_generator, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_uuid_short_generator, + &LOCK_short_uuid_generator, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_connection_count, &LOCK_connection_count, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_stats, &LOCK_stats, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_global_user_client_stats, + &LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_global_table_stats, + &LOCK_global_table_stats, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_global_index_stats, + &LOCK_global_index_stats, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_prepare_ordered, &LOCK_prepare_ordered, + MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered, + MY_MUTEX_INIT_SLOW); + #ifdef HAVE_OPENSSL mysql_mutex_init(key_LOCK_des_key_file, &LOCK_des_key_file, MY_MUTEX_INIT_FAST); @@ -3660,20 +4029,20 @@ static int init_thread_environment() #if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) static unsigned long openssl_id_function() -{ +{ return (unsigned long) pthread_self(); -} +} static openssl_lock_t *openssl_dynlock_create(const char *file, int line) -{ +{ openssl_lock_t *lock= new openssl_lock_t; mysql_rwlock_init(key_rwlock_openssl, &lock->lock); return lock; } -static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, +static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, int line) { mysql_rwlock_destroy(&lock->lock); @@ -3693,7 +4062,7 @@ static void openssl_lock_function(int mode, int n, const char *file, int line) } -static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, +static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, int line) { int err; @@ -3718,7 +4087,7 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode); abort(); } - if (err) + if (err) { sql_print_error("Fatal: can't %s OpenSSL lock", what); abort(); @@ -3774,6 +4143,32 @@ static void end_ssl() #endif /* HAVE_OPENSSL */ } +#ifdef _WIN32 +/** + Registers a file to be collected when Windows Error Reporting creates a crash + report. + + @note only works on Vista and later, since WerRegisterFile() is not available + on earlier Windows. +*/ +#include <werapi.h> +static void add_file_to_crash_report(char *file) +{ + /* Load WerRegisterFile function dynamically.*/ + HRESULT (WINAPI *pWerRegisterFile)(PCWSTR, WER_REGISTER_FILE_TYPE, DWORD) + =(HRESULT (WINAPI *) (PCWSTR, WER_REGISTER_FILE_TYPE, DWORD)) + GetProcAddress(GetModuleHandle("kernel32"),"WerRegisterFile"); + + if (pWerRegisterFile) + { + wchar_t wfile[MAX_PATH+1]= {0}; + if (mbstowcs(wfile, file, MAX_PATH) != (size_t)-1) + { + pWerRegisterFile(wfile, WerRegFileTypeOther, WER_FILE_ANONYMOUS_DATA); + } + } +} +#endif static int init_server_components() { @@ -3789,12 +4184,14 @@ static int init_server_components() query_cache_set_min_res_unit(query_cache_min_res_unit); query_cache_init(); query_cache_resize(query_cache_size); - randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); + my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2); setup_fpu(); init_thr_lock(); + my_uuid_init((ulong) (my_rnd(&sql_rand))*12345,12345); #ifdef HAVE_REPLICATION init_slave_list(); #endif + wt_init(); /* Setup logs */ @@ -3829,9 +4226,16 @@ static int init_server_components() if (!res) setbuf(stderr, NULL); + +#ifdef _WIN32 + /* Add error log to windows crash reporting. */ + add_file_to_crash_report(log_error_file); +#endif } } + /* set up the hook before initializing plugins which may use it */ + error_handler_hook= my_message_sql; proc_info_hook= set_thd_proc_info; #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE @@ -3933,8 +4337,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); } if (ln == buf) { - my_free(opt_bin_logname); - opt_bin_logname=my_strdup(buf, MYF(0)); + opt_bin_logname= my_once_strdup(buf, MYF(MY_WME)); } if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE)) { @@ -3943,7 +4346,10 @@ a file name for --log-bin-index option", opt_binlog_index_name); } /* call ha_init_key_cache() on all key caches to init them */ - process_key_caches(&ha_init_key_cache); + process_key_caches(&ha_init_key_cache, 0); + + init_global_table_stats(); + init_global_index_stats(); /* Allow storage engine to give real error messages */ if (ha_init_errors()) @@ -3989,8 +4395,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); if (remaining_argc > 1) { - fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n" - "Use --verbose --help to get a list of available options\n", + fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n", my_progname, remaining_argv[1]); unireg_abort(1); } @@ -4010,7 +4415,6 @@ a file name for --log-bin-index option", opt_binlog_index_name); unireg_abort(1); } -#ifdef WITH_CSV_STORAGE_ENGINE if (opt_bootstrap) log_output_options= LOG_FILE; else @@ -4044,10 +4448,6 @@ a file name for --log-bin-index option", opt_binlog_index_name); logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE, opt_log ? log_output_options:LOG_NONE); } -#else - logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE, - opt_log ? LOG_FILE:LOG_NONE); -#endif /* Set the default storage engine @@ -4079,9 +4479,18 @@ a file name for --log-bin-index option", opt_binlog_index_name); Need to unlock as global_system_variables.table_plugin was acquired during plugin_init() */ + mysql_mutex_lock(&LOCK_global_system_variables); plugin_unlock(0, global_system_variables.table_plugin); global_system_variables.table_plugin= plugin; + mysql_mutex_unlock(&LOCK_global_system_variables); } +#if defined(WITH_ARIA_STORAGE_ENGINE) && defined(USE_ARIA_FOR_TMP_TABLES) + if (!ha_storage_engine_is_enabled(maria_hton) && !opt_bootstrap) + { + sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables"); + unireg_abort(1); + } +#endif tc_log= (total_ha_2pc > 1 ? (opt_bin_log ? (TC_LOG *) &mysql_bin_log : @@ -4140,6 +4549,8 @@ a file name for --log-bin-index option", opt_binlog_index_name); init_max_user_conn(); init_update_queries(); + init_global_user_stats(); + init_global_client_stats(); DBUG_RETURN(0); } @@ -4213,7 +4624,7 @@ static void handle_connections_methods() handler_count--; } } -#endif +#endif while (handler_count > 0) mysql_cond_wait(&COND_handler_count, &LOCK_thread_count); @@ -4395,13 +4806,6 @@ int mysqld_main(int argc, char **argv) init_error_log_mutex(); - /* Set signal used to kill MySQL */ -#if defined(SIGUSR2) - thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2; -#else - thr_kill_signal= SIGINT; -#endif - /* Initialize audit interface globals. Audit plugins are inited later. */ mysql_audit_initialize(); @@ -4489,13 +4893,14 @@ int mysqld_main(int argc, char **argv) #ifndef DBUG_OFF test_lc_time_sz(); + srand((uint) time(NULL)); #endif /* We have enough space for fiddling with the argv, continue */ check_data_home(mysql_real_data_home); - if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help) + if (my_setwd(mysql_real_data_home, opt_help ? 0 : MYF(MY_WME)) && !opt_help) unireg_abort(1); /* purecov: inspected */ if ((user_info= check_user(mysqld_user))) @@ -4545,7 +4950,6 @@ int mysqld_main(int argc, char **argv) init signals & alarm After this we can't quit by a simple unireg_abort */ - error_handler_hook= my_message_sql; start_signal_handler(); // Creates pidfile if (mysql_rm_tmp_tables() || acl_init(opt_noacl) || @@ -4617,7 +5021,13 @@ int mysqld_main(int argc, char **argv) { select_thread_in_use= 0; // Allow 'kill' to work bootstrap(mysql_stdin); - unireg_abort(bootstrap_error ? 1 : 0); + if (!kill_in_progress) + unireg_abort(bootstrap_error ? 1 : 0); + else + { + sleep(2); // Wait for kill + exit(0); + } } if (opt_init_file && *opt_init_file) { @@ -4625,6 +5035,12 @@ int mysqld_main(int argc, char **argv) unireg_abort(1); } + /* + We must have LOCK_open before LOCK_global_system_variables because + LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. + */ + mysql_mutex_record_order(&LOCK_open, &LOCK_global_system_variables); + create_shutdown_thread(); start_handle_manager(); @@ -4651,7 +5067,7 @@ int mysqld_main(int argc, char **argv) #endif /* _WIN32 || HAVE_SMEM */ /* (void) pthread_attr_destroy(&connection_attrib); */ - + DBUG_PRINT("quit",("Exiting main thread")); #ifndef __WIN__ @@ -4693,7 +5109,6 @@ int mysqld_main(int argc, char **argv) CloseHandle(hEventShutdown); } #endif - clean_up(1); mysqld_exit(0); } @@ -4742,10 +5157,8 @@ static char *add_quoted_string(char *to, const char *from, char *to_end) @param file_path Path to this program @param startup_option Startup option to mysqld - @retval - 0 option handled - @retval - 1 Could not handle option + @retval 0 option handled + @retval 1 Could not handle option */ static bool @@ -4999,7 +5412,7 @@ void handle_connection_in_main_thread(THD *thd) thread_cache_size=0; // Safety threads.append(thd); mysql_mutex_unlock(&LOCK_thread_count); - thd->start_utime= my_micro_time(); + thd->start_utime= microsecond_interval_timer(); do_handle_one_connection(thd); } @@ -5025,7 +5438,7 @@ void create_thread_to_handle_connection(THD *thd) thread_created++; threads.append(thd); DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id)); - thd->prior_thr_create_utime= thd->start_utime= my_micro_time(); + thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer(); if ((error= mysql_thread_create(key_thread_one_connection, &thd->real_id, &connection_attrib, handle_one_connection, @@ -5040,7 +5453,7 @@ void create_thread_to_handle_connection(THD *thd) mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_lock(&LOCK_connection_count); - --connection_count; + (*thd->scheduler->connection_count)--; mysql_mutex_unlock(&LOCK_connection_count); statistic_increment(aborted_connects,&LOCK_status); @@ -5085,20 +5498,22 @@ static void create_new_thread(THD *thd) mysql_mutex_lock(&LOCK_connection_count); - if (connection_count >= max_connections + 1 || abort_loop) + if (*thd->scheduler->connection_count >= + *thd->scheduler->max_connections + 1|| abort_loop) { mysql_mutex_unlock(&LOCK_connection_count); DBUG_PRINT("error",("Too many connections")); close_connection(thd, ER_CON_COUNT_ERROR); + statistic_increment(denied_connections, &LOCK_status); delete thd; DBUG_VOID_RETURN; } - ++connection_count; + ++*thd->scheduler->connection_count; - if (connection_count > max_used_connections) - max_used_connections= connection_count; + if (connection_count + extra_connection_count > max_used_connections) + max_used_connections= connection_count + extra_connection_count; mysql_mutex_unlock(&LOCK_connection_count); @@ -5115,7 +5530,7 @@ static void create_new_thread(THD *thd) thread_count++; - MYSQL_CALLBACK(thread_scheduler, add_connection, (thd)); + MYSQL_CALLBACK(thd->scheduler, add_connection, (thd)); DBUG_VOID_RETURN; } @@ -5127,10 +5542,11 @@ inline void kill_broken_server() { /* hack to get around signals ignored in syscalls for problem OS's */ if (unix_sock == INVALID_SOCKET || - (!opt_disable_networking && ip_sock == INVALID_SOCKET)) + (!opt_disable_networking && base_ip_sock == INVALID_SOCKET)) { select_thread_in_use = 0; /* The following call will never return */ + DBUG_PRINT("general", ("killing server because socket is closed")); kill_server((void*) MYSQL_KILL_SIGNAL); } } @@ -5150,49 +5566,39 @@ void handle_connections_sockets() THD *thd; struct sockaddr_storage cAddr; int ip_flags=0,socket_flags=0,flags=0,retval; + int extra_ip_flags=0; st_vio *vio_tmp; #ifdef HAVE_POLL int socket_count= 0; - struct pollfd fds[2]; // for ip_sock and unix_sock + struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock +#define setup_fds(X) \ + fds[socket_count].fd= X; \ + fds[socket_count].events= POLLIN; \ + socket_count++ #else fd_set readFDs,clientFDs; - uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1); + uint max_used_connection= (uint) + max(max(base_ip_sock, unix_sock), extra_ip_sock) + 1; +#define setup_fds(X) FD_SET(X,&clientFDs) + FD_ZERO(&clientFDs); #endif DBUG_ENTER("handle_connections_sockets"); - (void) ip_flags; - (void) socket_flags; - -#ifndef HAVE_POLL - FD_ZERO(&clientFDs); -#endif - - if (ip_sock != INVALID_SOCKET) + if (base_ip_sock != INVALID_SOCKET) { -#ifdef HAVE_POLL - fds[socket_count].fd= ip_sock; - fds[socket_count].events= POLLIN; - socket_count++; -#else - FD_SET(ip_sock,&clientFDs); -#endif -#ifdef HAVE_FCNTL - ip_flags = fcntl(ip_sock, F_GETFL, 0); -#endif + setup_fds(base_ip_sock); + ip_flags = fcntl(base_ip_sock, F_GETFL, 0); + } + if (extra_ip_sock != INVALID_SOCKET) + { + setup_fds(extra_ip_sock); + extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0); } #ifdef HAVE_SYS_UN_H -#ifdef HAVE_POLL - fds[socket_count].fd= unix_sock; - fds[socket_count].events= POLLIN; - socket_count++; -#else - FD_SET(unix_sock,&clientFDs); -#endif -#ifdef HAVE_FCNTL + setup_fds(unix_sock); socket_flags=fcntl(unix_sock, F_GETFL, 0); #endif -#endif DBUG_PRINT("general",("Waiting for connections.")); MAYBE_BROKEN_SYSCALL; @@ -5230,26 +5636,26 @@ void handle_connections_sockets() if (fds[i].revents & POLLIN) { sock= fds[i].fd; -#ifdef HAVE_FCNTL flags= fcntl(sock, F_GETFL, 0); -#else - flags= 0; -#endif // HAVE_FCNTL break; } } #else // HAVE_POLL -#ifdef HAVE_SYS_UN_H - if (FD_ISSET(unix_sock,&readFDs)) + if (FD_ISSET(base_ip_sock,&readFDs)) { - sock = unix_sock; - flags= socket_flags; + sock= base_ip_sock; + flags= ip_flags; } else -#endif // HAVE_SYS_UN_H + if (FD_ISSET(extra_ip_sock,&readFDs)) { - sock = ip_sock; - flags= ip_flags; + sock= extra_ip_sock; + flags= extra_ip_flags; + } + else + { + sock = unix_sock; + flags= socket_flags; } #endif // HAVE_POLL @@ -5296,7 +5702,7 @@ void handle_connections_sockets() #ifdef HAVE_LIBWRAP { - if (sock == ip_sock) + if (sock == base_ip_sock || sock == extra_ip_sock) { struct request_info req; signal(SIGCHLD, SIG_DFL); @@ -5377,6 +5783,11 @@ void handle_connections_sockets() if (sock == unix_sock) thd->security_ctx->host=(char*) my_localhost; + if (sock == extra_ip_sock) + { + thd->extra_port= 1; + thd->scheduler= extra_thread_scheduler; + } create_new_thread(thd); } DBUG_VOID_RETURN; @@ -5838,9 +6249,12 @@ struct my_option my_long_options[]= &disconnect_slave_event_count, &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_REPLICATION */ +#ifdef HAVE_STACKTRACE + {"stack-trace", 0 , "Print a symbolic stack trace on failure", + &opt_stack_trace, &opt_stack_trace, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif /* HAVE_STACKTRACE */ {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"external-locking", 0, "Use system (external) locking (disabled by " "default). With this option enabled you can run myisamchk to test " "(not repair) tables while the MySQL server is running. Disable with " @@ -5873,11 +6287,22 @@ struct my_option my_long_options[]= {"log", 'l', "Log connections and queries to file (deprecated option, use " "--general-log/--general-log-file instead).", &opt_logname, &opt_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-basename", OPT_LOG_BASENAME, + "Basename for all log files and the .pid file. This sets all log file " + "names at once (in 'datadir') and is normally the only option you need " + "for specifying log files. Sets names for --log-bin, --log-bin-index, " + "--relay-log, --relay-log-index, --general-log-file, " + "--log-slow-query-log-file, --log-error-file, and --pid-file", + &opt_log_basename, &opt_log_basename, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, - "Log update queries in binary format. Optional (but strongly recommended " - "to avoid replication problems if server's hostname changes) argument " - "should be the chosen location for the binary log files.", - &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC, + "Log update queries in binary format. Optional argument should be name for " + "binary log. If not given " + "datadir/'log-basename'-bin or 'datadir'/mysql-bin will be used (the later if " + "--log-basename is not specified). We strongly recommend to use either " + "--log-basename or specify a filename to ensure that replication doesn't " + "stop if the real hostname of the computer changes'.", + &opt_bin_logname, &opt_bin_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin-index", 0, "File that holds the names for last binary log files.", @@ -5899,9 +6324,10 @@ struct my_option my_long_options[]= &opt_log_slow_slave_statements, &opt_log_slow_slave_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-slow-queries", OPT_SLOW_QUERY_LOG, - "Log slow queries to a table or log file. Defaults logging to table " - "mysql.slow_log or hostname-slow.log if --log-output=file is used. " - "Must be enabled to activate other slow log options. " + "Enable logging of slow queries (longer than --long-query-time) to log file " + "or table. Optional argument is a file name for the slow log. If not given, " + "'log-basename'-slow.log will be used. Use --log-output=TABLE if you want " + "to have the log in the table 'mysql.slow_log'. " "Deprecated option, use --slow-query-log/--slow-query-log-file instead.", &opt_slow_logname, &opt_slow_logname, 0, GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -5913,12 +6339,13 @@ struct my_option my_long_options[]= #ifdef HAVE_MMAP {"log-tc-size", 0, "Size of transaction coordinator log.", &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (longlong) ULONG_MAX, 0, TC_LOG_PAGE_SIZE, 0}, #endif {"master-info-file", 0, "The location and name of the file that remembers the master and where " - "the I/O replication thread is in the master's binlogs.", + "the I/O replication thread is in the master's binlogs. Defaults to " + "master.info", &master_info_file, &master_info_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"master-retry-count", 0, @@ -6013,6 +6440,9 @@ struct my_option my_long_options[]= "Show user and password in SHOW SLAVE HOSTS on this master.", &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"skip-bdb", OPT_DEPRECATED_OPTION, + "Deprecated option; Exist only for compatiblity with old my.cnf files", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DISABLE_GRANT_OPTIONS {"skip-grant-tables", 0, "Start without grant tables. This gives all users FULL ACCESS to all tables.", @@ -6021,14 +6451,9 @@ struct my_option my_long_options[]= #endif {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-slave-start", 0, "If set, slave is not autostarted.", &opt_skip_slave_start, &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-stack-trace", OPT_SKIP_STACK_TRACE, - "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, - 0, 0, 0, 0}, {"skip-thread-priority", OPT_SKIP_PRIOR, "Don't give threads different priorities. This option is deprecated " "because it has no effect; the implied behavior is already the default.", @@ -6058,7 +6483,10 @@ struct my_option my_long_options[]= purify. These are not suppressed: instead we disable symlinks option if compiled with valgrind support. */ - IF_PURIFY(0,1), 0, 0, 0, 0, 0}, + IF_VALGRIND(0,1), 0, 0, 0, 0, 0}, + {"sync_sys", 0, + "Enable system sync calls. Disable only when running tests or debugging!", + &opt_sync, &opt_sync, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"sysdate-is-now", 0, "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. " "Since 5.0, SYSDATE() returns a `dynamic' value different for different " @@ -6106,6 +6534,12 @@ struct my_option my_long_options[]= {"table_cache", 0, "Deprecated; use --table-open-cache instead.", &table_cache_size, &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0}, +#ifndef DBUG_OFF + {"debug-assert-if-crashed-table", 0, + "Do an assert in handler::print_error() if we get a crashed table", + &debug_assert_if_crashed_table, &debug_assert_if_crashed_table, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -6409,7 +6843,7 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *bu } /* - Functions relying on SSL + Functions relying on SSL Note: In the show_ssl_* functions, we need to check if we have a valid vio-object since this isn't always true, specifically when session_status or global_status is requested from @@ -6503,6 +6937,46 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ +static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff) +{ + struct st_data { + KEY_CACHE_STATISTICS stats; + SHOW_VAR var[8]; + } *data; + SHOW_VAR *v; + + data=(st_data *)buff; + v= data->var; + + var->type= SHOW_ARRAY; + var->value= (char*)v; + + get_key_cache_statistics(dflt_key_cache, 0, &data->stats); + +#define set_one_keycache_var(X,Y) \ + v->name= X; \ + v->type= SHOW_LONGLONG; \ + v->value= (char*)&data->stats.Y; \ + v++; + + set_one_keycache_var("blocks_not_flushed", blocks_changed); + set_one_keycache_var("blocks_unused", blocks_unused); + set_one_keycache_var("blocks_used", blocks_used); + set_one_keycache_var("blocks_warm", blocks_warm); + set_one_keycache_var("read_requests", read_requests); + set_one_keycache_var("reads", reads); + set_one_keycache_var("write_requests", write_requests); + set_one_keycache_var("writes", writes); + + v->name= 0; + + DBUG_ASSERT((char*)(v+1) <= buff + SHOW_VAR_FUNC_BUFF_SIZE); + +#undef set_one_keycache_var + + return 0; +} + /* Variables shown by SHOW STATUS in alphabetical order @@ -6511,21 +6985,26 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) SHOW_VAR status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, + {"Access_denied_errors", (char*) offsetof(STATUS_VAR, access_denied_errors), SHOW_LONG_STATUS}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, {"Binlog_stmt_cache_disk_use",(char*) &binlog_stmt_cache_disk_use, SHOW_LONG}, {"Binlog_stmt_cache_use", (char*) &binlog_stmt_cache_use, SHOW_LONG}, + {"Busy_time", (char*) offsetof(STATUS_VAR, busy_time), SHOW_DOUBLE_STATUS}, {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS}, {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, + {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, {"Compression", (char*) &show_net_compression, SHOW_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, + {"Cpu_time", (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS}, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS}, {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG}, + {"Empty_queries", (char*) offsetof(STATUS_VAR, empty_queries), SHOW_LONG_STATUS}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, @@ -6543,13 +7022,9 @@ SHOW_VAR status_vars[]= { {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS}, {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, - {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG}, - {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG}, - {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG}, - {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG}, - {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG}, - {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG}, + {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS}, + {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, + {"Key", (char*) &show_default_keycache, SHOW_FUNC}, {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG}, {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, @@ -6561,6 +7036,9 @@ SHOW_VAR status_vars[]= { {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC}, + {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, + {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, + {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS}, #ifdef HAVE_QUERY_CACHE {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH}, {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH}, @@ -6621,6 +7099,13 @@ SHOW_VAR status_vars[]= { {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC}, #endif #endif /* HAVE_OPENSSL */ + {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH}, + /* + Expression cache used only for caching subqueries now, so its statistic + variables we call subquery_cache*. + */ + {"Subquery_cache_hit", (char*) &subquery_cache_hit, SHOW_LONG}, + {"Subquery_cache_miss", (char*) &subquery_cache_miss, SHOW_LONG}, {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, #ifdef HAVE_MMAP @@ -6768,13 +7253,17 @@ static int mysql_init_variables(void) /* Things reset to zero */ opt_skip_slave_start= opt_reckless_slave = 0; mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; +#if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH) + /* We can only test for sub paths if my_symlink.c is using realpath */ myisam_test_invalid_symlink= test_if_data_home_dir; +#endif opt_log= opt_slow_log= 0; opt_bin_log= 0; opt_disable_networking= opt_skip_show_db=0; opt_skip_name_resolve= 0; opt_ignore_builtin_innodb= 0; - opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0; + opt_logname= opt_binlog_index_name= opt_slow_logname= 0; + opt_log_basename= 0; opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name ! opt_secure_auth= 0; opt_bootstrap= opt_myisam_log= 0; @@ -6791,6 +7280,7 @@ static int mysql_init_variables(void) abort_loop= select_thread_in_use= signal_thread_in_use= 0; ready_to_exit= shutdown_in_progress= grant_option= 0; aborted_threads= aborted_connects= 0; + subquery_cache_miss= subquery_cache_hit= 0; delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0; delayed_insert_errors= thread_created= 0; specialflag= 0; @@ -6816,7 +7306,7 @@ static int mysql_init_variables(void) character_set_filesystem= &my_charset_bin; opt_specialflag= SPECIAL_ENGLISH; - unix_sock= ip_sock= INVALID_SOCKET; + unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET; mysql_home_ptr= mysql_home; pidfile_name_ptr= pidfile_name; log_error_file_ptr= log_error_file; @@ -6837,6 +7327,7 @@ static int mysql_init_variables(void) sql_print_error("Cannot allocate the keycache"); return 1; } + /* set key_cache_hash.default_value = dflt_key_cache */ multi_keycache_init(); @@ -6862,6 +7353,7 @@ static int mysql_init_variables(void) #ifndef DBUG_OFF default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", "d:t:i:o,/tmp/mysqld.trace"); + current_dbug_option= default_dbug_option; #endif opt_error_log= IF_WIN(1,0); #ifdef ENABLED_PROFILING @@ -6956,12 +7448,27 @@ mysqld_get_one_option(int optid, char *argument) { switch(optid) { - case '#': #ifndef DBUG_OFF - DBUG_SET_INITIAL(argument ? argument : default_dbug_option); -#endif + case '#': + if (!argument) + argument= (char*) default_dbug_option; + if (argument[0] == '0' && !argument[1]) + { + DEBUGGER_OFF; + break; + } + DEBUGGER_ON; + if (argument[0] == '1' && !argument[1]) + break; + DBUG_SET_INITIAL(argument); opt_endinfo=1; /* unireg: memory allocation */ break; +#endif + case OPT_DEPRECATED_OPTION: + sql_print_warning("'%s' is deprecated. It does nothing and exists only " + "for compatiblity with old my.cnf files.", + opt->name); + break; case 'a': global_system_variables.sql_mode= MODE_ANSI; global_system_variables.tx_isolation= ISO_SERIALIZABLE; @@ -7019,6 +7526,34 @@ mysqld_get_one_option(int optid, case (int) OPT_BIN_LOG: opt_bin_log= test(argument != disabled_my_option); break; + case (int) OPT_LOG_BASENAME: + { + if (opt_log_basename[0] == 0 || strchr(opt_log_basename, FN_EXTCHAR) || + strchr(opt_log_basename,FN_LIBCHAR)) + { + sql_print_error("Wrong argument for --log-basename. It can't be empty or contain '.' or '" FN_DIRSEP "'"); + return 1; + } + if (log_error_file_ptr != disabled_my_option) + log_error_file_ptr= opt_log_basename; + + make_default_log_name(&opt_logname, ".log", false); + make_default_log_name(&opt_slow_logname, "-slow.log", false); + make_default_log_name(&opt_bin_logname, "-bin", true); + make_default_log_name(&opt_binlog_index_name, "-bin.index", true); + make_default_log_name(&opt_relay_logname, "-relay-bin", true); + make_default_log_name(&opt_relaylog_index_name, "-relay-bin.index", true); + + pidfile_name_ptr= pidfile_name; + strmake(pidfile_name, argument, sizeof(pidfile_name)-5); + strmov(fn_ext(pidfile_name),".pid"); + + /* check for errors */ + if (!opt_bin_logname || !opt_relaylog_index_name || ! opt_logname || + ! opt_slow_logname || !pidfile_name_ptr) + return 1; // out of memory error + break; + } #ifdef HAVE_REPLICATION case (int)OPT_REPLICATE_IGNORE_DB: { @@ -7032,6 +7567,7 @@ mysqld_get_one_option(int optid, } case (int)OPT_REPLICATE_REWRITE_DB: { + /* See also OPT_REWRITE_DB handling in client/mysqlbinlog.cc */ char* key = argument,*p, *val; if (!(p= strstr(argument, "->"))) @@ -7112,23 +7648,14 @@ mysqld_get_one_option(int optid, WARN_DEPRECATED(NULL, 7, 0, "--log-slow-queries", "'--slow-query-log'/'--slow-query-log-file'"); opt_slow_log= 1; break; - case (int) OPT_SKIP_NEW: - opt_specialflag|= SPECIAL_NO_NEW_FUNC; - delay_key_write_options= DELAY_KEY_WRITE_NONE; - myisam_concurrent_insert=0; - myisam_recover_options= HA_RECOVER_OFF; - sp_automatic_privileges=0; - my_use_symdir=0; - ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE); -#ifdef HAVE_QUERY_CACHE - query_cache_size=0; -#endif - break; case (int) OPT_SAFE: - opt_specialflag|= SPECIAL_SAFE_MODE; - delay_key_write_options= DELAY_KEY_WRITE_NONE; + opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC; + delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE; myisam_recover_options= HA_RECOVER_DEFAULT; ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE); +#ifdef HAVE_QUERY_CACHE + query_cache_size=0; +#endif break; case (int) OPT_SKIP_PRIOR: opt_specialflag|= SPECIAL_NO_PRIOR; @@ -7146,9 +7673,6 @@ mysqld_get_one_option(int optid, case (int) OPT_WANT_CORE: test_flags |= TEST_CORE_ON_SIGNAL; break; - case (int) OPT_SKIP_STACK_TRACE: - test_flags|=TEST_NO_STACKTRACE; - break; case (int) OPT_BIND_ADDRESS: { struct addrinfo *res_lst, hints; @@ -7182,7 +7706,7 @@ mysqld_get_one_option(int optid, server_id_supplied = 1; break; case OPT_ONE_THREAD: - thread_handling= SCHEDULER_ONE_THREAD_PER_CONNECTION; + thread_handling= SCHEDULER_NO_THREADS; break; case OPT_LOWER_CASE_TABLE_NAMES: lower_case_table_names_used= 1; @@ -7225,7 +7749,6 @@ mysqld_get_one_option(int optid, break; case OPT_MAX_LONG_DATA_SIZE: max_long_data_size_used= true; - WARN_DEPRECATED(NULL, 5, 6, "--max_long_data_size", "'--max_allowed_packet'"); break; } return 0; @@ -7247,6 +7770,7 @@ mysql_getopt_value(const char *keyname, uint key_length, case OPT_KEY_CACHE_BLOCK_SIZE: case OPT_KEY_CACHE_DIVISION_LIMIT: case OPT_KEY_CACHE_AGE_THRESHOLD: + case OPT_KEY_CACHE_PARTITIONS: { KEY_CACHE *key_cache; if (!(key_cache= get_or_create_key_cache(keyname, key_length))) @@ -7264,6 +7788,8 @@ mysql_getopt_value(const char *keyname, uint key_length, return &key_cache->param_division_limit; case OPT_KEY_CACHE_AGE_THRESHOLD: return &key_cache->param_age_threshold; + case OPT_KEY_CACHE_PARTITIONS: + return (uchar**) &key_cache->param_partitions; } } } @@ -7311,7 +7837,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) opt < my_long_options + array_elements(my_long_options) - 1; opt++) insert_dynamic(&all_options, (uchar*) opt); - sys_var_add_options(&all_options, sys_var::PARSE_NORMAL); + sys_var_add_options(&all_options, 0); add_terminator(&all_options); /* Skip unknown options so that they may be processed later by plugins */ @@ -7367,7 +7893,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) } if (opt_disable_networking) - mysqld_port= 0; + mysqld_port= mysqld_extra_port= 0; if (opt_skip_show_db) opt_specialflag|= SPECIAL_SKIP_SHOW_DB; @@ -7408,7 +7934,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr) if (opt_debugging) { /* Allow break with SIGINT, no core or stack trace */ - test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE; + test_flags|= TEST_SIGINT; + opt_stack_trace= 1; test_flags&= ~TEST_CORE_ON_SIGNAL; } /* Set global MyISAM variables from delay_key_write_options */ @@ -7430,6 +7957,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr) In most cases the global variables will not be used */ my_disable_locking= myisam_single_user= test(opt_external_locking == 0); + my_disable_sync= opt_sync == 0; + my_disable_thr_alarm= opt_thread_alarm == 0; my_default_record_cache_size=global_system_variables.read_buff_size; global_system_variables.long_query_time= (ulonglong) @@ -7447,12 +7976,19 @@ static int get_options(int *argc_ptr, char ***argv_ptr) return 1; #ifdef EMBEDDED_LIBRARY - one_thread_scheduler(); + one_thread_scheduler(thread_scheduler); + one_thread_scheduler(extra_thread_scheduler); #else if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION) - one_thread_per_connection_scheduler(); - else /* thread_handling == SCHEDULER_NO_THREADS) */ - one_thread_scheduler(); + one_thread_per_connection_scheduler(thread_scheduler, &max_connections, + &connection_count); + else if (thread_handling == SCHEDULER_NO_THREADS) + one_thread_scheduler(thread_scheduler); + else + pool_of_threads_scheduler(thread_scheduler); /* purecov: tested */ + one_thread_per_connection_scheduler(extra_thread_scheduler, + &extra_max_connections, + &extra_connection_count); #endif global_system_variables.engine_condition_pushdown= @@ -7563,9 +8099,7 @@ bool is_secure_file_path(char *path) /* The supplied file path might have been a file and not a directory. */ - int length= (int)dirname_length(path); - if (length >= FN_REFLEN) - return FALSE; + size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN memcpy(buff2, path, length); buff2[length]= '\0'; if (length == 0 || my_realpath(buff1, buff2, 0)) @@ -7593,6 +8127,8 @@ bool is_secure_file_path(char *path) static int fix_paths(void) { char buff[FN_REFLEN],*pos; + DBUG_ENTER("fix_paths"); + convert_dirname(mysql_home,mysql_home,NullS); /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */ my_realpath(mysql_home,mysql_home,MYF(0)); @@ -7611,6 +8147,7 @@ static int fix_paths(void) (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr : get_relative_path(PLUGINDIR), mysql_home); opt_plugin_dir_ptr= opt_plugin_dir; + pidfile_name_ptr= pidfile_name; my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0)); mysql_unpacked_real_data_home_len= @@ -7637,7 +8174,7 @@ static int fix_paths(void) charsets_dir=mysql_charsets_dir; if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) - return 1; + DBUG_RETURN(1); if (!opt_mysql_tmpdir) opt_mysql_tmpdir= mysql_tmpdir; #ifdef HAVE_REPLICATION @@ -7647,7 +8184,7 @@ static int fix_paths(void) /* Convert the secure-file-priv option to system format, allowing a quick strcmp to check if read or write is in an allowed dir - */ + */ if (opt_secure_file_priv) { if (*opt_secure_file_priv == 0) @@ -7662,7 +8199,7 @@ static int fix_paths(void) if (my_realpath(buff, opt_secure_file_priv, 0)) { sql_print_warning("Failed to normalize the argument for --secure-file-priv."); - return 1; + DBUG_RETURN(1); } char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE)); convert_dirname(secure_file_real_path, buff, NullS); @@ -7670,8 +8207,7 @@ static int fix_paths(void) opt_secure_file_priv= secure_file_real_path; } } - - return 0; + DBUG_RETURN(0); } /** @@ -7679,12 +8215,9 @@ static int fix_paths(void) @param dir_name Directory to test - @retval - -1 Don't know (Test failed) - @retval - 0 File system is case sensitive - @retval - 1 File system is case insensitive + @retval -1 Don't know (Test failed) + @retval 0 File system is case sensitive + @retval 1 File system is case insensitive */ static int test_if_case_insensitive(const char *dir_name) @@ -7703,7 +8236,8 @@ static int test_if_case_insensitive(const char *dir_name) if ((file= mysql_file_create(key_file_casetest, buff, 0666, O_RDWR, MYF(0))) < 0) { - sql_print_warning("Can't create test file %s", buff); + if (!opt_help) + sql_print_warning("Can't create test file %s", buff); DBUG_RETURN(-1); } mysql_file_close(file, MYF(0)); @@ -7752,12 +8286,14 @@ void refresh_status(THD *thd) /* Reset thread's status variables */ bzero((uchar*) &thd->status_var, sizeof(thd->status_var)); + bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var)); + thd->start_bytes_received= 0; /* Reset some global variables */ reset_status_vars(); /* Reset the counters of all key caches (default and named). */ - process_key_caches(reset_key_cache_counters); + process_key_caches(reset_key_cache_counters, 0); flush_status_time= time((time_t*) 0); mysql_mutex_unlock(&LOCK_status); @@ -7792,258 +8328,3 @@ template class I_List<Statement>; template class I_List_iterator<Statement>; #endif -#ifdef HAVE_PSI_INTERFACE -#ifdef HAVE_MMAP -PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool; -#endif /* HAVE_MMAP */ - -#ifdef HAVE_OPENSSL -PSI_mutex_key key_LOCK_des_key_file; -#endif /* HAVE_OPENSSL */ - -PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, - key_delayed_insert_mutex, key_hash_filo_lock, key_LOCK_active_mi, - key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create, - key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log, - key_LOCK_gdl, key_LOCK_global_system_variables, - key_LOCK_manager, - key_LOCK_prepared_stmt_count, - key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status, - key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data, - key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log, - key_master_info_data_lock, key_master_info_run_lock, - key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, - key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, - key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, - key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, - key_PARTITION_LOCK_auto_inc; -PSI_mutex_key key_RELAYLOG_LOCK_index; - -static PSI_mutex_info all_server_mutexes[]= -{ -#ifdef HAVE_MMAP - { &key_PAGE_lock, "PAGE::lock", 0}, - { &key_LOCK_sync, "TC_LOG_MMAP::LOCK_sync", 0}, - { &key_LOCK_active, "TC_LOG_MMAP::LOCK_active", 0}, - { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pool", 0}, -#endif /* HAVE_MMAP */ - -#ifdef HAVE_OPENSSL - { &key_LOCK_des_key_file, "LOCK_des_key_file", PSI_FLAG_GLOBAL}, -#endif /* HAVE_OPENSSL */ - - { &key_BINLOG_LOCK_index, "MYSQL_BIN_LOG::LOCK_index", 0}, - { &key_BINLOG_LOCK_prep_xids, "MYSQL_BIN_LOG::LOCK_prep_xids", 0}, - { &key_RELAYLOG_LOCK_index, "MYSQL_RELAY_LOG::LOCK_index", 0}, - { &key_delayed_insert_mutex, "Delayed_insert::mutex", 0}, - { &key_hash_filo_lock, "hash_filo::lock", 0}, - { &key_LOCK_active_mi, "LOCK_active_mi", PSI_FLAG_GLOBAL}, - { &key_LOCK_connection_count, "LOCK_connection_count", PSI_FLAG_GLOBAL}, - { &key_LOCK_crypt, "LOCK_crypt", PSI_FLAG_GLOBAL}, - { &key_LOCK_delayed_create, "LOCK_delayed_create", PSI_FLAG_GLOBAL}, - { &key_LOCK_delayed_insert, "LOCK_delayed_insert", PSI_FLAG_GLOBAL}, - { &key_LOCK_delayed_status, "LOCK_delayed_status", PSI_FLAG_GLOBAL}, - { &key_LOCK_error_log, "LOCK_error_log", PSI_FLAG_GLOBAL}, - { &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL}, - { &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL}, - { &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL}, - { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL}, - { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL}, - { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL}, - { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL}, - { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL}, - { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL}, - { &key_LOCK_thd_data, "THD::LOCK_thd_data", 0}, - { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL}, - { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL}, - { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, - { &key_master_info_data_lock, "Master_info::data_lock", 0}, - { &key_master_info_run_lock, "Master_info::run_lock", 0}, - { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, - { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0}, - { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0}, - { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0}, - { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0}, - { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0}, - { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL}, - { &key_LOG_INFO_lock, "LOG_INFO::lock", 0}, - { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL}, - { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0} -}; - -PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger, - key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave, - key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock; - -static PSI_rwlock_info all_server_rwlocks[]= -{ -#if defined (HAVE_OPENSSL) && !defined(HAVE_YASSL) - { &key_rwlock_openssl, "CRYPTO_dynlock_value::lock", 0}, -#endif - { &key_rwlock_LOCK_grant, "LOCK_grant", PSI_FLAG_GLOBAL}, - { &key_rwlock_LOCK_logger, "LOGGER::LOCK_logger", 0}, - { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL}, - { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL}, - { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL}, - { &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0} -}; - -#ifdef HAVE_MMAP -PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool; -#endif /* HAVE_MMAP */ - -PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond, - key_COND_cache_status_changed, key_COND_manager, - key_COND_rpl_status, key_COND_server_started, - key_delayed_insert_cond, key_delayed_insert_cond_client, - key_item_func_sleep_cond, key_master_info_data_cond, - key_master_info_start_cond, key_master_info_stop_cond, - key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, - key_relay_log_info_start_cond, key_relay_log_info_stop_cond, - key_TABLE_SHARE_cond, key_user_level_lock_cond, - key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; -PSI_cond_key key_RELAYLOG_update_cond; - -static PSI_cond_info all_server_conds[]= -{ -#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) - { &key_COND_handler_count, "COND_handler_count", PSI_FLAG_GLOBAL}, -#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ -#ifdef HAVE_MMAP - { &key_PAGE_cond, "PAGE::cond", 0}, - { &key_COND_active, "TC_LOG_MMAP::COND_active", 0}, - { &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0}, -#endif /* HAVE_MMAP */ - { &key_BINLOG_COND_prep_xids, "MYSQL_BIN_LOG::COND_prep_xids", 0}, - { &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0}, - { &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0}, - { &key_COND_cache_status_changed, "Query_cache::COND_cache_status_changed", 0}, - { &key_COND_manager, "COND_manager", PSI_FLAG_GLOBAL}, - { &key_COND_rpl_status, "COND_rpl_status", PSI_FLAG_GLOBAL}, - { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL}, - { &key_delayed_insert_cond, "Delayed_insert::cond", 0}, - { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0}, - { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0}, - { &key_master_info_data_cond, "Master_info::data_cond", 0}, - { &key_master_info_start_cond, "Master_info::start_cond", 0}, - { &key_master_info_stop_cond, "Master_info::stop_cond", 0}, - { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0}, - { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0}, - { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0}, - { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0}, - { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0}, - { &key_user_level_lock_cond, "User_level_lock::cond", 0}, - { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL}, - { &key_COND_thread_cache, "COND_thread_cache", PSI_FLAG_GLOBAL}, - { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL} -}; - -PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert, - key_thread_handle_manager, key_thread_main, - key_thread_one_connection, key_thread_signal_hand; - -static PSI_thread_info all_server_threads[]= -{ -#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) - { &key_thread_handle_con_namedpipes, "con_named_pipes", PSI_FLAG_GLOBAL}, -#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ - -#if defined(HAVE_SMEM) && !defined(EMBEDDED_LIBRARY) - { &key_thread_handle_con_sharedmem, "con_shared_mem", PSI_FLAG_GLOBAL}, -#endif /* HAVE_SMEM && !EMBEDDED_LIBRARY */ - -#if (defined(_WIN32) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY) - { &key_thread_handle_con_sockets, "con_sockets", PSI_FLAG_GLOBAL}, -#endif /* _WIN32 || HAVE_SMEM && !EMBEDDED_LIBRARY */ - -#ifdef __WIN__ - { &key_thread_handle_shutdown, "shutdown", PSI_FLAG_GLOBAL}, -#endif /* __WIN__ */ - - { &key_thread_bootstrap, "bootstrap", PSI_FLAG_GLOBAL}, - { &key_thread_delayed_insert, "delayed_insert", 0}, - { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL}, - { &key_thread_main, "main", PSI_FLAG_GLOBAL}, - { &key_thread_one_connection, "one_connection", 0}, - { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL} -}; - -#ifdef HAVE_MMAP -PSI_file_key key_file_map; -#endif /* HAVE_MMAP */ - -PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, - key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, - key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, - key_file_loadfile, key_file_log_event_data, key_file_log_event_info, - key_file_master_info, key_file_misc, key_file_partition, - key_file_pid, key_file_relay_log_info, key_file_send_file, key_file_tclog, - key_file_trg, key_file_trn, key_file_init; -PSI_file_key key_file_query_log, key_file_slow_log; -PSI_file_key key_file_relaylog, key_file_relaylog_index; - -static PSI_file_info all_server_files[]= -{ -#ifdef HAVE_MMAP - { &key_file_map, "map", 0}, -#endif /* HAVE_MMAP */ - { &key_file_binlog, "binlog", 0}, - { &key_file_binlog_index, "binlog_index", 0}, - { &key_file_relaylog, "relaylog", 0}, - { &key_file_relaylog_index, "relaylog_index", 0}, - { &key_file_casetest, "casetest", 0}, - { &key_file_dbopt, "dbopt", 0}, - { &key_file_des_key_file, "des_key_file", 0}, - { &key_file_ERRMSG, "ERRMSG", 0}, - { &key_select_to_file, "select_to_file", 0}, - { &key_file_fileparser, "file_parser", 0}, - { &key_file_frm, "FRM", 0}, - { &key_file_global_ddl_log, "global_ddl_log", 0}, - { &key_file_load, "load", 0}, - { &key_file_loadfile, "LOAD_FILE", 0}, - { &key_file_log_event_data, "log_event_data", 0}, - { &key_file_log_event_info, "log_event_info", 0}, - { &key_file_master_info, "master_info", 0}, - { &key_file_misc, "misc", 0}, - { &key_file_partition, "partition", 0}, - { &key_file_pid, "pid", 0}, - { &key_file_query_log, "query_log", 0}, - { &key_file_relay_log_info, "relay_log_info", 0}, - { &key_file_send_file, "send_file", 0}, - { &key_file_slow_log, "slow_log", 0}, - { &key_file_tclog, "tclog", 0}, - { &key_file_trg, "trigger_name", 0}, - { &key_file_trn, "trigger", 0}, - { &key_file_init, "init", 0} -}; - -/** - Initialise all the performance schema instrumentation points - used by the server. -*/ -void init_server_psi_keys(void) -{ - const char* category= "sql"; - int count; - - if (PSI_server == NULL) - return; - - count= array_elements(all_server_mutexes); - PSI_server->register_mutex(category, all_server_mutexes, count); - - count= array_elements(all_server_rwlocks); - PSI_server->register_rwlock(category, all_server_rwlocks, count); - - count= array_elements(all_server_conds); - PSI_server->register_cond(category, all_server_conds, count); - - count= array_elements(all_server_threads); - PSI_server->register_thread(category, all_server_threads, count); - - count= array_elements(all_server_files); - PSI_server->register_file(category, all_server_files, count); -} - -#endif /* HAVE_PSI_INTERFACE */ - |