summaryrefslogtreecommitdiff
path: root/sql/mysqld.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/mysqld.cc')
-rw-r--r--sql/mysqld.cc241
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)
{