From f272463b028d3c377acf02b4818ba8d607f71d1c Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 25 Apr 2023 21:16:43 +0300 Subject: [PATCH 1/3] Cleanup of MDEV-14974: --port ignored for --host=localhost The old code added to 10.6 was inconsisting in how TCP/IP and socket connection was chosen. One got also a confusing warning in some cases. Examples: > ../client/mysql --print-defaults ../client/mysql would have been started with the following arguments: --socket=/tmp/mariadbd.sock --port=3307 --no-auto-rehash > ../client/mysql ERROR 2002 (HY000): Can't connect to local server through socket '/tmp/mariadbd.sock' (2) > ../client/mysql --print-defaults ../client/mysql would have been started with the following arguments: --socket=/tmp/mariadbd.sock --port=3307 --no-auto-rehash > ../client/mysql --port=3333 WARNING: Forcing protocol to TCP due to option specification. Please explicitly state intended protocol. ERROR 2002 (HY000): Can't connect to server on 'localhost' (111) > ../client/mysql --port=3333 --socket=sss ERROR 2002 (HY000): Can't connect to local server through socket 'sss' (2) > ../client/mysql --socket=sss --port=3333 ERROR 2002 (HY000): Can't connect to local server through socket 'sss' (2) Some notable things: - One gets a warning if one uses just --port if config file sets socket - Using port and socket gives no warning - Using socket and then port still uses socket This patch changes things the following ways: If --port= is given on the command line, the the protocol is automatically changed to "TCP/IP". - If --socket= is given on the command line, the protocol is automatically changed to "socket". - The last option wins - No warning is given if protocol changes automatically. --- client/client_priv.h | 48 ------------- client/mysql.cc | 64 +++-------------- client/mysqladmin.cc | 61 +++------------- client/mysqlbinlog.cc | 53 +++----------- client/mysqlcheck.c | 59 ++------------- client/mysqldump.c | 72 ++++--------------- client/mysqlimport.c | 58 ++------------- client/mysqlshow.c | 59 ++------------- client/mysqlslap.c | 57 ++------------- .../cli_options_force_protocol_not_win.result | 24 +++---- .../cli_options_force_protocol_not_win.test | 34 +++++---- .../cli_options_force_protocol_win.result | 25 +++---- .../main/cli_options_force_protocol_win.test | 38 ++++------ 13 files changed, 113 insertions(+), 539 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 56e81ebb94f..3856859f89d 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -148,51 +148,3 @@ enum options_client #else #define SOCKET_PROTOCOL_TO_FORCE MYSQL_PROTOCOL_PIPE #endif - -/** - Utility function to implicitly change the connection protocol to a - consistent value given the command line arguments. Additionally, - warns the user that the protocol has been changed. - - Arguments: - @param [in] host Name of the host to connect to - @param [in, out] opt_protocol Location of the protocol option - variable to update - @param [in] new_protocol New protocol to force -*/ -static inline void warn_protocol_override(char *host, - uint *opt_protocol, - uint new_protocol) -{ - DBUG_ASSERT(new_protocol == MYSQL_PROTOCOL_TCP - || new_protocol == SOCKET_PROTOCOL_TO_FORCE); - - - if ((host == NULL - || strncmp(host, LOCAL_HOST, sizeof(LOCAL_HOST)-1) == 0)) - { - const char *protocol_name; - - if (*opt_protocol == MYSQL_PROTOCOL_DEFAULT -#ifndef _WIN32 - && new_protocol == MYSQL_PROTOCOL_SOCKET -#else - && new_protocol == MYSQL_PROTOCOL_TCP -#endif - ) - { - /* This is already the default behavior, do nothing */ - return; - } - - protocol_name= sql_protocol_typelib.type_names[new_protocol-1]; - - fprintf(stderr, "%s %s %s\n", - "WARNING: Forcing protocol to ", - protocol_name, - " due to option specification. " - "Please explicitly state intended protocol."); - - *opt_protocol = new_protocol; - } -} diff --git a/client/mysql.cc b/client/mysql.cc index 889b67cfa4d..bf3091ed262 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -210,8 +210,6 @@ static uint opt_protocol=0; static const char *opt_protocol_type= ""; static CHARSET_INFO *charset_info= &my_charset_latin1; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - #include "sslopt-vars.h" const char *default_dbug_option="d:t:o,/tmp/mariadb.trace"; @@ -1180,14 +1178,6 @@ int main(int argc,char *argv[]) exit(status.exit_status); } - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(current_host, &opt_protocol, protocol_to_force); - } - - if (status.batch && !status.line_buff && !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) { @@ -1737,11 +1727,9 @@ static void usage(int version) my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *filename) +get_one_option(const struct my_option *opt, const char *argument, + const char *filename) { - /* Track when protocol is set via CLI to not force port TCP protocol override */ - static my_bool ignore_protocol_override = FALSE; - switch(opt->id) { case OPT_CHARSETS_DIR: strmake_buf(mysql_charsets_dir, argument); @@ -1802,18 +1790,11 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi #ifndef EMBEDDED_LIBRARY if (!argument[0]) opt_protocol= 0; - else if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib, + else if ((opt_protocol= + find_type_with_warning(argument, &sql_protocol_typelib, opt->name)) <= 0) exit(1); #endif - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case OPT_SERVER_ARG: #ifdef EMBEDDED_LIBRARY @@ -1913,13 +1894,6 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi #ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; opt_protocol_type= "pipe"; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; #include @@ -1932,35 +1906,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi mysql_end(-1); break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; case 'I': diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 38c1caf654a..e11dd4f91be 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -54,8 +54,6 @@ static bool sql_log_bin_off= false; static uint opt_protocol=0; static myf error_flags; /* flags to pass to my_printf_error, like ME_BELL */ -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - /* When using extended-status relatively, ex_val_max_len is the estimated maximum length for any relative value printed by extended-status. The @@ -243,12 +241,9 @@ static const char *load_default_groups[]= 0 }; my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *filename) +get_one_option(const struct my_option *opt, const char *argument, + const char *filename) { - - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - switch(opt->id) { case 'c': opt_count_iterations= 1; @@ -280,13 +275,6 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi case 'W': #ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; case '#': @@ -322,45 +310,19 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; } @@ -388,13 +350,6 @@ int main(int argc,char *argv[]) temp_argv= mask_password(argc, &argv); temp_argc= argc; - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(host, &opt_protocol, protocol_to_force); - } - if (debug_info_flag) my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; if (debug_check_flag) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 460ab22c3c9..d644a9bda49 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -98,8 +98,6 @@ static const char *output_prefix= ""; static char **defaults_argv= 0; static MEM_ROOT glob_root; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - #ifndef DBUG_OFF static const char *default_dbug_option = "d:t:o,/tmp/mariadb-binlog.trace"; const char *current_dbug_option= default_dbug_option; @@ -1898,13 +1896,11 @@ static my_time_t convert_str_to_timestamp(const char* str) extern "C" my_bool -get_one_option(const struct my_option *opt, const char *argument, const char *filename) +get_one_option(const struct my_option *opt, const char *argument, + const char *filename) { bool tty_password=0; - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - switch (opt->id) { #ifndef DBUG_OFF case '#': @@ -1954,14 +1950,6 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi sf_leaking_memory= 1; /* no memory leak reports here */ die(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; #ifdef WHEN_FLASHBACK_REVIEW_READY case opt_flashback_review: @@ -2039,35 +2027,17 @@ get_one_option(const struct my_option *opt, const char *argument, const char *fi print_row_event_positions_used= 1; break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; case 'v': @@ -3043,13 +3013,6 @@ int main(int argc, char** argv) parse_args(&argc, (char***)&argv); - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(host, &opt_protocol, protocol_to_force); - } - if (!argc || opt_version) { if (!opt_version) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index c37e258f186..c6f384ac185 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -57,8 +57,6 @@ DYNAMIC_ARRAY tables4repair, tables4rebuild, alter_table_cmds; DYNAMIC_ARRAY views4repair; static uint opt_protocol=0; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_FIX_NAMES }; const char *operation_name[]= { @@ -291,10 +289,6 @@ get_one_option(const struct my_option *opt, const char *filename) { int orig_what_to_do= what_to_do; - - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - DBUG_ENTER("get_one_option"); switch(opt->id) { @@ -357,13 +351,6 @@ get_one_option(const struct my_option *opt, case 'W': #ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; case '#': @@ -387,45 +374,19 @@ get_one_option(const struct my_option *opt, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; } @@ -1248,14 +1209,6 @@ int main(int argc, char **argv) if (get_options(&argc, &argv)) goto end1; - - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(current_host, &opt_protocol, protocol_to_force); - } - sf_leaking_memory=0; /* from now on we cleanup properly */ ret= EX_MYSQLERR; diff --git a/client/mysqldump.c b/client/mysqldump.c index 9c973b9b8cb..50ace857b9e 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -194,12 +194,10 @@ FILE *stderror_file=0; static uint opt_protocol= 0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - /* -Dynamic_string wrapper functions. In this file use these -wrappers, they will terminate the process if there is -an allocation failure. + Dynamic_string wrapper functions. In this file use these + wrappers, they will terminate the process if there is + an allocation failure. */ static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, size_t init_alloc, size_t alloc_increment); @@ -871,9 +869,6 @@ get_one_option(const struct my_option *opt, const char *filename) { - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - switch (opt->id) { case 'p': if (argument == disabled_my_option) @@ -904,13 +899,6 @@ get_one_option(const struct my_option *opt, case 'W': #ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; case 'N': @@ -1061,49 +1049,23 @@ get_one_option(const struct my_option *opt, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case (int) OPT_DEFAULT_CHARSET: if (default_charset == disabled_my_option) default_charset= (char *)mysql_universal_client_charset; break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; } @@ -1152,19 +1114,9 @@ static int get_options(int *argc, char ***argv) return(ho_error); /* - Command line options override configured protocol - */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(current_host, &opt_protocol, protocol_to_force); - } - - - /* - Dumping under --system=stats with --replace or --insert-ignore is safe and will not - result into race condition. Otherwise dump only structure and ignore data by default - while dumping. + Dumping under --system=stats with --replace or --insert-ignore is + safe and will not result into race condition. Otherwise dump only + structure and ignore data by default while dumping. */ if (!(opt_system & OPT_SYSTEM_STATS) && !(opt_ignore || opt_replace_into)) { diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 185cf69b9b6..8628b32dd53 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -64,8 +64,6 @@ static char * opt_mysql_unix_port=0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; static longlong opt_ignore_lines= -1; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - #include static char **argv_to_free; @@ -227,9 +225,6 @@ static my_bool get_one_option(const struct my_option *opt, const char *argument, const char *filename) { - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - switch(opt->id) { case 'p': if (argument == disabled_my_option) @@ -256,14 +251,6 @@ get_one_option(const struct my_option *opt, const char *argument, case 'W': opt_protocol = MYSQL_PROTOCOL_PIPE; opt_local_file=1; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; #endif case OPT_MYSQL_PROTOCOL: @@ -273,45 +260,19 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; case '#': @@ -709,13 +670,6 @@ int main(int argc, char **argv) return(1); } - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(current_host, &opt_protocol, protocol_to_force); - } - sf_leaking_memory=0; /* from now on we cleanup properly */ if (opt_use_threads && !lock_tables) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 23bafa3ccea..824686173ec 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -41,8 +41,6 @@ static char *opt_plugin_dir= 0, *opt_default_auth= 0; static uint opt_protocol=0; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - static void get_options(int *argc,char ***argv); static uint opt_mysql_port=0; static int list_dbs(MYSQL *mysql,const char *wild); @@ -81,14 +79,6 @@ int main(int argc, char **argv) get_options(&argc,&argv); - - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(host, &opt_protocol, protocol_to_force); - } - sf_leaking_memory=0; /* from now on we cleanup properly */ wild=0; if (argc) @@ -307,9 +297,6 @@ get_one_option(const struct my_option *opt, const char *argument, const char *filename) { - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - switch(opt->id) { case 'v': opt_verbose++; @@ -338,13 +325,6 @@ get_one_option(const struct my_option *opt, const char *argument, case 'W': #ifdef _WIN32 opt_protocol = MYSQL_PROTOCOL_PIPE; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; case OPT_MYSQL_PROTOCOL: @@ -354,47 +334,22 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; + break; case '#': DBUG_PUSH(argument ? argument : "d:t:o"); debug_check_flag= 1; diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 27a80a115fd..79e5fe1f8bc 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -172,8 +172,6 @@ File csv_file; static uint opt_protocol= 0; -static uint protocol_to_force= MYSQL_PROTOCOL_DEFAULT; - static int get_options(int *argc,char ***argv); static uint opt_mysql_port= 0; @@ -335,13 +333,6 @@ int main(int argc, char **argv) exit(1); } - /* Command line options override configured protocol */ - if (protocol_to_force > MYSQL_PROTOCOL_DEFAULT - && protocol_to_force != opt_protocol) - { - warn_protocol_override(host, &opt_protocol, protocol_to_force); - } - sf_leaking_memory=0; /* from now on we cleanup properly */ /* Seed the random number generator if we will be using it. */ @@ -744,9 +735,6 @@ static my_bool get_one_option(const struct my_option *opt, const char *argument, const char *filename) { - /* Track when protocol is set via CLI to not force overrides */ - static my_bool ignore_protocol_override = FALSE; - DBUG_ENTER("get_one_option"); switch(opt->id) { case 'v': @@ -776,13 +764,6 @@ get_one_option(const struct my_option *opt, const char *argument, case 'W': #ifdef _WIN32 opt_protocol= MYSQL_PROTOCOL_PIPE; - - /* Prioritize pipe if explicit via command line */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } #endif break; case OPT_MYSQL_PROTOCOL: @@ -792,45 +773,19 @@ get_one_option(const struct my_option *opt, const char *argument, sf_leaking_memory= 1; /* no memory leak reports here */ exit(1); } - - /* Specification of protocol via CLI trumps implicit overrides */ - if (filename[0] == '\0') - { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - break; case 'P': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == SOCKET_PROTOCOL_TO_FORCE) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* If port is set via CLI, try to force protocol to TCP */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = MYSQL_PROTOCOL_TCP; + /* Port given on command line, switch protocol to use TCP */ + opt_protocol= MYSQL_PROTOCOL_TCP; } break; case 'S': - /* If port and socket are set, fall back to default behavior */ - if (protocol_to_force == MYSQL_PROTOCOL_TCP) + if (filename[0] == '\0') { - ignore_protocol_override = TRUE; - protocol_to_force = MYSQL_PROTOCOL_DEFAULT; - } - - /* Prioritize socket if set via command line */ - if (filename[0] == '\0' && - !ignore_protocol_override && - protocol_to_force == MYSQL_PROTOCOL_DEFAULT) - { - protocol_to_force = SOCKET_PROTOCOL_TO_FORCE; + /* Socket given on command line, switch protocol to use SOCKETSt */ + opt_protocol= MYSQL_PROTOCOL_SOCKET; } break; case '#': diff --git a/mysql-test/main/cli_options_force_protocol_not_win.result b/mysql-test/main/cli_options_force_protocol_not_win.result index 20b12eb2cc0..46ee29dc509 100644 --- a/mysql-test/main/cli_options_force_protocol_not_win.result +++ b/mysql-test/main/cli_options_force_protocol_not_win.result @@ -4,21 +4,19 @@ # # The following group of tests should produce no warnings # -# exec MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:\|WARNING:" +# exec MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:" Connection: Localhost via UNIX socket -# exec MYSQL --port=MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:\|WARNING:" +# exec MYSQL --port=MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:" Connection: localhost via TCP/IP -# exec MYSQL --host=localhost --port=MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:\|WARNING:" +# exec MYSQL --host=localhost --port=MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:" Connection: Localhost via UNIX socket -# exec MYSQL --host=127.0.0.1 --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" +# exec MYSQL --host=127.0.0.1 --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" Connection: 127.0.0.1 via TCP/IP -# exec MYSQL --host=localhost --socket=MASTER_MYSOCK --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" -Connection: Localhost via UNIX socket -# exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:\|WARNING:" -Connection: Localhost via UNIX socket -# -# The remaining tests should produce warnings -# -# exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" -WARNING: Forcing protocol to TCP due to option specification. Please explicitly state intended protocol. +# exec MYSQL --host=localhost --socket=MASTER_MYSOCK --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" +Connection: localhost via TCP/IP +# exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" +Connection: Localhost via UNIX socket +# exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" +Connection: Localhost via UNIX socket +# exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" Connection: localhost via TCP/IP diff --git a/mysql-test/main/cli_options_force_protocol_not_win.test b/mysql-test/main/cli_options_force_protocol_not_win.test index a3c495f26ee..a92f6b93c4d 100644 --- a/mysql-test/main/cli_options_force_protocol_not_win.test +++ b/mysql-test/main/cli_options_force_protocol_not_win.test @@ -10,28 +10,26 @@ --echo # The following group of tests should produce no warnings --echo # ---echo # exec MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost -e "status" 2>&1 | grep "Connection:" ---echo # exec MYSQL --port=MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --port=$MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --port=MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --port=$MASTER_MYPORT --protocol=tcp -e "status" 2>&1 | grep "Connection:" ---echo # exec MYSQL --host=localhost --port=MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=localhost --port=$MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=localhost --port=MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost --port=$MASTER_MYPORT --protocol=socket -e "status" 2>&1 | grep "Connection:" ---echo # exec MYSQL --host=127.0.0.1 --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=127.0.0.1 --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=127.0.0.1 --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=127.0.0.1 --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" ---echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" ---echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost --port=MASTER_MYPORT --socket=$MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" +--echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | grep "Connection:" ---echo # ---echo # The remaining tests should produce warnings ---echo # - ---echo # exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" ---exec $MYSQL --host=localhost --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:\|WARNING:" +--echo # exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" +--exec $MYSQL --host=localhost --port=$MASTER_MYPORT -e "status" 2>&1 | grep "Connection:" diff --git a/mysql-test/main/cli_options_force_protocol_win.result b/mysql-test/main/cli_options_force_protocol_win.result index 4fffc2a4837..eedfde4f1de 100644 --- a/mysql-test/main/cli_options_force_protocol_win.result +++ b/mysql-test/main/cli_options_force_protocol_win.result @@ -1,24 +1,17 @@ # # MDEV-14974: --port ignored for --host=localhost # -# -# The following group of tests should produce no warnings -# -# exec MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +# exec MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" Connection: localhost via TCP/IP -# exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +# exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" Connection: localhost via TCP/IP -# exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +# exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" Connection: localhost via TCP/IP -# exec MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +# exec MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" Connection: localhost via named pipe -# exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" -Connection: localhost via named pipe -# exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" -Connection: localhost via named pipe -# -# The remaining tests should produce warnings -# -# exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" -WARNING: Forcing protocol to PIPE due to option specification. Please explicitly state intended protocol. +# exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" Connection: localhost via named pipe +# exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" +Connection: localhost via TCP/IP +# exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" +Connection: localhost via TCP/IP diff --git a/mysql-test/main/cli_options_force_protocol_win.test b/mysql-test/main/cli_options_force_protocol_win.test index 54fbb78e5dc..63024f3b620 100644 --- a/mysql-test/main/cli_options_force_protocol_win.test +++ b/mysql-test/main/cli_options_force_protocol_win.test @@ -5,33 +5,23 @@ --source include/not_embedded.inc --source include/windows.inc +--echo # exec MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" ---echo # ---echo # The following group of tests should produce no warnings ---echo # +--echo # exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost --port=$MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" ---echo # exec MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +--echo # exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" ---echo # exec MYSQL --host=localhost --port=MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost --port=$MASTER_MYPORT -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +--echo # exec MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" ---echo # exec MYSQL --host=localhost --port=MASTER_MYPORT --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +--echo # exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" ---echo # exec MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost --protocol=pipe -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +--echo # exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost -W --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" ---echo # exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" - ---echo # exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost -W --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" - - ---echo # ---echo # The remaining tests should produce warnings ---echo # - ---echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" ---exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" /c:"WARNING:" +--echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" +--exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" From 4a668c18926eca055a45b4153467bc6a5c50ff19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 27 Apr 2023 17:11:32 +0300 Subject: [PATCH 2/3] MDEV-29401 InnoDB history list length increased in 10.6 compared to 10.5 The InnoDB buffer pool and locking were heavily refactored in MariaDB Server 10.6. Among other things, dict_sys.mutex was removed, and the contended lock_sys.mutex was replaced with a combination of lock_sys.latch and distributed latches in hash tables. Also, a default value was changed to innodb_flush_method=O_DIRECT to improve performance in write-heavy workloads. One thing where an adjustment was missing is around the parameters innodb_max_purge_lag (number of committed transactions waiting to be purged), and innodb_max_purge_lag_delay (maximum number of microseconds to delay a DML operation). purge_coordinator_state::do_purge(): Pass the history_size to trx_purge() and reset srv_dml_needed_delay if the history is empty. Keep executing the loop non-stop as long as srv_dml_needed_delay is set. trx_purge_dml_delay(): Made part of trx_purge(). Set srv_dml_needed_delay=0 when nothing can be purged (!n_pages_handled). row_mysql_delay_if_needed(): Mimic the logic of innodb_max_purge_lag_wait_update(). Reviewed by: Thirunarayanan Balathandayuthapani --- storage/innobase/include/trx0purge.h | 7 +-- storage/innobase/row/row0mysql.cc | 26 ++++++----- storage/innobase/srv/srv0mon.cc | 6 ++- storage/innobase/srv/srv0srv.cc | 27 +++++++----- storage/innobase/trx/trx0purge.cc | 65 ++++++++++------------------ 5 files changed, 64 insertions(+), 67 deletions(-) diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index ac39d3ec45b..bf6f6eb8eff 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -41,10 +41,11 @@ void trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr); /** Run a purge batch. -@param n_tasks number of purge tasks to submit to the queue -@param truncate whether to truncate the history at the end of the batch +@param n_tasks number of purge tasks to submit to the queue +@param history_size trx_sys.history_size() +@param truncate whether to truncate the history at the end of the batch @return number of undo log pages handled in the batch */ -ulint trx_purge(ulint n_tasks, bool truncate); +ulint trx_purge(ulint n_tasks, ulint history_size, bool truncate); /** Rollback segements from a given transaction with trx-no scheduled for purge. */ diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index d27fc964219..98b76c34ff5 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -67,17 +67,23 @@ Created 9/17/2000 Heikki Tuuri #include -/*******************************************************************//** -Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */ -static -void -row_mysql_delay_if_needed(void) -/*===========================*/ +/** Delay an INSERT, DELETE or UPDATE operation if the purge is lagging. */ +static void row_mysql_delay_if_needed() { - if (srv_dml_needed_delay) { - std::this_thread::sleep_for( - std::chrono::microseconds(srv_dml_needed_delay)); - } + const auto delay= srv_dml_needed_delay; + if (UNIV_UNLIKELY(delay != 0)) + { + /* Adjust for purge_coordinator_state::refresh() */ + mysql_mutex_lock(&log_sys.mutex); + const lsn_t last= log_sys.last_checkpoint_lsn, + max_age= log_sys.max_checkpoint_age; + mysql_mutex_unlock(&log_sys.mutex); + const lsn_t lsn= log_sys.get_lsn(); + if ((lsn - last) / 4 >= max_age / 5) + buf_flush_ahead(last + max_age / 5, false); + srv_wake_purge_thread_if_not_active(); + std::this_thread::sleep_for(std::chrono::microseconds(delay)); + } } /*******************************************************************//** diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 2a3720641bc..971f4f330c8 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -752,7 +752,8 @@ static monitor_info_t innodb_counter_info[] = {"purge_dml_delay_usec", "purge", "Microseconds DML to be delayed due to purge lagging", - MONITOR_DISPLAY_CURRENT, + static_cast( + MONITOR_EXISTING | MONITOR_DISPLAY_CURRENT), MONITOR_DEFAULT_START, MONITOR_DML_PURGE_DELAY}, {"purge_stop_count", "purge", @@ -1710,6 +1711,9 @@ srv_mon_process_existing_counter( case MONITOR_RSEG_CUR_SIZE: value = srv_mon_get_rseg_size(); break; + case MONITOR_DML_PURGE_DELAY: + value = srv_max_purge_lag_delay; + break; case MONITOR_NUM_UNDO_SLOT_USED: value = srv_mon_get_rseg_used(); break; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 21faf792d84..f87c748bb67 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1689,27 +1689,32 @@ fewer_threads: m_history_length= history_size; - if (history_size && - trx_purge(n_use_threads, - !(++count % srv_purge_rseg_truncate_frequency) || - purge_sys.truncate.current || - (srv_shutdown_state != SRV_SHUTDOWN_NONE && - srv_fast_shutdown == 0))) + if (!history_size) + srv_dml_needed_delay= 0; + else if (trx_purge(n_use_threads, history_size, + !(++count % srv_purge_rseg_truncate_frequency) || + purge_sys.truncate.current || + (srv_shutdown_state != SRV_SHUTDOWN_NONE && + srv_fast_shutdown == 0))) continue; - if (m_running == sigcount) + if (srv_dml_needed_delay); + else if (m_running == sigcount) { /* Purge was not woken up by srv_wake_purge_thread_if_not_active() */ /* The magic number 5000 is an approximation for the case where we have cached undo log records which prevent truncate of rollback segments. */ - wakeup= history_size && - (history_size >= 5000 || - history_size != trx_sys.history_size_approx()); + wakeup= history_size >= 5000 || + (history_size && history_size != trx_sys.history_size_approx()); break; } - else if (!trx_sys.history_exists()) + + if (!trx_sys.history_exists()) + { + srv_dml_needed_delay= 0; break; + } if (!srv_purge_should_exit()) goto loop; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 7a63b1155b6..b04e71ba871 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -1243,43 +1243,6 @@ trx_purge_attach_undo_recs(ulint n_purge_threads) return(n_pages_handled); } -/*******************************************************************//** -Calculate the DML delay required. -@return delay in microseconds or ULINT_MAX */ -static -ulint -trx_purge_dml_delay(void) -/*=====================*/ -{ - /* Determine how much data manipulation language (DML) statements - need to be delayed in order to reduce the lagging of the purge - thread. */ - ulint delay = 0; /* in microseconds; default: no delay */ - - /* If purge lag is set then calculate the new DML delay. */ - - if (srv_max_purge_lag > 0) { - double ratio = static_cast(trx_sys.history_size()) / - static_cast(srv_max_purge_lag); - - if (ratio > 1.0) { - /* If the history list length exceeds the - srv_max_purge_lag, the data manipulation - statements are delayed by at least 5000 - microseconds. */ - delay = (ulint) ((ratio - .5) * 10000); - } - - if (delay > srv_max_purge_lag_delay) { - delay = srv_max_purge_lag_delay; - } - - MONITOR_SET(MONITOR_DML_PURGE_DELAY, delay); - } - - return(delay); -} - extern tpool::waitable_task purge_worker_task; /** Wait for pending purge jobs to complete. */ @@ -1323,18 +1286,18 @@ TRANSACTIONAL_INLINE void purge_sys_t::clone_end_view() /** Run a purge batch. -@param n_tasks number of purge tasks to submit to the queue -@param truncate whether to truncate the history at the end of the batch +@param n_tasks number of purge tasks to submit to the queue +@param history_size trx_sys.history_size() +@param truncate whether to truncate the history at the end of the batch @return number of undo log pages handled in the batch */ -TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, bool truncate) +TRANSACTIONAL_TARGET +ulint trx_purge(ulint n_tasks, ulint history_size, bool truncate) { que_thr_t* thr = NULL; ulint n_pages_handled; ut_ad(n_tasks > 0); - srv_dml_needed_delay = trx_purge_dml_delay(); - purge_sys.clone_oldest_view(); #ifdef UNIV_DEBUG @@ -1346,6 +1309,24 @@ TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, bool truncate) /* Fetch the UNDO recs that need to be purged. */ n_pages_handled = trx_purge_attach_undo_recs(n_tasks); + { + ulint delay = n_pages_handled ? srv_max_purge_lag : 0; + if (UNIV_UNLIKELY(delay)) { + if (delay >= history_size) { + no_throttle: + delay = 0; + } else if (const ulint max_delay = + srv_max_purge_lag_delay) { + delay = std::min(max_delay, + 10000 * history_size / delay + - 5000); + } else { + goto no_throttle; + } + } + srv_dml_needed_delay = delay; + } + /* Submit tasks to workers queue if using multi-threaded purge. */ for (ulint i = n_tasks; --i; ) { thr = que_fork_scheduler_round_robin(purge_sys.query, thr); From 7d967423fe2fd061c51f43230e0286cf7868c5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 28 Apr 2023 12:15:45 +0300 Subject: [PATCH 3/3] MDEV-31147 json_normalize does not work correctly with MSAN build json_normalize_number(): Avoid accessing str past str_len. The function would seem to work incorrectly when some digits are not followed by a decimal point (.) or an exponent (E or e). --- mysql-test/main/func_json.result | 13 +++++++++++++ mysql-test/main/func_json.test | 13 +++++++++++++ strings/json_normalize.c | 17 ++++++++++------- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 7d60801abec..73cc64d95aa 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -1673,3 +1673,16 @@ DROP TABLE t; # # End of 10.6 tests # +# +# MDEV-31147 json_normalize does not work correctly with MSAN build +# +CREATE TABLE t1 (val JSON); +ALTER TABLE t1 ADD COLUMN normalized_json JSON AS (JSON_NORMALIZE(val)); +INSERT INTO t1 (val) VALUES ('15'); +SELECT * FROM t1; +val normalized_json +15 1.5E1 +DROP TABLE t1; +# +# End of 10.8 tests +# diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 9f6c51cbc27..1f61f9abd13 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1112,3 +1112,16 @@ DROP TABLE t; --echo # --echo # End of 10.6 tests --echo # + +--echo # +--echo # MDEV-31147 json_normalize does not work correctly with MSAN build +--echo # +CREATE TABLE t1 (val JSON); +ALTER TABLE t1 ADD COLUMN normalized_json JSON AS (JSON_NORMALIZE(val)); +INSERT INTO t1 (val) VALUES ('15'); +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.8 tests +--echo # diff --git a/strings/json_normalize.c b/strings/json_normalize.c index 0b7f172dae6..2c66c712e81 100644 --- a/strings/json_normalize.c +++ b/strings/json_normalize.c @@ -147,13 +147,16 @@ json_normalize_number(DYNAMIC_STRING *out, const char *str, size_t str_len) magnitude = (long)(j - 1); - /* skip the . */ - if (str[i] == '.') - ++i; + if (i < str_len) + { + /* skip the . */ + if (str[i] == '.') + ++i; - /* grab rest of digits before the E */ - for (; i < str_len && str[i] != 'e' && str[i] != 'E'; ++i) - buf[j++] = str[i]; + /* grab rest of digits before the E */ + for (; i < str_len && str[i] != 'e' && str[i] != 'E'; ++i) + buf[j++] = str[i]; + } /* trim trailing zeros */ for (k = j - 1; k && buf[k] == '0'; --k, --j) @@ -187,7 +190,7 @@ json_normalize_number(DYNAMIC_STRING *out, const char *str, size_t str_len) err|= dynstr_append_mem(out, STRING_WITH_LEN("E")); - if (str[i] == 'e' || str[i] == 'E') + if (i < str_len && (str[i] == 'e' || str[i] == 'E')) { char *endptr = NULL; /* skip the [eE] */