From bf74f7f9ff40f8a17e739e9ab6f5c906ccb9e892 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Mon, 15 Jun 2020 15:57:01 +0530 Subject: MDEV-20428: "Start binlog_dump" message doesn't indicate GTID position Problem: ======= The "Start binlog_dump" message hasn't been updated to include the slave's requested GTID position: 20:05:05 139836760311552 [Note] Start binlog_dump to slave_server(2), pos(, 4) For diagnostic purposes, it would be helpful if the GTID position were included. Fix: === Imporve "Start binlog_dump" print message to include "using_gtid" and "GTID position" requested by slave. Ex: [Note] Start binlog_dump to slave_server(2), pos(, 4), using_gtid(1), gtid('1-1-201,2-2-100') [Note] Start binlog_dump to slave_server(3), pos('mariadb-bin.004142', 507988273), using_gtid(0), gtid('') --- sql/sql_repl.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 851bff5fd24..38c2b9b5b8e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2027,9 +2027,13 @@ static int init_binlog_sender(binlog_send_info *info, }); if (global_system_variables.log_warnings > 1) + { sql_print_information( - "Start binlog_dump to slave_server(%lu), pos(%s, %lu)", - thd->variables.server_id, log_ident, (ulong)*pos); + "Start binlog_dump to slave_server(%lu), pos(%s, %lu), " + "using_gtid(%d), gtid('%s')", thd->variables.server_id, + log_ident, (ulong)*pos, info->using_gtid_state, + connect_gtid_state.c_ptr_quick()); + } #ifndef DBUG_OFF if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2)) -- cgit v1.2.1 From 26907e7ef18964dad7b6b1fc19c7d1e65e915020 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 19 Jun 2020 16:04:45 +0400 Subject: MDEV-22941 Assertion `idx < array.elements' failed in Dynamic_array::at The code in fill_schema_schemata() did not take into account that make_db_list() can leave empty db_names if the requested database name was too long, so the call for db_names.at(0) crashed on assert. - Moving the code testing if the database directory exists into a separate function verify_database_directory_exists() - Modifying the test to check if db_names is not empty --- sql/sql_show.cc | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4f217159e5c..70cab968f43 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4953,6 +4953,29 @@ bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name, } +/* + Check if the specified database exists on disk. + + @param dbname - the database name + @retval true - on error, the database directory does not exists + @retval false - on success, the database directory exists +*/ +static bool verify_database_directory_exists(const LEX_STRING &dbname) +{ + DBUG_ENTER("verity_database_exists"); + char path[FN_REFLEN + 16]; + uint path_len; + MY_STAT stat_info; + if (!dbname.str[0]) + DBUG_RETURN(true); // Empty database name: does not exits. + path_len= build_table_filename(path, sizeof(path) - 1, dbname.str, "", "", 0); + path[path_len - 1]= 0; + if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0))) + DBUG_RETURN(true); // The database directory was not found: does not exists. + DBUG_RETURN(false); // The database directory was found. +} + + int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) { /* @@ -4981,19 +5004,10 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond) If we have lookup db value we should check that the database exists */ if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value && - db_names.at(0) != &INFORMATION_SCHEMA_NAME) - { - char path[FN_REFLEN+16]; - uint path_len; - MY_STAT stat_info; - if (!lookup_field_vals.db_value.str[0]) - DBUG_RETURN(0); - path_len= build_table_filename(path, sizeof(path) - 1, - lookup_field_vals.db_value.str, "", "", 0); - path[path_len-1]= 0; - if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0))) - DBUG_RETURN(0); - } + (!db_names.elements() /* The database name was too long */|| + (db_names.at(0) != &INFORMATION_SCHEMA_NAME && + verify_database_directory_exists(lookup_field_vals.db_value)))) + DBUG_RETURN(0); for (size_t i=0; i < db_names.elements(); i++) { -- cgit v1.2.1 From e0793d386517f4ff9c0267830d558f91c75263aa Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 23 Jun 2020 13:42:11 +0200 Subject: Fix result of merge. --- sql/sql_class.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 7ca3896a69d..4d14b42b065 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3408,11 +3408,7 @@ public: inline bool is_error() const { return m_stmt_da->is_error(); } /// Returns Diagnostics-area for the current statement. - Diagnostics_area *get_stmt_da() - { return m_stmt_da; } - - /// Returns Diagnostics-area for the current statement. - const Diagnostics_area *get_stmt_da() const + Diagnostics_area *get_stmt_da() const { return m_stmt_da; } /// Sets Diagnostics-area for the current statement. -- cgit v1.2.1 From f1838434b85db2d640ee21d0cbc2a4df1dc550e1 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Fri, 29 May 2020 11:36:28 +0530 Subject: MDEV-22706: Assertion `!current' failed in PROFILING::start_new_query Analysis: ======== When "Profiling" is enabled, server collects the resource usage of each statement that gets executed in current session. Profiling doesn't support nested statements. In order to ensure this behavior when profiling is enabled for a statement, there should not be any other active query which is being profiled. This active query information is stored in 'current' variable. When a nested query arrives it finds 'current' being not NULL and server aborts. When 'init_connect' and 'init_slave' system variables are set they contain a set of statements to be executed. "execute_init_command" is the function call which invokes "dispatch_command" for each statement provided in 'init_connect', 'init_slave' system variables. "execute_init_command" invokes "start_new_query" and it passes the statement list to "dispatch_command". This "dispatch_command" intern invokes "start_new_query" which leads to nesting of queries. Hence '!current' assert is triggered. Fix: === Remove profiling from "execute_init_command" as it will be done within "dispatch_command" execution. --- sql/sql_parse.cc | 8 -------- 1 file changed, 8 deletions(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 656da3b6a79..14ac657862f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -669,11 +669,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command, char *buf= thd->strmake(init_command->str, len); mysql_rwlock_unlock(var_lock); -#if defined(ENABLED_PROFILING) - thd->profiling.start_new_query(); - thd->profiling.set_query_source(buf, len); -#endif - THD_STAGE_INFO(thd, stage_execution_of_init_command); save_client_capabilities= thd->client_capabilities; thd->client_capabilities|= CLIENT_MULTI_QUERIES; @@ -688,9 +683,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command, thd->client_capabilities= save_client_capabilities; thd->net.vio= save_vio; -#if defined(ENABLED_PROFILING) - thd->profiling.finish_current_query(); -#endif } -- cgit v1.2.1 From 3bc89395529b099ef744953263ddc10b1f0ea1bd Mon Sep 17 00:00:00 2001 From: Sujatha Date: Wed, 17 Jun 2020 10:48:28 +0530 Subject: MDEV-22806: MSAN reports use-of-uninitialized-value for rpl_parallel_conflicts.test Problem: ======== Relay_log_info::flush reports following MSAN issue. ==17820==WARNING: MemorySanitizer: use-of-uninitialized-value is reported #5 0x00005584f0981441 in my_write (Filedes=22, Buffer=0x72500003e818 "5\n./slave-relay-bin.000003\n21385\n master-bin.000001\n21643\n0\n", '\245' ..., Count=118, MyFlags=532) at /home/sujatha/bug_repo/test-10.5-msan/mysys/my_write.c:49 Analysis: ========= In parallel replication at the end of each statement execution the worker execution status is updated in 'relay-log.info' file. When two workers try to flush the status at the same time, since the write to cache is not serialized both workers write to the same address simultaneously and increment the length twice. Because of this the length of buffer is more than actual data. When flush code tries to read the buffer beyond valid data length MSAN reports uninitialized values error. Fix: === Serialize the relay log flush operation using "rli->data_lock". --- sql/rpl_rli.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql') diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 905462ecfbd..c196a65809a 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1445,8 +1445,14 @@ bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd, } DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE();); if (mi->using_gtid == Master_info::USE_GTID_NO) + { + if (rgi->is_parallel_exec) + mysql_mutex_lock(&data_lock); if (flush_relay_log_info(this)) error= 1; + if (rgi->is_parallel_exec) + mysql_mutex_unlock(&data_lock); + } DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE();); } DBUG_RETURN(error); -- cgit v1.2.1 From 37cb7a0071febdba7a5ae61c2cd9e87def37454e Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sat, 27 Jun 2020 12:55:55 +0530 Subject: MDEV-17606: Query returns wrong results (while using CHARACTER SET utf8) The issue here was that the left expr and right expr of the ANY subquery had different character sets, so we were converting the left expr to utf8 character set. So when this conversion was happening we were actually converting the item inside the cache, it looked like (convert(t1.l1 using utf8)), which is incorrect. To fix this problem we are going to store the reference of the left expr and convert that to utf8 character set, it would look like convert((`test`.`t1`.`l1`) using utf8) --- sql/item_subselect.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 16ef8a192c5..ebe8e23add5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2015,7 +2015,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join) The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)' where we want to evaluate the sub query even if f1 would be null. */ - subs= func->create_swap(thd, *(optimizer->get_cache()), subs); + subs= func->create_swap(thd, expr, subs); thd->change_item_tree(place, subs); if (subs->fix_fields(thd, &subs)) DBUG_RETURN(true); -- cgit v1.2.1 From ca55e09e9a9a5e30c4137384d96a3bc07493fb01 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 23 Jun 2020 15:37:41 +1000 Subject: signal handler: use mariadb kb URL rather than MySQL one --- sql/signal_handler.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index d9b3fece854..05e1d2176f9 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -229,7 +229,7 @@ extern "C" sig_handler handle_fatal_signal(int sig) } my_safe_printf_stderr("%s", "The manual page at " - "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n" + "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains\n" "information that should help you find out what is causing the crash.\n"); #endif /* HAVE_STACKTRACE */ -- cgit v1.2.1