diff options
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r-- | sql/mysqld.cc | 241 |
1 files changed, 160 insertions, 81 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0de9d7a9f0b..9a6aa2676d7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2016, MariaDB + Copyright (c) 2008, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,7 +12,7 @@ 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ #include "sql_plugin.h" // Includes my_global.h #include "sql_priv.h" @@ -111,7 +111,7 @@ #include <poll.h> #endif -#include <my_systemd.h> +#include <my_service_manager.h> #define mysqld_charset &my_charset_latin1 @@ -482,7 +482,7 @@ my_bool opt_master_verify_checksum= 0; my_bool opt_slave_sql_verify_checksum= 1; const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS}; volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */ -uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; +uint mysqld_port, select_errors, dropping_tables, ha_open_options; uint mysqld_extra_port; uint mysqld_port_timeout; ulong delay_key_write_options; @@ -509,6 +509,7 @@ ulonglong max_binlog_cache_size=0; ulong slave_max_allowed_packet= 0; ulonglong binlog_stmt_cache_size=0; ulonglong max_binlog_stmt_cache_size=0; +ulonglong test_flags; ulonglong query_cache_size=0; ulong query_cache_limit=0; ulong executed_events=0; @@ -540,7 +541,7 @@ bool max_user_connections_checking=0; Limit of the total number of prepared statements in the server. Is necessary to protect the server against out-of-memory attacks. */ -ulong max_prepared_stmt_count; +uint max_prepared_stmt_count; /** Current total number of prepared statements in the server. This number is exact, and therefore may not be equal to the difference between @@ -551,7 +552,7 @@ ulong max_prepared_stmt_count; two different connections, this counts as two distinct prepared statements. */ -ulong prepared_stmt_count=0; +uint prepared_stmt_count=0; ulong thread_id=1L,current_pid; ulong slow_launch_threads = 0; uint sync_binlog_period= 0, sync_relaylog_period= 0, @@ -753,6 +754,7 @@ char *master_info_file; char *relay_log_info_file, *report_user, *report_password, *report_host; char *opt_relay_logname = 0, *opt_relaylog_index_name=0; char *opt_logname, *opt_slow_logname, *opt_bin_logname; +char *opt_binlog_index_name=0; /* Static variables */ @@ -762,7 +764,6 @@ my_bool opt_expect_abort= 0, opt_bootstrap= 0; static my_bool opt_myisam_log; static int cleanup_done; static ulong opt_specialflag; -static char *opt_binlog_index_name; char *mysql_home_ptr, *pidfile_name_ptr; /** Initial command line arguments (count), after load_defaults().*/ static int defaults_argc; @@ -1412,9 +1413,9 @@ static NTService Service; ///< Service object for WinNT #endif /* __WIN__ */ #ifdef _WIN32 +#include <sddl.h> /* ConvertStringSecurityDescriptorToSecurityDescriptor */ static char pipe_name[512]; static SECURITY_ATTRIBUTES saPipeSecurity; -static SECURITY_DESCRIPTOR sdPipeDescriptor; static HANDLE hPipe = INVALID_HANDLE_VALUE; #endif @@ -1724,7 +1725,14 @@ static void close_connections(void) tmp->thread_id, (tmp->main_security_ctx.user ? tmp->main_security_ctx.user : "")); + /* + close_connection() might need a valid current_thd + for memory allocation tracking. + */ + THD* save_thd= current_thd; + set_current_thd(tmp); close_connection(tmp,ER_SERVER_SHUTDOWN); + set_current_thd(save_thd); } #endif #ifdef WITH_WSREP @@ -2611,21 +2619,20 @@ static void network_init(void) strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\", mysqld_unix_port, NullS); - bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity)); - bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor)); - if (!InitializeSecurityDescriptor(&sdPipeDescriptor, - SECURITY_DESCRIPTOR_REVISION)) + /* + Create a security descriptor for pipe. + - Use low integrity level, so that it is possible to connect + from any process. + - Give Everyone read/write access to pipe. + */ + if (!ConvertStringSecurityDescriptorToSecurityDescriptor( + "S:(ML;; NW;;; LW) D:(A;; FRFW;;; WD)", + SDDL_REVISION_1, &saPipeSecurity.lpSecurityDescriptor, NULL)) { sql_perror("Can't start server : Initialize security descriptor"); unireg_abort(1); } - if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE)) - { - sql_perror("Can't start server : Set security descriptor"); - unireg_abort(1); - } saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES); - saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor; saPipeSecurity.bInheritHandle = FALSE; if ((hPipe= CreateNamedPipe(pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, @@ -3907,14 +3914,16 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) { THD *thd= current_thd; - if (is_thread_specific) /* If thread specific memory */ - { - /* - When thread specfic is set, both mysqld_server_initialized and thd - must be set - */ - DBUG_ASSERT(mysqld_server_initialized && thd); + /* + When thread specific is set, both mysqld_server_initialized and thd + must be set, and we check that with DBUG_ASSERT. + However, do not crash, if current_thd is NULL, in release version. + */ + DBUG_ASSERT(!is_thread_specific || (mysqld_server_initialized && thd)); + + if (is_thread_specific && likely(thd)) /* If thread specific memory */ + { DBUG_PRINT("info", ("thd memory_used: %lld size: %lld", (longlong) thd->status_var.local_memory_used, size)); @@ -4000,6 +4009,39 @@ static int init_early_variables() return 0; } +#ifdef _WIN32 +static void get_win_tzname(char* buf, size_t size) +{ + static struct + { + const wchar_t* windows_name; + const char* tzdb_name; + } + tz_data[] = + { +#include "win_tzname_data.h" + {0,0} + }; + DYNAMIC_TIME_ZONE_INFORMATION tzinfo; + if (GetDynamicTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_UNKNOWN) + { + strncpy(buf, "unknown", size); + return; + } + + for (size_t i= 0; tz_data[i].windows_name; i++) + { + if (wcscmp(tzinfo.TimeZoneKeyName, tz_data[i].windows_name) == 0) + { + strncpy(buf, tz_data[i].tzdb_name, size); + return; + } + } + wcstombs(buf, tzinfo.TimeZoneKeyName, size); + buf[size-1]= 0; + return; +} +#endif static int init_common_variables() { @@ -4044,23 +4086,13 @@ static int init_common_variables() if (ignore_db_dirs_init()) return 1; - -#ifdef HAVE_TZNAME +#ifdef _WIN32 + get_win_tzname(system_time_zone, sizeof(system_time_zone)); +#elif defined(HAVE_TZNAME) struct tm tm_tmp; localtime_r(&server_start_time,&tm_tmp); const char *tz_name= tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]; -#ifdef _WIN32 - /* - Time zone name may be localized and contain non-ASCII characters, - Convert from ANSI encoding to UTF8. - */ - wchar_t wtz_name[sizeof(system_time_zone)]; - mbstowcs(wtz_name, tz_name, sizeof(system_time_zone)-1); - WideCharToMultiByte(CP_UTF8,0, wtz_name, -1, system_time_zone, - sizeof(system_time_zone) - 1, NULL, NULL); -#else strmake_buf(system_time_zone, tz_name); -#endif /* _WIN32 */ #endif /* HAVE_TZNAME */ /* @@ -4287,11 +4319,25 @@ static int init_common_variables() /* connections and databases needs lots of files */ { - uint files, wanted_files, max_open_files; + uint files, wanted_files, max_open_files, min_tc_size, extra_files, + min_connections; + ulong org_max_connections, org_tc_size; + /* Number of files reserved for temporary files */ + extra_files= 30; + min_connections= 10; /* MyISAM requires two file handles per table. */ - wanted_files= (10 + max_connections + extra_max_connections + + wanted_files= (extra_files + max_connections + extra_max_connections + tc_size * 2); +#if defined(HAVE_POOL_OF_THREADS) && !defined(__WIN__) + // add epoll or kevent fd for each threadpool group, in case pool of threads is used + wanted_files+= (thread_handling > SCHEDULER_NO_THREADS) ? 0 : threadpool_size; +#endif + + min_tc_size= MY_MIN(tc_size, TABLE_OPEN_CACHE_MIN); + org_max_connections= max_connections; + org_tc_size= tc_size; + /* We are trying to allocate no less than max_connections*5 file handles (i.e. we are trying to set the limit so that they will @@ -4303,41 +4349,52 @@ static int init_common_variables() requested (value of wanted_files). */ max_open_files= MY_MAX(MY_MAX(wanted_files, - (max_connections + extra_max_connections)*5), - open_files_limit); + (max_connections + extra_max_connections)*5), + open_files_limit); files= my_set_max_open_files(max_open_files); + SYSVAR_AUTOSIZE_IF_CHANGED(open_files_limit, files, ulong); - if (files < wanted_files) - { - if (!open_files_limit) - { - /* - If we have requested too much file handles than we bring - max_connections in supported bounds. - */ - SYSVAR_AUTOSIZE(max_connections, - (ulong) MY_MIN(files-10-TABLE_OPEN_CACHE_MIN*2, max_connections)); - /* - Decrease tc_size according to max_connections, but - not below TABLE_OPEN_CACHE_MIN. Outer MY_MIN() ensures that we - never increase tc_size automatically (that could - happen if max_connections is decreased above). - */ - SYSVAR_AUTOSIZE(tc_size, - (ulong) MY_MIN(MY_MAX((files - 10 - max_connections) / 2, - TABLE_OPEN_CACHE_MIN), tc_size)); - DBUG_PRINT("warning", - ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", - files, max_connections, tc_size)); - if (global_system_variables.log_warnings > 1) - sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", - files, max_connections, tc_size); - } - else if (global_system_variables.log_warnings) - sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); - } - SYSVAR_AUTOSIZE(open_files_limit, files); + if (files < wanted_files && global_system_variables.log_warnings) + sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + + /* + If we have requested too much file handles than we bring + max_connections in supported bounds. Still leave at least + 'min_connections' connections + */ + SYSVAR_AUTOSIZE_IF_CHANGED(max_connections, + (ulong) MY_MAX(MY_MIN(files- extra_files- + min_tc_size*2, + max_connections), + min_connections), + ulong); + + /* + Decrease tc_size according to max_connections, but + not below min_tc_size. Outer MY_MIN() ensures that we + never increase tc_size automatically (that could + happen if max_connections is decreased above). + */ + SYSVAR_AUTOSIZE_IF_CHANGED(tc_size, + (ulong) MY_MIN(MY_MAX((files - extra_files - + max_connections) / 2, + min_tc_size), + tc_size), ulong); + DBUG_PRINT("warning", + ("Current limits: max_open_files: %u max_connections: %ld table_cache: %ld", + files, max_connections, tc_size)); + if (global_system_variables.log_warnings > 1 && + (max_connections < org_max_connections || + tc_size < org_tc_size)) + sql_print_warning("Changed limits: max_open_files: %u max_connections: %lu (was %lu) table_cache: %lu (was %lu)", + files, max_connections, org_max_connections, + tc_size, org_tc_size); } + /* + Max_connections and tc_cache are now set. + Now we can fix other variables depending on this variable. + */ + unireg_init(opt_specialflag); /* Set up extern variabels */ if (!(my_default_lc_messages= my_locale_by_name(lc_messages))) @@ -4529,6 +4586,20 @@ static int init_common_variables() return 1; } +#ifdef WITH_WSREP + /* + We need to initialize auxiliary variables, that will be + further keep the original values of auto-increment options + as they set by the user. These variables used to restore + user-defined values of the auto-increment options after + setting of the wsrep_auto_increment_control to 'OFF'. + */ + global_system_variables.saved_auto_increment_increment= + global_system_variables.auto_increment_increment; + global_system_variables.saved_auto_increment_offset= + global_system_variables.auto_increment_offset; +#endif /* WITH_WSREP */ + return 0; } @@ -5485,6 +5556,11 @@ int win_main(int argc, char **argv) int mysqld_main(int argc, char **argv) #endif { +#ifndef _WIN32 + /* We can't close stdin just now, because it may be booststrap mode. */ + bool please_close_stdin= fcntl(STDIN_FILENO, F_GETFD) >= 0; +#endif + /* Perform basic thread library and malloc initialization, to be able to read defaults files and parse options. @@ -5511,8 +5587,7 @@ int mysqld_main(int argc, char **argv) orig_argc= argc; orig_argv= argv; my_getopt_use_args_separator= TRUE; - if (load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv)) - return 1; + load_defaults_or_exit(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv); my_getopt_use_args_separator= FALSE; defaults_argc= argc; defaults_argv= argv; @@ -5871,12 +5946,14 @@ int mysqld_main(int argc, char **argv) mysqld_port, MYSQL_COMPILATION_COMMENT); +#ifndef _WIN32 // try to keep fd=0 busy - if (!freopen(IF_WIN("NUL","/dev/null"), "r", stdin)) + if (please_close_stdin && !freopen("/dev/null", "r", stdin)) { // fall back on failure fclose(stdin); } +#endif #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) Service.SetRunning(); @@ -6461,7 +6538,7 @@ void handle_connections_sockets() #endif sd_notify(0, "READY=1\n" - "STATUS=Taking your SQL requests now..."); + "STATUS=Taking your SQL requests now...\n"); DBUG_PRINT("general",("Waiting for connections.")); MAYBE_BROKEN_SYSCALL; @@ -6679,7 +6756,7 @@ void handle_connections_sockets() set_current_thd(0); } sd_notify(0, "STOPPING=1\n" - "STATUS=Shutdown in progress"); + "STATUS=Shutdown in progress\n"); DBUG_VOID_RETURN; } @@ -6785,6 +6862,7 @@ pthread_handler_t handle_connections_namedpipes(void *arg) create_new_thread(thd); set_current_thd(0); } + LocalFree(saPipeSecurity.lpSecurityDescriptor); CloseHandle(connectOverlapped.hEvent); DBUG_LEAVE; decrement_handler_count(); @@ -8573,8 +8651,8 @@ static void usage(void) "\nbecause execution stopped before plugins were initialized."); } - puts("\nTo see what values a running MySQL server is using, type" - "\n'mysqladmin variables' instead of 'mysqld --verbose --help'."); + puts("\nTo see what variables a running MySQL server is using, type" + "\n'mysqladmin variables' instead of 'mysqld --verbose --help'."); } DBUG_VOID_RETURN; } @@ -8975,7 +9053,8 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument) val= p--; while (my_isspace(mysqld_charset, *p) && p > argument) *p-- = 0; - if (p == argument) + /* Db name can be one char also */ + if (p == argument && my_isspace(mysqld_charset, *p)) { sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n"); return 1; @@ -9439,7 +9518,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr) else global_system_variables.option_bits&= ~OPTION_BIG_SELECTS; - if (!opt_bootstrap && WSREP_PROVIDER_EXISTS && + if (!opt_bootstrap && WSREP_PROVIDER_EXISTS && WSREP_ON && global_system_variables.binlog_format != BINLOG_FORMAT_ROW) { |