diff options
author | Michael Widenius <monty@askmonty.org> | 2012-08-14 17:23:34 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-08-14 17:23:34 +0300 |
commit | 60589aeee03949033c66da5c1eae70d4342179fc (patch) | |
tree | 1cd399dbed17c5c7b4ed16eb7b872dc979af1c93 /sql | |
parent | b39e6e3d093b45f792959ef06fea1c175263ae1a (diff) | |
download | mariadb-git-60589aeee03949033c66da5c1eae70d4342179fc.tar.gz |
Next part of merge. See TODO for details
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/lex.h | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 952 | ||||
-rw-r--r-- | sql/mysqld.h | 131 | ||||
-rw-r--r-- | sql/rpl_mi.cc | 1 | ||||
-rw-r--r-- | sql/rpl_mi.h | 1 | ||||
-rw-r--r-- | sql/set_var.h | 3 | ||||
-rw-r--r-- | sql/sql_class.cc | 205 | ||||
-rw-r--r-- | sql/sql_class.h | 81 | ||||
-rw-r--r-- | sql/sql_cmd.h | 161 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 7 | ||||
-rw-r--r-- | sql/sql_lex.h | 86 | ||||
-rw-r--r-- | sql/sql_parse.cc | 67 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 | ||||
-rw-r--r-- | sql/sys_vars.cc | 218 | ||||
-rw-r--r-- | sql/sys_vars.h | 2 | ||||
-rw-r--r-- | sql/threadpool_unix.cc | 4 |
19 files changed, 1657 insertions, 290 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 805f7b34e04..6c53930f23d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -76,7 +76,7 @@ SET (SQL_SOURCE sql_profile.cc event_parse_data.cc sql_alter.cc sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc transaction.cc sys_vars.cc sql_truncate.cc datadict.cc - sql_reload.cc + sql_reload.cc sql_cmd.h # added in MariaDB: sql_lifo_buffer.h sql_join_cache.h sql_join_cache.cc diff --git a/sql/lex.h b/sql/lex.h index 9f4369630a0..9bd1a9b93aa 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -340,6 +340,8 @@ static SYMBOL symbols[] = { { "MASTER_SSL_CAPATH",SYM(MASTER_SSL_CAPATH_SYM)}, { "MASTER_SSL_CERT", SYM(MASTER_SSL_CERT_SYM)}, { "MASTER_SSL_CIPHER",SYM(MASTER_SSL_CIPHER_SYM)}, + { "MASTER_SSL_CRL", SYM(MASTER_SSL_CRL_SYM)}, + { "MASTER_SSL_CRLPATH",SYM(MASTER_SSL_CRLPATH_SYM)}, { "MASTER_SSL_KEY", SYM(MASTER_SSL_KEY_SYM)}, { "MASTER_SSL_VERIFY_SERVER_CERT", SYM(MASTER_SSL_VERIFY_SERVER_CERT_SYM)}, { "MASTER_USER", SYM(MASTER_USER_SYM)}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ef0de79820d..f88b4047c17 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -78,6 +78,10 @@ #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" @@ -734,8 +738,8 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids, 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_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_relay_log_info_sleep_lock, + key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; @@ -917,6 +921,10 @@ static PSI_thread_info all_server_threads[]= { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL} }; +#ifdef HAVE_MMAP +PSI_file_key key_file_map; +#endif /* HAVE_MMAP */ + PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file, key_file_fileparser, key_file_frm, key_file_global_ddl_log, key_file_load, @@ -927,67 +935,89 @@ PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, PSI_file_key key_file_query_log, key_file_slow_log; PSI_file_key key_file_relaylog, key_file_relaylog_index; -static PSI_file_info all_server_files[]= -{ - { &key_file_binlog, "binlog", 0}, - { &key_file_binlog_index, "binlog_index", 0}, - { &key_file_relaylog, "relaylog", 0}, - { &key_file_relaylog_index, "relaylog_index", 0}, - { &key_file_casetest, "casetest", 0}, - { &key_file_dbopt, "dbopt", 0}, - { &key_file_des_key_file, "des_key_file", 0}, - { &key_file_ERRMSG, "ERRMSG", 0}, - { &key_select_to_file, "select_to_file", 0}, - { &key_file_fileparser, "file_parser", 0}, - { &key_file_frm, "FRM", 0}, - { &key_file_global_ddl_log, "global_ddl_log", 0}, - { &key_file_load, "load", 0}, - { &key_file_loadfile, "LOAD_FILE", 0}, - { &key_file_log_event_data, "log_event_data", 0}, - { &key_file_log_event_info, "log_event_info", 0}, - { &key_file_master_info, "master_info", 0}, - { &key_file_misc, "misc", 0}, - { &key_file_partition, "partition", 0}, - { &key_file_pid, "pid", 0}, - { &key_file_query_log, "query_log", 0}, - { &key_file_relay_log_info, "relay_log_info", 0}, - { &key_file_send_file, "send_file", 0}, - { &key_file_slow_log, "slow_log", 0}, - { &key_file_tclog, "tclog", 0}, - { &key_file_trg, "trigger_name", 0}, - { &key_file_trn, "trigger", 0}, - { &key_file_init, "init", 0} -}; +#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; + if (thd->m_server_idle) + { + /* + 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); + if (thd->m_server_idle) + { + /* + 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); - 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 */ +void init_net_server_extension(THD *thd) +{ +#ifdef HAVE_PSI_INTERFACE + /* Start with a clean state for connection events. */ + thd->m_idle_psi= NULL; + thd->m_statement_psi= NULL; + thd->m_server_idle= false; + /* 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; +#else + thd->net.extension= NULL; +#endif +} +#endif /* EMBEDDED_LIBRARY */ /* Since buffered_option_error_reporter is only used currently @@ -1152,7 +1182,7 @@ C_MODE_END #endif /* !EMBEDDED_LIBRARY */ #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ -static my_socket unix_sock, base_ip_sock, extra_ip_sock; +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 @@ -1216,7 +1246,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, @@ -1343,17 +1375,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 @@ -1381,12 +1413,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. @@ -1491,22 +1523,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; } @@ -1522,9 +1546,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 @@ -1745,7 +1769,9 @@ static void mysqld_exit(int exit_code) clean_up_mutexes(); clean_up_error_log_mutex(); my_end((opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0)); - shutdown_performance_schema(); // we do it as late as possible +#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE + shutdown_performance_schema(); +#endif exit(exit_code); /* purecov: inspected */ } @@ -2110,14 +2136,14 @@ 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; + MYSQL_SOCKET ip_sock= MYSQL_INVALID_SOCKET; DBUG_ENTER("activate_tcp_port"); DBUG_PRINT("general",("IP Socket is %d",port)); @@ -2137,25 +2163,29 @@ static my_socket activate_tcp_port(uint port) for (a= ai; a != NULL; a= a->ai_next) { - ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol); - if (ip_sock != INVALID_SOCKET) + ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family, + a->ai_socktype, a->ai_protocol); + if (mysql_socket_getfd(ip_sock) != INVALID_SOCKET) break; } - 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 @@ -2171,8 +2201,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 /* @@ -2187,7 +2217,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; @@ -2206,7 +2236,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", @@ -2307,7 +2337,8 @@ 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 */ @@ -2317,11 +2348,12 @@ static void network_init(void) 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); @@ -2331,7 +2363,7 @@ 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); } @@ -2485,13 +2517,12 @@ 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_CALL(delete_current_thread)(); #endif while (!abort_loop && ! wake_thread && ! kill_cached_threads) @@ -2507,18 +2538,14 @@ static bool cache_thread() 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_CALL(new_thread)(key_thread_one_connection, + thd, thd->thread_id); + PSI_CALL(set_thread)(psi); #endif /* @@ -3033,10 +3060,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_CALL(delete_current_thread)(); #endif #ifdef USE_ONE_SIGNAL_HAND pthread_t tmp; @@ -3393,6 +3419,68 @@ 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/com/query" can mutate into "statement/sql/..." */ + com_statement_info[(uint) COM_QUERY].m_flags= PSI_FLAG_MUTABLE; +} +#endif + + static int init_common_variables() { umask(((~my_umask) & 0666)); @@ -3446,8 +3534,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, @@ -3732,6 +3821,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; } @@ -4013,7 +4106,8 @@ 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)); if (!ssl_acceptor_fd) { @@ -4656,9 +4750,16 @@ int mysqld_main(int argc, char **argv) */ buffered_logs.init(); my_getopt_error_reporter= buffered_option_error_reporter; + my_charset_error_reporter= buffered_option_error_reporter; + + /* + Initialize the array of performance schema instrument configurations. + */ + init_pfs_instrument_array(); ho_error= handle_options(&remaining_argc, &remaining_argv, - (my_option*)(all_early_options.buffer), NULL); + (my_option*)(all_early_options.buffer), + mysqld_get_one_option); delete_dynamic(&all_early_options); if (ho_error == 0) { @@ -4694,27 +4795,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_CALL(new_thread)(key_thread_main, NULL, 0); + PSI_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 */ @@ -4858,7 +4961,7 @@ int mysqld_main(int argc, char **argv) if (!opt_bootstrap) mysql_file_delete(key_file_pid, pidfile_name, MYF(MY_WME)); // Not needed anymore - if (unix_sock != INVALID_SOCKET) + if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET) unlink(mysqld_unix_port); exit(1); } @@ -4939,8 +5042,8 @@ int mysqld_main(int argc, char **argv) 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); #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) @@ -4978,13 +5081,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_CALL(delete_current_thread)(); #endif /* Wait until cleanup is done */ @@ -5438,8 +5540,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 */ @@ -5458,7 +5561,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; @@ -5467,36 +5571,40 @@ 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; \ + pfs_fds[socket_count]= (X); \ + fds[socket_count].fd= mysql_socket_getfd(X); \ fds[socket_count].events= POLLIN; \ socket_count++ #else 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) + max(max(mysql_socket_getfd(base_ip_sock), mysql_socket_getfd(unix_sock)), + mysqld_socket_getfd(extra_ip_sock)) + 1; +#define setup_fds(X) FD_SET(mysql_socket_getfd(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.")); @@ -5534,8 +5642,8 @@ 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; } } @@ -5562,18 +5670,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; @@ -5581,15 +5690,18 @@ 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) { if ((error_count++ & 255) == 0) // This can happen often sql_perror("Error in accept"); @@ -5605,7 +5717,8 @@ void handle_connections_sockets() { 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)) { @@ -5627,7 +5740,7 @@ 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); continue; } } @@ -5638,12 +5751,13 @@ void handle_connections_sockets() size_socket dummyLen; struct sockaddr_storage dummy; dummyLen = sizeof(dummy); - if ( getsockname(new_sock,(struct sockaddr *)&dummy, - (SOCKET_SIZE_TYPE *)&dummyLen) < 0 ) + if (getsockname(mysql_socket_getfd(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); + (void) mysql_socket_close(new_sock); continue; } } @@ -5655,14 +5769,17 @@ void handle_connections_sockets() if (!(thd= new THD)) { (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); - (void) closesocket(new_sock); + (void) mysql_socket_close(new_sock); 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)) + 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)) { /* Only delete the temporary vio if we didn't already attach it to the @@ -5674,15 +5791,15 @@ 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; continue; } - if (sock == unix_sock) + 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; @@ -6231,9 +6348,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 " @@ -6410,7 +6524,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 @@ -6869,6 +6983,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) @@ -7049,6 +7267,10 @@ SHOW_VAR status_vars[]= { {"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_server_not_before", (char*) &show_ssl_get_server_not_before, + SHOW_FUNC}, + {"Ssl_server_not_after", (char*) &show_ssl_get_server_not_after, + SHOW_FUNC}, #endif #endif /* HAVE_OPENSSL */ {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH}, @@ -7267,7 +7489,7 @@ 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; @@ -7714,6 +7936,74 @@ mysqld_get_one_option(int optid, case OPT_MAX_LONG_DATA_SIZE: max_long_data_size_used= true; break; + case OPT_PFS_INSTRUMENT: +#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE + /* 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 + break; } return 0; } @@ -8299,23 +8589,305 @@ void refresh_status(THD *thd) mysql_mutex_unlock(&LOCK_thread_count); } +PSI_stage_info stage_after_create= { 0, "After create", 0}; +PSI_stage_info stage_allocating_local_table= { 0, "allocating local table", 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 MyISAM", 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_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_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_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_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_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_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}; -/***************************************************************************** - Instantiate variables for missing storage engines - This section should go away soon -*****************************************************************************/ +#ifdef HAVE_PSI_INTERFACE -/***************************************************************************** - Instantiate templates -*****************************************************************************/ +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} +}; + +PSI_stage_info *all_server_stages[]= +{ + & stage_after_create, + & stage_allocating_local_table, + & 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_copying_to_group_table, + & stage_copying_to_tmp_table, + & stage_copy_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_end, + & stage_executing, + & stage_execution_of_init_command, + & stage_explaining, + & 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_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_slave_has_read_all_relay_log, + & 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_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_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_slave_mutex_on_exit, + & stage_waiting_for_slave_thread_to_start, + & stage_waiting_for_table_flush, + & stage_waiting_for_query_cache_lock, + & stage_waiting_for_the_next_event_in_relay_log, + & stage_waiting_for_the_slave_thread_to_advance_position, + & stage_waiting_to_finalize_termination, + & stage_waiting_to_get_readlock +}; + +PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection; + +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} +}; + +/** + Initialise all the performance schema instrumentation points + used by the server. +*/ +void init_server_psi_keys(void) +{ + const char* category= "sql"; + int count; -#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>; + 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(); + count= array_elements(com_statement_info); + mysql_statement_register(category, com_statement_info, count); + + /* + When a new packet is received, + it is instrumented as "statement/com/". + Based on the packet type found, it later mutates to the + proper narrow type, for example + "statement/com/query" or "statement/com/ping". + In cases of "statement/com/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= ""; + stmt_info_new_packet.m_flags= PSI_FLAG_MUTABLE; + mysql_statement_register(category, & stmt_info_new_packet, 1); #endif +} +#endif /* HAVE_PSI_INTERFACE */ diff --git a/sql/mysqld.h b/sql/mysqld.h index 6b073eac59b..e2beb59908b 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -23,6 +23,7 @@ #include "my_atomic.h" /* my_atomic_rwlock_t */ #include "mysql/psi/mysql_file.h" /* MYSQL_FILE */ #include "sql_list.h" /* I_List */ +#include "sql_cmd.h" class THD; struct handlerton; @@ -285,10 +286,133 @@ extern PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest, key_file_trg, key_file_trn, key_file_init; extern PSI_file_key key_file_query_log, key_file_slow_log; extern PSI_file_key key_file_relaylog, key_file_relaylog_index; +extern PSI_socket_key key_socket_tcpip, key_socket_unix, + key_socket_client_connection; void init_server_psi_keys(); #endif /* HAVE_PSI_INTERFACE */ +/* + MAINTAINER: Please keep this list in order, to limit merge collisions. + Hint: grep PSI_stage_info | sort -u +*/ +extern PSI_stage_info stage_after_create; +extern PSI_stage_info stage_allocating_local_table; +extern PSI_stage_info stage_changing_master; +extern PSI_stage_info stage_checking_master_version; +extern PSI_stage_info stage_checking_permissions; +extern PSI_stage_info stage_checking_privileges_on_cached_query; +extern PSI_stage_info stage_checking_query_cache_for_query; +extern PSI_stage_info stage_cleaning_up; +extern PSI_stage_info stage_closing_tables; +extern PSI_stage_info stage_connecting_to_master; +extern PSI_stage_info stage_converting_heap_to_myisam; +extern PSI_stage_info stage_copying_to_group_table; +extern PSI_stage_info stage_copying_to_tmp_table; +extern PSI_stage_info stage_copy_to_tmp_table; +extern PSI_stage_info stage_creating_delayed_handler; +extern PSI_stage_info stage_creating_sort_index; +extern PSI_stage_info stage_creating_table; +extern PSI_stage_info stage_creating_tmp_table; +extern PSI_stage_info stage_deleting_from_main_table; +extern PSI_stage_info stage_deleting_from_reference_tables; +extern PSI_stage_info stage_discard_or_import_tablespace; +extern PSI_stage_info stage_end; +extern PSI_stage_info stage_executing; +extern PSI_stage_info stage_execution_of_init_command; +extern PSI_stage_info stage_explaining; +extern PSI_stage_info stage_finished_reading_one_binlog_switching_to_next_binlog; +extern PSI_stage_info stage_flushing_relay_log_and_master_info_repository; +extern PSI_stage_info stage_flushing_relay_log_info_file; +extern PSI_stage_info stage_freeing_items; +extern PSI_stage_info stage_fulltext_initialization; +extern PSI_stage_info stage_got_handler_lock; +extern PSI_stage_info stage_got_old_table; +extern PSI_stage_info stage_init; +extern PSI_stage_info stage_insert; +extern PSI_stage_info stage_invalidating_query_cache_entries_table; +extern PSI_stage_info stage_invalidating_query_cache_entries_table_list; +extern PSI_stage_info stage_killing_slave; +extern PSI_stage_info stage_logging_slow_query; +extern PSI_stage_info stage_making_temp_file_append_before_load_data; +extern PSI_stage_info stage_making_temp_file_create_before_load_data; +extern PSI_stage_info stage_manage_keys; +extern PSI_stage_info stage_master_has_sent_all_binlog_to_slave; +extern PSI_stage_info stage_opening_tables; +extern PSI_stage_info stage_optimizing; +extern PSI_stage_info stage_preparing; +extern PSI_stage_info stage_purging_old_relay_logs; +extern PSI_stage_info stage_query_end; +extern PSI_stage_info stage_queueing_master_event_to_the_relay_log; +extern PSI_stage_info stage_reading_event_from_the_relay_log; +extern PSI_stage_info stage_registering_slave_on_master; +extern PSI_stage_info stage_removing_duplicates; +extern PSI_stage_info stage_removing_tmp_table; +extern PSI_stage_info stage_rename; +extern PSI_stage_info stage_rename_result_table; +extern PSI_stage_info stage_requesting_binlog_dump; +extern PSI_stage_info stage_reschedule; +extern PSI_stage_info stage_searching_rows_for_update; +extern PSI_stage_info stage_sending_binlog_event_to_slave; +extern PSI_stage_info stage_sending_cached_result_to_client; +extern PSI_stage_info stage_sending_data; +extern PSI_stage_info stage_setup; +extern PSI_stage_info stage_slave_has_read_all_relay_log; +extern PSI_stage_info stage_sorting_for_group; +extern PSI_stage_info stage_sorting_for_order; +extern PSI_stage_info stage_sorting_result; +extern PSI_stage_info stage_sql_thd_waiting_until_delay; +extern PSI_stage_info stage_statistics; +extern PSI_stage_info stage_storing_result_in_query_cache; +extern PSI_stage_info stage_storing_row_into_queue; +extern PSI_stage_info stage_system_lock; +extern PSI_stage_info stage_update; +extern PSI_stage_info stage_updating; +extern PSI_stage_info stage_updating_main_table; +extern PSI_stage_info stage_updating_reference_tables; +extern PSI_stage_info stage_upgrading_lock; +extern PSI_stage_info stage_user_lock; +extern PSI_stage_info stage_user_sleep; +extern PSI_stage_info stage_verifying_table; +extern PSI_stage_info stage_waiting_for_delay_list; +extern PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log; +extern PSI_stage_info stage_waiting_for_handler_insert; +extern PSI_stage_info stage_waiting_for_handler_lock; +extern PSI_stage_info stage_waiting_for_handler_open; +extern PSI_stage_info stage_waiting_for_insert; +extern PSI_stage_info stage_waiting_for_master_to_send_event; +extern PSI_stage_info stage_waiting_for_master_update; +extern PSI_stage_info stage_waiting_for_relay_log_space; +extern PSI_stage_info stage_waiting_for_slave_mutex_on_exit; +extern PSI_stage_info stage_waiting_for_slave_thread_to_start; +extern PSI_stage_info stage_waiting_for_query_cache_lock; +extern PSI_stage_info stage_waiting_for_table_flush; +extern PSI_stage_info stage_waiting_for_the_next_event_in_relay_log; +extern PSI_stage_info stage_waiting_for_the_slave_thread_to_advance_position; +extern PSI_stage_info stage_waiting_to_finalize_termination; +extern PSI_stage_info stage_waiting_to_get_readlock; +extern PSI_stage_info stage_slave_waiting_worker_to_release_partition; +extern PSI_stage_info stage_slave_waiting_worker_to_free_events; +extern PSI_stage_info stage_slave_waiting_worker_queue; +extern PSI_stage_info stage_slave_waiting_event_from_coordinator; +extern PSI_stage_info stage_slave_waiting_workers_to_exit; +#ifdef HAVE_PSI_STATEMENT_INTERFACE +/** + Statement instrumentation keys (sql). + The last entry, at [SQLCOM_END], is for parsing errors. +*/ +extern PSI_statement_info sql_statement_info[(uint) SQLCOM_END + 1]; + +/** + Statement instrumentation keys (com). + The last entry, at [COM_END], is for packet errors. +*/ +extern PSI_statement_info com_statement_info[(uint) COM_END + 1]; + +void init_sql_statement_info(); +void init_com_statement_info(); +#endif /* HAVE_PSI_STATEMENT_INTERFACE */ + #ifndef __WIN__ extern pthread_t signal_thread; #endif @@ -349,7 +473,7 @@ extern int32 thread_running; extern my_atomic_rwlock_t thread_running_lock; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, - *opt_ssl_key; + *opt_ssl_key, *opt_ssl_crl, *opt_ssl_crlpath; extern MYSQL_PLUGIN_IMPORT pthread_key(THD*, THR_THD); @@ -407,7 +531,10 @@ enum options_mysqld OPT_WANT_CORE, OPT_ENGINE_CONDITION_PUSHDOWN, OPT_LOG_ERROR, - OPT_MAX_LONG_DATA_SIZE + OPT_MAX_LONG_DATA_SIZE, + OPT_SSL_CRL, + OPT_SSL_CRLPATH, + OPT_PFS_INSTRUMENT }; #endif diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 3c5a99121fa..c1a4347d508 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -39,6 +39,7 @@ Master_info::Master_info(bool is_slave_recovery) host[0] = 0; user[0] = 0; password[0] = 0; ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; ssl_cipher[0]= 0; ssl_key[0]= 0; + ssl_crl[0]= 0; ssl_crlpath[0]= 0; my_init_dynamic_array(&ignore_server_ids, sizeof(::server_id), 16, 16); bzero((char*) &file, sizeof(file)); diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index a885576ef1c..462d0cfe1ed 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -72,6 +72,7 @@ class Master_info : public Slave_reporting_capability bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN]; + char ssl_crl[FN_REFLEN], ssl_crlpath[FN_REFLEN]; bool ssl_verify_server_cert; my_off_t master_log_pos; diff --git a/sql/set_var.h b/sql/set_var.h index 6edfd6adb39..1d07a1b73e9 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -60,7 +60,8 @@ public: sys_var *next; LEX_CSTRING name; enum flag_enum { GLOBAL, SESSION, ONLY_SESSION, SCOPE_MASK=1023, - READONLY=1024, ALLOCATED=2048, PARSE_EARLY=4096 }; + READONLY=1024, ALLOCATED=2048, INVISIBLE= 4096, + PARSE_EARLY=8192 }; /** Enumeration type to indicate for a system variable whether it will be written to the binlog or not. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 67a9312b6e6..3a3cf4520e1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -426,7 +426,7 @@ void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var) */ my_socket thd_get_fd(THD *thd) { - return thd->net.vio->sd; + return mysql_socket_getfd(thd->net.vio->mysql_socket); } /** @@ -491,27 +491,74 @@ int thd_tablespace_op(const THD *thd) return test(thd->tablespace_op); } - extern "C" -const char *set_thd_proc_info(THD *thd, const char *info, +const char *set_thd_proc_info(THD *thd_arg, const char *info, const char *calling_function, const char *calling_file, const unsigned int calling_line) { - if (!thd) + PSI_stage_info old_stage; + PSI_stage_info new_stage; + + old_stage.m_key= 0; + old_stage.m_name= info; + + set_thd_stage_info(thd_arg, & old_stage, & new_stage, + calling_function, calling_file, calling_line); + + return new_stage.m_name; +} + +extern "C" +void set_thd_stage_info(void *opaque_thd, + const PSI_stage_info *new_stage, + PSI_stage_info *old_stage, + const char *calling_func, + const char *calling_file, + const unsigned int calling_line) +{ + THD *thd= (THD*) opaque_thd; + if (thd == NULL) thd= current_thd; - const char *old_info= thd->proc_info; - DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, info)); + thd->enter_stage(new_stage, old_stage, calling_func, calling_file, + calling_line); +} + +void THD::enter_stage(const PSI_stage_info *new_stage, + PSI_stage_info *old_stage, + const char *calling_func, + const char *calling_file, + const unsigned int calling_line) +{ + DBUG_PRINT("THD::enter_stage", ("%s:%d", calling_file, calling_line)); + + if (old_stage != NULL) + { + old_stage->m_key= m_current_stage_key; + old_stage->m_name= proc_info; + } + + if (new_stage != NULL) + { + const char *msg= new_stage->m_name; #if defined(ENABLED_PROFILING) - thd->profiling.status_change(info, - calling_function, calling_file, calling_line); + profiling.status_change(msg, calling_func, calling_file, calling_line); #endif - thd->proc_info= info; - return old_info; + + m_current_stage_key= new_stage->m_key; + proc_info= msg; + +#ifdef HAVE_PSI_THREAD_INTERFACE + PSI_CALL(set_thread_state)(msg); + MYSQL_SET_STAGE(m_current_stage_key, calling_file, calling_line); +#endif + } + return; } + extern "C" const char* thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, mysql_mutex_t *mutex, const char *msg) @@ -746,6 +793,9 @@ THD::THD() accessed_rows_and_keys(0), warning_info(&main_warning_info), stmt_da(&main_da), + m_statement_psi(NULL), + m_idle_psi(NULL), + m_server_idle(false), global_disable_checkpoint(0), is_fatal_error(0), transaction_rollback_request(0), @@ -4186,6 +4236,141 @@ void THD::set_statement(Statement *stmt) mysql_mutex_unlock(&LOCK_thd_data); } +void THD::set_sent_row_count(ha_rows count) +{ + sent_row_count= count; + MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, sent_row_count); +} + +void THD::set_examined_row_count(ha_rows count) +{ + examined_row_count= count; + MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, examined_row_count); +} + +void THD::inc_sent_row_count(ha_rows count) +{ + sent_row_count+= count; + MYSQL_SET_STATEMENT_ROWS_SENT(m_statement_psi, sent_row_count); +} + +void THD::inc_examined_row_count(ha_rows count) +{ + examined_row_count+= count; + MYSQL_SET_STATEMENT_ROWS_EXAMINED(m_statement_psi, examined_row_count); +} + +void THD::inc_status_created_tmp_disk_tables() +{ + status_var_increment(status_var.created_tmp_disk_tables); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_created_tmp_disk_tables)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_created_tmp_tables() +{ + status_var_increment(status_var.created_tmp_tables); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_created_tmp_tables)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_select_full_join() +{ + status_var_increment(status_var.select_full_join_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_select_full_join)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_select_full_range_join() +{ + status_var_increment(status_var.select_full_range_join_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_select_full_range_join)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_select_range() +{ + status_var_increment(status_var.select_range_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_select_range)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_select_range_check() +{ + status_var_increment(status_var.select_range_check_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_select_range_check)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_select_scan() +{ + status_var_increment(status_var.select_scan_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_select_scan)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_sort_merge_passes() +{ + status_var_increment(status_var.filesort_merge_passes); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_sort_merge_passes)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_sort_range() +{ + status_var_increment(status_var.filesort_range_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_sort_range)(m_statement_psi, 1); +#endif +} + +void THD::inc_status_sort_rows(ha_rows count) +{ + statistic_add(status_var.filesort_rows, count, &LOCK_status); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_sort_rows)(m_statement_psi, count); +#endif +} + +void THD::inc_status_sort_scan() +{ + status_var_increment(status_var.filesort_scan_count); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(inc_statement_sort_scan)(m_statement_psi, 1); +#endif +} + +void THD::set_status_no_index_used() +{ + server_status|= SERVER_QUERY_NO_INDEX_USED; +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(set_statement_no_index_used)(m_statement_psi); +#endif +} + +void THD::set_status_no_good_index_used() +{ + server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED; +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_CALL(set_statement_no_good_index_used)(m_statement_psi); +#endif +} + +void THD::set_command(enum enum_server_command command_arg) +{ + command= command_arg; +#ifdef HAVE_PSI_THREAD_INTERFACE + PSI_CALL(set_thread_command)(command); +#endif +} /** Assign a new value to thd->query. */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 9a4a3dece67..b21f60a7a78 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -43,7 +43,11 @@ #include "violite.h" /* vio_is_connected */ #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA, THR_LOCK_INFO */ +#include <mysql/psi/mysql_stage.h> +#include <mysql/psi/mysql_statement.h> +#include <mysql/psi/mysql_idle.h> #include <mysql/psi/mysql_table.h> +#include <mysql_com_server.h> class Reprepare_observer; class Relay_log_info; @@ -1588,6 +1592,8 @@ public: Query_cache_tls query_cache_tls; #endif NET net; // client connection descriptor + /** Aditional network instrumentation for the server only. */ + NET_SERVER m_net_server_extension; scheduler_functions *scheduler; // Scheduler for this connection Protocol *protocol; // Current protocol Protocol_text protocol_text; // Normal protocol @@ -1653,6 +1659,19 @@ public: */ const char *proc_info; +private: + unsigned int m_current_stage_key; + +public: + void enter_stage(const PSI_stage_info *stage, + PSI_stage_info *old_stage, + const char *calling_func, + const char *calling_file, + const unsigned int calling_line); + + const char *get_proc_info() const + { return proc_info; } + /* Used in error messages to tell user in what part of MySQL we found an error. E. g. when where= "having clause", if fix_fields() fails, user @@ -2115,6 +2134,27 @@ public: changed or written. */ ulonglong accessed_rows_and_keys; + + void set_sent_row_count(ha_rows count); + void set_examined_row_count(ha_rows count); + + void inc_sent_row_count(ha_rows count); + void inc_examined_row_count(ha_rows count); + + void inc_status_created_tmp_disk_tables(); + void inc_status_created_tmp_files(); + void inc_status_created_tmp_tables(); + void inc_status_select_full_join(); + void inc_status_select_full_range_join(); + void inc_status_select_range(); + void inc_status_select_range_check(); + void inc_status_select_scan(); + void inc_status_sort_merge_passes(); + void inc_status_sort_range(); + void inc_status_sort_rows(ha_rows count); + void inc_status_sort_scan(); + void set_status_no_index_used(); + void set_status_no_good_index_used(); /** Check if the number of rows accessed by a statement exceeded LIMIT ROWS EXAMINED. If so, signal the query engine to stop execution. @@ -2133,6 +2173,21 @@ public: PROFILING profiling; #endif + /** Current statement instrumentation. */ + PSI_statement_locker *m_statement_psi; +#ifdef HAVE_PSI_STATEMENT_INTERFACE + /** Current statement instrumentation state. */ + PSI_statement_locker_state m_statement_state; +#endif /* HAVE_PSI_STATEMENT_INTERFACE */ + /** Idle instrumentation. */ + PSI_idle_locker *m_idle_psi; +#ifdef HAVE_PSI_IDLE_INTERFACE + /** Idle instrumentation state. */ + PSI_idle_locker_state m_idle_state; +#endif /* HAVE_PSI_IDLE_INTERFACE */ + /** True if the server code is IDLE for this connection. */ + bool m_server_idle; + /* Id of current query. Statement can be reused to execute several queries query_id is global in context of the whole MySQL server. @@ -2482,7 +2537,12 @@ public: my_hrtime_t hrtime= { hrtime_from_time(t) + sec_part }; set_time(hrtime); } - void set_time_after_lock() { utime_after_lock= microsecond_interval_timer(); } + void set_time_after_lock() + { + utime_after_lock= microsecond_interval_timer(); + MYSQL_SET_STATEMENT_LOCK_TIME(m_statement_psi, + (utime_after_lock - start_utime)); + } ulonglong current_utime() { return microsecond_interval_timer(); } /** @@ -2650,6 +2710,11 @@ public: To raise this flag, use my_error(). */ inline bool is_error() const { return stmt_da->is_error(); } + + /// Returns Diagnostics-area for the current statement. + Diagnostics_area *get_stmt_da() + { return stmt_da; } + inline CHARSET_INFO *charset() { return variables.character_set_client; } void update_charset(); @@ -2973,6 +3038,9 @@ private: public: /** Overloaded to guard query/query_length fields */ virtual void set_statement(Statement *stmt); + void set_command(enum enum_server_command command); + inline enum enum_server_command get_command() const + { return command; } /** Assign a new value to thd->query and thd->query_id and mysys_var. @@ -4368,6 +4436,17 @@ inline int handler::ha_update_tmp_row(const uchar *old_data, uchar *new_data) extern pthread_attr_t *get_connection_attrib(void); +extern "C" +void set_thd_stage_info(void *thd, + const PSI_stage_info *new_stage, + PSI_stage_info *old_stage, + const char *calling_func, + const char *calling_file, + const unsigned int calling_line); + +#define THD_STAGE_INFO(thd, stage) \ + (thd)->enter_stage(& stage, NULL, __func__, __FILE__, __LINE__) + #endif /* MYSQL_SERVER */ #endif /* SQL_CLASS_INCLUDED */ diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h new file mode 100644 index 00000000000..29b478bfb52 --- /dev/null +++ b/sql/sql_cmd.h @@ -0,0 +1,161 @@ +/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + @file Representation of an SQL command. +*/ + +#ifndef SQL_CMD_INCLUDED +#define SQL_CMD_INCLUDED + +/* + When a command is added here, be sure it's also added in mysqld.cc + in "struct show_var_st status_vars[]= {" ... + + If the command returns a result set or is not allowed in stored + functions or triggers, please also make sure that + sp_get_flags_for_command (sp_head.cc) returns proper flags for the + added SQLCOM_. +*/ + +enum enum_sql_command { + SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE, + SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT, + SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX, + + SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, + SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_ENGINE_LOGS, SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_MUTEX, + SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, + SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, + SQLCOM_SHOW_TRIGGERS, + + SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, + SQLCOM_GRANT, + SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, + SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, + SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, + SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, + SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS, + SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, + SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT, + SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_RELEASE_SAVEPOINT, + SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, + SQLCOM_BEGIN, SQLCOM_CHANGE_MASTER, + SQLCOM_RENAME_TABLE, + SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_PURGE_BEFORE, SQLCOM_SHOW_BINLOGS, + SQLCOM_SHOW_OPEN_TABLES, + SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, + SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_UPDATE_MULTI, + SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_DO, + SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, + SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, + SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER, + SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, + SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, + SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, + SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC, + SQLCOM_SHOW_STATUS_PROC, SQLCOM_SHOW_STATUS_FUNC, + SQLCOM_PREPARE, SQLCOM_EXECUTE, SQLCOM_DEALLOCATE_PREPARE, + SQLCOM_CREATE_VIEW, SQLCOM_DROP_VIEW, + SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER, + SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE, + SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER, + SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, + SQLCOM_ALTER_TABLESPACE, + SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN, + SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT, + SQLCOM_SHOW_PLUGINS, + SQLCOM_SHOW_CONTRIBUTORS, + SQLCOM_CREATE_SERVER, SQLCOM_DROP_SERVER, SQLCOM_ALTER_SERVER, + SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT, + SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS, + SQLCOM_SHOW_CREATE_TRIGGER, + SQLCOM_ALTER_DB_UPGRADE, + SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES, + SQLCOM_SIGNAL, SQLCOM_RESIGNAL, + SQLCOM_SHOW_RELAYLOG_EVENTS, + SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, + SQLCOM_SHOW_CLIENT_STATS, + + /* + When a command is added here, be sure it's also added in mysqld.cc + in "struct show_var_st status_vars[]= {" ... + */ + /* This should be the last !!! */ + SQLCOM_END +}; + +/** + @class Sql_cmd - Representation of an SQL command. + + This class is an interface between the parser and the runtime. + The parser builds the appropriate derived classes of Sql_cmd + to represent a SQL statement in the parsed tree. + The execute() method in the derived classes of Sql_cmd contain the runtime + implementation. + Note that this interface is used for SQL statements recently implemented, + the code for older statements tend to load the LEX structure with more + attributes instead. + Implement new statements by sub-classing Sql_cmd, as this improves + code modularity (see the 'big switch' in dispatch_command()), and decreases + the total size of the LEX structure (therefore saving memory in stored + programs). + The recommended name of a derived class of Sql_cmd is Sql_cmd_<derived>. + + Notice that the Sql_cmd class should not be confused with the + Statement class. Statement is a class that is used to manage an SQL + command or a set of SQL commands. When the SQL statement text is + analyzed, the parser will create one or more Sql_cmd objects to + represent the actual SQL commands. +*/ +class Sql_cmd : public Sql_alloc +{ +private: + Sql_cmd(const Sql_cmd &); // No copy constructor wanted + void operator=(Sql_cmd &); // No assignment operator wanted + +public: + /** + @brief Return the command code for this statement + */ + virtual enum_sql_command sql_command_code() const = 0; + + /** + Execute this SQL statement. + @param thd the current thread. + @retval false on success. + @retval true on error + */ + virtual bool execute(THD *thd) = 0; + +protected: + Sql_cmd() + {} + + virtual ~Sql_cmd() + { + /* + Sql_cmd objects are allocated in thd->mem_root. + In MySQL, the C++ destructor is never called, the underlying MEM_ROOT is + simply destroyed instead. + Do not rely on the destructor for any cleanup. + */ + DBUG_ASSERT(FALSE); + } +}; + +#endif // SQL_CMD_INCLUDED diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index c50cded7470..fd348e0b75f 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -97,6 +97,7 @@ public: int mysql_open_cursor(THD *thd, select_result *result, Server_side_cursor **pcursor) { + PSI_statement_locker *parent_locker; select_result *save_result; Select_materialize *result_materialize; LEX *lex= thd->lex; @@ -115,7 +116,10 @@ int mysql_open_cursor(THD *thd, select_result *result, &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 2); + parent_locker= thd->m_statement_psi; + thd->m_statement_psi= NULL; rc= mysql_execute_command(thd); + thd->m_statement_psi= parent_locker; MYSQL_QUERY_EXEC_DONE(rc); lex->result= save_result; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index cf0a8674316..5f18d9861a9 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -970,6 +970,7 @@ int MYSQLlex(void *arg, void *yythd) lip->lookahead_token= -1; *yylval= *(lip->lookahead_yylval); lip->lookahead_yylval= NULL; + lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, token, yylval); return token; } @@ -987,8 +988,12 @@ int MYSQLlex(void *arg, void *yythd) token= lex_one_token(arg, yythd); switch(token) { case CUBE_SYM: + lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, WITH_CUBE_SYM, + yylval); return WITH_CUBE_SYM; case ROLLUP_SYM: + lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, WITH_ROLLUP_SYM, + yylval); return WITH_ROLLUP_SYM; default: /* @@ -997,6 +1002,7 @@ int MYSQLlex(void *arg, void *yythd) lip->lookahead_yylval= lip->yylval; lip->yylval= NULL; lip->lookahead_token= token; + lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, WITH, yylval); return WITH; } break; @@ -1004,6 +1010,7 @@ int MYSQLlex(void *arg, void *yythd) break; } + lip->m_digest_psi= MYSQL_ADD_TOKEN(lip->m_digest_psi, token, yylval); return token; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2f3214646de..3dd978e93b3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -25,6 +25,7 @@ #include "item.h" /* From item_subselect.h: subselect_union_engine */ #include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */ #include "mem_root_array.h" +#include "sql_cmd.h" /* YACC and LEX Definitions */ @@ -123,85 +124,6 @@ struct sys_var_with_base #endif #endif -/* - When a command is added here, be sure it's also added in mysqld.cc - in "struct show_var_st status_vars[]= {" ... - - If the command returns a result set or is not allowed in stored - functions or triggers, please also make sure that - sp_get_flags_for_command (sp_head.cc) returns proper flags for the - added SQLCOM_. -*/ - -enum enum_sql_command { - SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE, - SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT, - SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX, - - SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, - SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS, - SQLCOM_SHOW_ENGINE_LOGS, SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_MUTEX, - SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, - SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, - SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, - SQLCOM_SHOW_TRIGGERS, - - SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, - SQLCOM_GRANT, - SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, - SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, - SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, - SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, - SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS, - SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, - SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT, - SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_RELEASE_SAVEPOINT, - SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, - SQLCOM_BEGIN, SQLCOM_CHANGE_MASTER, - SQLCOM_RENAME_TABLE, - SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_PURGE_BEFORE, SQLCOM_SHOW_BINLOGS, - SQLCOM_SHOW_OPEN_TABLES, - SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, - SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_DELETE_MULTI, SQLCOM_UPDATE_MULTI, - SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_DO, - SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, - SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, - SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER, - SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, - SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, - SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, - SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC, - SQLCOM_SHOW_STATUS_PROC, SQLCOM_SHOW_STATUS_FUNC, - SQLCOM_PREPARE, SQLCOM_EXECUTE, SQLCOM_DEALLOCATE_PREPARE, - SQLCOM_CREATE_VIEW, SQLCOM_DROP_VIEW, - SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER, - SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE, - SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER, - SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, - SQLCOM_ALTER_TABLESPACE, - SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN, - SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT, - SQLCOM_SHOW_PLUGINS, - SQLCOM_SHOW_CONTRIBUTORS, - SQLCOM_CREATE_SERVER, SQLCOM_DROP_SERVER, SQLCOM_ALTER_SERVER, - SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT, - SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS, - SQLCOM_SHOW_CREATE_TRIGGER, - SQLCOM_ALTER_DB_UPGRADE, - SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES, - SQLCOM_SIGNAL, SQLCOM_RESIGNAL, - SQLCOM_SHOW_RELAYLOG_EVENTS, - SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, - SQLCOM_SHOW_CLIENT_STATS, - - /* - When a command is added here, be sure it's also added in mysqld.cc - in "struct show_var_st status_vars[]= {" ... - */ - /* This should be the last !!! */ - SQLCOM_END -}; - // describe/explain types #define DESCRIBE_NORMAL 1 #define DESCRIBE_EXTENDED 2 @@ -285,6 +207,7 @@ struct LEX_MASTER_INFO DYNAMIC_ARRAY repl_ignore_server_ids; char *host, *user, *password, *log_file_name; char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher; + char *ssl_crl, *ssl_crlpath; char *relay_log_name; ulonglong pos; ulong relay_log_pos; @@ -2270,6 +2193,11 @@ public: NOTE: this member must be used within MYSQLlex() function only. */ CHARSET_INFO *m_underscore_cs; + + /** + Current statement digest instrumentation. + */ + PSI_digest_locker* m_digest_psi; }; /** diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 19a8ba2b533..48ae2f066db 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -865,18 +865,32 @@ bool do_command(THD *thd) */ DEBUG_SYNC(thd, "before_do_command_net_read"); - if ((packet_length= my_net_read(net)) == packet_error) + thd->m_server_idle= TRUE; + packet_length= my_net_read(net); + thd->m_server_idle= FALSE; + + if ((packet_length == packet_error)) { DBUG_PRINT("info",("Got error %d reading command from socket %s", net->error, vio_description(net->vio))); + /* Instrument this broken statement as "statement/com/error" */ + thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi, + com_statement_info[COM_END]. + m_key); + + /* Check if we can continue without closing the connection */ /* The error must be set. */ DBUG_ASSERT(thd->is_error()); thd->protocol->end_statement(); + /* Mark the statement completed. */ + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= NULL; + if (net->error != 3) { return_value= TRUE; // We have to close it. @@ -922,6 +936,8 @@ bool do_command(THD *thd) return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1)); out: + /* The statement instrumentation must be closed in all cases. */ + DBUG_ASSERT(thd->m_statement_psi == NULL); DBUG_RETURN(return_value); } #endif /* EMBEDDED_LIBRARY */ @@ -1034,7 +1050,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { DBUG_PRINT("crash_dispatch_command_before", ("now")); DBUG_ABORT(); }); - thd->command=command; + /* Performance Schema Interface instrumentation, begin */ + thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi, + com_statement_info[command]. + m_key); + thd->set_command(command); + /* Commands which always take a long time are logged into the slow log only if opt_log_slow_admin_statements is set. @@ -1176,6 +1197,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #if defined(ENABLED_PROFILING) thd->profiling.set_query_source(thd->query(), thd->query_length()); #endif + MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), + thd->query_length()); + Parser_state parser_state; if (parser_state.init(thd, thd->query(), thd->query_length())) break; @@ -1209,6 +1233,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, length--; } + /* PSI end */ + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= NULL; + + /* DTRACE end */ if (MYSQL_QUERY_DONE_ENABLED()) { MYSQL_QUERY_DONE(thd->is_error()); @@ -1220,11 +1249,21 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->profiling.set_query_source(beginning_of_next_stmt, length); #endif + /* DTRACE begin */ MYSQL_QUERY_START(beginning_of_next_stmt, thd->thread_id, (char *) (thd->db ? thd->db : ""), &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip); + /* PSI begin */ + thd->m_statement_psi= + MYSQL_START_STATEMENT(&thd->m_statement_state, + com_statement_info[command]. m_key, + thd->db, thd->db_length); + THD_STAGE_INFO(thd, stage_init); + MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, beginning_of_next_stmt, + length); + thd->set_query_and_id(beginning_of_next_stmt, length, thd->charset(), next_query_id()); /* @@ -1571,7 +1610,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, "cleaning up"); thd->reset_query(); - thd->command=COM_SLEEP; + thd->set_command(COM_SLEEP); + + /* Performance Schema Interface instrumentation, end */ + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= NULL; + dec_thread_running(); thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory @@ -5836,6 +5880,10 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, if (!err) { + thd->m_statement_psi= + MYSQL_REFINE_STATEMENT(thd->m_statement_psi, + sql_statement_info[thd->lex->sql_command]. + m_key); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (mqh_used && thd->user_connect && check_mqh(thd, lex->sql_command)) @@ -5884,6 +5932,10 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, } else { + /* Instrument this broken statement as "statement/sql/error" */ + thd->m_statement_psi= + MYSQL_REFINE_STATEMENT(thd->m_statement_psi, + sql_statement_info[SQLCOM_END].m_key); DBUG_ASSERT(thd->is_error()); DBUG_PRINT("info",("Command aborted. Fatal_error: %d", thd->is_fatal_error)); @@ -5901,6 +5953,9 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, { /* Update statistics for getting the query from the cache */ thd->lex->sql_command= SQLCOM_SELECT; + thd->m_statement_psi= + MYSQL_REFINE_STATEMENT(thd->m_statement_psi, + sql_statement_info[SQLCOM_SELECT].m_key); } DBUG_VOID_RETURN; } @@ -7741,6 +7796,12 @@ bool parse_sql(THD *thd, thd->m_parser_state= parser_state; +#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE + /* Start Digest */ + thd->m_parser_state->m_lip.m_digest_psi= + MYSQL_DIGEST_START(thd->m_statement_psi); +#endif + /* Parse the query. */ bool mysql_parse_status= MYSQLparse(thd) != 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ed437c498e6..b579474ee4d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3072,6 +3072,7 @@ Execute_sql_statement(LEX_STRING sql_text) bool Execute_sql_statement::execute_server_code(THD *thd) { + PSI_statement_locker *parent_locker; bool error; if (alloc_query(thd, m_sql_text.str, m_sql_text.length)) @@ -3091,7 +3092,10 @@ Execute_sql_statement::execute_server_code(THD *thd) thd->lex->set_trg_event_type_for_tables(); + parent_locker= thd->m_statement_psi; + thd->m_statement_psi= NULL; error= mysql_execute_command(thd); + thd->m_statement_psi= parent_locker; /* report error issued during command execution */ if (error == 0 && thd->spcont == NULL) @@ -3877,13 +3881,17 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) if (query_cache_send_result_to_client(thd, thd->query(), thd->query_length()) <= 0) { + PSI_statement_locker *parent_locker; MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, (char *) (thd->db ? thd->db : ""), &thd->security_ctx->priv_user[0], (char *) thd->security_ctx->host_or_ip, 1); + parent_locker= thd->m_statement_psi; + thd->m_statement_psi= NULL; error= mysql_execute_command(thd); + thd->m_statement_psi= parent_locker; MYSQL_QUERY_EXEC_DONE(error); } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4e3629080be..e2263e21e8f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1103,6 +1103,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MASTER_SSL_CA_SYM %token MASTER_SSL_CERT_SYM %token MASTER_SSL_CIPHER_SYM +%token MASTER_SSL_CRL_SYM +%token MASTER_SSL_CRLPATH_SYM %token MASTER_SSL_KEY_SYM %token MASTER_SSL_SYM %token MASTER_SSL_VERIFY_SERVER_CERT_SYM @@ -1967,6 +1969,14 @@ master_def: Lex->mi.ssl_verify_server_cert= $3 ? LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE; } + | MASTER_SSL_CRL_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_crl= $3.str; + } + | MASTER_SSL_CRLPATH_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_crlpath= $3.str; + } | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal { @@ -13098,6 +13108,8 @@ keyword_sp: | MASTER_SSL_CAPATH_SYM {} | MASTER_SSL_CERT_SYM {} | MASTER_SSL_CIPHER_SYM {} + | MASTER_SSL_CRL_SYM {} + | MASTER_SSL_CRLPATH_SYM {} | MASTER_SSL_KEY_SYM {} | MAX_CONNECTIONS_PER_HOUR {} | MAX_QUERIES_PER_HOUR {} diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 97fbe76f149..ac84d820ca6 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -14,7 +14,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* +/** + @file + Definitions of all server's session or global variables. + How to add new variables: 1. copy one of the existing variables, and edit the declaration. @@ -69,6 +72,85 @@ static Sys_var_mybool Sys_pfs_enabled( PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_enabled), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); +static Sys_var_charptr Sys_pfs_instrument( + "performance_schema_instrument", + "Default startup value for a performance schema instrument.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_pfs_instrument), + CMD_LINE(OPT_ARG, OPT_PFS_INSTRUMENT), + IN_FS_CHARSET, DEFAULT("")); + +static Sys_var_mybool Sys_pfs_consumer_events_stages_current( + "performance_schema_consumer_events_stages_current", + "Default startup value for the events_stages_current consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_stages_current_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_stages_history( + "performance_schema_consumer_events_stages_history", + "Default startup value for the events_stages_history consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_stages_history_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_stages_history_long( + "performance_schema_consumer_events_stages_history_long", + "Default startup value for the events_stages_history_long consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_stages_history_long_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_statements_current( + "performance_schema_consumer_events_statements_current", + "Default startup value for the events_statements_current consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_statements_current_enabled), + CMD_LINE(OPT_ARG), DEFAULT(TRUE)); + +static Sys_var_mybool Sys_pfs_consumer_events_statements_history( + "performance_schema_consumer_events_statements_history", + "Default startup value for the events_statements_history consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_statements_history_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_statements_history_long( + "performance_schema_consumer_events_statements_history_long", + "Default startup value for the events_statements_history_long consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_statements_history_long_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_waits_current( + "performance_schema_consumer_events_waits_current", + "Default startup value for the events_waits_current consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_waits_current_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_waits_history( + "performance_schema_consumer_events_waits_history", + "Default startup value for the events_waits_history consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_waits_history_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_events_waits_history_long( + "performance_schema_consumer_events_waits_history_long", + "Default startup value for the events_waits_history_long consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_events_waits_history_long_enabled), + CMD_LINE(OPT_ARG), DEFAULT(FALSE)); + +static Sys_var_mybool Sys_pfs_consumer_global_instrumentation( + "performance_schema_consumer_global_instrumentation", + "Default startup value for the global_instrumentation consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_global_instrumentation_enabled), + CMD_LINE(OPT_ARG), DEFAULT(TRUE)); + +static Sys_var_mybool Sys_pfs_consumer_thread_instrumentation( + "performance_schema_consumer_thread_instrumentation", + "Default startup value for the thread_instrumentation consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_thread_instrumentation_enabled), + CMD_LINE(OPT_ARG), DEFAULT(TRUE)); + +static Sys_var_mybool Sys_pfs_consumer_statement_digest( + "performance_schema_consumer_statements_digest", + "Default startup value for the statements_digest consumer.", + PARSED_EARLY READ_ONLY NOT_VISIBLE GLOBAL_VAR(pfs_param.m_consumer_statement_digest_enabled), + CMD_LINE(OPT_ARG), DEFAULT(TRUE)); + static Sys_var_ulong Sys_pfs_events_waits_history_long_size( "performance_schema_events_waits_history_long_size", "Number of rows in EVENTS_WAITS_HISTORY_LONG.", @@ -119,6 +201,22 @@ static Sys_var_ulong Sys_pfs_max_file_instances( CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), DEFAULT(PFS_MAX_FILE), BLOCK_SIZE(1)); +static Sys_var_ulong Sys_pfs_max_sockets( + "performance_schema_max_socket_instances", + "Maximum number of opened instrumented sockets.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_socket_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_MAX_SOCKETS), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_max_socket_classes( + "performance_schema_max_socket_classes", + "Maximum number of socket instruments.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_socket_class_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256), + DEFAULT(PFS_MAX_SOCKET_CLASS), + BLOCK_SIZE(1)); + static Sys_var_ulong Sys_pfs_max_mutex_classes( "performance_schema_max_mutex_classes", "Maximum number of mutex instruments.", @@ -175,6 +273,111 @@ static Sys_var_ulong Sys_pfs_max_thread_instances( CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), DEFAULT(PFS_MAX_THREAD), BLOCK_SIZE(1)); +static Sys_var_ulong Sys_pfs_setup_actors_size( + "performance_schema_setup_actors_size", + "Maximum number of rows in SETUP_ACTORS.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_setup_actor_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), + DEFAULT(PFS_MAX_SETUP_ACTOR), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_setup_objects_size( + "performance_schema_setup_objects_size", + "Maximum number of rows in SETUP_OBJECTS.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_setup_object_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_MAX_SETUP_OBJECT), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_accounts_size( + "performance_schema_accounts_size", + "Maximum number of instrumented user@host accounts.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_account_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_MAX_ACCOUNT), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_hosts_size( + "performance_schema_hosts_size", + "Maximum number of instrumented hosts.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_host_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_MAX_HOST), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_users_size( + "performance_schema_users_size", + "Maximum number of instrumented users.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_user_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_MAX_USER), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_max_stage_classes( + "performance_schema_max_stage_classes", + "Maximum number of stage instruments.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_stage_class_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256), + DEFAULT(PFS_MAX_STAGE_CLASS), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_events_stages_history_long_size( + "performance_schema_events_stages_history_long_size", + "Number of rows in EVENTS_STAGES_HISTORY_LONG.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_long_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_STAGES_HISTORY_LONG_SIZE), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_events_stages_history_size( + "performance_schema_events_stages_history_size", + "Number of rows per thread in EVENTS_STAGES_HISTORY.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_stages_history_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), + DEFAULT(PFS_STAGES_HISTORY_SIZE), + BLOCK_SIZE(1)); + +/** + Variable performance_schema_max_statement_classes. + The default number of statement classes is the sum of: + - COM_END for all regular "statement/com/...", + - 1 for "statement/com/new_packet", for unknown enum_server_command + - 1 for "statement/com/Error", for invalid enum_server_command + - SQLCOM_END for all regular "statement/sql/...", + - 1 for "statement/sql/error", for invalid enum_sql_command. +*/ +static Sys_var_ulong Sys_pfs_max_statement_classes( + "performance_schema_max_statement_classes", + "Maximum number of statement instruments.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256), + DEFAULT((ulong) SQLCOM_END + (ulong) COM_END + 3), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_events_statements_history_long_size( + "performance_schema_events_statements_history_long_size", + "Number of rows in EVENTS_STATEMENTS_HISTORY_LONG.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_long_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024*1024), + DEFAULT(PFS_STATEMENTS_HISTORY_LONG_SIZE), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_events_statements_history_size( + "performance_schema_events_statements_history_size", + "Number of rows per thread in EVENTS_STATEMENTS_HISTORY.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_events_statements_history_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024), + DEFAULT(PFS_STATEMENTS_HISTORY_SIZE), + BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_pfs_digest_size( + "performance_schema_digests_size", + "Size of the statement digest.", + PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_digest_sizing), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 200), + DEFAULT(PFS_DIGEST_SIZE), + BLOCK_SIZE(1)); + #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ static Sys_var_ulong Sys_auto_increment_increment( @@ -2225,6 +2428,19 @@ static Sys_var_charptr Sys_ssl_key( READ_ONLY GLOBAL_VAR(opt_ssl_key), SSL_OPT(OPT_SSL_KEY), IN_FS_CHARSET, DEFAULT(0)); +static Sys_var_charptr Sys_ssl_crl( + "ssl_crl", + "CRL file in PEM format (check OpenSSL docs, implies --ssl)", + READ_ONLY GLOBAL_VAR(opt_ssl_crl), SSL_OPT(OPT_SSL_CRL), + IN_FS_CHARSET, DEFAULT(0)); + +static Sys_var_charptr Sys_ssl_crlpath( + "ssl_crlpath", + "CRL directory (check OpenSSL docs, implies --ssl)", + READ_ONLY GLOBAL_VAR(opt_ssl_crlpath), SSL_OPT(OPT_SSL_CRLPATH), + IN_FS_CHARSET, DEFAULT(0)); + + // why ENUM and not BOOL ? static const char *updatable_views_with_limit_names[]= {"NO", "YES", 0}; static Sys_var_enum Sys_updatable_views_with_limit( diff --git a/sql/sys_vars.h b/sql/sys_vars.h index b594ff35571..ff7ac46d96f 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -51,9 +51,11 @@ #define ON_CHECK(X) X #define ON_UPDATE(X) X #define READ_ONLY sys_var::READONLY+ +#define NOT_VISIBLE sys_var::INVISIBLE+ // this means that Sys_var_charptr initial value was malloc()ed #define PREALLOCATED sys_var::ALLOCATED+ #define PARSED_EARLY sys_var::PARSE_EARLY+ + /* Sys_var_bit meaning is reversed, like in @@foreign_key_checks <-> OPTION_NO_FOREIGN_KEY_CHECKS diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index f5ea771883d..60c3ad69c65 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -1361,7 +1361,7 @@ static int change_group(connection_t *c, thread_group_t *new_group) { int ret= 0; - int fd = c->thd->net.vio->sd; + int fd= mysql_socket_getfd(c->thd->net.vio->mysql_socket); DBUG_ASSERT(c->thread_group == old_group); @@ -1389,7 +1389,7 @@ static int change_group(connection_t *c, static int start_io(connection_t *connection) { - int fd = connection->thd->net.vio->sd; + int fd = mysql_socket_getfd(connection->thd->net.vio->mysql_socket); /* Usually, connection will stay in the same group for the entire |