From b2b6cf492e3c7fd99a2d0b6f152516efd28dadf4 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Wed, 4 Jan 2017 19:11:13 +0200 Subject: [PATCH 01/10] MDEV-10988 Sphinx test suite refuses to run silently Add diagnostics output if any Sphinx components aren't found --- storage/sphinx/mysql-test/sphinx/suite.pm | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/storage/sphinx/mysql-test/sphinx/suite.pm b/storage/sphinx/mysql-test/sphinx/suite.pm index e4c3c1b9f74..fc127ffd6c0 100644 --- a/storage/sphinx/mysql-test/sphinx/suite.pm +++ b/storage/sphinx/mysql-test/sphinx/suite.pm @@ -16,13 +16,26 @@ sub locate_sphinx_binary { for (@list) { return $_ if -x $_; } } -# Look for Sphinx binaries. +# Look for Sphinx binaries my $exe_sphinx_indexer = &locate_sphinx_binary('indexer'); + +unless ($exe_sphinx_indexer) { + mtr_report("Sphinx 'indexer' binary not found, sphinx suite will be skipped"); + return "No Sphinx"; +} my $exe_sphinx_searchd = &locate_sphinx_binary('searchd'); -return "No Sphinx" unless $exe_sphinx_indexer and $exe_sphinx_searchd; -return "No SphinxSE" unless $ENV{HA_SPHINX_SO} or - $::mysqld_variables{'sphinx'} eq "ON"; +unless ($exe_sphinx_searchd) { + mtr_report("Sphinx 'searchd' binary not found, sphinx suite will be skipped"); + return "No Sphinx"; +} + +# Check for Sphinx engine + +unless ($ENV{HA_SPHINX_SO} or $::mysqld_variables{'sphinx'} eq "ON") { + mtr_report("Sphinx engine not found, sphinx suite will be skipped"); + return "No SphinxSE"; +} { local $_ = `"$exe_sphinx_searchd" --help`; From 670b85804ca6d3b0e640a7ddbb5b6e494bec7c2b Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Sun, 1 Jan 2017 15:36:56 +0200 Subject: [PATCH 02/10] Replication tests fail on valgrind due to waiting-related timeouts MTR raises default wait_for_pos_timeout from 300 to 1500 when tests are run with valgrind. The same needs to be done for other replication-related waits. The change should fix one of failures mentioned in MDEV-10653 (rpl.rpl_parallel fails in buildbot with timeout), the one on the valgrind builder; but not all of them --- mysql-test/include/sync_slave_sql_with_io.inc | 4 ++++ mysql-test/include/sync_with_master_gtid.inc | 4 ++++ mysql-test/include/wait_for_slave_param.inc | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/mysql-test/include/sync_slave_sql_with_io.inc b/mysql-test/include/sync_slave_sql_with_io.inc index 8048f7a177c..9efede9a61f 100644 --- a/mysql-test/include/sync_slave_sql_with_io.inc +++ b/mysql-test/include/sync_slave_sql_with_io.inc @@ -26,6 +26,10 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { let $_slave_timeout= 300; + if ($VALGRIND_TEST) + { + let $_slave_timeout= 1500; + } } --let $_master_log_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1) diff --git a/mysql-test/include/sync_with_master_gtid.inc b/mysql-test/include/sync_with_master_gtid.inc index 97ada8eea29..777711b979c 100644 --- a/mysql-test/include/sync_with_master_gtid.inc +++ b/mysql-test/include/sync_with_master_gtid.inc @@ -34,6 +34,10 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { let $_slave_timeout= 120; + if ($VALGRIND_TEST) + { + let $_slave_timeout= 1200; + } } --let $_result= `SELECT master_gtid_wait('$master_pos', $_slave_timeout)` diff --git a/mysql-test/include/wait_for_slave_param.inc b/mysql-test/include/wait_for_slave_param.inc index d3f7ec56614..25020d46ed9 100644 --- a/mysql-test/include/wait_for_slave_param.inc +++ b/mysql-test/include/wait_for_slave_param.inc @@ -50,6 +50,10 @@ let $_slave_timeout= $slave_timeout; if (!$_slave_timeout) { let $_slave_timeout= 300; + if ($VALGRIND_TEST) + { + let $_slave_timeout= 1500; + } } if ($slave_error_param == '') From 43378f367c5c01ebc214919006e2072fb2356724 Mon Sep 17 00:00:00 2001 From: Kristian Nielsen Date: Mon, 25 Jul 2016 13:07:50 +0200 Subject: [PATCH 03/10] MDEV-10271: Stopped SQL slave thread doesn't print a message to error log like IO thread does Make the slave SQL thread always output to the error log the message "Slave SQL thread exiting, replication stopped in ..." whenever it previously outputted "Slave SQL thread initialized, starting replication ...". Before this patch, it was somewhat inconsistent in which cases the message would be output and in which not, depending on the exact time and cause of the condition that caused the SQL thread to stop. --- sql/slave.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 65bcdc48c6a..c4817ef4794 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4574,11 +4574,11 @@ pthread_handler_t handle_slave_sql(void *arg) { rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, "Error initializing relay log position: %s", errmsg); - goto err; + goto err_before_start; } rli->reset_inuse_relaylog(); if (rli->alloc_inuse_relaylog(rli->group_relay_log_name)) - goto err; + goto err_before_start; strcpy(rli->future_event_master_log_name, rli->group_master_log_name); THD_CHECK_SENTRY(thd); @@ -4738,6 +4738,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, } } + err: if (mi->using_parallel()) rli->parallel.wait_for_done(thd, rli); @@ -4757,15 +4758,7 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, tmp.c_ptr_safe()); } - err: - - /* - Once again, in case we aborted with an error and skipped the first one. - (We want the first one to be before the printout of stop position to - get the correct position printed.) - */ - if (mi->using_parallel()) - rli->parallel.wait_for_done(thd, rli); + err_before_start: /* Some events set some playgrounds, which won't be cleared because thread From e4978d26b79120c58706e57fc66e4de1ec4b230c Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Mon, 25 Jul 2016 16:06:52 +0300 Subject: [PATCH 04/10] MDEV-9084 Calling a stored function from a nested select from temporary table causes unpredictable behavior Cherry-pick: f4a0af070ce49abae60040f6f32e1074309c27fb Author: Dmitry Lenev Date: Mon Jul 25 16:06:52 2016 +0300 Fix for bug #16672723 "CAN'T FIND TEMPORARY TABLE". Attempt to execute prepared CREATE TABLE SELECT statement which used temporary table in the subquery in FROM clause and stored function failed with unwarranted ER_NO_SUCH_TABLE error. The same happened when such statement was used in stored procedure and this procedure was re-executed. The problem occurred because execution of such prepared statement/its re-execution as part of stored procedure incorrectly set Query_table_list::query_tables_own_last marker, indicating the last table which is directly used by statement. As result temporary table used in the subquery was treated as indirectly used/belonging to prelocking list and was not pre-opened by open_temporary_tables() call before statement execution. Thus causing ER_NO_SUCH_TABLE errors since our code assumes that temporary tables need to be correctly pre-opened before statement execution. This problem became visible only in version 5.6 after patches related to bug 11746602/27480 "EXTEND CREATE TEMPORARY TABLES PRIVILEGE TO ALLOW TEMP TABLE OPERATIONS" since they have introduced pre-opening of temporary tables for statements. Incorrect setting of Query_table_list::query_tables_own_last happened in LEX::first_lists_tables_same() method which is called by CREATE TABLE SELECT implementation as part of LEX::unlink_first_table(), which temporary excludes table list element for table being created from the query table list before handling SELECT part. LEX::first_lists_tables_same() tries to ensure that global table list of the statement starts with the first table list element from the first statement select. To do this it moves such table list element to the head of the global table list. If this table happens to be last directly-used table for the statement, query_tables_own_last marker is pointing to it. Since this marker was not updated when table list element was moved we ended up with all tables except the first table separated by it as if they were not directly used by statement (i.e. belonged to prelocked tables list). This fix changes code of LEX::first_lists_tables_same() to update query_tables_own_last marker in cases when it points to the table being moved. It is set to the table which precedes table being moved in this case. --- mysql-test/r/sp-prelocking.result | 23 +++++++++++++++++++++++ mysql-test/t/sp-prelocking.test | 30 ++++++++++++++++++++++++++++++ sql/sql_lex.cc | 3 +++ 3 files changed, 56 insertions(+) diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result index 5b594e9ea55..eb47cc21f41 100644 --- a/mysql-test/r/sp-prelocking.result +++ b/mysql-test/r/sp-prelocking.result @@ -340,3 +340,26 @@ f1() DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1,t2; +# +# Bug #16672723 "CAN'T FIND TEMPORARY TABLE". +# +CREATE FUNCTION f1() RETURNS INT RETURN 1; +CREATE TEMPORARY TABLE tmp1(a INT); +PREPARE stmt1 FROM "CREATE TEMPORARY TABLE tmp2 AS SELECT b FROM (SELECT f1() AS b FROM tmp1) AS t"; +# The below statement failed before the fix. +EXECUTE stmt1; +DROP TEMPORARY TABLES tmp1, tmp2; +DEALLOCATE PREPARE stmt1; +DROP FUNCTION f1; +create procedure sp1() +begin +drop table if exists t1, t2; +create temporary table t1 select 1 v; +create table t2 (col varchar(45)) select distinct col from (select sf1() as col from t1) t; +end$$ +create function sf1() returns text return 'blah'; +call test.sp1(); +call test.sp1(); +drop procedure sp1; +drop function sf1; +drop table t2; diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test index c1378d59196..38cbd5aa110 100644 --- a/mysql-test/t/sp-prelocking.test +++ b/mysql-test/t/sp-prelocking.test @@ -414,3 +414,33 @@ SELECT f1(); DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1,t2; + +--echo # +--echo # Bug #16672723 "CAN'T FIND TEMPORARY TABLE". +--echo # +CREATE FUNCTION f1() RETURNS INT RETURN 1; +CREATE TEMPORARY TABLE tmp1(a INT); +PREPARE stmt1 FROM "CREATE TEMPORARY TABLE tmp2 AS SELECT b FROM (SELECT f1() AS b FROM tmp1) AS t"; +--echo # The below statement failed before the fix. +EXECUTE stmt1; +DROP TEMPORARY TABLES tmp1, tmp2; +DEALLOCATE PREPARE stmt1; +DROP FUNCTION f1; + +# +# MDEV-9084 Calling a stored function from a nested select from temporary table causes unpredictable behavior +# +delimiter $$; +create procedure sp1() +begin + drop table if exists t1, t2; + create temporary table t1 select 1 v; + create table t2 (col varchar(45)) select distinct col from (select sf1() as col from t1) t; +end$$ +delimiter ;$$ +create function sf1() returns text return 'blah'; +call test.sp1(); +call test.sp1(); +drop procedure sp1; +drop function sf1; +drop table t2; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d20c5ae78af..22489913ded 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3158,6 +3158,9 @@ void LEX::first_lists_tables_same() if (query_tables_last == &first_table->next_global) query_tables_last= first_table->prev_global; + if (query_tables_own_last == &first_table->next_global) + query_tables_own_last= first_table->prev_global; + if ((next= *first_table->prev_global= first_table->next_global)) next->prev_global= first_table->prev_global; /* include in new place */ From ae6eb7a0020eb4d51f97f924e5320325e5b63934 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 4 Jan 2017 23:04:37 +0100 Subject: [PATCH 05/10] MDEV-11088 Client plugins cannot be loaded by command line tools in default installation. Added plugin-dir to the [client] section of the generated my.ini, so that installed services (MSI or mysql_install_db.exe) would be able to find plugin directory. --- sql/CMakeLists.txt | 1 + sql/mysql_install_db.cc | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 88ec26eb6f6..652664fa438 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -387,6 +387,7 @@ IF(WIN32) ${CMAKE_CURRENT_BINARY_DIR}/mysql_bootstrap_sql.c COMPONENT Server ) + SET_TARGET_PROPERTIES(mysql_install_db PROPERTIES COMPILE_FLAGS -DINSTALL_PLUGINDIR=${INSTALL_PLUGINDIR}) TARGET_LINK_LIBRARIES(mysql_install_db mysys) ADD_LIBRARY(winservice STATIC winservice.c) diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index c39789f7c97..c23a20ebac9 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -233,6 +233,20 @@ static void get_basedir(char *basedir, int size, const char *mysqld_path) } } +#define STR(s) _STR(s) +#define _STR(s) #s + +static char *get_plugindir() +{ + static char plugin_dir[2*MAX_PATH]; + get_basedir(plugin_dir, sizeof(plugin_dir), mysqld_path); + strcat(plugin_dir, "/" STR(INSTALL_PLUGINDIR)); + + if (access(plugin_dir, 0) == 0) + return plugin_dir; + + return NULL; +} /** Allocate and initialize command line for mysqld --bootstrap. @@ -313,6 +327,10 @@ static int create_myini() fprintf(myini,"protocol=pipe\n"); else if (opt_port) fprintf(myini,"port=%d\n",opt_port); + + char *plugin_dir = get_plugindir(); + if (plugin_dir) + fprintf(myini, "plugin-dir=%s\n", plugin_dir); fclose(myini); return 0; } From 82b8741ad00e1ffdcbd0e2cf82f3ab31a7f3ce8b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 4 Jan 2017 22:50:48 +0100 Subject: [PATCH 06/10] Windows : use meaningful DEFAULT_MYSQL_HOME - base directory for the default installation. It is now defined as "C:/Program Files/MariaDB ${MYSQL_BASE_VERSION}" which is where installer indeed puts it by default. It still does not cover every case -32bit installer on 64 bit Windows would put installation root under "C:/Program Files (x86)", but better than the path used previously C:/MariaDB${MYSQL_BASE_VERSION}, which was never correct. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0adbb85d431..b6ffedabd14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -303,7 +303,7 @@ ENDIF() # Set commonly used variables IF(WIN32) - SET(DEFAULT_MYSQL_HOME "C:/MariaDB${MYSQL_BASE_VERSION}") + SET(DEFAULT_MYSQL_HOME "C:/Program Files/MariaDB ${MYSQL_BASE_VERSION}") SET(SHAREDIR share) ELSE() SET(DEFAULT_MYSQL_HOME ${CMAKE_INSTALL_PREFIX}) From eaf6b053b83d2a46250834e8367477bd3d85d38f Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 4 Jan 2017 22:41:43 +0100 Subject: [PATCH 07/10] MDEV-11087 Search path for my.ini is wrong for default installation Add /data/my.ini to the search path - this my.ini location is used since MariaDB 5.2 --- mysys/my_default.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysys/my_default.c b/mysys/my_default.c index 0f9b70ca326..03cfa973b2c 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -90,7 +90,7 @@ static my_bool defaults_already_read= FALSE; /* Which directories are searched for options (and in which order) */ -#define MAX_DEFAULT_DIRS 6 +#define MAX_DEFAULT_DIRS 7 #define DEFAULT_DIRS_SIZE (MAX_DEFAULT_DIRS + 1) /* Terminate with NULL */ static const char **default_directories = NULL; @@ -1219,7 +1219,12 @@ static const char **init_default_directories(MEM_ROOT *alloc) errors += add_directory(alloc, "C:/", dirs); if (my_get_module_parent(fname_buffer, sizeof(fname_buffer)) != NULL) + { errors += add_directory(alloc, fname_buffer, dirs); + + strncat(fname_buffer, "/data", sizeof(fname_buffer)); + errors += add_directory(alloc, fname_buffer, dirs); + } } #else From eed319b6fb543849046c8009c38575455e173dc2 Mon Sep 17 00:00:00 2001 From: Monty Date: Sun, 8 Jan 2017 17:51:36 +0200 Subject: [PATCH 08/10] MDEV-11317: `! is_set()' or `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' fails in Diagnostics_area::set_ok_status on CREATE OR REPLACE with ARCHIVE table Problem was with deleting non existing .frm file for a storage engine that doesn't have .frm files (yet) Fixed by not giving an error for non existing .frm files for storage engines that are using discovery Fixed also valgrind supression related to the given test case --- mysql-test/suite/archive/discover.result | 7 +++++++ mysql-test/suite/archive/discover.test | 10 ++++++++++ mysql-test/valgrind.supp | 15 ++++++++++++++- sql/sql_table.cc | 16 ++++++++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index e1ca9cb6a65..0619ca2051a 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -139,3 +139,10 @@ flush tables; create table t1 (a int) engine=archive; ERROR 42S01: Table 't1' already exists drop table t1; +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +SELECT * FROM t1; +pk +DROP TABLE t1; diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 20cb69efa00..4ab35cf1115 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -132,3 +132,13 @@ flush tables; create table t1 (a int) engine=archive; drop table t1; +# +# MDEV-11317: Error in deleting non existing .frm for tables with disocvery +# + +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 ( pk INT AUTO_INCREMENT PRIMARY KEY ) ENGINE = ARCHIVE; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 77f17cf07ec..a7d7f2ee67a 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -353,10 +353,23 @@ Memcheck:Leak fun:memalign ... - fun:call_init + fun:call_init* fun:_dl_init } +# This one is on OpenSuse 10.3 with gcc 5.4 +{ + memory "loss" from _dl_init 2 + Memcheck:Leak + fun:malloc + fun:pool + ... + fun:call_init* + fun:_dl_init +} + + + # # dlclose can allocate memory for error message, the memory will be # freed by dlerror or other dl* function. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 62dff1b5928..8569771d5f1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2497,7 +2497,19 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, int frm_delete_error, trigger_drop_error= 0; /* Delete the table definition file */ strmov(end,reg_ext); - frm_delete_error= mysql_file_delete(key_file_frm, path, MYF(MY_WME)); + if (table_type && table_type != view_pseudo_hton && + table_type->discover_table) + { + /* + Table type is using discovery and may not need a .frm file. + Delete it silently if it exists + */ + (void) mysql_file_delete(key_file_frm, path, MYF(0)); + frm_delete_error= 0; + } + else + frm_delete_error= mysql_file_delete(key_file_frm, path, + MYF(MY_WME)); if (frm_delete_error) frm_delete_error= my_errno; else @@ -2513,7 +2525,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, else if (frm_delete_error && if_exists) thd->clear_error(); } - non_tmp_error= error ? TRUE : non_tmp_error; + non_tmp_error|= MY_TEST(error); } if (error) { From 171e59ed479ee347dae04a34855ea3c29b13349d Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 9 Jan 2017 23:37:42 +0400 Subject: [PATCH 09/10] MDEV-11548 Reproducible server crash after the 2nd ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS. Have to use 'keyname' to check the name uniqueness. --- mysql-test/r/alter_table.result | 15 +++++++++++++++ mysql-test/t/alter_table.test | 19 +++++++++++++++++++ sql/sql_table.cc | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 67de5f3160a..72e81895816 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -2076,3 +2076,18 @@ tab1 CREATE TABLE `tab1` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE `tab1`; +# +# MDEV-11548 Reproducible server crash after the 2nd ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS +# +CREATE TABLE t1 (id INT UNSIGNED NOT NULL PRIMARY KEY); +CREATE TABLE t2 (id1 INT UNSIGNED NOT NULL); +ALTER TABLE t2 +ADD FOREIGN KEY IF NOT EXISTS (id1) +REFERENCES t1 (id); +ALTER TABLE t2 +ADD FOREIGN KEY IF NOT EXISTS (id1) +REFERENCES t1 (id); +Warnings: +Note 1061 Duplicate key name 'id1' +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index d2b8a6082a6..6fe0f4d30ee 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1737,3 +1737,22 @@ SHOW CREATE TABLE `tab1`; ALTER TABLE `tab1` CHANGE COLUMN v_col `v_col` varchar(128) AS (IF(field11='option1',CONCAT_WS(":","field1",field2,field3,field4,field5,field6,field7,field8,field9,field10), CONCAT_WS(":","field1",field11,field2,field3,field4,field5,field6,field7,field8,field9,field10))) PERSISTENT; SHOW CREATE TABLE `tab1`; DROP TABLE `tab1`; + +--echo # +--echo # MDEV-11548 Reproducible server crash after the 2nd ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS +--echo # + +CREATE TABLE t1 (id INT UNSIGNED NOT NULL PRIMARY KEY); +CREATE TABLE t2 (id1 INT UNSIGNED NOT NULL); + +ALTER TABLE t2 +ADD FOREIGN KEY IF NOT EXISTS (id1) + REFERENCES t1 (id); + +ALTER TABLE t2 +ADD FOREIGN KEY IF NOT EXISTS (id1) +REFERENCES t1 (id); + +DROP TABLE t2; +DROP TABLE t1; + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8569771d5f1..31f61301c37 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5943,7 +5943,7 @@ drop_create_field: while ((f_key= fk_key_it++)) { if (my_strcasecmp(system_charset_info, f_key->foreign_id->str, - key->name.str) == 0) + keyname) == 0) goto remove_key; } } From 78e6fafcaa93bdd2cf793a82a812137eb7a779a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 10 Jan 2017 14:11:32 +0200 Subject: [PATCH 10/10] Fix an innodb_plugin leak noted in MDEV-11686 buf_flush_init_flush_rbt() was called too early in MariaDB server 10.0, 10.1, MySQL 5.5 and MySQL 5.6. The memory leak has been fixed in the XtraDB storage engine and in MySQL 5.7. As a result, when the server is started to initialize new data files, the buf_pool->flush_rbt will be created unnecessarily and then leaked. This memory leak was noticed in MariaDB server 10.1 when running the test encryption.innodb_first_page. --- storage/innobase/log/log0recv.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 85f4f6ea671..aed94d00834 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2,6 +2,7 @@ Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. +Copyright (c) 2017, MariaDB Corporation. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -387,12 +388,6 @@ recv_sys_init( } #ifndef UNIV_HOTBACKUP - /* Initialize red-black tree for fast insertions into the - flush_list during recovery process. - As this initialization is done while holding the buffer pool - mutex we perform it before acquiring recv_sys->mutex. */ - buf_flush_init_flush_rbt(); - mutex_enter(&(recv_sys->mutex)); recv_sys->heap = mem_heap_create_typed(256, @@ -3030,6 +3025,11 @@ recv_recovery_from_checkpoint_start_func( byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; dberr_t err; + + /* Initialize red-black tree for fast insertions into the + flush_list during recovery process. */ + buf_flush_init_flush_rbt(); + ut_when_dtor tmp(recv_sys->dblwr); #ifdef UNIV_LOG_ARCHIVE