summaryrefslogtreecommitdiff
path: root/sql/mysqld.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r--sql/mysqld.cc2893
1 files changed, 2124 insertions, 769 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index a9359ba047e..0abb394f89f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2015, SkySQL Ab.
+ Copyright (c) 2008, 2016, MariaDB
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
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
+#include "sql_plugin.h" // Includes my_global.h
#include "sql_priv.h"
#include "unireg.h"
#include <signal.h>
@@ -40,9 +40,7 @@
#include "hostname.h" // hostname_cache_free, hostname_cache_init
#include "sql_acl.h" // acl_free, grant_free, acl_init,
// grant_init
-#include "sql_base.h" // table_def_free, table_def_init,
- // cached_open_tables,
- // cached_table_definitions
+#include "sql_base.h"
#include "sql_test.h" // mysql_print_status
#include "item_create.h" // item_create_cleanup, item_create_init
#include "sql_servers.h" // servers_free, servers_init
@@ -52,6 +50,7 @@
#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 "sys_vars_shared.h"
#include <m_ctype.h>
#include <my_dir.h>
@@ -85,6 +84,10 @@ ulong wsrep_running_threads = 0; // # of currently running wsrep threads
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
#include "../storage/perfschema/pfs_server.h"
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+#include <mysql/psi/mysql_idle.h>
+#include <mysql/psi/mysql_socket.h>
+#include <mysql/psi/mysql_statement.h>
+#include "mysql_com_server.h"
#include "keycaches.h"
#include "../storage/myisam/ha_myisam.h"
@@ -118,7 +121,6 @@ ulong wsrep_running_threads = 0; // # of currently running wsrep threads
#endif
extern "C" { // Because of SCO 3.2V4.2
-#include <errno.h>
#include <sys/stat.h>
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
@@ -342,6 +344,13 @@ static PSI_rwlock_key key_rwlock_openssl;
volatile sig_atomic_t ld_assume_kernel_is_set= 0;
#endif
+/**
+ Statement instrumentation key for replication.
+*/
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+PSI_statement_info stmt_info_rpl;
+#endif
+
/* the default log output is log tables */
static bool lower_case_table_names_used= 0;
static bool max_long_data_size_used= false;
@@ -369,12 +378,14 @@ 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;
+mysql_cond_t COND_slave_init;
static DYNAMIC_ARRAY all_options;
/* Global variables */
#ifdef WITH_WSREP
ulong my_bind_addr;
+bool wsrep_new_cluster= false;
#endif /* WITH_WSREP */
bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0;
my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0;
@@ -483,17 +494,21 @@ ulong delay_key_write_options;
uint protocol_version;
uint lower_case_table_names;
ulong tc_heuristic_recover= 0;
-uint volatile thread_count;
+int32 thread_count, service_thread_count;
int32 thread_running;
+int32 slave_open_temp_tables;
ulong thread_created;
ulong back_log, connect_timeout, concurrency, server_id;
-ulong table_cache_size, table_def_size;
ulong what_to_log;
-ulong slow_launch_time, slave_open_temp_tables;
-ulong open_files_limit, max_binlog_size, max_relay_log_size;
+ulong slow_launch_time;
+ulong open_files_limit, max_binlog_size;
ulong slave_trans_retries;
uint slave_net_timeout;
ulong slave_exec_mode_options;
+#ifdef RBR_TRIGGERS
+ulong slave_run_triggers_for_rbr= 0;
+#endif //RBR_TRIGGERS
+ulong slave_ddl_exec_mode_options= SLAVE_EXEC_MODE_IDEMPOTENT;
ulonglong slave_type_conversions_options;
ulong thread_cache_size=0;
ulonglong binlog_cache_size=0;
@@ -502,11 +517,14 @@ ulong slave_max_allowed_packet= 0;
ulonglong binlog_stmt_cache_size=0;
ulonglong max_binlog_stmt_cache_size=0;
ulonglong query_cache_size=0;
-ulong refresh_version; /* Increments on each reload */
+ulong query_cache_limit=0;
ulong executed_events=0;
query_id_t global_query_id;
my_atomic_rwlock_t global_query_id_lock;
my_atomic_rwlock_t thread_running_lock;
+my_atomic_rwlock_t thread_count_lock;
+my_atomic_rwlock_t statistics_lock;
+my_atomic_rwlock_t slave_executed_entries_lock;
ulong aborted_threads, aborted_connects;
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
@@ -516,6 +534,9 @@ 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;
+ulong max_digest_length= 0;
+ulong slave_retried_transactions;
+ulong feature_files_opened_with_delayed_keys;
ulonglong denied_connections;
my_decimal decimal_zero;
@@ -558,6 +579,13 @@ ulong rpl_recovery_rank=0;
*/
ulong stored_program_cache_size= 0;
+ulong opt_slave_parallel_threads= 0;
+ulong opt_slave_domain_parallel_threads= 0;
+ulong opt_binlog_commit_wait_count= 0;
+ulong opt_binlog_commit_wait_usec= 0;
+ulong opt_slave_parallel_max_queued= 131072;
+my_bool opt_gtid_ignore_duplicates= FALSE;
+
const double log_10[] = {
1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009,
1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019,
@@ -623,6 +651,19 @@ const char *in_left_expr_name= "<left expr>";
const char *in_additional_cond= "<IN COND>";
const char *in_having_cond= "<IN HAVING>";
+/** Number of connection errors when selecting on the listening port */
+ulong connection_errors_select= 0;
+/** Number of connection errors when accepting sockets in the listening port. */
+ulong connection_errors_accept= 0;
+/** Number of connection errors from TCP wrappers. */
+ulong connection_errors_tcpwrap= 0;
+/** Number of connection errors from internal server errors. */
+ulong connection_errors_internal= 0;
+/** Number of connection errors from the server max_connection limit. */
+ulong connection_errors_max_connection= 0;
+/** Number of errors when reading the peer address. */
+ulong connection_errors_peer_addr= 0;
+
/* classes for comparation parsing/processing */
Eq_creator eq_creator;
Ne_creator ne_creator;
@@ -635,7 +676,8 @@ MYSQL_FILE *bootstrap_file;
int bootstrap_error;
I_List<THD> threads;
-Rpl_filter* rpl_filter;
+Rpl_filter* cur_rpl_filter;
+Rpl_filter* global_rpl_filter;
Rpl_filter* binlog_filter;
THD *first_global_thread()
@@ -672,19 +714,20 @@ SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress;
SHOW_COMP_OPTION have_profiling;
+SHOW_COMP_OPTION have_openssl;
/* Thread specific variables */
pthread_key(MEM_ROOT**,THR_MALLOC);
pthread_key(THD*, THR_THD);
-mysql_mutex_t LOCK_thread_count;
+mysql_mutex_t LOCK_thread_count, LOCK_thread_cache;
mysql_mutex_t
- LOCK_status, LOCK_error_log, LOCK_short_uuid_generator,
+ LOCK_status, LOCK_show_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;
+ LOCK_connection_count, LOCK_error_messages, LOCK_slave_init;
mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
LOCK_global_table_stats, LOCK_global_index_stats;
@@ -708,6 +751,8 @@ pthread_attr_t connection_attrib;
mysql_mutex_t LOCK_server_started;
mysql_cond_t COND_server_started;
+int mysqld_server_started=0, mysqld_server_initialized= 0;
+File_parser_dummy_hook file_parser_dummy_hook;
#ifdef WITH_WSREP
mysql_mutex_t LOCK_wsrep_ready;
mysql_cond_t COND_wsrep_ready;
@@ -725,9 +770,6 @@ mysql_mutex_t LOCK_wsrep_desync;
int wsrep_replaying= 0;
static void wsrep_close_threads(THD* thd);
#endif /* WITH_WSREP */
-int mysqld_server_started= 0;
-
-File_parser_dummy_hook file_parser_dummy_hook;
/* replication parameters, if master_host is not NULL, we are a slave */
uint report_port= 0;
@@ -766,32 +808,106 @@ static char **remaining_argv;
int orig_argc;
char **orig_argv;
+static struct my_option pfs_early_options[]=
+{
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+ {"performance_schema_instrument", OPT_PFS_INSTRUMENT,
+ "Default startup value for a performance schema instrument.",
+ &pfs_param.m_pfs_instrument, &pfs_param.m_pfs_instrument, 0, GET_STR,
+ OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_stages_current", 0,
+ "Default startup value for the events_stages_current consumer.",
+ &pfs_param.m_consumer_events_stages_current_enabled,
+ &pfs_param.m_consumer_events_stages_current_enabled, 0, GET_BOOL,
+ OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_stages_history", 0,
+ "Default startup value for the events_stages_history consumer.",
+ &pfs_param.m_consumer_events_stages_history_enabled,
+ &pfs_param.m_consumer_events_stages_history_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_stages_history_long", 0,
+ "Default startup value for the events_stages_history_long consumer.",
+ &pfs_param.m_consumer_events_stages_history_long_enabled,
+ &pfs_param.m_consumer_events_stages_history_long_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_statements_current", 0,
+ "Default startup value for the events_statements_current consumer.",
+ &pfs_param.m_consumer_events_statements_current_enabled,
+ &pfs_param.m_consumer_events_statements_current_enabled, 0,
+ GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_statements_history", 0,
+ "Default startup value for the events_statements_history consumer.",
+ &pfs_param.m_consumer_events_statements_history_enabled,
+ &pfs_param.m_consumer_events_statements_history_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_statements_history_long", 0,
+ "Default startup value for the events_statements_history_long consumer.",
+ &pfs_param.m_consumer_events_statements_history_long_enabled,
+ &pfs_param.m_consumer_events_statements_history_long_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_waits_current", 0,
+ "Default startup value for the events_waits_current consumer.",
+ &pfs_param.m_consumer_events_waits_current_enabled,
+ &pfs_param.m_consumer_events_waits_current_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_waits_history", 0,
+ "Default startup value for the events_waits_history consumer.",
+ &pfs_param.m_consumer_events_waits_history_enabled,
+ &pfs_param.m_consumer_events_waits_history_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_events_waits_history_long", 0,
+ "Default startup value for the events_waits_history_long consumer.",
+ &pfs_param.m_consumer_events_waits_history_long_enabled,
+ &pfs_param.m_consumer_events_waits_history_long_enabled, 0,
+ GET_BOOL, OPT_ARG, FALSE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_global_instrumentation", 0,
+ "Default startup value for the global_instrumentation consumer.",
+ &pfs_param.m_consumer_global_instrumentation_enabled,
+ &pfs_param.m_consumer_global_instrumentation_enabled, 0,
+ GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_thread_instrumentation", 0,
+ "Default startup value for the thread_instrumentation consumer.",
+ &pfs_param.m_consumer_thread_instrumentation_enabled,
+ &pfs_param.m_consumer_thread_instrumentation_enabled, 0,
+ GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0},
+ {"performance_schema_consumer_statements_digest", 0,
+ "Default startup value for the statements_digest consumer.",
+ &pfs_param.m_consumer_statement_digest_enabled,
+ &pfs_param.m_consumer_statement_digest_enabled, 0,
+ GET_BOOL, OPT_ARG, TRUE, 0, 0, 0, 0, 0}
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+};
+
#ifdef HAVE_PSI_INTERFACE
#ifdef HAVE_MMAP
-PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool;
+PSI_mutex_key key_PAGE_lock, key_LOCK_sync, key_LOCK_active, key_LOCK_pool,
+ key_LOCK_pending_checkpoint;
#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,
+PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_xid_list,
+ key_BINLOG_LOCK_binlog_background_thread,
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_rpl_status, key_LOCK_server_started,
+ key_LOCK_status, key_LOCK_show_status,
+ key_LOCK_system_variables_hash, 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_master_info_sleep_lock,
key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock,
+ key_rpl_group_info_sleep_lock,
key_relay_log_info_log_space_lock, key_relay_log_info_run_lock,
- key_relay_log_info_sleep_lock,
key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data,
- key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count,
+ key_LOCK_error_messages, key_LOG_INFO_lock,
+ key_LOCK_thread_count, key_LOCK_thread_cache,
key_PARTITION_LOCK_auto_inc;
#ifdef WITH_WSREP
PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd,
@@ -800,13 +916,18 @@ PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd,
key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync;
#endif
PSI_mutex_key key_RELAYLOG_LOCK_index;
+PSI_mutex_key key_LOCK_slave_state, key_LOCK_binlog_state,
+ key_LOCK_rpl_thread, key_LOCK_rpl_thread_pool, key_LOCK_parallel_entry;
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;
+ key_LOCK_wakeup_ready, key_LOCK_wait_commit;
+PSI_mutex_key key_LOCK_gtid_waiting;
-PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered;
+PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
+ key_LOCK_slave_init;
+PSI_mutex_key key_TABLE_SHARE_LOCK_share;
static PSI_mutex_info all_server_mutexes[]=
{
@@ -815,6 +936,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &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},
+ { &key_LOCK_pool, "TC_LOG_MMAP::LOCK_pending_checkpoint", 0},
#endif /* HAVE_MMAP */
#ifdef HAVE_OPENSSL
@@ -822,7 +944,8 @@ static PSI_mutex_info all_server_mutexes[]=
#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_BINLOG_LOCK_xid_list, "MYSQL_BIN_LOG::LOCK_xid_list", 0},
+ { &key_BINLOG_LOCK_binlog_background_thread, "MYSQL_BIN_LOG::LOCK_binlog_background_thread", 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},
@@ -840,13 +963,15 @@ static PSI_mutex_info all_server_mutexes[]=
{ &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_show_status, "LOCK_show_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_wait_commit, "wait_for_commit::LOCK_wait_commit", 0},
+ { &key_LOCK_gtid_waiting, "gtid_waiting::LOCK_gtid_waiting", 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},
@@ -858,14 +983,15 @@ static PSI_mutex_info all_server_mutexes[]=
{ &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_relay_log_info_sleep_lock, "Relay_log_info::sleep_lock", 0},
+ { &key_rpl_group_info_sleep_lock, "Rpl_group_info::sleep_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_TABLE_SHARE_LOCK_share, "TABLE_SHARE::LOCK_share", 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_LOCK_slave_init, "LOCK_slave_init", PSI_FLAG_GLOBAL},
{ &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
- { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
#ifdef WITH_WSREP
{ &key_LOCK_wsrep_ready, "LOCK_wsrep_ready", PSI_FLAG_GLOBAL},
{ &key_LOCK_wsrep_sst, "LOCK_wsrep_sst", PSI_FLAG_GLOBAL},
@@ -878,7 +1004,14 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_wsrep_slave_threads, "LOCK_wsrep_slave_threads", PSI_FLAG_GLOBAL},
{ &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL},
#endif
- { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0}
+ { &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
+ { &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
+ { &key_PARTITION_LOCK_auto_inc, "HA_DATA_PARTITION::LOCK_auto_inc", 0},
+ { &key_LOCK_slave_state, "LOCK_slave_state", 0},
+ { &key_LOCK_binlog_state, "LOCK_binlog_state", 0},
+ { &key_LOCK_rpl_thread, "LOCK_rpl_thread", 0},
+ { &key_LOCK_rpl_thread_pool, "LOCK_rpl_thread_pool", 0},
+ { &key_LOCK_parallel_entry, "LOCK_parallel_entry", 0}
};
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
@@ -902,7 +1035,9 @@ static PSI_rwlock_info all_server_rwlocks[]=
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,
+PSI_cond_key key_BINLOG_COND_xid_list, key_BINLOG_update_cond,
+ key_BINLOG_COND_binlog_background_thread,
+ key_BINLOG_COND_binlog_background_thread_end,
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,
@@ -911,7 +1046,7 @@ PSI_cond_key key_BINLOG_COND_prep_xids, key_BINLOG_update_cond,
key_master_info_sleep_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_relay_log_info_sleep_cond,
+ key_rpl_group_info_sleep_cond,
key_TABLE_SHARE_cond, key_user_level_lock_cond,
key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache,
key_BINLOG_COND_queue_busy;
@@ -920,9 +1055,15 @@ PSI_cond_key key_COND_wsrep_rollback,
key_COND_wsrep_replaying, key_COND_wsrep_ready, key_COND_wsrep_sst,
key_COND_wsrep_sst_init, key_COND_wsrep_sst_thread;
#endif /* WITH_WSREP */
-PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready;
+PSI_cond_key key_RELAYLOG_update_cond, key_COND_wakeup_ready,
+ key_COND_wait_commit;
PSI_cond_key key_RELAYLOG_COND_queue_busy;
PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
+PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
+ key_COND_rpl_thread_stop, key_COND_rpl_thread_pool,
+ key_COND_parallel_entry, key_COND_group_commit_orderer,
+ key_COND_prepare_ordered, key_COND_slave_init;
+PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
static PSI_cond_info all_server_conds[]=
{
@@ -935,15 +1076,17 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_pool, "TC_LOG_MMAP::COND_pool", 0},
{ &key_TC_LOG_MMAP_COND_queue_busy, "TC_LOG_MMAP::COND_queue_busy", 0},
#endif /* HAVE_MMAP */
- { &key_BINLOG_COND_prep_xids, "MYSQL_BIN_LOG::COND_prep_xids", 0},
+ { &key_BINLOG_COND_xid_list, "MYSQL_BIN_LOG::COND_xid_list", 0},
{ &key_BINLOG_update_cond, "MYSQL_BIN_LOG::update_cond", 0},
+ { &key_BINLOG_COND_binlog_background_thread, "MYSQL_BIN_LOG::COND_binlog_background_thread", 0},
+ { &key_BINLOG_COND_binlog_background_thread_end, "MYSQL_BIN_LOG::COND_binlog_background_thread_end", 0},
{ &key_BINLOG_COND_queue_busy, "MYSQL_BIN_LOG::COND_queue_busy", 0},
{ &key_RELAYLOG_update_cond, "MYSQL_RELAY_LOG::update_cond", 0},
{ &key_RELAYLOG_COND_queue_busy, "MYSQL_RELAY_LOG::COND_queue_busy", 0},
{ &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
+ { &key_COND_wait_commit, "wait_for_commit::COND_wait_commit", 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},
@@ -956,7 +1099,7 @@ static PSI_cond_info all_server_conds[]=
{ &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_relay_log_info_sleep_cond, "Relay_log_info::sleep_cond", 0},
+ { &key_rpl_group_info_sleep_cond, "Rpl_group_info::sleep_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},
@@ -969,12 +1112,23 @@ static PSI_cond_info all_server_conds[]=
{ &key_COND_wsrep_rollback, "COND_wsrep_rollback", PSI_FLAG_GLOBAL},
{ &key_COND_wsrep_replaying, "COND_wsrep_replaying", PSI_FLAG_GLOBAL},
#endif
- { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL}
+ { &key_COND_flush_thread_cache, "COND_flush_thread_cache", PSI_FLAG_GLOBAL},
+ { &key_COND_rpl_thread, "COND_rpl_thread", 0},
+ { &key_COND_rpl_thread_queue, "COND_rpl_thread_queue", 0},
+ { &key_COND_rpl_thread_stop, "COND_rpl_thread_stop", 0},
+ { &key_COND_rpl_thread_pool, "COND_rpl_thread_pool", 0},
+ { &key_COND_parallel_entry, "COND_parallel_entry", 0},
+ { &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
+ { &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
+ { &key_COND_slave_init, "COND_slave_init", 0},
+ { &key_COND_wait_gtid, "COND_wait_gtid", 0},
+ { &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
};
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;
+ key_thread_one_connection, key_thread_signal_hand,
+ key_thread_slave_init, key_rpl_parallel_thread;
static PSI_thread_info all_server_threads[]=
{
@@ -999,9 +1153,15 @@ static PSI_thread_info all_server_threads[]=
{ &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}
+ { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
+ { &key_thread_slave_init, "slave_init", PSI_FLAG_GLOBAL},
+ { &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
};
+#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,
@@ -1011,75 +1171,84 @@ PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
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;
+PSI_file_key key_file_binlog_state;
-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}
-};
+#endif /* HAVE_PSI_INTERFACE */
-/**
- Initialise all the performance schema instrumentation points
- used by the server.
-*/
-void init_server_psi_keys(void)
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+PSI_statement_info stmt_info_new_packet;
+#endif
+
+#ifndef EMBEDDED_LIBRARY
+void net_before_header_psi(struct st_net *net, void *user_data, size_t /* unused: count */)
{
- const char* category= "sql";
- int count;
+ THD *thd;
+ thd= static_cast<THD*> (user_data);
+ DBUG_ASSERT(thd != NULL);
- if (PSI_server == NULL)
- return;
+ /*
+ We only come where when the server is IDLE, waiting for the next command.
+ Technically, it is a wait on a socket, which may take a long time,
+ because the call is blocking.
+ Disable the socket instrumentation, to avoid recording a SOCKET event.
+ Instead, start explicitly an IDLE event.
+ */
+ MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_IDLE);
+ MYSQL_START_IDLE_WAIT(thd->m_idle_psi, &thd->m_idle_state);
+}
- count= array_elements(all_server_mutexes);
- PSI_server->register_mutex(category, all_server_mutexes, count);
+void net_after_header_psi(struct st_net *net, void *user_data,
+ size_t /* unused: count */, my_bool rc)
+{
+ THD *thd;
+ thd= static_cast<THD*> (user_data);
+ DBUG_ASSERT(thd != NULL);
- count= array_elements(all_server_rwlocks);
- PSI_server->register_rwlock(category, all_server_rwlocks, count);
+ /*
+ The server just got data for a network packet header,
+ from the network layer.
+ The IDLE event is now complete, since we now have a message to process.
+ We need to:
+ - start a new STATEMENT event
+ - start a new STAGE event, within this statement,
+ - start recording SOCKET WAITS events, within this stage.
+ The proper order is critical to get events numbered correctly,
+ and nested in the proper parent.
+ */
+ MYSQL_END_IDLE_WAIT(thd->m_idle_psi);
- count= array_elements(all_server_conds);
- PSI_server->register_cond(category, all_server_conds, count);
+ if (! rc)
+ {
+ thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
+ stmt_info_new_packet.m_key,
+ thd->db, thd->db_length,
+ thd->charset());
- count= array_elements(all_server_threads);
- PSI_server->register_thread(category, all_server_threads, count);
+ THD_STAGE_INFO(thd, stage_init);
+ }
- count= array_elements(all_server_files);
- PSI_server->register_file(category, all_server_files, count);
+ /*
+ TODO: consider recording a SOCKET event for the bytes just read,
+ by also passing count here.
+ */
+ MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_ACTIVE);
}
-#endif /* HAVE_PSI_INTERFACE */
-/*
- Since buffered_option_error_reporter is only used currently
- for parsing performance schema options, this code is not needed
- when the performance schema is not compiled in.
-*/
-#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+void init_net_server_extension(THD *thd)
+{
+ /* Start with a clean state for connection events. */
+ thd->m_idle_psi= NULL;
+ thd->m_statement_psi= NULL;
+ /* Hook up the NET_SERVER callback in the net layer. */
+ thd->m_net_server_extension.m_user_data= thd;
+ thd->m_net_server_extension.m_before_header= net_before_header_psi;
+ thd->m_net_server_extension.m_after_header= net_after_header_psi;
+ /* Activate this private extension for the mysqld server. */
+ thd->net.extension= & thd->m_net_server_extension;
+}
+#endif /* EMBEDDED_LIBRARY */
+
/**
A log message for the error log, buffered in memory.
Log messages are temporarily buffered when generated before the error log
@@ -1176,7 +1345,7 @@ private:
void Buffered_logs::init()
{
- init_alloc_root(&m_root, 1024, 0);
+ init_alloc_root(&m_root, 1024, 0, MYF(0));
}
void Buffered_logs::cleanup()
@@ -1215,6 +1384,9 @@ void Buffered_logs::print()
/** Logs reported before a logger is available. */
static Buffered_logs buffered_logs;
+static MYSQL_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
/**
Error reporter that buffer log messages.
@@ -1233,14 +1405,34 @@ static void buffered_option_error_reporter(enum loglevel level,
va_end(args);
buffered_logs.buffer(level, buffer);
}
-C_MODE_END
-#endif /* !EMBEDDED_LIBRARY */
-#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
-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
+/**
+ Character set and collation error reporter that prints to sql error log.
+ @param level log message level
+ @param format log message format string
+
+ This routine is used to print character set and collation
+ warnings and errors inside an already running mysqld server,
+ e.g. when a character set or collation is requested for the very first time
+ and its initialization does not go well for some reasons.
+
+ Note: At early mysqld initialization stage,
+ when error log is not yet available,
+ we use buffered_option_error_reporter() instead,
+ to print general character set subsystem initialization errors,
+ such as Index.xml syntax problems, bad XML tag hierarchy, etc.
+*/
+static void charset_error_reporter(enum loglevel level,
+ const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vprint_msg_to_log(level, format, args);
+ va_end(args);
+}
+C_MODE_END
+
struct passwd *user_info;
static pthread_t select_thread;
#endif
@@ -1278,7 +1470,9 @@ bool mysqld_embedded=0;
bool mysqld_embedded=1;
#endif
+#ifndef EMBEDDED_LIBRARY
static my_bool plugins_are_initialized= FALSE;
+#endif
#ifndef DBUG_OFF
static const char* default_dbug_option;
@@ -1301,7 +1495,9 @@ HANDLE smem_event_connect_request= 0;
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;
+ *opt_ssl_cipher= NULL, *opt_ssl_key= NULL, *opt_ssl_crl= NULL,
+ *opt_ssl_crlpath= NULL;
+
static scheduler_functions thread_scheduler_struct, extra_thread_scheduler_struct;
scheduler_functions *thread_scheduler= &thread_scheduler_struct,
@@ -1333,12 +1529,16 @@ struct st_VioSSLFd *ssl_acceptor_fd;
*/
uint connection_count= 0, extra_connection_count= 0;
+my_bool opt_gtid_strict_mode= FALSE;
+
+
/* Function declarations */
pthread_handler_t signal_hand(void *arg);
static int mysql_init_variables(void);
static int get_options(int *argc_ptr, char ***argv_ptr);
static bool add_terminator(DYNAMIC_ARRAY *options);
+static bool add_many_options(DYNAMIC_ARRAY *, my_option *, size_t);
extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
static int init_thread_environment();
static char *get_relative_path(const char *path);
@@ -1429,17 +1629,17 @@ static void close_connections(void)
DBUG_PRINT("quit",("Closing sockets"));
if (!opt_disable_networking )
{
- if (base_ip_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
{
(void) mysql_socket_shutdown(base_ip_sock, SHUT_RDWR);
- (void) closesocket(base_ip_sock);
- base_ip_sock= INVALID_SOCKET;
+ (void) mysql_socket_close(base_ip_sock);
+ base_ip_sock= MYSQL_INVALID_SOCKET;
}
- if (extra_ip_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
{
(void) mysql_socket_shutdown(extra_ip_sock, SHUT_RDWR);
- (void) closesocket(extra_ip_sock);
- extra_ip_sock= INVALID_SOCKET;
+ (void) mysql_socket_close(extra_ip_sock);
+ extra_ip_sock= MYSQL_INVALID_SOCKET;
}
}
#ifdef _WIN32
@@ -1467,12 +1667,12 @@ static void close_connections(void)
}
#endif
#ifdef HAVE_SYS_UN_H
- if (unix_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
{
(void) mysql_socket_shutdown(unix_sock, SHUT_RDWR);
- (void) closesocket(unix_sock);
+ (void) mysql_socket_close(unix_sock);
(void) unlink(mysqld_unix_port);
- unix_sock= INVALID_SOCKET;
+ unix_sock= MYSQL_INVALID_SOCKET;
}
#endif
end_thr_alarm(0); // Abort old alarms.
@@ -1532,8 +1732,21 @@ static void close_connections(void)
Events::deinit();
end_slave();
- /* Give threads time to die. */
- for (int i= 0; thread_count && i < 100; i++)
+ /*
+ Give threads time to die.
+
+ In 5.5, this was waiting 100 rounds @ 20 milliseconds/round, so as little
+ as 2 seconds, depending on thread scheduling.
+
+ From 10.0, we increase this to 1000 rounds / 20 seconds. The rationale is
+ that on a server with heavy I/O load, it is quite possible for eg. an
+ fsync() of the binlog or whatever to cause something like LOCK_log to be
+ held for more than 2 seconds. We do not want to force kill threads in
+ such cases, if it can be avoided. Note that normally, the wait will be
+ much smaller than even 2 seconds, this is only a safety fallback against
+ stuck threads so server shutdown is not held up forever.
+ */
+ for (int i= 0; *(volatile int32*) &thread_count && i < 1000; i++)
my_sleep(20000);
/*
@@ -1596,7 +1809,7 @@ static void close_connections(void)
/* All threads has now been aborted */
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
mysql_mutex_lock(&LOCK_thread_count);
- while (thread_count)
+ while (thread_count || service_thread_count)
{
mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
@@ -1609,22 +1822,14 @@ static void close_connections(void)
#ifdef HAVE_CLOSE_SERVER_SOCK
-static void close_socket(my_socket sock, const char *info)
+static void close_socket(MYSQL_SOCKET sock, const char *info)
{
DBUG_ENTER("close_socket");
- if (sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(sock) != INVALID_SOCKET)
{
DBUG_PRINT("info", ("calling shutdown on %s socket", info));
(void) mysql_socket_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;
}
@@ -1640,9 +1845,9 @@ static void close_server_sock()
close_socket(extra_ip_sock, "TCP/IP");
close_socket(unix_sock, "unix/IP");
- if (unix_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
(void) unlink(mysqld_unix_port);
- base_ip_sock= extra_ip_sock= unix_sock= INVALID_SOCKET;
+ base_ip_sock= extra_ip_sock= unix_sock= MYSQL_INVALID_SOCKET;
DBUG_VOID_RETURN;
#endif
@@ -1874,7 +2079,6 @@ extern "C" void unireg_abort(int exit_code)
wsrep_deinit(true);
}
#endif // WITH_WSREP
-
clean_up(!opt_abort && (exit_code || !opt_bootstrap)); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
mysqld_exit(exit_code);
@@ -1882,11 +2086,14 @@ extern "C" void unireg_abort(int exit_code)
static void mysqld_exit(int exit_code)
{
+ DBUG_ENTER("mysqld_exit");
/*
Important note: we wait for the signal thread to end,
but if a kill -15 signal was sent, the signal thread did
spawn the kill_server_thread thread, which is running concurrently.
*/
+ rpl_deinit_gtid_waiting();
+ rpl_deinit_gtid_slave_state();
wait_for_signal_thread_to_end();
mysql_audit_finalize();
clean_up_mutexes();
@@ -1895,6 +2102,7 @@ static void mysqld_exit(int exit_code)
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
shutdown_performance_schema(); // we do it as late as possible
#endif
+ DBUG_LEAVE;
exit(exit_code); /* purecov: inspected */
}
@@ -1906,7 +2114,12 @@ void clean_up(bool print_message)
if (cleanup_done++)
return; /* purecov: inspected */
- close_active_mi();
+#ifdef HAVE_REPLICATION
+ // We must call end_slave() as clean_up may have been called during startup
+ end_slave();
+ if (use_slave_mask)
+ my_bitmap_free(&slave_error_mask);
+#endif
stop_handle_manager();
release_ddl_log();
@@ -1921,24 +2134,20 @@ void clean_up(bool print_message)
injector::free_instance();
mysql_bin_log.cleanup();
-#ifdef HAVE_REPLICATION
- if (use_slave_mask)
- bitmap_free(&slave_error_mask);
-#endif
my_tz_free();
my_dboptions_cache_free();
ignore_db_dirs_free();
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
servers_free(1);
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
acl_free(1);
grant_free();
#endif
query_cache_destroy();
hostname_cache_free();
- item_user_lock_free();
+ item_func_sleep_free();
lex_free(); /* Free some memory */
item_create_cleanup();
- table_def_start_shutdown();
+ tdc_start_shutdown();
plugin_shutdown();
udf_free();
ha_end();
@@ -1946,7 +2155,7 @@ void clean_up(bool print_message)
tc_log->close();
delegates_destroy();
xid_cache_free();
- table_def_free();
+ tdc_deinit();
mdl_destroy();
key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache);
wt_end();
@@ -1958,24 +2167,24 @@ void clean_up(bool print_message)
if (defaults_argv)
free_defaults(defaults_argv);
free_tmpdir(&mysql_tmpdir_list);
- bitmap_free(&temp_pool);
+ my_bitmap_free(&temp_pool);
free_max_user_conn();
free_global_user_stats();
free_global_client_stats();
free_global_table_stats();
free_global_index_stats();
delete_dynamic(&all_options);
+ free_all_rpl_filters();
#ifdef HAVE_REPLICATION
end_slave_list();
#endif
my_uuid_end();
delete binlog_filter;
- delete rpl_filter;
+ delete global_rpl_filter;
end_ssl();
#ifndef EMBEDDED_LIBRARY
vio_end();
#endif /*!EMBEDDED_LIBRARY*/
- my_regex_end();
#if defined(ENABLED_DEBUG_SYNC)
/* End the debug sync facility. See debug_sync.cc. */
debug_sync_end();
@@ -1996,6 +2205,9 @@ void clean_up(bool print_message)
sys_var_end();
my_atomic_rwlock_destroy(&global_query_id_lock);
my_atomic_rwlock_destroy(&thread_running_lock);
+ my_atomic_rwlock_destroy(&thread_count_lock);
+ my_atomic_rwlock_destroy(&statistics_lock);
+ my_atomic_rwlock_destroy(&slave_executed_entries_lock);
free_charsets();
mysql_mutex_lock(&LOCK_thread_count);
DBUG_PRINT("quit", ("got thread count lock"));
@@ -2004,6 +2216,14 @@ void clean_up(bool print_message)
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
+ free_list(opt_plugin_load_list_ptr);
+
+ if (THR_THD)
+ (void) pthread_key_delete(THR_THD);
+
+ if (THR_MALLOC)
+ (void) pthread_key_delete(THR_MALLOC);
+
/*
The following lines may never be executed as the main thread may have
killed us
@@ -2039,7 +2259,9 @@ 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_thread_cache);
mysql_mutex_destroy(&LOCK_status);
+ mysql_mutex_destroy(&LOCK_show_status);
mysql_mutex_destroy(&LOCK_delayed_insert);
mysql_mutex_destroy(&LOCK_delayed_status);
mysql_mutex_destroy(&LOCK_delayed_create);
@@ -2060,7 +2282,6 @@ static void clean_up_mutexes()
#endif /* HAVE_OPENSSL */
#ifdef HAVE_REPLICATION
mysql_mutex_destroy(&LOCK_rpl_status);
- mysql_cond_destroy(&COND_rpl_status);
#endif /* HAVE_REPLICATION */
mysql_mutex_destroy(&LOCK_active_mi);
mysql_rwlock_destroy(&LOCK_sys_init_connect);
@@ -2090,7 +2311,10 @@ static void clean_up_mutexes()
mysql_mutex_destroy(&LOCK_server_started);
mysql_cond_destroy(&COND_server_started);
mysql_mutex_destroy(&LOCK_prepare_ordered);
+ mysql_cond_destroy(&COND_prepare_ordered);
mysql_mutex_destroy(&LOCK_commit_ordered);
+ mysql_mutex_destroy(&LOCK_slave_init);
+ mysql_cond_destroy(&COND_slave_init);
DBUG_VOID_RETURN;
}
@@ -2276,14 +2500,15 @@ static void set_root(const char *path)
Activate usage of a tcp port
*/
-static my_socket activate_tcp_port(uint port)
+static MYSQL_SOCKET activate_tcp_port(uint port)
{
struct addrinfo *ai, *a;
struct addrinfo hints;
int error;
int arg;
char port_buf[NI_MAXSERV];
- my_socket ip_sock= INVALID_SOCKET;
+ const char *real_bind_addr_str;
+ MYSQL_SOCKET ip_sock= MYSQL_INVALID_SOCKET;
DBUG_ENTER("activate_tcp_port");
DBUG_PRINT("general",("IP Socket is %d",port));
@@ -2291,34 +2516,55 @@ static my_socket activate_tcp_port(uint port)
hints.ai_flags= AI_PASSIVE;
hints.ai_socktype= SOCK_STREAM;
hints.ai_family= AF_UNSPEC;
+
+ if (my_bind_addr_str && strcmp(my_bind_addr_str, "*") == 0)
+ real_bind_addr_str= NULL; // windows doesn't seem to support * here
+ else
+ real_bind_addr_str= my_bind_addr_str;
my_snprintf(port_buf, NI_MAXSERV, "%d", port);
- error= getaddrinfo(my_bind_addr_str, port_buf, &hints, &ai);
+ error= getaddrinfo(real_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 */
+
+ sql_print_error("%s: %s", ER_DEFAULT(ER_IPSOCK_ERROR), gai_strerror(error));
unireg_abort(1); /* purecov: tested */
}
+ /*
+ special case: for wildcard addresses prefer ipv6 over ipv4,
+ because we later switch off IPV6_V6ONLY, so ipv6 wildcard
+ addresses will work for ipv4 too
+ */
+ if (!real_bind_addr_str && ai->ai_family == AF_INET && ai->ai_next
+ && ai->ai_next->ai_family == AF_INET6)
+ {
+ a= ai;
+ ai= ai->ai_next;
+ a->ai_next= ai->ai_next;
+ ai->ai_next= a;
+ }
+
for (a= ai; a != NULL; a= a->ai_next)
{
- ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
-
- char ip_addr[INET6_ADDRSTRLEN];
+ ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
+ a->ai_socktype, a->ai_protocol);
+ char ip_addr[INET6_ADDRSTRLEN];
if (vio_get_normalized_ip_string(a->ai_addr, a->ai_addrlen,
ip_addr, sizeof (ip_addr)))
{
ip_addr[0]= 0;
}
- if (ip_sock == INVALID_SOCKET)
+ if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
{
- sql_print_error("Failed to create a socket for %s '%s': errno: %d.",
- (a->ai_family == AF_INET) ? "IPv4" : "IPv6",
- (const char *) ip_addr,
- (int) socket_errno);
+ sql_print_message_func func= real_bind_addr_str ? sql_print_error
+ : sql_print_warning;
+ func("Failed to create a socket for %s '%s': errno: %d.",
+ (a->ai_family == AF_INET) ? "IPv4" : "IPv6",
+ (const char *) ip_addr, (int) socket_errno);
}
else
{
@@ -2328,20 +2574,23 @@ static my_socket activate_tcp_port(uint port)
}
}
- if (ip_sock == INVALID_SOCKET)
+ if (mysql_socket_getfd(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 */
}
+ mysql_socket_set_thread_owner(ip_sock);
+
#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));
+ (void) mysql_socket_setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
+ sizeof(arg));
#endif /* __WIN__ */
#ifdef IPV6_V6ONLY
@@ -2357,8 +2606,8 @@ static my_socket activate_tcp_port(uint port)
if (a->ai_family == AF_INET6)
{
arg= 0;
- (void) setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
- sizeof(arg));
+ (void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char*)&arg, sizeof(arg));
}
#endif
/*
@@ -2373,7 +2622,7 @@ static my_socket activate_tcp_port(uint port)
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 ) ||
+ if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
(socket_errno != SOCKET_EADDRINUSE) ||
(waited >= mysqld_port_timeout))
break;
@@ -2392,7 +2641,7 @@ static my_socket activate_tcp_port(uint port)
"port: %u ?", port);
unireg_abort(1);
}
- if (listen(ip_sock,(int) back_log) < 0)
+ if (mysql_socket_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",
@@ -2400,8 +2649,9 @@ static my_socket activate_tcp_port(uint port)
unireg_abort(1);
}
#if defined(WITH_WSREP) && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
- (void) fcntl(ip_sock, F_SETFD, FD_CLOEXEC);
+ (void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
#endif /* WITH_WSREP */
+
DBUG_RETURN(ip_sock);
}
@@ -2496,21 +2746,26 @@ static void network_init(void)
(uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
unireg_abort(1);
}
- if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ unix_sock= mysql_socket_socket(key_socket_unix, AF_UNIX, SOCK_STREAM, 0);
+ if (mysql_socket_getfd(unix_sock) < 0)
{
sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
unireg_abort(1); /* purecov: inspected */
}
+
+ mysql_socket_set_thread_owner(unix_sock);
+
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
UNIXaddr.sun_family = AF_UNIX;
strmov(UNIXaddr.sun_path, mysqld_unix_port);
(void) unlink(mysqld_unix_port);
arg= 1;
- (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
- sizeof(arg));
+ (void) mysql_socket_setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,
+ (char*)&arg, sizeof(arg));
umask(0);
- if (bind(unix_sock, reinterpret_cast<struct sockaddr *>(&UNIXaddr),
- sizeof(UNIXaddr)) < 0)
+ if (mysql_socket_bind(unix_sock,
+ reinterpret_cast<struct sockaddr *>(&UNIXaddr),
+ sizeof(UNIXaddr)) < 0)
{
sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
@@ -2520,11 +2775,11 @@ static void network_init(void)
#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
(void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
#endif
- if (listen(unix_sock,(int) back_log) < 0)
+ if (mysql_socket_listen(unix_sock,(int) back_log) < 0)
sql_print_warning("listen() on Unix socket failed with error %d",
socket_errno);
-#if defined(WITH_WSREP) && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
- (void) fcntl(unix_sock, F_SETFD, FD_CLOEXEC);
+#if defined(WITH_WSREP) && defined(HAVE_FCNTL)
+ (void) fcntl(mysql_socket_getfd(unix_sock), F_SETFD, FD_CLOEXEC);
#endif /* WITH_WSREP */
}
#endif
@@ -2560,7 +2815,7 @@ void close_connection(THD *thd, uint sql_errno)
{
sleep(0); /* Workaround to avoid tailcall optimisation */
}
- MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno);
+ mysql_audit_notify_connection_disconnect(thd, sql_errno);
DBUG_VOID_RETURN;
}
#endif /* EMBEDDED_LIBRARY */
@@ -2617,6 +2872,47 @@ void dec_connection_count(THD *thd)
/*
+ Delete THD and decrement thread counters, including thread_running
+*/
+
+void delete_running_thd(THD *thd)
+{
+ mysql_mutex_lock(&LOCK_thread_count);
+ thd->unlink();
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ delete thd;
+ dec_thread_running();
+ thread_safe_decrement32(&thread_count, &thread_count_lock);
+ signal_thd_deleted();
+}
+
+
+/*
+ Send a signal to unblock close_conneciton() if there is no more
+ threads running with a THD attached
+
+ It's safe to check for thread_count and service_thread_count outside
+ of a mutex as we are only interested to see if they where decremented
+ to 0 by a previous unlink_thd() call.
+
+ We should only signal COND_thread_count if both variables are 0,
+ false positives are ok.
+*/
+
+void signal_thd_deleted()
+{
+ if (!thread_count && ! service_thread_count)
+ {
+ /* Signal close_connections() that all THD's are freed */
+ mysql_mutex_lock(&LOCK_thread_count);
+ mysql_cond_broadcast(&COND_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_count);
+ }
+}
+
+
+/*
Unlink thd from global list of available connections and free thd
SYNOPSIS
@@ -2645,19 +2941,11 @@ void unlink_thd(THD *thd)
sync feature has been shut down at this point.
*/
DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5););
- if (unlikely(abort_loop))
- {
- /*
- During shutdown, we have to delete thd inside the mutex
- to not refer to mutexes that may be deleted during shutdown
- */
- delete thd;
- thd= 0;
- }
- thread_count--;
mysql_mutex_unlock(&LOCK_thread_count);
delete thd;
+ thread_safe_decrement32(&thread_count, &thread_count_lock);
+
DBUG_VOID_RETURN;
}
@@ -2669,7 +2957,7 @@ void unlink_thd(THD *thd)
cache_thread()
NOTES
- LOCK_thread_count has to be locked
+ LOCK_thread_cache is used to protect the cache variables
RETURN
0 Thread was not put in cache
@@ -2680,7 +2968,9 @@ void unlink_thd(THD *thd)
static bool cache_thread()
{
- mysql_mutex_assert_owner(&LOCK_thread_count);
+ DBUG_ENTER("cache_thread");
+
+ mysql_mutex_lock(&LOCK_thread_cache);
if (cached_thread_count < thread_cache_size &&
! abort_loop && !kill_cached_threads)
{
@@ -2688,17 +2978,16 @@ static bool cache_thread()
DBUG_PRINT("info", ("Adding thread to cache"));
cached_thread_count++;
-#ifdef HAVE_PSI_INTERFACE
+#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Delete the instrumentation for the job that just completed,
before parking this pthread in the cache (blocked on COND_thread_cache).
*/
- if (likely(PSI_server != NULL))
- PSI_server->delete_current_thread();
+ PSI_THREAD_CALL(delete_current_thread)();
#endif
while (!abort_loop && ! wake_thread && ! kill_cached_threads)
- mysql_cond_wait(&COND_thread_cache, &LOCK_thread_count);
+ mysql_cond_wait(&COND_thread_cache, &LOCK_thread_cache);
cached_thread_count--;
if (kill_cached_threads)
mysql_cond_signal(&COND_flush_thread_cache);
@@ -2707,21 +2996,19 @@ static bool cache_thread()
THD *thd;
wake_thread--;
thd= thread_cache.get();
+ mysql_mutex_unlock(&LOCK_thread_cache);
+
thd->thread_stack= (char*) &thd; // For store_globals
(void) thd->store_globals();
-#ifdef HAVE_PSI_INTERFACE
+#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Create new instrumentation for the new THD job,
and attach it to this running pthread.
*/
- if (likely(PSI_server != NULL))
- {
- PSI_thread *psi= PSI_server->new_thread(key_thread_one_connection,
- thd, thd->thread_id);
- if (likely(psi != NULL))
- PSI_server->set_thread(psi);
- }
+ PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_one_connection,
+ thd, thd->thread_id);
+ PSI_THREAD_CALL(set_thread)(psi);
#endif
/*
@@ -2732,11 +3019,16 @@ static bool cache_thread()
thd->mysys_var->abort= 0;
thd->thr_create_utime= microsecond_interval_timer();
thd->start_utime= thd->thr_create_utime;
+
+ /* Link thd into list of all active threads (THD's) */
+ mysql_mutex_lock(&LOCK_thread_count);
threads.append(thd);
- return(1);
+ mysql_mutex_unlock(&LOCK_thread_count);
+ DBUG_RETURN(1);
}
}
- return(0);
+ mysql_mutex_unlock(&LOCK_thread_cache);
+ DBUG_RETURN(0);
}
@@ -2764,33 +3056,25 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
DBUG_ENTER("one_thread_per_connection_end");
#ifdef WITH_WSREP
const bool wsrep_applier(thd->wsrep_applier);
-#endif /* WITH_WSREP */
+#endif
unlink_thd(thd);
/* Mark that current_thd is not valid anymore */
- my_pthread_setspecific_ptr(THR_THD, 0);
+ set_current_thd(0);
#ifdef WITH_WSREP
- if (put_in_cache && !wsrep_applier)
+ if (!wsrep_applier && put_in_cache && cache_thread())
#else
- if (put_in_cache)
+ if (put_in_cache && cache_thread())
#endif /* WITH_WSREP */
- {
- mysql_mutex_lock(&LOCK_thread_count);
- put_in_cache= cache_thread();
- mysql_mutex_unlock(&LOCK_thread_count);
- if (put_in_cache)
- DBUG_RETURN(0); // Thread is reused
- }
+ DBUG_RETURN(0); // Thread is reused
- /* It's safe to broadcast outside a lock (COND... is not deleted here) */
- DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
+ signal_thd_deleted();
DBUG_LEAVE; // Must match DBUG_ENTER()
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
ERR_remove_state(0);
#endif
my_thread_end();
- mysql_cond_broadcast(&COND_thread_count);
pthread_exit(0);
return 0; // Avoid compiler warnings
@@ -2799,15 +3083,17 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
void flush_thread_cache()
{
- mysql_mutex_lock(&LOCK_thread_count);
+ DBUG_ENTER("flush_thread_cache");
+ mysql_mutex_lock(&LOCK_thread_cache);
kill_cached_threads++;
while (cached_thread_count)
{
mysql_cond_broadcast(&COND_thread_cache);
- mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_count);
+ mysql_cond_wait(&COND_flush_thread_cache, &LOCK_thread_cache);
}
kill_cached_threads--;
- mysql_mutex_unlock(&LOCK_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_cache);
+ DBUG_VOID_RETURN;
}
@@ -3214,8 +3500,8 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
should not be any other mysql_cond_signal() calls.
*/
mysql_mutex_lock(&LOCK_thread_count);
- mysql_mutex_unlock(&LOCK_thread_count);
mysql_cond_broadcast(&COND_thread_count);
+ mysql_mutex_unlock(&LOCK_thread_count);
(void) pthread_sigmask(SIG_BLOCK,&set,NULL);
for (;;)
@@ -3251,10 +3537,9 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused)))
if (!abort_loop)
{
abort_loop=1; // mark abort for threads
-#ifdef HAVE_PSI_INTERFACE
+#ifdef HAVE_PSI_THREAD_INTERFACE
/* Delete the instrumentation for the signal thread */
- if (likely(PSI_server != NULL))
- PSI_server->delete_current_thread();
+ PSI_THREAD_CALL(delete_current_thread)();
#endif
#ifdef USE_ONE_SIGNAL_HAND
pthread_t tmp;
@@ -3326,28 +3611,28 @@ 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_condition::enum_warning_level level;
sql_print_message_func func;
-
DBUG_ENTER("my_message_sql");
- DBUG_PRINT("error", ("error: %u message: '%s' Flag: %d", error, str, MyFlags));
+ DBUG_PRINT("error", ("error: %u message: '%s' Flag: %lu", error, str,
+ MyFlags));
DBUG_ASSERT(str != NULL);
DBUG_ASSERT(error != 0);
if (MyFlags & ME_JUST_INFO)
{
- level= MYSQL_ERROR::WARN_LEVEL_NOTE;
+ level= Sql_condition::WARN_LEVEL_NOTE;
func= sql_print_information;
}
else if (MyFlags & ME_JUST_WARNING)
{
- level= MYSQL_ERROR::WARN_LEVEL_WARN;
+ level= Sql_condition::WARN_LEVEL_WARN;
func= sql_print_warning;
}
else
{
- level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ level= Sql_condition::WARN_LEVEL_ERROR;
func= sql_print_error;
}
@@ -3369,9 +3654,9 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
}
-#ifndef EMBEDDED_LIBRARY
extern "C" void *my_str_malloc_mysqld(size_t size);
extern "C" void my_str_free_mysqld(void *ptr);
+extern "C" void *my_str_realloc_mysqld(void *ptr, size_t size);
void *my_str_malloc_mysqld(size_t size)
{
@@ -3383,7 +3668,11 @@ void my_str_free_mysqld(void *ptr)
{
my_free(ptr);
}
-#endif /* EMBEDDED_LIBRARY */
+
+void *my_str_realloc_mysqld(void *ptr, size_t size)
+{
+ return my_realloc(ptr, size, MYF(MY_FAE));
+}
#ifdef __WIN__
@@ -3415,24 +3704,57 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
/**
This function is used to check for stack overrun for pathological
cases of regular expressions and 'like' expressions.
- The call to current_thd is quite expensive, so we try to avoid it
- for the normal cases.
+*/
+extern "C" int
+check_enough_stack_size_slow()
+{
+ uchar stack_top;
+ THD *my_thd= current_thd;
+ if (my_thd != NULL)
+ return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
+ return 0;
+}
+
+
+/*
+ The call to current_thd in check_enough_stack_size_slow is quite expensive,
+ so we try to avoid it for the normal cases.
The size of each stack frame for the wildcmp() routines is ~128 bytes,
so checking *every* recursive call is not necessary.
*/
extern "C" int
check_enough_stack_size(int recurse_level)
{
- uchar stack_top;
if (recurse_level % 16 != 0)
return 0;
+ return check_enough_stack_size_slow();
+}
+#endif
- THD *my_thd= current_thd;
- if (my_thd != NULL)
- return check_stack_overrun(my_thd, STACK_MIN_SIZE * 2, &stack_top);
- return 0;
+
+
+/*
+ Initialize my_str_malloc() and my_str_free()
+*/
+static void init_libstrings()
+{
+ my_str_malloc= &my_str_malloc_mysqld;
+ my_str_free= &my_str_free_mysqld;
+ my_str_realloc= &my_str_realloc_mysqld;
+#ifndef EMBEDDED_LIBRARY
+ my_string_stack_guard= check_enough_stack_size;
+#endif
}
+
+
+static void init_pcre()
+{
+ pcre_malloc= pcre_stack_malloc= my_str_malloc_mysqld;
+ pcre_free= pcre_stack_free= my_str_free_mysqld;
+#ifndef EMBEDDED_LIBRARY
+ pcre_stack_guard= check_enough_stack_size_slow;
#endif
+}
/**
@@ -3490,6 +3812,7 @@ SHOW_VAR com_status_vars[]= {
{"create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
{"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
{"create_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
+ {"create_role", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_ROLE]), SHOW_LONG_STATUS},
{"create_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
{"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
{"create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
@@ -3505,6 +3828,7 @@ SHOW_VAR com_status_vars[]= {
{"drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
{"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
{"drop_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
+ {"drop_role", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_ROLE]), SHOW_LONG_STATUS},
{"drop_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
{"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
{"drop_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
@@ -3513,7 +3837,9 @@ SHOW_VAR com_status_vars[]= {
{"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
{"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
{"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
+ {"get_diagnostics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GET_DIAGNOSTICS]), SHOW_LONG_STATUS},
{"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
+ {"grant_role", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT_ROLE]), SHOW_LONG_STATUS},
{"ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
{"ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
{"ha_read", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
@@ -3539,6 +3865,7 @@ SHOW_VAR com_status_vars[]= {
{"resignal", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESIGNAL]), SHOW_LONG_STATUS},
{"revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
{"revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
+ {"revoke_role", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ROLE]), SHOW_LONG_STATUS},
{"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
{"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
{"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
@@ -3563,6 +3890,7 @@ SHOW_VAR com_status_vars[]= {
{"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
{"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
{"show_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
+ {"show_explain", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EXPLAIN]), SHOW_LONG_STATUS},
{"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
#ifndef DBUG_OFF
{"show_function_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
@@ -3594,9 +3922,10 @@ SHOW_VAR com_status_vars[]= {
{"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},
+ {"shutdown", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHUTDOWN]), SHOW_LONG_STATUS},
{"signal", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SIGNAL]), SHOW_LONG_STATUS},
- {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
- {"slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
+ {"start_all_slaves", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_START]), SHOW_LONG_STATUS},
+ {"start_slave", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
{"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
{"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
{"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
@@ -3604,6 +3933,8 @@ SHOW_VAR com_status_vars[]= {
{"stmt_reprepare", (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
{"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
{"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
+ {"stop_all_slaves", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_STOP]), SHOW_LONG_STATUS},
+ {"stop_slave", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
{"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
{"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
{"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
@@ -3618,21 +3949,154 @@ SHOW_VAR com_status_vars[]= {
{NullS, NullS, SHOW_LONG}
};
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+PSI_statement_info sql_statement_info[(uint) SQLCOM_END + 1];
+PSI_statement_info com_statement_info[(uint) COM_END + 1];
+
+/**
+ Initialize the command names array.
+ Since we do not want to maintain a separate array,
+ this is populated from data mined in com_status_vars,
+ which already has one name for each command.
+*/
+void init_sql_statement_info()
+{
+ char *first_com= (char*) offsetof(STATUS_VAR, com_stat[0]);
+ char *last_com= (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_END]);
+ int record_size= (char*) offsetof(STATUS_VAR, com_stat[1])
+ - (char*) offsetof(STATUS_VAR, com_stat[0]);
+ char *ptr;
+ uint i;
+ uint com_index;
+
+ static const char* dummy= "";
+ for (i= 0; i < ((uint) SQLCOM_END + 1); i++)
+ {
+ sql_statement_info[i].m_name= dummy;
+ sql_statement_info[i].m_flags= 0;
+ }
+
+ SHOW_VAR *var= &com_status_vars[0];
+ while (var->name != NULL)
+ {
+ ptr= var->value;
+ if ((first_com <= ptr) && (ptr <= last_com))
+ {
+ com_index= ((int)(ptr - first_com))/record_size;
+ DBUG_ASSERT(com_index < (uint) SQLCOM_END);
+ sql_statement_info[com_index].m_name= var->name;
+ }
+ var++;
+ }
+
+ DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SELECT].m_name, "select") == 0);
+ DBUG_ASSERT(strcmp(sql_statement_info[(uint) SQLCOM_SIGNAL].m_name, "signal") == 0);
+
+ sql_statement_info[(uint) SQLCOM_END].m_name= "error";
+}
+
+void init_com_statement_info()
+{
+ uint index;
+
+ for (index= 0; index < (uint) COM_END + 1; index++)
+ {
+ com_statement_info[index].m_name= command_name[index].str;
+ com_statement_info[index].m_flags= 0;
+ }
+
+ /* "statement/abstract/query" can mutate into "statement/sql/..." */
+ com_statement_info[(uint) COM_QUERY].m_flags= PSI_FLAG_MUTABLE;
+}
+#endif
+
+
+#ifdef SAFEMALLOC
+/*
+ Return the id for the current THD, to allow safemalloc to associate
+ the memory with the right id.
+*/
+
+extern "C" my_thread_id mariadb_dbug_id()
+{
+ THD *thd;
+ if ((thd= current_thd))
+ {
+ return thd->thread_id;
+ }
+ return my_thread_dbug_id();
+}
+#endif /* SAFEMALLOC */
+
+/* Thread Mem Usage By P.Linux */
+extern "C" {
+static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
+{
+ /* If thread specific memory */
+ if (is_thread_specific)
+ {
+ THD *thd= current_thd;
+ if (mysqld_server_initialized || thd)
+ {
+ /*
+ THD may not be set if we are called from my_net_init() before THD
+ thread has started.
+ However, this should never happen, so better to assert and
+ fix this.
+ */
+ DBUG_ASSERT(thd);
+ if (thd)
+ {
+ DBUG_PRINT("info", ("memory_used: %lld size: %lld",
+ (longlong) thd->status_var.memory_used, size));
+ thd->status_var.memory_used+= size;
+ DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0);
+ }
+ }
+ }
+ // workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1)
+ int64 volatile * volatile ptr=&global_status_var.memory_used;
+ my_atomic_add64(ptr, size);
+}
+}
+
+
static int init_common_variables()
{
umask(((~my_umask) & 0666));
+ connection_errors_select= 0;
+ connection_errors_accept= 0;
+ connection_errors_tcpwrap= 0;
+ connection_errors_internal= 0;
+ connection_errors_max_connection= 0;
+ connection_errors_peer_addr= 0;
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
+ if (pthread_key_create(&THR_THD,NULL) ||
+ pthread_key_create(&THR_MALLOC,NULL))
+ {
+ sql_print_error("Can't create thread-keys");
+ return 1;
+ }
+
+ set_current_thd(0);
+ set_malloc_size_cb(my_malloc_size_cb_func);
+
+ init_libstrings();
tzset(); // Set tzname
sf_leaking_memory= 0; // no memory leaks from now on
+#ifdef SAFEMALLOC
+ sf_malloc_dbug_id= mariadb_dbug_id;
+#endif
max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= flush_status_time= my_time(0);
- rpl_filter= new Rpl_filter;
+ global_rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter;
- if (!rpl_filter || !binlog_filter)
+ if (!global_rpl_filter || !binlog_filter)
{
sql_perror("Could not allocate replication and binlog filters");
return 1;
@@ -3674,8 +4138,9 @@ static int init_common_variables()
#ifdef HAVE_PSI_INTERFACE
/*
Complete the mysql_bin_log initialization.
- Instrumentation keys are known only after the performance schema initialization,
- and can not be set in the MYSQL_BIN_LOG constructor (called before main()).
+ Instrumentation keys are known only after the performance schema
+ initialization, and can not be set in the MYSQL_BIN_LOG
+ constructor (called before main()).
*/
mysql_bin_log.set_psi_keys(key_BINLOG_LOCK_index,
key_BINLOG_update_cond,
@@ -3866,7 +4331,7 @@ static int init_common_variables()
/* MyISAM requires two file handles per table. */
wanted_files= (10 + max_connections + extra_max_connections +
- table_cache_size*2);
+ tc_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
@@ -3877,7 +4342,7 @@ 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_open_files= MY_MAX(MY_MAX(wanted_files,
(max_connections + extra_max_connections)*5),
open_files_limit);
files= my_set_max_open_files(max_open_files);
@@ -3890,23 +4355,22 @@ static int init_common_variables()
If we have requested too much file handles than we bring
max_connections in supported bounds.
*/
- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections= (ulong) MY_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
max_connections);
/*
- Decrease table_cache_size according to max_connections, but
- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
- never increase table_cache_size automatically (that could
+ Decrease tc_size according to max_connections, but
+ not below TABLE_OPEN_CACHE_MIN. Outer MY_MIN() ensures that we
+ never increase tc_size automatically (that could
happen if max_connections is decreased above).
*/
- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
- TABLE_OPEN_CACHE_MIN),
- table_cache_size);
+ tc_size= (ulong) MY_MIN(MY_MAX((files - 10 - max_connections) / 2,
+ TABLE_OPEN_CACHE_MIN), tc_size);
DBUG_PRINT("warning",
("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
- files, max_connections, table_cache_size));
+ files, max_connections, tc_size));
if (global_system_variables.log_warnings)
sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
- files, max_connections, table_cache_size);
+ files, max_connections, tc_size);
}
else if (global_system_variables.log_warnings)
sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
@@ -3929,12 +4393,7 @@ static int init_common_variables()
if (item_create_init())
return 1;
item_init();
-#ifndef EMBEDDED_LIBRARY
- my_regex_init(&my_charset_latin1, check_enough_stack_size);
- my_string_stack_guard= check_enough_stack_size;
-#else
- my_regex_init(&my_charset_latin1, NULL);
-#endif
+ init_pcre();
/*
Process a comma-separated character set list and choose
the first available character set. This is mostly for
@@ -3968,6 +4427,10 @@ static int init_common_variables()
default_collation= get_charset_by_name(default_collation_name, MYF(0));
if (!default_collation)
{
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+ buffered_logs.print();
+ buffered_logs.cleanup();
+#endif
sql_print_error(ER_DEFAULT(ER_UNKNOWN_COLLATION), default_collation_name);
return 1;
}
@@ -3985,7 +4448,15 @@ static int init_common_variables()
global_system_variables.collation_database= default_charset_info;
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 (default_charset_info->mbminlen > 1)
+ {
+ global_system_variables.character_set_client= &my_charset_latin1;
+ sql_print_warning("Cannot use %s as character_set_client, %s will be used instead",
+ default_charset_info->csname,
+ global_system_variables.character_set_client->csname);
+ }
+ else
+ global_system_variables.character_set_client= default_charset_info;
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
@@ -4026,7 +4497,7 @@ static int init_common_variables()
#endif /* defined(ENABLED_DEBUG_SYNC) */
#if (ENABLE_TEMP_POOL)
- if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
+ if (use_temp_pool && my_bitmap_init(&temp_pool,0,1024,1))
return 1;
#else
use_temp_pool= 0;
@@ -4104,8 +4575,11 @@ static int init_common_variables()
static int init_thread_environment()
{
+ DBUG_ENTER("init_thread_environment");
mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_thread_cache, &LOCK_thread_cache, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(key_LOCK_show_status, &LOCK_show_status, MY_MUTEX_INIT_SLOW);
mysql_mutex_init(key_LOCK_delayed_insert,
&LOCK_delayed_insert, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_delayed_status,
@@ -4117,6 +4591,7 @@ static int init_thread_environment()
mysql_mutex_init(key_LOCK_active_mi, &LOCK_active_mi, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_global_system_variables,
&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
+ mysql_mutex_record_order(&LOCK_active_mi, &LOCK_global_system_variables);
mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash,
&LOCK_system_variables_hash);
mysql_mutex_init(key_LOCK_prepared_stmt_count,
@@ -4136,8 +4611,12 @@ static int init_thread_environment()
&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_prepare_ordered, &LOCK_prepare_ordered,
MY_MUTEX_INIT_SLOW);
+ mysql_cond_init(key_COND_prepare_ordered, &COND_prepare_ordered, NULL);
mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
MY_MUTEX_INIT_SLOW);
+ mysql_mutex_init(key_LOCK_slave_init, &LOCK_slave_init,
+ MY_MUTEX_INIT_SLOW);
+ mysql_cond_init(key_COND_slave_init, &COND_slave_init, NULL);
#ifdef HAVE_OPENSSL
mysql_mutex_init(key_LOCK_des_key_file,
@@ -4161,7 +4640,6 @@ static int init_thread_environment()
mysql_cond_init(key_COND_flush_thread_cache, &COND_flush_thread_cache, NULL);
#ifdef HAVE_REPLICATION
mysql_mutex_init(key_LOCK_rpl_status, &LOCK_rpl_status, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_COND_rpl_status, &COND_rpl_status, NULL);
#endif
mysql_mutex_init(key_LOCK_server_started,
&LOCK_server_started, MY_MUTEX_INIT_FAST);
@@ -4170,18 +4648,18 @@ static int init_thread_environment()
#ifdef HAVE_EVENT_SCHEDULER
Events::init_mutexes();
#endif
+ init_show_explain_psi_keys();
/* Parameter for threads created for connections */
(void) pthread_attr_init(&connection_attrib);
(void) pthread_attr_setdetachstate(&connection_attrib,
PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
- if (pthread_key_create(&THR_THD,NULL) ||
- pthread_key_create(&THR_MALLOC,NULL))
- {
- sql_print_error("Can't create thread-keys");
- return 1;
- }
+#ifdef HAVE_REPLICATION
+ rpl_init_gtid_slave_state();
+ rpl_init_gtid_waiting();
+#endif
+
#ifdef WITH_WSREP
mysql_mutex_init(key_LOCK_wsrep_ready,
&LOCK_wsrep_ready, MY_MUTEX_INIT_FAST);
@@ -4203,7 +4681,8 @@ static int init_thread_environment()
mysql_mutex_init(key_LOCK_wsrep_desync,
&LOCK_wsrep_desync, MY_MUTEX_INIT_FAST);
#endif
- return 0;
+
+ DBUG_RETURN(0);
}
@@ -4280,9 +4759,9 @@ static void init_ssl()
/* having ssl_acceptor_fd != 0 signals the use of SSL */
ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
opt_ssl_ca, opt_ssl_capath,
- opt_ssl_cipher, &error);
+ opt_ssl_cipher, &error,
+ opt_ssl_crl, opt_ssl_crlpath);
DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
- ERR_remove_state(0);
if (!ssl_acceptor_fd)
{
sql_print_warning("Failed to setup SSL");
@@ -4290,6 +4769,14 @@ static void init_ssl()
opt_use_ssl = 0;
have_ssl= SHOW_OPTION_DISABLED;
}
+ if (global_system_variables.log_warnings > 0)
+ {
+ ulong err;
+ while ((err= ERR_get_error()))
+ sql_print_warning("SSL error: %s", ERR_error_string(err, NULL));
+ }
+ else
+ ERR_remove_state(0);
}
else
{
@@ -4349,12 +4836,13 @@ static int init_server_components()
all things are initialized so that unireg_abort() doesn't fail
*/
mdl_init();
- if (table_def_init() | hostname_cache_init())
+ if (tdc_init() | hostname_cache_init())
unireg_abort(1);
query_cache_set_min_res_unit(query_cache_min_res_unit);
query_cache_init();
query_cache_resize(query_cache_size);
+ query_cache_result_size_limit(query_cache_limit);
my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
setup_fpu();
init_thr_lock();
@@ -4407,7 +4895,7 @@ static int init_server_components()
/* set up the hook before initializing plugins which may use it */
error_handler_hook= my_message_sql;
- proc_info_hook= set_thd_proc_info;
+ proc_info_hook= set_thd_stage_info;
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
/*
@@ -4421,6 +4909,15 @@ static int init_server_components()
buffered_logs.cleanup();
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+#ifndef EMBEDDED_LIBRARY
+ /*
+ Now that the logger is available, redirect character set
+ errors directly to the logger
+ (instead of the buffered_logs used at the server startup time).
+ */
+ my_charset_error_reporter= charset_error_reporter;
+#endif
+
if (xid_cache_init())
{
sql_print_error("Out of memory");
@@ -4462,56 +4959,19 @@ static int init_server_components()
{
if (opt_bin_log)
{
- sql_print_error("using --replicate-same-server-id in conjunction with \
---log-slave-updates is impossible, it would lead to infinite loops in this \
-server.");
+ sql_print_error("using --replicate-same-server-id in conjunction with "
+ "--log-slave-updates is impossible, it would lead to "
+ "infinite loops in this server.");
unireg_abort(1);
}
else
- sql_print_warning("using --replicate-same-server-id in conjunction with \
---log-slave-updates would lead to infinite loops in this server. However this \
-will be ignored as the --log-bin option is not defined.");
+ sql_print_warning("using --replicate-same-server-id in conjunction with "
+ "--log-slave-updates would lead to infinite loops in "
+ "this server. However this will be ignored as the "
+ "--log-bin option is not defined.");
}
#endif
-#ifdef WITH_WSREP /* WSREP BEFORE SE */
- if (!wsrep_recovery && !opt_help)
- {
- if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
- {
- wsrep_provider_init(WSREP_NONE);
- if (wsrep_init()) unireg_abort(1);
- }
- else // full wsrep initialization
- {
- // add basedir/bin to PATH to resolve wsrep script names
- char* const tmp_path((char*)alloca(strlen(mysql_home) +
- strlen("/bin") + 1));
- if (tmp_path)
- {
- strcpy(tmp_path, mysql_home);
- strcat(tmp_path, "/bin");
- wsrep_prepend_PATH(tmp_path);
- }
- else
- {
- WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
- }
-
- if (wsrep_before_SE())
- {
-#ifndef EMBEDDED_LIBRARY
- set_ports(); // this is also called in network_init() later but we need
- // to know mysqld_port now - lp:1071882
-#endif /* !EMBEDDED_LIBRARY */
-
- wsrep_init_startup(true);
- }
- }
- }
-#endif /* WITH_WSREP */
- DBUG_ASSERT(!opt_bin_log || opt_bin_logname);
-
if (opt_bin_log)
{
/* Reports an error and aborts, if the --log-bin's path
@@ -4519,8 +4979,8 @@ will be ignored as the --log-bin option is not defined.");
if (opt_bin_logname[0] &&
opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
{
- sql_print_error("Path '%s' is a directory name, please specify \
-a file name for --log-bin option", opt_bin_logname);
+ sql_print_error("Path '%s' is a directory name, please specify "
+ "a file name for --log-bin option", opt_bin_logname);
unireg_abort(1);
}
@@ -4530,8 +4990,9 @@ a file name for --log-bin option", opt_bin_logname);
opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
== FN_LIBCHAR)
{
- sql_print_error("Path '%s' is a directory name, please specify \
-a file name for --log-bin-index option", opt_binlog_index_name);
+ sql_print_error("Path '%s' is a directory name, please specify "
+ "a file name for --log-bin-index option",
+ opt_binlog_index_name);
unireg_abort(1);
}
@@ -4559,10 +5020,72 @@ a file name for --log-bin-index option", opt_binlog_index_name);
{
opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
}
+#ifdef WITH_WSREP /* WSREP BEFORE SE */
+ /*
+ Wsrep initialization must happen at this point, because:
+ - opt_bin_logname must be known when starting replication
+ since SST may need it
+ - SST may modify binlog index file, so it must be opened
+ after SST has happened
+ */
+ }
+ if (!wsrep_recovery && !opt_help)
+ {
+ if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
+ {
+ wsrep_provider_init(WSREP_NONE);
+ if (wsrep_init()) unireg_abort(1);
+ }
+ else // full wsrep initialization
+ {
+ // add basedir/bin to PATH to resolve wsrep script names
+ char* const tmp_path((char*)alloca(strlen(mysql_home) +
+ strlen("/bin") + 1));
+ if (tmp_path)
+ {
+ strcpy(tmp_path, mysql_home);
+ strcat(tmp_path, "/bin");
+ wsrep_prepend_PATH(tmp_path);
+ }
+ else
+ {
+ WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
+ }
+
+ if (wsrep_before_SE())
+ {
+ set_ports(); // this is also called in network_init() later but we need
+ // to know mysqld_port now - lp:1071882
+ /*
+ Plugin initialization (plugin_init()) hasn't happened yet, set
+ maria_hton to 0.
+ */
+ maria_hton= 0;
+ wsrep_init_startup(true);
+ }
+ }
+ }
+ if (opt_bin_log)
+ {
+ /*
+ Variable ln is not defined at this scope. We use opt_bin_logname instead.
+ It should be the same as ln since
+ - mysql_bin_log.generate_name() returns first argument if new log name
+ is not generated
+ - if new log name is generated, return value is assigned to ln and copied
+ to opt_bin_logname above
+ */
+ if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
+ TRUE))
+ {
+ unireg_abort(1);
+ }
+#else
if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
{
unireg_abort(1);
}
+#endif /* WITH_WSREP */
}
/* call ha_init_key_cache() on all key caches to init them */
@@ -4614,12 +5137,12 @@ a file name for --log-bin-index option", opt_binlog_index_name);
variables that allocates memory for this THD.
*/
THD *current_thd_saved= current_thd;
- my_pthread_setspecific_ptr(THR_THD, tmp);
+ set_current_thd(tmp);
tmp->init_for_queries();
/* Restore current_thd. */
- my_pthread_setspecific_ptr(THR_THD, current_thd_saved);
+ set_current_thd(current_thd_saved);
tmp->server_status= server_status_saved;
tmp->variables.option_bits= option_bits_saved;
@@ -4629,13 +5152,6 @@ a file name for --log-bin-index option", opt_binlog_index_name);
}
#endif
- have_csv= plugin_status(STRING_WITH_LEN("csv"),
- MYSQL_STORAGE_ENGINE_PLUGIN);
- have_ndbcluster= plugin_status(STRING_WITH_LEN("ndbcluster"),
- MYSQL_STORAGE_ENGINE_PLUGIN);
- have_partitioning= plugin_status(STRING_WITH_LEN("partition"),
- MYSQL_STORAGE_ENGINE_PLUGIN);
-
/* we do want to exit if there are any other unknown options */
if (remaining_argc > 1)
{
@@ -4721,7 +5237,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
plugin_ref plugin;
handlerton *hton;
if ((plugin= ha_resolve_by_name(0, &name)))
- hton= plugin_data(plugin, handlerton*);
+ hton= plugin_hton(plugin);
else
{
sql_print_error("Unknown/unsupported storage engine: %s",
@@ -4749,7 +5265,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
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)
+#ifdef 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");
@@ -4774,6 +5290,12 @@ a file name for --log-bin-index option", opt_binlog_index_name);
#ifdef WITH_WSREP
if (WSREP_ON && tc_log == &tc_log_mmap)
tc_log= &tc_log_dummy;
+
+ WSREP_DEBUG("Initial TC log open: %s",
+ (tc_log == &mysql_bin_log) ? "binlog" :
+ (tc_log == &tc_log_mmap) ? "mmap" :
+ (tc_log == &tc_log_dummy) ? "dummy" : "unknown"
+ );
#endif
if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
@@ -4788,7 +5310,7 @@ a file name for --log-bin-index option", opt_binlog_index_name);
}
if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
- WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
+ WRITE_CACHE, max_binlog_size, 0, TRUE))
unireg_abort(1);
#ifdef HAVE_REPLICATION
@@ -4830,8 +5352,13 @@ a file name for --log-bin-index option", opt_binlog_index_name);
init_update_queries();
init_global_user_stats();
init_global_client_stats();
+ if (!opt_bootstrap)
+ servers_init(0);
+ init_status_vars();
DBUG_RETURN(0);
}
+
+
#ifndef EMBEDDED_LIBRARY
static void create_shutdown_thread()
@@ -4874,7 +5401,7 @@ pthread_handler_t start_wsrep_THD(void *arg)
thread_created++;
threads.append(thd);
- my_net_init(&thd->net,(st_vio*) 0);
+ my_net_init(&thd->net,(st_vio*) 0, MYF(0));
DBUG_PRINT("wsrep",(("creating thread %lld"), (long long)thd->thread_id));
thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer();
@@ -4928,7 +5455,7 @@ pthread_handler_t start_wsrep_THD(void *arg)
/* handle_one_connection() again... */
//thd->version= refresh_version;
thd->proc_info= 0;
- thd->command= COM_SLEEP;
+ thd->set_command(COM_SLEEP);
if (wsrep_creating_startup_threads == 0)
{
@@ -4998,7 +5525,7 @@ static bool abort_replicated(THD *thd)
bool ret_code= false;
if (thd->wsrep_query_state== QUERY_COMMITTING)
{
- if (wsrep_debug) WSREP_INFO("aborting replicated trx: %lu", thd->real_id);
+ WSREP_DEBUG("aborting replicated trx: %lu", thd->real_id);
(void)wsrep_abort_thd(thd, thd, TRUE);
ret_code= true;
@@ -5099,7 +5626,6 @@ static my_bool have_committing_connections()
if (is_committing_connection(tmp))
{
- mysql_mutex_unlock(&LOCK_thread_count);
return TRUE;
}
}
@@ -5184,8 +5710,7 @@ void wsrep_close_client_connections(my_bool wait_to_end)
}
DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
- if (wsrep_debug)
- WSREP_INFO("waiting for client connections to close: %u", thread_count);
+ WSREP_DEBUG("waiting for client connections to close: %u", thread_count);
while (wait_to_end && have_client_connections())
{
@@ -5227,28 +5752,6 @@ static void wsrep_close_threads(THD *thd)
mysql_mutex_unlock(&LOCK_thread_count);
}
-void wsrep_close_applier_threads(int count)
-{
- THD *tmp;
- mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
-
- I_List_iterator<THD> it(threads);
- while ((tmp=it++) && count)
- {
- DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
- tmp->thread_id));
- /* We skip slave threads & scheduler on this first loop through. */
- if (tmp->wsrep_applier)
- {
- WSREP_DEBUG("closing wsrep applier thread %ld", tmp->thread_id);
- tmp->wsrep_applier_closing= TRUE;
- count--;
- }
- }
-
- mysql_mutex_unlock(&LOCK_thread_count);
-}
-
void wsrep_wait_appliers_close(THD *thd)
{
/* Wait for wsrep appliers to gracefully exit */
@@ -5458,6 +5961,7 @@ static void test_lc_time_sz()
}
#endif//DBUG_OFF
+
#ifdef __WIN__
int win_main(int argc, char **argv)
#else
@@ -5470,6 +5974,8 @@ int mysqld_main(int argc, char **argv)
*/
my_progname= argv[0];
sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
+ mysqld_server_started= mysqld_server_initialized= 0;
+
#ifdef HAVE_NPTL
ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
#endif
@@ -5481,9 +5987,6 @@ int mysqld_main(int argc, char **argv)
return 1;
}
#endif
-#ifdef WITH_WSREP
- wsrep_filter_new_cluster (&argc, argv);
-#endif /* WITH_WSREP */
orig_argc= argc;
orig_argv= argv;
@@ -5504,38 +6007,33 @@ int mysqld_main(int argc, char **argv)
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
/*
- The performance schema needs to be initialized as early as possible,
- before to-be-instrumented objects of the server are initialized.
+ Initialize the array of performance schema instrument configurations.
*/
- int ho_error;
- DYNAMIC_ARRAY all_early_options;
-
- my_getopt_register_get_addr(NULL);
- /* Skip unknown options so that they may be processed later */
- my_getopt_skip_unknown= TRUE;
-
- /* prepare all_early_options array */
- my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25);
- sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
- add_terminator(&all_early_options);
-
+ init_pfs_instrument_array();
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
/*
Logs generated while parsing the command line
options are buffered and printed later.
*/
buffered_logs.init();
my_getopt_error_reporter= buffered_option_error_reporter;
+ my_charset_error_reporter= buffered_option_error_reporter;
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+ pfs_param.m_pfs_instrument= const_cast<char*>("");
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
- ho_error= handle_options(&remaining_argc, &remaining_argv,
- (my_option*)(all_early_options.buffer), NULL);
- delete_dynamic(&all_early_options);
+ int ho_error __attribute__((unused))= handle_early_options();
+
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
if (ho_error == 0)
{
- /* Add back the program name handle_options removes */
- remaining_argc++;
- remaining_argv--;
- if (pfs_param.m_enabled)
+ if (pfs_param.m_enabled && !opt_help && !opt_bootstrap)
{
+ /* Add sizing hints from the server sizing parameters. */
+ pfs_param.m_hints.m_table_definition_cache= tdc_size;
+ pfs_param.m_hints.m_table_open_cache= tc_size;
+ pfs_param.m_hints.m_max_connections= max_connections;
+ pfs_param.m_hints.m_open_files_limit= open_files_limit;
PSI_hook= initialize_performance_schema(&pfs_param);
if (PSI_hook == NULL)
{
@@ -5563,27 +6061,29 @@ int mysqld_main(int argc, char **argv)
if available.
*/
if (PSI_hook)
- PSI_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);
-
- if (PSI_server)
{
- /*
- Now that we have parsed the command line arguments, and have initialized
- the performance schema itself, the next step is to register all the
- server instruments.
- */
- init_server_psi_keys();
- /* Instrument the main thread */
- PSI_thread *psi= PSI_server->new_thread(key_thread_main, NULL, 0);
- if (psi)
- PSI_server->set_thread(psi);
+ PSI *psi_server= (PSI*) PSI_hook->get_interface(PSI_CURRENT_VERSION);
+ if (likely(psi_server != NULL))
+ {
+ set_psi_server(psi_server);
- /*
- Now that some instrumentation is in place,
- recreate objects which were initialised early,
- so that they are instrumented as well.
- */
- my_thread_global_reinit();
+ /*
+ Now that we have parsed the command line arguments, and have
+ initialized the performance schema itself, the next step is to
+ register all the server instruments.
+ */
+ init_server_psi_keys();
+ /* Instrument the main thread */
+ PSI_thread *psi= PSI_THREAD_CALL(new_thread)(key_thread_main, NULL, 0);
+ PSI_THREAD_CALL(set_thread)(psi);
+
+ /*
+ Now that some instrumentation is in place,
+ recreate objects which were initialised early,
+ so that they are instrumented as well.
+ */
+ my_thread_global_reinit();
+ }
}
#endif /* HAVE_PSI_INTERFACE */
@@ -5668,9 +6168,9 @@ int mysqld_main(int argc, char **argv)
set_user(mysqld_user, user_info);
}
- if (opt_bin_log && !server_id)
+ if (opt_bin_log && !global_system_variables.server_id)
{
- server_id= 1;
+ global_system_variables.server_id= ::server_id= 1;
#ifdef EXTRA_DEBUG
sql_print_warning("You have enabled the binary log, but you haven't set "
"server-id to a non-zero value: we force server id to 1; "
@@ -5703,12 +6203,6 @@ int mysqld_main(int argc, char **argv)
}
#endif
- /*
- Initialize my_str_malloc() and my_str_free()
- */
- my_str_malloc= &my_str_malloc_mysqld;
- my_str_free= &my_str_free_mysqld;
-
#ifdef WITH_WSREP /* WSREP AFTER SE */
if (wsrep_recovery)
{
@@ -5717,6 +6211,7 @@ int mysqld_main(int argc, char **argv)
unireg_abort(0);
}
#endif /* WITH_WSREP */
+
/*
init signals & alarm
After this we can't quit by a simple unireg_abort
@@ -5733,7 +6228,7 @@ int mysqld_main(int argc, char **argv)
delete_pid_file(MYF(MY_WME));
- if (unix_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
unlink(mysqld_unix_port);
exit(1);
}
@@ -5741,26 +6236,12 @@ int mysqld_main(int argc, char **argv)
if (!opt_noacl)
(void) grant_init();
- if (!opt_bootstrap)
- servers_init(0);
-
udf_init();
- init_status_vars();
if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
opt_skip_slave_start= 1;
binlog_unsafe_map_init();
- /*
- init_slave() must be called after the thread keys are created.
- Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
- places) assume that active_mi != 0, so let's fail if it's 0 (out of
- memory); a message has already been printed.
- */
- if (init_slave() && !active_mi)
- {
- unireg_abort(1);
- }
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
initialize_performance_schema_acl(opt_bootstrap);
@@ -5778,17 +6259,18 @@ int mysqld_main(int argc, char **argv)
execute_ddl_log_recovery();
- if (Events::init(opt_noacl || opt_bootstrap))
+ /*
+ Change EVENTS_ORIGINAL to EVENTS_OFF (the default value) as there is no
+ point in using ORIGINAL during startup
+ */
+ if (Events::opt_event_scheduler == Events::EVENTS_ORIGINAL)
+ Events::opt_event_scheduler= Events::EVENTS_OFF;
+
+ Events::set_original_state(Events::opt_event_scheduler);
+ if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
unireg_abort(1);
#ifdef WITH_WSREP /* WSREP AFTER SE */
- if (wsrep_recovery)
- {
- select_thread_in_use= 0;
- wsrep_recover();
- unireg_abort(0);
- }
-
if (opt_bootstrap)
{
/*! bootstrap wsrep init was taken care of above */
@@ -5813,7 +6295,7 @@ int mysqld_main(int argc, char **argv)
wsrep_create_appliers(wsrep_slave_threads - 1);
}
#endif /* WITH_WSREP */
- if (opt_bootstrap)
+ if (opt_bootstrap)
{
select_thread_in_use= 0; // Allow 'kill' to work
bootstrap(mysql_stdin);
@@ -5825,31 +6307,58 @@ int mysqld_main(int argc, char **argv)
exit(0);
}
}
+
+ /* It's now safe to use thread specific memory */
+ mysqld_server_initialized= 1;
+
+ create_shutdown_thread();
+ start_handle_manager();
+
+ /* Copy default global rpl_filter to global_rpl_filter */
+ copy_filter_setting(global_rpl_filter, get_or_create_rpl_filter("", 0));
+
+ /*
+ init_slave() must be called after the thread keys are created.
+ Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
+ places) assume that active_mi != 0, so let's fail if it's 0 (out of
+ memory); a message has already been printed.
+ */
+ if (init_slave() && !active_mi)
+ {
+ unireg_abort(1);
+ }
+
if (opt_init_file && *opt_init_file)
{
if (read_init_file(opt_init_file))
unireg_abort(1);
}
- create_shutdown_thread();
- start_handle_manager();
-
sql_print_information(ER_DEFAULT(ER_STARTUP),my_progname,server_version,
- ((unix_sock == INVALID_SOCKET) ? (char*) ""
- : mysqld_unix_port),
+ ((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
+ (char*) "" : mysqld_unix_port),
mysqld_port,
MYSQL_COMPILATION_COMMENT);
+
+ // try to keep fd=0 busy
+ if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin))
+ {
+ // fall back on failure
+ fclose(stdin);
+ }
+
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
Service.SetRunning();
#endif
-
/* Signal threads waiting for server to be started */
mysql_mutex_lock(&LOCK_server_started);
mysqld_server_started= 1;
mysql_cond_signal(&COND_server_started);
mysql_mutex_unlock(&LOCK_server_started);
+ MYSQL_SET_STAGE(0 ,__FILE__, __LINE__);
+
#if defined(_WIN32) || defined(HAVE_SMEM)
handle_connections_methods();
#else
@@ -5877,13 +6386,12 @@ int mysqld_main(int argc, char **argv)
#endif
#endif /* __WIN__ */
-#ifdef HAVE_PSI_INTERFACE
+#ifdef HAVE_PSI_THREAD_INTERFACE
/*
Disable the main thread instrumentation,
to avoid recording events during the shutdown.
*/
- if (PSI_server)
- PSI_server->delete_current_thread();
+ PSI_THREAD_CALL(delete_current_thread)();
#endif
/* Wait until cleanup is done */
@@ -6137,11 +6645,11 @@ static void bootstrap(MYSQL_FILE *file)
thd->variables.wsrep_on= 0;
#endif
thd->bootstrap=1;
- my_net_init(&thd->net,(st_vio*) 0);
+ my_net_init(&thd->net,(st_vio*) 0, MYF(0));
thd->max_client_packet_length= thd->net.max_packet;
thd->security_ctx->master_access= ~(ulong)0;
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
- thread_count++;
+ thread_count++; // Safe as only one thread running
in_bootstrap= TRUE;
bootstrap_file=file;
@@ -6225,55 +6733,70 @@ void handle_connection_in_main_thread(THD *thd)
void create_thread_to_handle_connection(THD *thd)
{
+ DBUG_ENTER("create_thread_to_handle_connection");
+ mysql_mutex_assert_owner(&LOCK_thread_count);
+
+ /* Check if we can get thread from the cache */
if (cached_thread_count > wake_thread)
{
- /* Get thread from cache */
- thread_cache.push_back(thd);
- wake_thread++;
- mysql_cond_signal(&COND_thread_cache);
+ mysql_mutex_lock(&LOCK_thread_cache);
+ /* Recheck condition when we have the lock */
+ if (cached_thread_count > wake_thread)
+ {
+ mysql_mutex_unlock(&LOCK_thread_count);
+ /* Get thread from cache */
+ thread_cache.push_back(thd);
+ wake_thread++;
+ mysql_cond_signal(&COND_thread_cache);
+ mysql_mutex_unlock(&LOCK_thread_cache);
+ DBUG_PRINT("info",("Thread created"));
+ DBUG_VOID_RETURN;
+ }
+ mysql_mutex_unlock(&LOCK_thread_cache);
}
- else
+
+ char error_message_buff[MYSQL_ERRMSG_SIZE];
+ /* Create new thread to handle connection */
+ int error;
+ thread_created++;
+ threads.append(thd);
+ DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
+ thd->prior_thr_create_utime= microsecond_interval_timer();
+ if ((error= mysql_thread_create(key_thread_one_connection,
+ &thd->real_id, &connection_attrib,
+ handle_one_connection,
+ (void*) thd)))
{
- char error_message_buff[MYSQL_ERRMSG_SIZE];
- /* Create new thread to handle connection */
- int error;
- thread_created++;
- threads.append(thd);
- DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
- thd->prior_thr_create_utime= microsecond_interval_timer();
- if ((error= mysql_thread_create(key_thread_one_connection,
- &thd->real_id, &connection_attrib,
- handle_one_connection,
- (void*) thd)))
- {
- /* purecov: begin inspected */
- DBUG_PRINT("error",
- ("Can't create thread to handle request (error %d)",
- error));
+ /* purecov: begin inspected */
+ DBUG_PRINT("error",
+ ("Can't create thread to handle request (error %d)",
+ error));
+ thd->killed= KILL_CONNECTION; // Safety
+ mysql_mutex_unlock(&LOCK_thread_count);
- thread_count--;
- thd->killed= KILL_CONNECTION; // Safety
- mysql_mutex_unlock(&LOCK_thread_count);
+ mysql_mutex_lock(&LOCK_connection_count);
+ (*thd->scheduler->connection_count)--;
+ mysql_mutex_unlock(&LOCK_connection_count);
- mysql_mutex_lock(&LOCK_connection_count);
- (*thd->scheduler->connection_count)--;
- mysql_mutex_unlock(&LOCK_connection_count);
+ statistic_increment(aborted_connects,&LOCK_status);
+ statistic_increment(connection_errors_internal, &LOCK_status);
+ /* Can't use my_error() since store_globals has not been called. */
+ my_snprintf(error_message_buff, sizeof(error_message_buff),
+ ER_THD(thd, ER_CANT_CREATE_THREAD), error);
+ net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
+ close_connection(thd, ER_OUT_OF_RESOURCES);
- statistic_increment(aborted_connects,&LOCK_status);
- /* Can't use my_error() since store_globals has not been called. */
- my_snprintf(error_message_buff, sizeof(error_message_buff),
- ER_THD(thd, ER_CANT_CREATE_THREAD), error);
- net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
- close_connection(thd, ER_OUT_OF_RESOURCES);
- mysql_mutex_lock(&LOCK_thread_count);
- delete thd;
- mysql_mutex_unlock(&LOCK_thread_count);
- return;
- /* purecov: end */
- }
+ mysql_mutex_lock(&LOCK_thread_count);
+ thd->unlink();
+ mysql_mutex_unlock(&LOCK_thread_count);
+ delete thd;
+ thread_safe_decrement32(&thread_count, &thread_count_lock);
+ return;
+ /* purecov: end */
}
mysql_mutex_unlock(&LOCK_thread_count);
DBUG_PRINT("info",("Thread created"));
+ DBUG_VOID_RETURN;
}
@@ -6310,6 +6833,7 @@ static void create_new_thread(THD *thd)
close_connection(thd, ER_CON_COUNT_ERROR);
statistic_increment(denied_connections, &LOCK_status);
delete thd;
+ statistic_increment(connection_errors_max_connection, &LOCK_status);
DBUG_VOID_RETURN;
}
@@ -6320,10 +6844,10 @@ static void create_new_thread(THD *thd)
mysql_mutex_unlock(&LOCK_connection_count);
- /* Start a new thread to handle connection. */
+ thread_safe_increment32(&thread_count, &thread_count_lock);
+ /* Start a new thread to handle connection. */
mysql_mutex_lock(&LOCK_thread_count);
-
/*
The initialization of thread_id is done in create_embedded_thd() for
the embedded library.
@@ -6331,8 +6855,6 @@ static void create_new_thread(THD *thd)
*/
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
- thread_count++;
-
MYSQL_CALLBACK(thd->scheduler, add_connection, (thd));
DBUG_VOID_RETURN;
@@ -6344,8 +6866,9 @@ static void create_new_thread(THD *thd)
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 && base_ip_sock == INVALID_SOCKET))
+ if (mysql_socket_getfd(unix_sock) == INVALID_SOCKET ||
+ (!opt_disable_networking &&
+ mysql_socket_getfd(base_ip_sock) == INVALID_SOCKET))
{
select_thread_in_use = 0;
/* The following call will never return */
@@ -6364,7 +6887,8 @@ inline void kill_broken_server()
void handle_connections_sockets()
{
- my_socket UNINIT_VAR(sock), UNINIT_VAR(new_sock);
+ MYSQL_SOCKET sock= mysql_socket_invalid();
+ MYSQL_SOCKET new_sock= mysql_socket_invalid();
uint error_count=0;
THD *thd;
struct sockaddr_storage cAddr;
@@ -6373,36 +6897,38 @@ void handle_connections_sockets()
int extra_ip_flags __attribute__((unused))=0;
int flags=0,retval;
st_vio *vio_tmp;
+ bool is_unix_sock;
#ifdef HAVE_POLL
int socket_count= 0;
struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
+ MYSQL_SOCKET pfs_fds[3]; // for performance schema
#define setup_fds(X) \
- fds[socket_count].fd= X; \
+ mysql_socket_set_thread_owner(X); \
+ pfs_fds[socket_count]= (X); \
+ fds[socket_count].fd= mysql_socket_getfd(X); \
fds[socket_count].events= POLLIN; \
socket_count++
#else
+#define setup_fds(X) FD_SET(mysql_socket_getfd(X),&clientFDs)
fd_set readFDs,clientFDs;
- 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");
- if (base_ip_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
{
setup_fds(base_ip_sock);
- ip_flags = fcntl(base_ip_sock, F_GETFL, 0);
+ ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0);
}
- if (extra_ip_sock != INVALID_SOCKET)
+ if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
{
setup_fds(extra_ip_sock);
- extra_ip_flags = fcntl(extra_ip_sock, F_GETFL, 0);
+ extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0);
}
#ifdef HAVE_SYS_UN_H
setup_fds(unix_sock);
- socket_flags=fcntl(unix_sock, F_GETFL, 0);
+ socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0);
#endif
DBUG_PRINT("general",("Waiting for connections."));
@@ -6413,14 +6939,19 @@ void handle_connections_sockets()
retval= poll(fds, socket_count, -1);
#else
readFDs=clientFDs;
-
- retval= select((int) max_used_connection,&readFDs,0,0,0);
+ retval= select((int) 0,&readFDs,0,0,0);
#endif
if (retval < 0)
{
if (socket_errno != SOCKET_EINTR)
{
+ /*
+ select(2)/poll(2) failed on the listening port.
+ There is not much details to report about the client,
+ increment the server global status variable.
+ */
+ statistic_increment(connection_errors_accept, &LOCK_status);
if (!select_errors++ && !abort_loop) /* purecov: inspected */
sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
}
@@ -6440,19 +6971,19 @@ void handle_connections_sockets()
{
if (fds[i].revents & POLLIN)
{
- sock= fds[i].fd;
- flags= fcntl(sock, F_GETFL, 0);
+ sock= pfs_fds[i];
+ flags= fcntl(mysql_socket_getfd(sock), F_GETFL, 0);
break;
}
}
#else // HAVE_POLL
- if (FD_ISSET(base_ip_sock,&readFDs))
+ if (FD_ISSET(mysql_socket_getfd(base_ip_sock),&readFDs))
{
sock= base_ip_sock;
flags= ip_flags;
}
else
- if (FD_ISSET(extra_ip_sock,&readFDs))
+ if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
{
sock= extra_ip_sock;
flags= extra_ip_flags;
@@ -6468,18 +6999,19 @@ void handle_connections_sockets()
if (!(test_flags & TEST_BLOCKING))
{
#if defined(O_NONBLOCK)
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NONBLOCK);
#elif defined(O_NDELAY)
- fcntl(sock, F_SETFL, flags | O_NDELAY);
+ fcntl(mysql_socket_getfd(sock), F_SETFL, flags | O_NDELAY);
#endif
}
#endif /* NO_FCNTL_NONBLOCK */
for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
{
size_socket length= sizeof(struct sockaddr_storage);
- new_sock= accept(sock, (struct sockaddr *)(&cAddr),
- &length);
- if (new_sock != INVALID_SOCKET ||
+ new_sock= mysql_socket_accept(key_socket_client_connection, sock,
+ (struct sockaddr *)(&cAddr),
+ &length);
+ if (mysql_socket_getfd(new_sock) != INVALID_SOCKET ||
(socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
break;
MAYBE_BROKEN_SYSCALL;
@@ -6487,16 +7019,25 @@ void handle_connections_sockets()
if (!(test_flags & TEST_BLOCKING))
{
if (retry == MAX_ACCEPT_RETRY - 1)
- fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK
+ {
+ // Try without O_NONBLOCK
+ fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
+ }
}
#endif
}
#if !defined(NO_FCNTL_NONBLOCK)
if (!(test_flags & TEST_BLOCKING))
- fcntl(sock, F_SETFL, flags);
+ fcntl(mysql_socket_getfd(sock), F_SETFL, flags);
#endif
- if (new_sock == INVALID_SOCKET)
+ if (mysql_socket_getfd(new_sock) == INVALID_SOCKET)
{
+ /*
+ accept(2) failed on the listening port, after many retries.
+ There is not much details to report about the client,
+ increment the server global status variable.
+ */
+ statistic_increment(connection_errors_accept, &LOCK_status);
if ((error_count++ & 255) == 0) // This can happen often
sql_perror("Error in accept");
MAYBE_BROKEN_SYSCALL;
@@ -6505,16 +7046,18 @@ void handle_connections_sockets()
continue;
}
#if defined(WITH_WSREP) && defined(HAVE_FCNTL) && defined(FD_CLOEXEC)
- (void) fcntl(new_sock, F_SETFD, FD_CLOEXEC);
+ (void) fcntl(mysql_socket_getfd(new_sock), F_SETFD, FD_CLOEXEC);
#endif /* WITH_WSREP */
#ifdef HAVE_LIBWRAP
{
- if (sock == base_ip_sock || sock == extra_ip_sock)
+ if (mysql_socket_getfd(sock) == mysql_socket_getfd(base_ip_sock) ||
+ mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
{
struct request_info req;
signal(SIGCHLD, SIG_DFL);
- request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
+ request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE,
+ mysql_socket_getfd(new_sock), NULL);
my_fromhost(&req);
if (!my_hosts_access(&req))
{
@@ -6536,42 +7079,42 @@ void handle_connections_sockets()
((void (*)(int))req.sink)(req.fd);
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
- (void) closesocket(new_sock);
+ (void) mysql_socket_close(new_sock);
+ /*
+ The connection was refused by TCP wrappers.
+ There are no details (by client IP) available to update the
+ host_cache.
+ */
+ statistic_increment(connection_errors_tcpwrap, &LOCK_status);
continue;
}
}
}
#endif /* HAVE_LIBWRAP */
- {
- size_socket dummyLen;
- struct sockaddr_storage dummy;
- dummyLen = sizeof(dummy);
- if ( getsockname(new_sock,(struct sockaddr *)&dummy,
- (SOCKET_SIZE_TYPE *)&dummyLen) < 0 )
- {
- sql_perror("Error on new connection socket");
- (void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
- (void) closesocket(new_sock);
- continue;
- }
- }
-
/*
** Don't allow too many connections
*/
+ DBUG_PRINT("info", ("Creating THD for new connection"));
if (!(thd= new THD))
{
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
- (void) closesocket(new_sock);
+ (void) mysql_socket_close(new_sock);
+ statistic_increment(connection_errors_internal, &LOCK_status);
continue;
}
- if (!(vio_tmp=vio_new(new_sock,
- sock == unix_sock ? VIO_TYPE_SOCKET :
- VIO_TYPE_TCPIP,
- sock == unix_sock ? VIO_LOCALHOST: 0)) ||
- my_net_init(&thd->net,vio_tmp))
+ /* Set to get io buffers to be part of THD */
+ set_current_thd(thd);
+
+ is_unix_sock= (mysql_socket_getfd(sock) ==
+ mysql_socket_getfd(unix_sock));
+
+ if (!(vio_tmp=
+ mysql_socket_vio_new(new_sock,
+ is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
+ is_unix_sock ? VIO_LOCALHOST: 0)) ||
+ my_net_init(&thd->net, vio_tmp, MYF(MY_THREAD_SPECIFIC)))
{
/*
Only delete the temporary vio if we didn't already attach it to the
@@ -6583,20 +7126,24 @@ void handle_connections_sockets()
else
{
(void) mysql_socket_shutdown(new_sock, SHUT_RDWR);
- (void) closesocket(new_sock);
+ (void) mysql_socket_close(new_sock);
}
delete thd;
+ statistic_increment(connection_errors_internal, &LOCK_status);
continue;
}
- if (sock == unix_sock)
+
+ init_net_server_extension(thd);
+ if (is_unix_sock)
thd->security_ctx->host=(char*) my_localhost;
- if (sock == extra_ip_sock)
+ if (mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
{
thd->extra_port= 1;
thd->scheduler= extra_thread_scheduler;
}
create_new_thread(thd);
+ set_current_thd(0);
}
DBUG_VOID_RETURN;
}
@@ -6690,8 +7237,9 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
CloseHandle(hConnectedPipe);
continue;
}
+ set_current_thd(thd);
if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
- my_net_init(&thd->net, thd->net.vio))
+ my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC)))
{
close_connection(thd, ER_OUT_OF_RESOURCES);
delete thd;
@@ -6700,6 +7248,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
/* Host is unknown */
thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
create_new_thread(thd);
+ set_current_thd(0);
}
CloseHandle(connectOverlapped.hEvent);
DBUG_LEAVE;
@@ -6879,6 +7428,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
errmsg= "Could not set client to read mode";
goto errorconn;
}
+ set_current_thd(thd);
if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
handle_client_map,
event_client_wrote,
@@ -6886,7 +7436,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
event_server_wrote,
event_server_read,
event_conn_closed)) ||
- my_net_init(&thd->net, thd->net.vio))
+ my_net_init(&thd->net, thd->net.vio, MYF(MY_THREAD_SPECIFIC)))
{
close_connection(thd, ER_OUT_OF_RESOURCES);
errmsg= 0;
@@ -6895,6 +7445,7 @@ pthread_handler_t handle_connections_shared_memory(void *arg)
thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
create_new_thread(thd);
connect_number++;
+ set_current_thd(thd);
continue;
errorconn:
@@ -6922,6 +7473,7 @@ errorconn:
CloseHandle(event_conn_closed);
delete thd;
}
+ set_current_thd(0);
/* End shared memory handling */
error:
@@ -6952,6 +7504,64 @@ error:
Handle start options
******************************************************************************/
+
+/**
+ Process command line options flagged as 'early'.
+ Some components needs to be initialized as early as possible,
+ because the rest of the server initialization depends on them.
+ Options that needs to be parsed early includes:
+ - the performance schema, when compiled in,
+ - options related to the help,
+ - options related to the bootstrap
+ The performance schema needs to be initialized as early as possible,
+ before to-be-instrumented objects of the server are initialized.
+*/
+
+int handle_early_options()
+{
+ int ho_error;
+ DYNAMIC_ARRAY all_early_options;
+
+ my_getopt_register_get_addr(NULL);
+ /* Skip unknown options so that they may be processed later */
+ my_getopt_skip_unknown= TRUE;
+
+ /* prepare all_early_options array */
+ my_init_dynamic_array(&all_early_options, sizeof(my_option), 100, 25, MYF(0));
+ add_many_options(&all_early_options, pfs_early_options,
+ array_elements(pfs_early_options));
+ sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);
+ add_terminator(&all_early_options);
+
+ ho_error= handle_options(&remaining_argc, &remaining_argv,
+ (my_option*)(all_early_options.buffer),
+ mysqld_get_one_option);
+ if (ho_error == 0)
+ {
+ /* Add back the program name handle_options removes */
+ remaining_argc++;
+ remaining_argv--;
+ }
+
+ delete_dynamic(&all_early_options);
+
+ return ho_error;
+}
+
+
+#define MYSQL_COMPATIBILITY_OPTION(option) \
+ { option, OPT_MYSQL_COMPATIBILITY, \
+ 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
+
+#define MYSQL_TO_BE_IMPLEMENTED_OPTION(option) \
+ { option, OPT_MYSQL_TO_BE_IMPLEMENTED, \
+ 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
+
+#define MYSQL_SUGGEST_ANALOG_OPTION(option, str) \
+ { option, OPT_MYSQL_COMPATIBILITY, \
+ 0, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0 }
+
+
/**
System variables are automatically command-line options (few
exceptions are documented in sys_var.h), so don't need
@@ -6980,7 +7590,7 @@ struct my_option my_long_options[]=
{"autocommit", 0, "Set default value for autocommit (0 or 1)",
&opt_autocommit, &opt_autocommit, 0,
GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, NULL},
- {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
+ {"bind-address", 0, "IP address to bind to.",
&my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-do-db", OPT_BINLOG_DO_DB,
@@ -7140,9 +7750,6 @@ struct my_option my_long_options[]=
"Set the language used for the month names and the days of the week.",
&lc_time_names_name, &lc_time_names_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
- {"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 "
@@ -7179,25 +7786,11 @@ struct my_option my_long_options[]=
"Log slow statements executed by slave thread to the slow log if it is open.",
&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,
- "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},
{"log-tc", 0,
"Path to transaction coordinator log (used for transactions that affect "
"more than one storage engine, when binary log is disabled).",
&opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#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, (ulonglong) 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. Defaults to "
@@ -7215,10 +7808,6 @@ struct my_option my_long_options[]=
#endif /* HAVE_REPLICATION */
{"memlock", 0, "Lock mysqld in memory.", &locked_in_memory,
&locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"one-thread", OPT_ONE_THREAD,
- "(Deprecated): Only use one thread (for debugging under Linux). Use "
- "thread-handling=no-threads instead.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"old-style-user-limits", 0,
"Enable old-style user limits (before 5.0.3, user resources were counted "
"per each user+host vs. per account).",
@@ -7236,28 +7825,28 @@ struct my_option my_long_options[]=
"while having selected a different or no database. If you need cross "
"database updates to work, make sure you have 3.23.28 or later, and use "
"replicate-wild-do-table=db_name.%.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-do-table", OPT_REPLICATE_DO_TABLE,
"Tells the slave thread to restrict replication to the specified table. "
"To specify more than one table, use the directive multiple times, once "
"for each table. This will work for cross-database updates, in contrast "
- "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "to replicate-do-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
"Tells the slave thread to not replicate to the specified database. To "
"specify more than one database to ignore, use the directive multiple "
"times, once for each database. This option will not work if you use "
"cross database updates. If you need cross database updates to work, "
"make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
- "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "table=db_name.%. ", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
"Tells the slave thread to not replicate to the specified table. To specify "
"more than one table to ignore, use the directive multiple times, once for "
"each table. This will work for cross-database updates, in contrast to "
- "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ "replicate-ignore-db.", 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
"Updates to a database with a different name than the original. Example: "
"replicate-rewrite-db=master_db_name->slave_db_name.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_REPLICATION
{"replicate-same-server-id", 0,
"In replication, if set to 1, do not skip events having our server id. "
@@ -7273,7 +7862,7 @@ struct my_option my_long_options[]=
"database updates. Example: replicate-wild-do-table=foo%.bar% will "
"replicate only updates to tables in all databases that start with foo "
"and whose table names start with bar.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
"Tells the slave thread to not replicate to the tables that match the "
"given wildcard pattern. To specify more than one table to ignore, use "
@@ -7281,7 +7870,7 @@ struct my_option my_long_options[]=
"cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
"will not do updates to tables in databases that start with foo and whose "
"table names start with bar.",
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, GET_STR | GET_ASK_ADDR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing). Deprecated.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"safe-user-create", 0,
@@ -7306,10 +7895,6 @@ struct my_option my_long_options[]=
{"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-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.",
- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
{"slow-start-timeout", 0,
"Maximum number of milliseconds that the service control manager should wait "
@@ -7319,7 +7904,7 @@ struct my_option my_long_options[]=
#endif
#ifdef HAVE_OPENSSL
{"ssl", 0,
- "Enable SSL for connection (automatically enabled with other flags).",
+ "Enable SSL for connection (automatically enabled if an ssl option is used).",
&opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
0, 0, 0},
#endif
@@ -7362,24 +7947,85 @@ struct my_option my_long_options[]=
&global_system_variables.tx_isolation,
&global_system_variables.tx_isolation, &tx_isolation_typelib,
GET_ENUM, REQUIRED_ARG, ISO_REPEATABLE_READ, 0, 0, 0, 0, 0},
+ {"transaction-read-only", 0,
+ "Default transaction access mode. "
+ "True if transactions are read-only.",
+ &global_system_variables.tx_read_only,
+ &global_system_variables.tx_read_only, 0,
+ GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Used with --help option for detailed help.",
&opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
- {"plugin-load", 0,
+ {"plugin-load", OPT_PLUGIN_LOAD,
"Semicolon-separated list of plugins to load, where each plugin is "
"specified as ether a plugin_name=library_file pair or only a library_file. "
"If the latter case, all plugins from a given library_file will be loaded.",
- &opt_plugin_load, &opt_plugin_load, 0,
+ 0, 0, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"plugin-load-add", OPT_PLUGIN_LOAD_ADD,
+ "Optional semicolon-separated list of plugins to load. This option adds "
+ "to the list specified by --plugin-load in an incremental way. "
+ "It can be specified many times, adding more plugins every time.",
+ 0, 0, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"table_cache", 0, "Deprecated; use --table-open-cache instead.",
- &table_cache_size, &table_cache_size, 0, GET_ULONG,
+ &tc_size, &tc_size, 0, GET_ULONG,
REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
- {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-};
+#ifdef WITH_WSREP
+ {"wsrep-new-cluster", 0, "Bootstrap a cluster. It works by overriding the "
+ "current value of wsrep_cluster_address. It is recommended not to add this "
+ "option to the config file as this will trigger bootstrap on every server "
+ "start.", &wsrep_new_cluster, &wsrep_new_cluster, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
+ /* The following options exist in 5.6 but not in 10.0 */
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("default-tmp-storage-engine"),
+ MYSQL_COMPATIBILITY_OPTION("log-raw"),
+ MYSQL_COMPATIBILITY_OPTION("log-bin-use-v1-row-events"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("default-authentication-plugin"),
+ MYSQL_COMPATIBILITY_OPTION("binlog-max-flush-queue-time"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("binlog-row-image"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("explicit-defaults-for-timestamp"),
+ MYSQL_COMPATIBILITY_OPTION("master-info-repository"),
+ MYSQL_COMPATIBILITY_OPTION("relay-log-info-repository"),
+ MYSQL_SUGGEST_ANALOG_OPTION("binlog-rows-query-log-events", "--binlog-annotate-row-events"),
+ MYSQL_COMPATIBILITY_OPTION("binlog-order-commits"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("log-throttle-queries-not-using-indexes"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("end-markers-in-json"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace"), // OPTIMIZER_TRACE
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-features"), // OPTIMIZER_TRACE
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-offset"), // OPTIMIZER_TRACE
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-limit"), // OPTIMIZER_TRACE
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("optimizer-trace-max-mem-size"), // OPTIMIZER_TRACE
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("eq-range-index-dive-limit"),
+ MYSQL_COMPATIBILITY_OPTION("server-id-bits"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-rows-search-algorithms"), // HAVE_REPLICATION
+ MYSQL_COMPATIBILITY_OPTION("table-open-cache-instances"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("slave-allow-batching"), // HAVE_REPLICATION
+ MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-period"), // HAVE_REPLICATION
+ MYSQL_COMPATIBILITY_OPTION("slave-checkpoint-group"), // HAVE_REPLICATION
+ MYSQL_SUGGEST_ANALOG_OPTION("slave-parallel-workers", "--slave-parallel-threads"), // HAVE_REPLICATION
+ MYSQL_SUGGEST_ANALOG_OPTION("slave-pending-jobs-size-max", "--slave-parallel-max-queued"), // HAVE_REPLICATION
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("disconnect-on-expired-password"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-private-key-path"), // HAVE_OPENSSL && !HAVE_YASSL
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("sha256-password-public-key-path"), // HAVE_OPENSSL && !HAVE_YASSL
+
+ /* The following options exist in 5.5 and 5.6 but not in 10.0 */
+ MYSQL_SUGGEST_ANALOG_OPTION("abort-slave-event-count", "--debug-abort-slave-event-count"),
+ MYSQL_SUGGEST_ANALOG_OPTION("disconnect-slave-event-count", "--debug-disconnect-slave-event-count"),
+ MYSQL_SUGGEST_ANALOG_OPTION("exit-info", "--debug-exit-info"),
+ MYSQL_SUGGEST_ANALOG_OPTION("max-binlog-dump-events", "--debug-max-binlog-dump-events"),
+ MYSQL_SUGGEST_ANALOG_OPTION("sporadic-binlog-dump-fail", "--debug-sporadic-binlog-dump-fail"),
+ MYSQL_COMPATIBILITY_OPTION("new"),
+
+ /* The following options were added after 5.6.10 */
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("rpl-stop-slave-timeout"),
+ MYSQL_TO_BE_IMPLEMENTED_OPTION("validate-user-plugins") // NO_EMBEDDED_ACCESS_CHECKS
+};
static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
{
@@ -7424,52 +8070,109 @@ static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
{
+ Master_info *mi= NULL;
+ bool tmp;
+ LINT_INIT(tmp);
+
var->type= SHOW_MY_BOOL;
var->value= buff;
- *((my_bool *)buff)= (my_bool) (active_mi &&
- active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
- active_mi->rli.slave_running);
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (master_info_index)
+ {
+ mi= master_info_index->
+ get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE);
+ if (mi)
+ tmp= (my_bool) (mi->slave_running == MYSQL_SLAVE_RUN_READING &&
+ mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN);
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ if (mi)
+ *((my_bool *)buff)= tmp;
+ else
+ var->type= SHOW_UNDEF;
return 0;
}
-static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
+
+/* How many slaves are connected to this master */
+
+static int show_slaves_connected(THD *thd, SHOW_VAR *var, char *buff)
{
- /*
- TODO: with multimaster, have one such counter per line in
- SHOW SLAVE STATUS, and have the sum over all lines here.
- */
- if (active_mi)
- {
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (long)active_mi->rli.retried_trans;
- }
- else
- var->type= SHOW_UNDEF;
+
+ var->type= SHOW_LONGLONG;
+ var->value= buff;
+ mysql_mutex_lock(&LOCK_slave_list);
+
+ *((longlong *)buff)= slave_list.records;
+
+ mysql_mutex_unlock(&LOCK_slave_list);
+ return 0;
+}
+
+
+/* How many masters this slave is connected to */
+
+
+static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_LONGLONG;
+ var->value= buff;
+ mysql_mutex_lock(&LOCK_active_mi);
+
+ *((longlong *)buff)= master_info_index->any_slave_sql_running();
+
+ mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
+
static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff)
{
- if (active_mi)
- {
- var->type= SHOW_LONGLONG;
- var->value= buff;
- *((longlong *)buff)= active_mi->received_heartbeats;
- }
+ Master_info *mi= NULL;
+ longlong tmp;
+ LINT_INIT(tmp);
+
+ var->type= SHOW_LONGLONG;
+ var->value= buff;
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (master_info_index)
+ {
+ mi= master_info_index->
+ get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE);
+ if (mi)
+ tmp= mi->received_heartbeats;
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ if (mi)
+ *((longlong *)buff)= tmp;
else
var->type= SHOW_UNDEF;
return 0;
}
+
static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff)
{
- if (active_mi)
- {
- var->type= SHOW_CHAR;
- var->value= buff;
- sprintf(buff, "%.3f", active_mi->heartbeat_period);
- }
+ Master_info *mi= NULL;
+ float tmp;
+ LINT_INIT(tmp);
+
+ var->type= SHOW_CHAR;
+ var->value= buff;
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (master_info_index)
+ {
+ mi= master_info_index->
+ get_master_info(&thd->variables.default_master_connection,
+ Sql_condition::WARN_LEVEL_NOTE);
+ if (mi)
+ tmp= mi->heartbeat_period;
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ if (mi)
+ sprintf(buff, "%.3f", tmp);
else
var->type= SHOW_UNDEF;
return 0;
@@ -7482,7 +8185,7 @@ static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_LONG;
var->value= buff;
- *((long *)buff)= (long)cached_open_tables();
+ *((long *) buff)= (long) tc_records();
return 0;
}
@@ -7500,10 +8203,20 @@ static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
{
var->type= SHOW_LONG;
var->value= buff;
- *((long *)buff)= (long)cached_table_definitions();
+ *((long *) buff)= (long) tdc_records();
return 0;
}
+
+static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_LONG;
+ var->value= buff;
+ *((long *) buff)= (long) tdc_refresh_version();
+ return 0;
+}
+
+
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
/* Functions relying on CTX */
static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
@@ -7760,6 +8473,110 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+
+#ifdef HAVE_YASSL
+
+static char *
+my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
+{
+ return yaSSL_ASN1_TIME_to_string(time, buf, len);
+}
+
+#else /* openssl */
+
+static char *
+my_asn1_time_to_string(ASN1_TIME *time, char *buf, size_t len)
+{
+ int n_read;
+ char *res= NULL;
+ BIO *bio= BIO_new(BIO_s_mem());
+
+ if (bio == NULL)
+ return NULL;
+
+ if (!ASN1_TIME_print(bio, time))
+ goto end;
+
+ n_read= BIO_read(bio, buf, (int) (len - 1));
+
+ if (n_read > 0)
+ {
+ buf[n_read]= 0;
+ res= buf;
+ }
+
+end:
+ BIO_free(bio);
+ return res;
+}
+
+#endif
+
+
+/**
+ Handler function for the 'ssl_get_server_not_before' variable
+
+ @param thd the mysql thread structure
+ @param var the data for the variable
+ @param[out] buf the string to put the value of the variable into
+
+ @return status
+ @retval 0 success
+*/
+
+static int
+show_ssl_get_server_not_before(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_CHAR;
+ if(thd->vio_ok() && thd->net.vio->ssl_arg)
+ {
+ SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
+ X509 *cert= SSL_get_certificate(ssl);
+ ASN1_TIME *not_before= X509_get_notBefore(cert);
+
+ var->value= my_asn1_time_to_string(not_before, buff,
+ SHOW_VAR_FUNC_BUFF_SIZE);
+ if (!var->value)
+ return 1;
+ var->value= buff;
+ }
+ else
+ var->value= empty_c_string;
+ return 0;
+}
+
+
+/**
+ Handler function for the 'ssl_get_server_not_after' variable
+
+ @param thd the mysql thread structure
+ @param var the data for the variable
+ @param[out] buf the string to put the value of the variable into
+
+ @return status
+ @retval 0 success
+*/
+
+static int
+show_ssl_get_server_not_after(THD *thd, SHOW_VAR *var, char *buff)
+{
+ var->type= SHOW_CHAR;
+ if(thd->vio_ok() && thd->net.vio->ssl_arg)
+ {
+ SSL *ssl= (SSL*) thd->net.vio->ssl_arg;
+ X509 *cert= SSL_get_certificate(ssl);
+ ASN1_TIME *not_after= X509_get_notAfter(cert);
+
+ var->value= my_asn1_time_to_string(not_after, buff,
+ SHOW_VAR_FUNC_BUFF_SIZE);
+ if (!var->value)
+ return 1;
+ }
+ else
+ var->value= empty_c_string;
+ return 0;
+}
+
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff)
@@ -7802,6 +8619,42 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff)
return 0;
}
+#ifndef DBUG_OFF
+static int debug_status_func(THD *thd, SHOW_VAR *var, char *buff)
+{
+#define add_var(X,Y,Z) \
+ v->name= X; \
+ v->value= (char*)Y; \
+ v->type= Z; \
+ v++;
+
+ var->type= SHOW_ARRAY;
+ var->value= buff;
+
+ SHOW_VAR *v= (SHOW_VAR *)buff;
+
+ if (_db_keyword_(0, "role_merge_stats", 1))
+ {
+ static SHOW_VAR roles[]= {
+ {"global", (char*) &role_global_merges, SHOW_ULONG},
+ {"db", (char*) &role_db_merges, SHOW_ULONG},
+ {"table", (char*) &role_table_merges, SHOW_ULONG},
+ {"column", (char*) &role_column_merges, SHOW_ULONG},
+ {"routine", (char*) &role_routine_merges, SHOW_ULONG},
+ {NullS, NullS, SHOW_LONG}
+ };
+
+ add_var("role_merges", roles, SHOW_ARRAY);
+ }
+
+ v->name= 0;
+
+#undef add_var
+
+ return 0;
+}
+#endif
+
#ifdef HAVE_POOL_OF_THREADS
int show_threadpool_idle_threads(THD *thd, SHOW_VAR *var, char *buff)
{
@@ -7829,35 +8682,46 @@ SHOW_VAR status_vars[]= {
{"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
{"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
{"Com", (char*) com_status_vars, SHOW_ARRAY},
- {"Compression", (char*) &show_net_compression, SHOW_FUNC},
+ {"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC},
{"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
+ {"Connection_errors_accept", (char*) &connection_errors_accept, SHOW_LONG},
+ {"Connection_errors_internal", (char*) &connection_errors_internal, SHOW_LONG},
+ {"Connection_errors_max_connections", (char*) &connection_errors_max_connection, SHOW_LONG},
+ {"Connection_errors_peer_address", (char*) &connection_errors_peer_addr, SHOW_LONG},
+ {"Connection_errors_select", (char*) &connection_errors_select, SHOW_LONG},
+ {"Connection_errors_tcpwrap", (char*) &connection_errors_tcpwrap, SHOW_LONG},
{"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_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},
+ {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables_), SHOW_LONG_STATUS},
+#ifndef DBUG_OFF
+ {"Debug", (char*) &debug_status_func, SHOW_FUNC},
+#endif
{"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},
{"Executed_events", (char*) &executed_events, SHOW_LONG_NOFLUSH },
{"Executed_triggers", (char*) offsetof(STATUS_VAR, executed_triggers), SHOW_LONG_STATUS},
+ {"Feature_delay_key_write", (char*) &feature_files_opened_with_delayed_keys, SHOW_LONG },
{"Feature_dynamic_columns", (char*) offsetof(STATUS_VAR, feature_dynamic_columns), SHOW_LONG_STATUS},
{"Feature_fulltext", (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS},
{"Feature_gis", (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS},
{"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS},
{"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS},
{"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS},
- {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
- {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
- {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
+ {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
+ {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
+ {"Flush_commands", (char*) &show_flush_commands, SHOW_SIMPLE_FUNC},
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
{"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
+ {"Handler_external_lock", (char*) offsetof(STATUS_VAR, ha_external_lock_count), SHOW_LONGLONG_STATUS},
{"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS},
{"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS},
{"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS},
- {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS},
- {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS},
+ {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS},
+ {"Handler_mrr_rowid_refills",(char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS},
{"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
{"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
{"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
@@ -7877,18 +8741,20 @@ SHOW_VAR status_vars[]= {
{"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},
+ {"Memory_used", (char*) offsetof(STATUS_VAR, memory_used), SHOW_LONGLONG_STATUS},
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
{"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH},
{"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH},
- {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC},
- {"Open_tables", (char*) &show_open_tables, SHOW_FUNC},
+ {"Open_table_definitions", (char*) &show_table_definitions, SHOW_SIMPLE_FUNC},
+ {"Open_tables", (char*) &show_open_tables, SHOW_SIMPLE_FUNC},
{"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
+ {"Opened_plugin_libraries", (char*) &dlopen_count, SHOW_LONG},
{"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
{"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
- {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS},
- {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
- {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
+ {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS},
+ {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_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},
@@ -7900,54 +8766,60 @@ SHOW_VAR status_vars[]= {
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
#endif /*HAVE_QUERY_CACHE*/
- {"Queries", (char*) &show_queries, SHOW_FUNC},
+ {"Queries", (char*) &show_queries, SHOW_SIMPLE_FUNC},
{"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
#ifdef HAVE_REPLICATION
- {"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC},
-#endif
- {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
- {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
- {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
- {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
- {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
- {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
+ {"Rpl_status", (char*) &show_rpl_status, SHOW_SIMPLE_FUNC},
+#endif
+ {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count_), SHOW_LONG_STATUS},
+ {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count_), SHOW_LONG_STATUS},
+ {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count_), SHOW_LONG_STATUS},
+ {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count_), SHOW_LONG_STATUS},
+ {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count_), SHOW_LONG_STATUS},
+ {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_INT},
#ifdef HAVE_REPLICATION
- {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_FUNC},
- {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC},
- {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
- {"Slave_running", (char*) &show_slave_running, SHOW_FUNC},
+ {"Slaves_connected", (char*) &show_slaves_connected, SHOW_SIMPLE_FUNC },
+ {"Slaves_running", (char*) &show_slaves_running, SHOW_SIMPLE_FUNC },
+ {"Slave_connections", (char*) offsetof(STATUS_VAR, com_register_slave), SHOW_LONG_STATUS},
+ {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC},
+ {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC},
+ {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG},
+ {"Slave_running", (char*) &show_slave_running, SHOW_SIMPLE_FUNC},
#endif
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
- {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
- {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
- {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
- {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
+ {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes_), SHOW_LONG_STATUS},
+ {"Sort_priority_queue_sorts",(char*) offsetof(STATUS_VAR, filesort_pq_sorts_), SHOW_LONG_STATUS},
+ {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count_), SHOW_LONG_STATUS},
+ {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows_), SHOW_LONG_STATUS},
+ {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count_), SHOW_LONG_STATUS},
#ifdef HAVE_OPENSSL
#ifndef EMBEDDED_LIBRARY
- {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC},
- {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC},
- {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC},
- {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_FUNC},
- {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_FUNC},
- {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC},
- {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC},
- {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC},
- {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC},
- {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_FUNC},
- {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC},
- {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC},
- {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC},
- {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC},
- {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC},
- {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC},
- {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC},
- {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC},
- {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_FUNC},
- {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC},
- {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
- {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
- {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
+ {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_SIMPLE_FUNC},
+ {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_SIMPLE_FUNC},
+ {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_SIMPLE_FUNC},
+ {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_SIMPLE_FUNC},
+ {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_SIMPLE_FUNC},
+ {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_SIMPLE_FUNC},
+ {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_SIMPLE_FUNC},
+ {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_SIMPLE_FUNC},
+ {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_SIMPLE_FUNC},
+ {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_SIMPLE_FUNC},
+ {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_SIMPLE_FUNC},
+ {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_SIMPLE_FUNC},
+ {"Ssl_server_not_after", (char*) &show_ssl_get_server_not_after, SHOW_SIMPLE_FUNC},
+ {"Ssl_server_not_before", (char*) &show_ssl_get_server_not_before, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_SIMPLE_FUNC},
+ {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_SIMPLE_FUNC},
+ {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_SIMPLE_FUNC},
+ {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC},
+ {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC},
+ {"Ssl_version", (char*) &show_ssl_get_version, SHOW_SIMPLE_FUNC},
#endif
#endif /* HAVE_OPENSSL */
{"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH},
@@ -7965,16 +8837,16 @@ SHOW_VAR status_vars[]= {
{"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG},
#endif
#ifdef HAVE_POOL_OF_THREADS
- {"Threadpool_idle_threads", (char *) &show_threadpool_idle_threads, SHOW_FUNC},
+ {"Threadpool_idle_threads", (char *) &show_threadpool_idle_threads, SHOW_SIMPLE_FUNC},
{"Threadpool_threads", (char *) &tp_stats.num_worker_threads, SHOW_INT},
#endif
{"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
{"Threads_connected", (char*) &connection_count, SHOW_INT},
{"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
{"Threads_running", (char*) &thread_running, SHOW_INT},
- {"Uptime", (char*) &show_starttime, SHOW_FUNC},
+ {"Uptime", (char*) &show_starttime, SHOW_SIMPLE_FUNC},
#ifdef ENABLED_PROFILING
- {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_FUNC},
+ {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_SIMPLE_FUNC},
#endif
#ifdef WITH_WSREP
{"wsrep_connected", (char*) &wsrep_connected, SHOW_BOOL},
@@ -7984,7 +8856,7 @@ SHOW_VAR status_vars[]= {
{"wsrep_cluster_status", (char*) &wsrep_cluster_status, SHOW_CHAR_PTR},
{"wsrep_cluster_size", (char*) &wsrep_cluster_size, SHOW_LONG_NOFLUSH},
{"wsrep_local_index", (char*) &wsrep_local_index, SHOW_LONG_NOFLUSH},
- {"wsrep_local_bf_aborts", (char*) &wsrep_show_bf_aborts, SHOW_FUNC},
+ {"wsrep_local_bf_aborts", (char*) &wsrep_show_bf_aborts, SHOW_SIMPLE_FUNC},
{"wsrep_provider_name", (char*) &wsrep_provider_name, SHOW_CHAR_PTR},
{"wsrep_provider_version", (char*) &wsrep_provider_version, SHOW_CHAR_PTR},
{"wsrep_provider_vendor", (char*) &wsrep_provider_vendor, SHOW_CHAR_PTR},
@@ -7994,12 +8866,21 @@ SHOW_VAR status_vars[]= {
{NullS, NullS, SHOW_LONG}
};
-bool add_terminator(DYNAMIC_ARRAY *options)
+static bool add_terminator(DYNAMIC_ARRAY *options)
{
my_option empty_element= {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0};
return insert_dynamic(options, (uchar *)&empty_element);
}
+static bool add_many_options(DYNAMIC_ARRAY *options, my_option *list,
+ size_t elements)
+{
+ for (my_option *opt= list; opt < list + elements; opt++)
+ if (insert_dynamic(options, opt))
+ return 1;
+ return 0;
+}
+
#ifndef EMBEDDED_LIBRARY
static void print_version(void)
{
@@ -8031,22 +8912,30 @@ static int option_cmp(my_option *a, my_option *b)
return 1;
}
}
- DBUG_ASSERT(a->name == b->name);
return 0;
}
static void print_help()
{
MEM_ROOT mem_root;
- init_alloc_root(&mem_root, 4096, 4096);
+ init_alloc_root(&mem_root, 4096, 4096, MYF(0));
pop_dynamic(&all_options);
+ add_many_options(&all_options, pfs_early_options,
+ array_elements(pfs_early_options));
sys_var_add_options(&all_options, sys_var::PARSE_EARLY);
add_plugin_options(&all_options, &mem_root);
sort_dynamic(&all_options, (qsort_cmp) option_cmp);
+ sort_dynamic(&all_options, (qsort_cmp) option_cmp);
add_terminator(&all_options);
my_print_help((my_option*) all_options.buffer);
+
+ /* Add variables that can be shown but not changed, like version numbers */
+ pop_dynamic(&all_options);
+ sys_var_add_options(&all_options, sys_var::SHOW_VALUE_IN_HELP);
+ sort_dynamic(&all_options, (qsort_cmp) option_cmp);
+ add_terminator(&all_options);
my_print_variables((my_option*) all_options.buffer);
free_root(&mem_root, MYF(0));
@@ -8070,16 +8959,15 @@ static void usage(void)
else
{
#ifdef __WIN__
- puts("NT and Win32 specific options:\n\
- --install Install the default service (NT).\n\
- --install-manual Install the default service started manually (NT).\n\
- --install service_name Install an optional service (NT).\n\
- --install-manual service_name Install an optional service started manually (NT).\n\
- --remove Remove the default service from the service list (NT).\n\
- --remove service_name Remove the service_name from the service list (NT).\n\
- --enable-named-pipe Only to be used for the default server (NT).\n\
- --standalone Dummy option to start as a standalone server (NT).\
-");
+ puts("NT and Win32 specific options:\n"
+ " --install Install the default service (NT).\n"
+ " --install-manual Install the default service started manually (NT).\n"
+ " --install service_name Install an optional service (NT).\n"
+ " --install-manual service_name Install an optional service started manually (NT).\n"
+ " --remove Remove the default service from the service list (NT).\n"
+ " --remove service_name Remove the service_name from the service list (NT).\n"
+ " --enable-named-pipe Only to be used for the default server (NT).\n"
+ " --standalone Dummy option to start as a standalone server (NT).");
puts("");
#endif
print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
@@ -8091,14 +8979,12 @@ static void usage(void)
if (! plugins_are_initialized)
{
- puts("\n\
-Plugins have parameters that are not reflected in this list\n\
-because execution stopped before plugins were initialized.");
+ puts("\nPlugins have parameters that are not reflected in this list"
+ "\nbecause execution stopped before plugins were initialized.");
}
- puts("\n\
-To see what values a running MySQL server is using, type\n\
-'mysqladmin variables' instead of 'mysqld --verbose --help'.");
+ puts("\nTo see what values a running MySQL server is using, type"
+ "\n'mysqladmin variables' instead of 'mysqld --verbose --help'.");
}
DBUG_VOID_RETURN;
}
@@ -8141,7 +9027,8 @@ static int mysql_init_variables(void)
cleanup_done= 0;
server_id_supplied= 0;
test_flags= select_errors= dropping_tables= ha_open_options=0;
- thread_count= thread_running= kill_cached_threads= wake_thread=0;
+ thread_count= thread_running= kill_cached_threads= wake_thread= 0;
+ service_thread_count= 0;
slave_open_temp_tables= 0;
cached_thread_count= 0;
opt_endinfo= using_udf_functions= 0;
@@ -8175,17 +9062,20 @@ static int mysql_init_variables(void)
character_set_filesystem= &my_charset_bin;
opt_specialflag= SPECIAL_ENGLISH;
- unix_sock= base_ip_sock= extra_ip_sock= INVALID_SOCKET;
+ unix_sock= base_ip_sock= extra_ip_sock= MYSQL_INVALID_SOCKET;
mysql_home_ptr= mysql_home;
pidfile_name_ptr= pidfile_name;
log_error_file_ptr= log_error_file;
protocol_version= PROTOCOL_VERSION;
what_to_log= ~ (1L << (uint) COM_TIME);
- refresh_version= 2L; /* Increments on each reload. 0 and 1 are reserved */
+ denied_connections= 0;
executed_events= 0;
global_query_id= thread_id= 1L;
my_atomic_rwlock_init(&global_query_id_lock);
my_atomic_rwlock_init(&thread_running_lock);
+ my_atomic_rwlock_init(&thread_count_lock);
+ my_atomic_rwlock_init(&statistics_lock);
+ my_atomic_rwlock_init(&slave_executed_entries_lock);
strnmov(server_version, MYSQL_SERVER_VERSION, sizeof(server_version)-1);
threads.empty();
thread_cache.empty();
@@ -8209,6 +9099,7 @@ static int mysql_init_variables(void)
relay_log_info_file= (char*) "relay-log.info";
report_user= report_password = report_host= 0; /* TO BE DELETED */
opt_relay_logname= opt_relaylog_index_name= 0;
+ slave_retried_transactions= 0;
/* Variables in libraries */
charsets_dir= 0;
@@ -8233,8 +9124,13 @@ static int mysql_init_variables(void)
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
have_ssl=SHOW_OPTION_YES;
+#if HAVE_YASSL
+ have_openssl= SHOW_OPTION_NO;
+#else
+ have_openssl= SHOW_OPTION_YES;
+#endif
#else
- have_ssl=SHOW_OPTION_NO;
+ have_openssl= have_ssl= SHOW_OPTION_NO;
#endif
#ifdef HAVE_BROKEN_REALPATH
have_symlink=SHOW_OPTION_NO;
@@ -8344,6 +9240,14 @@ mysqld_get_one_option(int optid,
"for compatiblity with old my.cnf files.",
opt->name);
break;
+ case OPT_MYSQL_COMPATIBILITY:
+ sql_print_warning("'%s' is MySQL 5.6 compatible option. Not used or needed "
+ "in MariaDB.", opt->name);
+ break;
+ case OPT_MYSQL_TO_BE_IMPLEMENTED:
+ sql_print_warning("'%s' is MySQL 5.6 compatible option. To be implemented "
+ "in later versions.", opt->name);
+ break;
case 'a':
global_system_variables.sql_mode= MODE_ANSI;
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
@@ -8355,10 +9259,6 @@ mysqld_get_one_option(int optid,
if (default_collation_name == compiled_default_collation_name)
default_collation_name= 0;
break;
- case 'l':
- WARN_DEPRECATED(NULL, 7, 0, "--log", "'--general-log'/'--general-log-file'");
- opt_log=1;
- break;
case 'h':
strmake_buf(mysql_real_data_home, argument);
/* Correct pointer set by my_getopt (for embedded library) */
@@ -8402,7 +9302,7 @@ mysqld_get_one_option(int optid,
opt_myisam_log=1;
break;
case (int) OPT_BIN_LOG:
- opt_bin_log= test(argument != disabled_my_option);
+ opt_bin_log= MY_TEST(argument != disabled_my_option);
opt_bin_log_used= 1;
break;
case (int) OPT_LOG_BASENAME:
@@ -8436,12 +9336,12 @@ mysqld_get_one_option(int optid,
#ifdef HAVE_REPLICATION
case (int)OPT_REPLICATE_IGNORE_DB:
{
- rpl_filter->add_ignore_db(argument);
+ cur_rpl_filter->add_ignore_db(argument);
break;
}
case (int)OPT_REPLICATE_DO_DB:
{
- rpl_filter->add_do_db(argument);
+ cur_rpl_filter->add_do_db(argument);
break;
}
case (int)OPT_REPLICATE_REWRITE_DB:
@@ -8472,7 +9372,7 @@ mysqld_get_one_option(int optid,
return 1;
}
- rpl_filter->add_db_rewrite(key, val);
+ cur_rpl_filter->add_db_rewrite(key, val);
break;
}
@@ -8488,7 +9388,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_DO_TABLE:
{
- if (rpl_filter->add_do_table(argument))
+ if (cur_rpl_filter->add_do_table(argument))
{
sql_print_error("Could not add do table rule '%s'!\n", argument);
return 1;
@@ -8497,7 +9397,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_WILD_DO_TABLE:
{
- if (rpl_filter->add_wild_do_table(argument))
+ if (cur_rpl_filter->add_wild_do_table(argument))
{
sql_print_error("Could not add do table rule '%s'!\n", argument);
return 1;
@@ -8506,7 +9406,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
{
- if (rpl_filter->add_wild_ignore_table(argument))
+ if (cur_rpl_filter->add_wild_ignore_table(argument))
{
sql_print_error("Could not add ignore table rule '%s'!\n", argument);
return 1;
@@ -8515,7 +9415,7 @@ mysqld_get_one_option(int optid,
}
case (int)OPT_REPLICATE_IGNORE_TABLE:
{
- if (rpl_filter->add_ignore_table(argument))
+ if (cur_rpl_filter->add_ignore_table(argument))
{
sql_print_error("Could not add ignore table rule '%s'!\n", argument);
return 1;
@@ -8523,10 +9423,6 @@ mysqld_get_one_option(int optid,
break;
}
#endif /* HAVE_REPLICATION */
- case (int) OPT_SLOW_QUERY_LOG:
- WARN_DEPRECATED(NULL, 7, 0, "--log-slow-queries", "'--slow-query-log'/'--slow-query-log-file'");
- opt_slow_log= 1;
- break;
case (int) OPT_SAFE:
opt_specialflag|= SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC;
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
@@ -8538,12 +9434,6 @@ mysqld_get_one_option(int optid,
sql_print_warning("The syntax '--safe-mode' is deprecated and will be "
"removed in a future release.");
break;
- case (int) OPT_SKIP_PRIOR:
- opt_specialflag|= SPECIAL_NO_PRIOR;
- sql_print_warning("The --skip-thread-priority startup option is deprecated "
- "and will be removed in MySQL 7.0. This option has no effect "
- "as the implied behavior is already the default.");
- break;
case (int) OPT_SKIP_HOST_CACHE:
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
@@ -8563,9 +9453,7 @@ mysqld_get_one_option(int optid,
break;
case OPT_SERVER_ID:
server_id_supplied = 1;
- break;
- case OPT_ONE_THREAD:
- thread_handling= SCHEDULER_NO_THREADS;
+ ::server_id= global_system_variables.server_id;
break;
case OPT_LOWER_CASE_TABLE_NAMES:
lower_case_table_names_used= 1;
@@ -8594,18 +9482,6 @@ mysqld_get_one_option(int optid,
}
break;
#endif /* defined(ENABLED_DEBUG_SYNC) */
- case OPT_ENGINE_CONDITION_PUSHDOWN:
- /*
- The last of --engine-condition-pushdown and --optimizer_switch on
- command line wins (see get_options().
- */
- if (global_system_variables.engine_condition_pushdown)
- global_system_variables.optimizer_switch|=
- OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN;
- else
- global_system_variables.optimizer_switch&=
- ~OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN;
- break;
case OPT_LOG_ERROR:
/*
"No --log-error" == "write errors to stderr",
@@ -8614,11 +9490,6 @@ mysqld_get_one_option(int optid,
if (argument == NULL) /* no argument */
log_error_file_ptr= const_cast<char*>("");
break;
- case OPT_MAX_LONG_DATA_SIZE:
- max_long_data_size_used= true;
- break;
-
-
case OPT_IGNORE_DB_DIRECTORY:
if (*argument == 0)
ignore_db_dirs_reset();
@@ -8633,6 +9504,85 @@ mysqld_get_one_option(int optid,
}
}
break;
+
+ case OPT_PLUGIN_LOAD:
+ free_list(opt_plugin_load_list_ptr);
+ /* fall through */
+ case OPT_PLUGIN_LOAD_ADD:
+ opt_plugin_load_list_ptr->push_back(new i_string(argument));
+ break;
+ case OPT_MAX_LONG_DATA_SIZE:
+ max_long_data_size_used= true;
+ break;
+ case OPT_PFS_INSTRUMENT:
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+#ifndef EMBEDDED_LIBRARY
+ /* Parse instrument name and value from argument string */
+ char* name = argument,*p, *val;
+
+ /* Assignment required */
+ if (!(p= strchr(argument, '=')))
+ {
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "Missing value for performance_schema_instrument "
+ "'%s'", argument);
+ return 0;
+ }
+
+ /* Option value */
+ val= p + 1;
+ if (!*val)
+ {
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "Missing value for performance_schema_instrument "
+ "'%s'", argument);
+ return 0;
+ }
+
+ /* Trim leading spaces from instrument name */
+ while (*name && my_isspace(mysqld_charset, *name))
+ name++;
+
+ /* Trim trailing spaces and slashes from instrument name */
+ while (p > argument && (my_isspace(mysqld_charset, p[-1]) || p[-1] == '/'))
+ p--;
+ *p= 0;
+
+ if (!*name)
+ {
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "Invalid instrument name for "
+ "performance_schema_instrument '%s'", argument);
+ return 0;
+ }
+
+ /* Trim leading spaces from option value */
+ while (*val && my_isspace(mysqld_charset, *val))
+ val++;
+
+ /* Trim trailing spaces from option value */
+ if ((p= my_strchr(mysqld_charset, val, val+strlen(val), ' ')) != NULL)
+ *p= 0;
+
+ if (!*val)
+ {
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "Invalid value for performance_schema_instrument "
+ "'%s'", argument);
+ return 0;
+ }
+
+ /* Add instrument name and value to array of configuration options */
+ if (add_pfs_instr_to_array(name, val))
+ {
+ my_getopt_error_reporter(WARNING_LEVEL,
+ "Invalid value for performance_schema_instrument "
+ "'%s'", argument);
+ return 0;
+ }
+#endif /* EMBEDDED_LIBRARY */
+#endif
+ break;
}
return 0;
}
@@ -8643,7 +9593,7 @@ mysqld_get_one_option(int optid,
C_MODE_START
static void*
-mysql_getopt_value(const char *keyname, uint key_length,
+mysql_getopt_value(const char *name, uint length,
const struct my_option *option, int *error)
{
if (error)
@@ -8654,9 +9604,10 @@ mysql_getopt_value(const char *keyname, uint key_length,
case OPT_KEY_CACHE_DIVISION_LIMIT:
case OPT_KEY_CACHE_AGE_THRESHOLD:
case OPT_KEY_CACHE_PARTITIONS:
+ case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
{
KEY_CACHE *key_cache;
- if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
+ if (!(key_cache= get_or_create_key_cache(name, length)))
{
if (error)
*error= EXIT_OUT_OF_MEMORY;
@@ -8673,8 +9624,26 @@ mysql_getopt_value(const char *keyname, uint key_length,
return &key_cache->param_age_threshold;
case OPT_KEY_CACHE_PARTITIONS:
return (uchar**) &key_cache->param_partitions;
+ case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
+ return (uchar**) &key_cache->changed_blocks_hash_size;
}
}
+ case OPT_REPLICATE_DO_DB:
+ case OPT_REPLICATE_DO_TABLE:
+ case OPT_REPLICATE_IGNORE_DB:
+ case OPT_REPLICATE_IGNORE_TABLE:
+ case OPT_REPLICATE_WILD_DO_TABLE:
+ case OPT_REPLICATE_WILD_IGNORE_TABLE:
+ case OPT_REPLICATE_REWRITE_DB:
+ {
+ /* Store current filter for mysqld_get_one_option() */
+ if (!(cur_rpl_filter= get_or_create_rpl_filter(name, length)))
+ {
+ if (error)
+ *error= EXIT_OUT_OF_MEMORY;
+ }
+ return 0;
+ }
}
return option->value;
}
@@ -8715,11 +9684,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
/* prepare all_options array */
my_init_dynamic_array(&all_options, sizeof(my_option),
array_elements(my_long_options),
- array_elements(my_long_options)/4);
- for (my_option *opt= my_long_options;
- opt < my_long_options + array_elements(my_long_options) - 1;
- opt++)
- insert_dynamic(&all_options, (uchar*) opt);
+ array_elements(my_long_options)/4, MYF(0));
+ add_many_options(&all_options, my_long_options, array_elements(my_long_options));
sys_var_add_options(&all_options, 0);
add_terminator(&all_options);
@@ -8839,7 +9805,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
global_system_variables.sql_mode=
expand_sql_mode(global_system_variables.sql_mode);
-#if defined(HAVE_BROKEN_REALPATH)
+#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
have_symlink=SHOW_OPTION_NO;
@@ -8875,7 +9841,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
Set some global variables from the global_system_variables
In most cases the global variables will not be used
*/
- my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
+ my_disable_locking= myisam_single_user= MY_TEST(opt_external_locking == 0);
my_default_record_cache_size=global_system_variables.read_buff_size;
/*
@@ -8932,8 +9898,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
#endif
global_system_variables.engine_condition_pushdown=
- test(global_system_variables.optimizer_switch &
- OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN);
+ MY_TEST(global_system_variables.optimizer_switch &
+ OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN);
opt_readonly= read_only;
@@ -8944,8 +9910,37 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
if (!max_long_data_size_used)
max_long_data_size= global_system_variables.max_allowed_packet;
- /* Rember if max_user_connections was 0 at startup */
+ /* Remember if max_user_connections was 0 at startup */
max_user_connections_checking= global_system_variables.max_user_connections != 0;
+
+ {
+ sys_var *max_relay_log_size_var, *max_binlog_size_var;
+ /* If max_relay_log_size is 0, then set it to max_binlog_size */
+ if (!global_system_variables.max_relay_log_size)
+ global_system_variables.max_relay_log_size= max_binlog_size;
+
+ /*
+ Fix so that DEFAULT and limit checking works with max_relay_log_size
+ (Yes, this is a hack, but it's required as the definition of
+ max_relay_log_size allows it to be set to 0).
+ */
+ max_relay_log_size_var= intern_find_sys_var("max_relay_log_size", 0);
+ max_binlog_size_var= intern_find_sys_var("max_binlog_size", 0);
+ if (max_binlog_size_var && max_relay_log_size_var)
+ {
+ max_relay_log_size_var->option.min_value=
+ max_binlog_size_var->option.min_value;
+ max_relay_log_size_var->option.def_value=
+ max_binlog_size_var->option.def_value;
+ }
+ }
+
+ /* Ensure that some variables are not set higher than needed */
+ if (back_log > max_connections)
+ back_log= max_connections;
+ if (thread_cache_size > max_connections)
+ thread_cache_size= max_connections;
+
return 0;
}
@@ -9197,8 +10192,6 @@ static int test_if_case_insensitive(const char *dir_name)
DBUG_PRINT("exit", ("result: %d", result));
DBUG_RETURN(result);
}
-
-
#ifndef EMBEDDED_LIBRARY
/**
@@ -9256,7 +10249,7 @@ void refresh_status(THD *thd)
add_to_status(&global_status_var, &thd->status_var);
/* Reset thread's status variables */
- bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
+ thd->set_status_var_init();
bzero((uchar*) &thd->org_status_var, sizeof(thd->org_status_var));
thd->start_bytes_received= 0;
@@ -9273,32 +10266,394 @@ void refresh_status(THD *thd)
/*
Set max_used_connections to the number of currently open
- connections. Lock LOCK_thread_count out of LOCK_status to avoid
- deadlocks. Status reset becomes not atomic, but status data is
- not exact anyway.
+ connections. This is not perfect, but status data is not exact anyway.
*/
- mysql_mutex_lock(&LOCK_thread_count);
- max_used_connections= thread_count-delayed_insert_threads;
- mysql_mutex_unlock(&LOCK_thread_count);
+ max_used_connections= connection_count + extra_connection_count;
}
+#ifdef HAVE_PSI_INTERFACE
+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},
+ { &key_file_binlog_state, "binlog_state", 0}
+};
+#endif /* HAVE_PSI_INTERFACE */
+
+PSI_stage_info stage_after_create= { 0, "After create", 0};
+PSI_stage_info stage_after_opening_tables= { 0, "After opening tables", 0};
+PSI_stage_info stage_after_table_lock= { 0, "After table lock", 0};
+PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 0};
+PSI_stage_info stage_alter_inplace_prepare= { 0, "preparing for alter table", 0};
+PSI_stage_info stage_alter_inplace= { 0, "altering table", 0};
+PSI_stage_info stage_alter_inplace_commit= { 0, "committing alter table to storage engine", 0};
+PSI_stage_info stage_changing_master= { 0, "Changing master", 0};
+PSI_stage_info stage_checking_master_version= { 0, "Checking master version", 0};
+PSI_stage_info stage_checking_permissions= { 0, "checking permissions", 0};
+PSI_stage_info stage_checking_privileges_on_cached_query= { 0, "checking privileges on cached query", 0};
+PSI_stage_info stage_checking_query_cache_for_query= { 0, "checking query cache for query", 0};
+PSI_stage_info stage_cleaning_up= { 0, "cleaning up", 0};
+PSI_stage_info stage_closing_tables= { 0, "closing tables", 0};
+PSI_stage_info stage_connecting_to_master= { 0, "Connecting to master", 0};
+PSI_stage_info stage_converting_heap_to_myisam= { 0, "converting HEAP to " TMP_ENGINE_NAME, 0};
+PSI_stage_info stage_copying_to_group_table= { 0, "Copying to group table", 0};
+PSI_stage_info stage_copying_to_tmp_table= { 0, "Copying to tmp table", 0};
+PSI_stage_info stage_copy_to_tmp_table= { 0, "copy to tmp table", 0};
+PSI_stage_info stage_creating_delayed_handler= { 0, "Creating delayed handler", 0};
+PSI_stage_info stage_creating_sort_index= { 0, "Creating sort index", 0};
+PSI_stage_info stage_creating_table= { 0, "creating table", 0};
+PSI_stage_info stage_creating_tmp_table= { 0, "Creating tmp table", 0};
+PSI_stage_info stage_deleting_from_main_table= { 0, "deleting from main table", 0};
+PSI_stage_info stage_deleting_from_reference_tables= { 0, "deleting from reference tables", 0};
+PSI_stage_info stage_discard_or_import_tablespace= { 0, "discard_or_import_tablespace", 0};
+PSI_stage_info stage_enabling_keys= { 0, "enabling keys", 0};
+PSI_stage_info stage_end= { 0, "end", 0};
+PSI_stage_info stage_executing= { 0, "executing", 0};
+PSI_stage_info stage_execution_of_init_command= { 0, "Execution of init_command", 0};
+PSI_stage_info stage_explaining= { 0, "explaining", 0};
+PSI_stage_info stage_finding_key_cache= { 0, "Finding key cache", 0};
+PSI_stage_info stage_finished_reading_one_binlog_switching_to_next_binlog= { 0, "Finished reading one binlog; switching to next binlog", 0};
+PSI_stage_info stage_flushing_relay_log_and_master_info_repository= { 0, "Flushing relay log and master info repository.", 0};
+PSI_stage_info stage_flushing_relay_log_info_file= { 0, "Flushing relay-log info file.", 0};
+PSI_stage_info stage_freeing_items= { 0, "freeing items", 0};
+PSI_stage_info stage_fulltext_initialization= { 0, "FULLTEXT initialization", 0};
+PSI_stage_info stage_got_handler_lock= { 0, "got handler lock", 0};
+PSI_stage_info stage_got_old_table= { 0, "got old table", 0};
+PSI_stage_info stage_init= { 0, "init", 0};
+PSI_stage_info stage_insert= { 0, "insert", 0};
+PSI_stage_info stage_invalidating_query_cache_entries_table= { 0, "invalidating query cache entries (table)", 0};
+PSI_stage_info stage_invalidating_query_cache_entries_table_list= { 0, "invalidating query cache entries (table list)", 0};
+PSI_stage_info stage_killing_slave= { 0, "Killing slave", 0};
+PSI_stage_info stage_logging_slow_query= { 0, "logging slow query", 0};
+PSI_stage_info stage_making_temp_file_append_before_load_data= { 0, "Making temporary file (append) before replaying LOAD DATA INFILE.", 0};
+PSI_stage_info stage_making_temp_file_create_before_load_data= { 0, "Making temporary file (create) before replaying LOAD DATA INFILE.", 0};
+PSI_stage_info stage_manage_keys= { 0, "manage keys", 0};
+PSI_stage_info stage_master_has_sent_all_binlog_to_slave= { 0, "Master has sent all binlog to slave; waiting for binlog to be updated", 0};
+PSI_stage_info stage_opening_tables= { 0, "Opening tables", 0};
+PSI_stage_info stage_optimizing= { 0, "optimizing", 0};
+PSI_stage_info stage_preparing= { 0, "preparing", 0};
+PSI_stage_info stage_purging_old_relay_logs= { 0, "Purging old relay logs", 0};
+PSI_stage_info stage_query_end= { 0, "query end", 0};
+PSI_stage_info stage_queueing_master_event_to_the_relay_log= { 0, "Queueing master event to the relay log", 0};
+PSI_stage_info stage_reading_event_from_the_relay_log= { 0, "Reading event from the relay log", 0};
+PSI_stage_info stage_recreating_table= { 0, "recreating table", 0};
+PSI_stage_info stage_registering_slave_on_master= { 0, "Registering slave on master", 0};
+PSI_stage_info stage_removing_duplicates= { 0, "Removing duplicates", 0};
+PSI_stage_info stage_removing_tmp_table= { 0, "removing tmp table", 0};
+PSI_stage_info stage_rename= { 0, "rename", 0};
+PSI_stage_info stage_rename_result_table= { 0, "rename result table", 0};
+PSI_stage_info stage_requesting_binlog_dump= { 0, "Requesting binlog dump", 0};
+PSI_stage_info stage_reschedule= { 0, "reschedule", 0};
+PSI_stage_info stage_searching_rows_for_update= { 0, "Searching rows for update", 0};
+PSI_stage_info stage_sending_binlog_event_to_slave= { 0, "Sending binlog event to slave", 0};
+PSI_stage_info stage_sending_cached_result_to_client= { 0, "sending cached result to client", 0};
+PSI_stage_info stage_sending_data= { 0, "Sending data", 0};
+PSI_stage_info stage_setup= { 0, "setup", 0};
+PSI_stage_info stage_show_explain= { 0, "show explain", 0};
+PSI_stage_info stage_slave_has_read_all_relay_log= { 0, "Slave has read all relay log; waiting for the slave I/O thread to update it", 0};
+PSI_stage_info stage_sorting= { 0, "Sorting", 0};
+PSI_stage_info stage_sorting_for_group= { 0, "Sorting for group", 0};
+PSI_stage_info stage_sorting_for_order= { 0, "Sorting for order", 0};
+PSI_stage_info stage_sorting_result= { 0, "Sorting result", 0};
+PSI_stage_info stage_statistics= { 0, "statistics", 0};
+PSI_stage_info stage_sql_thd_waiting_until_delay= { 0, "Waiting until MASTER_DELAY seconds after master executed event", 0 };
+PSI_stage_info stage_storing_result_in_query_cache= { 0, "storing result in query cache", 0};
+PSI_stage_info stage_storing_row_into_queue= { 0, "storing row into queue", 0};
+PSI_stage_info stage_system_lock= { 0, "System lock", 0};
+PSI_stage_info stage_table_lock= { 0, "Table lock", 0};
+PSI_stage_info stage_filling_schema_table= { 0, "Filling schema table", 0};
+PSI_stage_info stage_update= { 0, "update", 0};
+PSI_stage_info stage_updating= { 0, "updating", 0};
+PSI_stage_info stage_updating_main_table= { 0, "updating main table", 0};
+PSI_stage_info stage_updating_reference_tables= { 0, "updating reference tables", 0};
+PSI_stage_info stage_upgrading_lock= { 0, "upgrading lock", 0};
+PSI_stage_info stage_user_lock= { 0, "User lock", 0};
+PSI_stage_info stage_user_sleep= { 0, "User sleep", 0};
+PSI_stage_info stage_verifying_table= { 0, "verifying table", 0};
+PSI_stage_info stage_waiting_for_delay_list= { 0, "waiting for delay_list", 0};
+PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log= { 0, "waiting for GTID to be written to binary log", 0};
+PSI_stage_info stage_waiting_for_handler_insert= { 0, "waiting for handler insert", 0};
+PSI_stage_info stage_waiting_for_handler_lock= { 0, "waiting for handler lock", 0};
+PSI_stage_info stage_waiting_for_handler_open= { 0, "waiting for handler open", 0};
+PSI_stage_info stage_waiting_for_insert= { 0, "Waiting for INSERT", 0};
+PSI_stage_info stage_waiting_for_master_to_send_event= { 0, "Waiting for master to send event", 0};
+PSI_stage_info stage_waiting_for_master_update= { 0, "Waiting for master update", 0};
+PSI_stage_info stage_waiting_for_relay_log_space= { 0, "Waiting for the slave SQL thread to free enough relay log space", 0};
+PSI_stage_info stage_waiting_for_slave_mutex_on_exit= { 0, "Waiting for slave mutex on exit", 0};
+PSI_stage_info stage_waiting_for_slave_thread_to_start= { 0, "Waiting for slave thread to start", 0};
+PSI_stage_info stage_waiting_for_table_flush= { 0, "Waiting for table flush", 0};
+PSI_stage_info stage_waiting_for_query_cache_lock= { 0, "Waiting for query cache lock", 0};
+PSI_stage_info stage_waiting_for_the_next_event_in_relay_log= { 0, "Waiting for the next event in relay log", 0};
+PSI_stage_info stage_waiting_for_the_slave_thread_to_advance_position= { 0, "Waiting for the slave SQL thread to advance position", 0};
+PSI_stage_info stage_waiting_to_finalize_termination= { 0, "Waiting to finalize termination", 0};
+PSI_stage_info stage_waiting_to_get_readlock= { 0, "Waiting to get readlock", 0};
+PSI_stage_info stage_slave_waiting_workers_to_exit= { 0, "Waiting for workers to exit", 0};
+PSI_stage_info stage_slave_waiting_worker_to_release_partition= { 0, "Waiting for Slave Worker to release partition", 0};
+PSI_stage_info stage_slave_waiting_worker_to_free_events= { 0, "Waiting for Slave Workers to free pending events", 0};
+PSI_stage_info stage_slave_waiting_worker_queue= { 0, "Waiting for Slave Worker queue", 0};
+PSI_stage_info stage_slave_waiting_event_from_coordinator= { 0, "Waiting for an event from Coordinator", 0};
+PSI_stage_info stage_binlog_waiting_background_tasks= { 0, "Waiting for background binlog tasks", 0};
+PSI_stage_info stage_binlog_processing_checkpoint_notify= { 0, "Processing binlog checkpoint notification", 0};
+PSI_stage_info stage_binlog_stopping_background_thread= { 0, "Stopping binlog background thread", 0};
+PSI_stage_info stage_waiting_for_work_from_sql_thread= { 0, "Waiting for work from SQL thread", 0};
+PSI_stage_info stage_waiting_for_prior_transaction_to_commit= { 0, "Waiting for prior transaction to commit", 0};
+PSI_stage_info stage_waiting_for_prior_transaction_to_start_commit= { 0, "Waiting for prior transaction to start commit before starting next transaction", 0};
+PSI_stage_info stage_waiting_for_room_in_worker_thread= { 0, "Waiting for room in worker thread event queue", 0};
+PSI_stage_info stage_waiting_for_workers_idle= { 0, "Waiting for worker threads to be idle", 0};
+PSI_stage_info stage_waiting_for_ftwrl= { 0, "Waiting due to global read lock", 0};
+PSI_stage_info stage_waiting_for_ftwrl_threads_to_pause= { 0, "Waiting for worker threads to pause for global read lock", 0};
+PSI_stage_info stage_waiting_for_rpl_thread_pool= { 0, "Waiting while replication worker thread pool is busy", 0};
+PSI_stage_info stage_master_gtid_wait_primary= { 0, "Waiting in MASTER_GTID_WAIT() (primary waiter)", 0};
+PSI_stage_info stage_master_gtid_wait= { 0, "Waiting in MASTER_GTID_WAIT()", 0};
+PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master connection to process GTID received on multiple master connections", 0};
+
+#ifdef HAVE_PSI_INTERFACE
+
+PSI_stage_info *all_server_stages[]=
+{
+ & stage_after_create,
+ & stage_after_opening_tables,
+ & stage_after_table_lock,
+ & stage_allocating_local_table,
+ & stage_alter_inplace,
+ & stage_alter_inplace_commit,
+ & stage_alter_inplace_prepare,
+ & stage_binlog_processing_checkpoint_notify,
+ & stage_binlog_stopping_background_thread,
+ & stage_binlog_waiting_background_tasks,
+ & stage_changing_master,
+ & stage_checking_master_version,
+ & stage_checking_permissions,
+ & stage_checking_privileges_on_cached_query,
+ & stage_checking_query_cache_for_query,
+ & stage_cleaning_up,
+ & stage_closing_tables,
+ & stage_connecting_to_master,
+ & stage_converting_heap_to_myisam,
+ & stage_copy_to_tmp_table,
+ & stage_copying_to_group_table,
+ & stage_copying_to_tmp_table,
+ & stage_creating_delayed_handler,
+ & stage_creating_sort_index,
+ & stage_creating_table,
+ & stage_creating_tmp_table,
+ & stage_deleting_from_main_table,
+ & stage_deleting_from_reference_tables,
+ & stage_discard_or_import_tablespace,
+ & stage_enabling_keys,
+ & stage_end,
+ & stage_executing,
+ & stage_execution_of_init_command,
+ & stage_explaining,
+ & stage_finding_key_cache,
+ & stage_finished_reading_one_binlog_switching_to_next_binlog,
+ & stage_flushing_relay_log_and_master_info_repository,
+ & stage_flushing_relay_log_info_file,
+ & stage_freeing_items,
+ & stage_fulltext_initialization,
+ & stage_got_handler_lock,
+ & stage_got_old_table,
+ & stage_init,
+ & stage_insert,
+ & stage_invalidating_query_cache_entries_table,
+ & stage_invalidating_query_cache_entries_table_list,
+ & stage_killing_slave,
+ & stage_logging_slow_query,
+ & stage_making_temp_file_append_before_load_data,
+ & stage_making_temp_file_create_before_load_data,
+ & stage_manage_keys,
+ & stage_master_has_sent_all_binlog_to_slave,
+ & stage_opening_tables,
+ & stage_optimizing,
+ & stage_preparing,
+ & stage_purging_old_relay_logs,
+ & stage_query_end,
+ & stage_queueing_master_event_to_the_relay_log,
+ & stage_reading_event_from_the_relay_log,
+ & stage_recreating_table,
+ & stage_registering_slave_on_master,
+ & stage_removing_duplicates,
+ & stage_removing_tmp_table,
+ & stage_rename,
+ & stage_rename_result_table,
+ & stage_requesting_binlog_dump,
+ & stage_reschedule,
+ & stage_searching_rows_for_update,
+ & stage_sending_binlog_event_to_slave,
+ & stage_sending_cached_result_to_client,
+ & stage_sending_data,
+ & stage_setup,
+ & stage_show_explain,
+ & stage_slave_has_read_all_relay_log,
+ & stage_slave_waiting_event_from_coordinator,
+ & stage_slave_waiting_worker_queue,
+ & stage_slave_waiting_worker_to_free_events,
+ & stage_slave_waiting_worker_to_release_partition,
+ & stage_slave_waiting_workers_to_exit,
+ & stage_sorting,
+ & stage_sorting_for_group,
+ & stage_sorting_for_order,
+ & stage_sorting_result,
+ & stage_sql_thd_waiting_until_delay,
+ & stage_statistics,
+ & stage_storing_result_in_query_cache,
+ & stage_storing_row_into_queue,
+ & stage_system_lock,
+ & stage_table_lock,
+ & stage_filling_schema_table,
+ & stage_update,
+ & stage_updating,
+ & stage_updating_main_table,
+ & stage_updating_reference_tables,
+ & stage_upgrading_lock,
+ & stage_user_lock,
+ & stage_user_sleep,
+ & stage_verifying_table,
+ & stage_waiting_for_delay_list,
+ & stage_waiting_for_gtid_to_be_written_to_binary_log,
+ & stage_waiting_for_handler_insert,
+ & stage_waiting_for_handler_lock,
+ & stage_waiting_for_handler_open,
+ & stage_waiting_for_insert,
+ & stage_waiting_for_master_to_send_event,
+ & stage_waiting_for_master_update,
+ & stage_waiting_for_prior_transaction_to_commit,
+ & stage_waiting_for_prior_transaction_to_start_commit,
+ & stage_waiting_for_query_cache_lock,
+ & stage_waiting_for_relay_log_space,
+ & stage_waiting_for_room_in_worker_thread,
+ & stage_waiting_for_slave_mutex_on_exit,
+ & stage_waiting_for_slave_thread_to_start,
+ & stage_waiting_for_table_flush,
+ & stage_waiting_for_the_next_event_in_relay_log,
+ & stage_waiting_for_the_slave_thread_to_advance_position,
+ & stage_waiting_for_work_from_sql_thread,
+ & stage_waiting_to_finalize_termination,
+ & stage_waiting_to_get_readlock,
+ & stage_master_gtid_wait_primary,
+ & stage_master_gtid_wait,
+ & stage_gtid_wait_other_connection
+};
-/*****************************************************************************
- Instantiate variables for missing storage engines
- This section should go away soon
-*****************************************************************************/
+PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection;
-/*****************************************************************************
- Instantiate templates
-*****************************************************************************/
+static PSI_socket_info all_server_sockets[]=
+{
+ { &key_socket_tcpip, "server_tcpip_socket", PSI_FLAG_GLOBAL},
+ { &key_socket_unix, "server_unix_socket", PSI_FLAG_GLOBAL},
+ { &key_socket_client_connection, "client_connection", 0}
+};
-#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-/* Used templates */
-template class I_List<THD>;
-template class I_List_iterator<THD>;
-template class I_List<i_string>;
-template class I_List<i_string_pair>;
-template class I_List<Statement>;
-template class I_List_iterator<Statement>;
+/**
+ Initialise all the performance schema instrumentation points
+ used by the server.
+*/
+void init_server_psi_keys(void)
+{
+ const char* category= "sql";
+ int count;
+
+ count= array_elements(all_server_mutexes);
+ mysql_mutex_register(category, all_server_mutexes, count);
+
+ count= array_elements(all_server_rwlocks);
+ mysql_rwlock_register(category, all_server_rwlocks, count);
+
+ count= array_elements(all_server_conds);
+ mysql_cond_register(category, all_server_conds, count);
+
+ count= array_elements(all_server_threads);
+ mysql_thread_register(category, all_server_threads, count);
+
+ count= array_elements(all_server_files);
+ mysql_file_register(category, all_server_files, count);
+
+ count= array_elements(all_server_stages);
+ mysql_stage_register(category, all_server_stages, count);
+
+ count= array_elements(all_server_sockets);
+ mysql_socket_register(category, all_server_sockets, count);
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ init_sql_statement_info();
+ count= array_elements(sql_statement_info);
+ mysql_statement_register(category, sql_statement_info, count);
+
+ category= "com";
+ init_com_statement_info();
+
+ /*
+ Register [0 .. COM_QUERY - 1] as "statement/com/..."
+ */
+ count= (int) COM_QUERY;
+ mysql_statement_register(category, com_statement_info, count);
+
+ /*
+ Register [COM_QUERY + 1 .. COM_END] as "statement/com/..."
+ */
+ count= (int) COM_END - (int) COM_QUERY;
+ mysql_statement_register(category, & com_statement_info[(int) COM_QUERY + 1], count);
+
+ category= "abstract";
+ /*
+ Register [COM_QUERY] as "statement/abstract/com_query"
+ */
+ mysql_statement_register(category, & com_statement_info[(int) COM_QUERY], 1);
+
+ /*
+ When a new packet is received,
+ it is instrumented as "statement/abstract/new_packet".
+ Based on the packet type found, it later mutates to the
+ proper narrow type, for example
+ "statement/abstract/query" or "statement/com/ping".
+ In cases of "statement/abstract/query", SQL queries are given to
+ the parser, which mutates the statement type to an even more
+ narrow classification, for example "statement/sql/select".
+ */
+ stmt_info_new_packet.m_key= 0;
+ stmt_info_new_packet.m_name= "new_packet";
+ stmt_info_new_packet.m_flags= PSI_FLAG_MUTABLE;
+ mysql_statement_register(category, &stmt_info_new_packet, 1);
+
+ /*
+ Statements processed from the relay log are initially instrumented as
+ "statement/abstract/relay_log". The parser will mutate the statement type to
+ a more specific classification, for example "statement/sql/insert".
+ */
+ stmt_info_rpl.m_key= 0;
+ stmt_info_rpl.m_name= "relay_log";
+ stmt_info_rpl.m_flags= PSI_FLAG_MUTABLE;
+ mysql_statement_register(category, &stmt_info_rpl, 1);
#endif
+}
+#endif /* HAVE_PSI_INTERFACE */