From 7355f7b1f5cec0f3db60053941d0c78288917c43 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 7 Apr 2022 06:13:22 +0400 Subject: Adding MTR tests to cover how keywords of different kinds behave in various contexts --- mysql-test/main/keywords.result | 421 ++++++++++++++++++++++++++++++++++++++++ mysql-test/main/keywords.test | 77 ++++++++ 2 files changed, 498 insertions(+) diff --git a/mysql-test/main/keywords.result b/mysql-test/main/keywords.result index 2765c05b3cb..8db364ac156 100644 --- a/mysql-test/main/keywords.result +++ b/mysql-test/main/keywords.result @@ -391,3 +391,424 @@ END $$ compressed 1 +# +# Testing various keywords in various contexts +# +CREATE PROCEDURE p1(query TEXT, var TEXT) +BEGIN +DECLARE errmsg TEXT DEFAULT ''; +DECLARE CONTINUE HANDLER +FOR SQLEXCEPTION +BEGIN +GET DIAGNOSTICS CONDITION 1 errmsg = MESSAGE_TEXT; +SET errmsg= REPLACE(errmsg, 'You have an error in your SQL ', '..'); +SET errmsg= REPLACE(errmsg, '; check the manual that corresponds to your MariaDB server version for the right syntax to use', '..'); +END; +SET query=REPLACE(query, '$(VAR)', var); +EXECUTE IMMEDIATE query; +SELECT CONCAT(query, '; -- ', LEFT(COALESCE(errmsg,''),40)) AS `--------`; +END; +$$ +CREATE PROCEDURE p2(query TEXT) +BEGIN +FOR row IN (SELECT word FROM t1 ORDER BY category, word) +DO +CALL p1(query, row.word); +END FOR; +END; +$$ +CREATE TABLE t1 (word TEXT, category TEXT); +INSERT INTO t1 VALUES ('non_keyword', '00 Simple identifier'); +INSERT INTO t1 VALUES ('lpad', '01 Built-in native function'); +INSERT INTO t1 VALUES ('rpad', '01 Built-in native function'); +INSERT INTO t1 VALUES ('adddate', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('substr', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('substring', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('trim_oracle', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('ascii', '03 function_call_conflict'); +INSERT INTO t1 VALUES ('replace', '03 function_call_conflict'); +INSERT INTO t1 VALUES ('weight_string', '03 function_call_conflict'); +INSERT INTO t1 VALUES ('char', '04 function_call_keyword'); +INSERT INTO t1 VALUES ('trim', '04 function_call_keyword'); +INSERT INTO t1 VALUES ('year', '04 function_call_keyword'); +INSERT INTO t1 VALUES ('create', '05 Reserved keyword'); +CALL p2('SELECT @@$(VAR)'); +-------- +SELECT @@non_keyword; -- Unknown system variable 'non_keyword' +-------- +SELECT @@lpad; -- Unknown system variable 'lpad' +-------- +SELECT @@rpad; -- Unknown system variable 'rpad' +-------- +SELECT @@adddate; -- Unknown system variable 'adddate' +-------- +SELECT @@substr; -- Unknown system variable 'substr' +-------- +SELECT @@substring; -- Unknown system variable 'substring' +-------- +SELECT @@trim_oracle; -- Unknown system variable 'trim_oracle' +-------- +SELECT @@ascii; -- Unknown system variable 'ascii' +-------- +SELECT @@replace; -- ..syntax.. near 'replace' at line 1 +-------- +SELECT @@weight_string; -- Unknown system variable 'weight_string' +-------- +SELECT @@char; -- ..syntax.. near 'char' at line 1 +-------- +SELECT @@trim; -- Unknown system variable 'trim' +-------- +SELECT @@year; -- Unknown system variable 'year' +-------- +SELECT @@create; -- ..syntax.. near 'create' at line 1 +CALL p2('SELECT @@global.$(VAR)'); +-------- +SELECT @@global.non_keyword; -- Unknown system variable 'non_keyword' +-------- +SELECT @@global.lpad; -- Unknown system variable 'lpad' +-------- +SELECT @@global.rpad; -- Unknown system variable 'rpad' +-------- +SELECT @@global.adddate; -- Unknown system variable 'adddate' +-------- +SELECT @@global.substr; -- Unknown system variable 'substr' +-------- +SELECT @@global.substring; -- Unknown system variable 'substring' +-------- +SELECT @@global.trim_oracle; -- Unknown system variable 'trim_oracle' +-------- +SELECT @@global.ascii; -- Unknown system variable 'ascii' +-------- +SELECT @@global.replace; -- Unknown system variable 'replace' +-------- +SELECT @@global.weight_string; -- Unknown system variable 'weight_string' +-------- +SELECT @@global.char; -- Unknown system variable 'char' +-------- +SELECT @@global.trim; -- Unknown system variable 'trim' +-------- +SELECT @@global.year; -- Unknown system variable 'year' +-------- +SELECT @@global.create; -- Unknown system variable 'create' +CALL p2('SELECT @@global.$(VAR)()'); +-------- +SELECT @@global.non_keyword(); -- Unknown system variable 'non_keyword' +-------- +SELECT @@global.lpad(); -- Unknown system variable 'lpad' +-------- +SELECT @@global.rpad(); -- Unknown system variable 'rpad' +-------- +SELECT @@global.adddate(); -- Unknown system variable 'adddate' +-------- +SELECT @@global.substr(); -- Unknown system variable 'substr' +-------- +SELECT @@global.substring(); -- Unknown system variable 'substring' +-------- +SELECT @@global.trim_oracle(); -- Unknown system variable 'trim_oracle' +-------- +SELECT @@global.ascii(); -- Unknown system variable 'ascii' +-------- +SELECT @@global.replace(); -- Unknown system variable 'replace' +-------- +SELECT @@global.weight_string(); -- Unknown system variable 'weight_string' +-------- +SELECT @@global.char(); -- Unknown system variable 'char' +-------- +SELECT @@global.trim(); -- Unknown system variable 'trim' +-------- +SELECT @@global.year(); -- Unknown system variable 'year' +-------- +SELECT @@global.create(); -- Unknown system variable 'create' +CALL p2('SELECT $(VAR)()'); +-------- +SELECT non_keyword(); -- FUNCTION test.non_keyword does not exist +-------- +SELECT lpad(); -- Incorrect parameter count in the call to +-------- +SELECT rpad(); -- Incorrect parameter count in the call to +-------- +SELECT adddate(); -- ..syntax.. near ')' at line 1 +-------- +SELECT substr(); -- ..syntax.. near ')' at line 1 +-------- +SELECT substring(); -- ..syntax.. near ')' at line 1 +-------- +SELECT trim_oracle(); -- ..syntax.. near ')' at line 1 +-------- +SELECT ascii(); -- ..syntax.. near ')' at line 1 +-------- +SELECT replace(); -- ..syntax.. near ')' at line 1 +-------- +SELECT weight_string(); -- ..syntax.. near ')' at line 1 +-------- +SELECT char(); -- ..syntax.. near ')' at line 1 +-------- +SELECT trim(); -- ..syntax.. near ')' at line 1 +-------- +SELECT year(); -- ..syntax.. near ')' at line 1 +-------- +SELECT create(); -- ..syntax.. near 'create()' at line 1 +CALL p2('SELECT test.$(VAR)()'); +-------- +SELECT test.non_keyword(); -- FUNCTION test.non_keyword does not exist +-------- +SELECT test.lpad(); -- FUNCTION test.lpad does not exist +-------- +SELECT test.rpad(); -- FUNCTION test.rpad does not exist +-------- +SELECT test.adddate(); -- FUNCTION test.adddate does not exist. Ch +-------- +SELECT test.substr(); -- FUNCTION test.substr does not exist. Che +-------- +SELECT test.substring(); -- FUNCTION test.substring does not exist. +-------- +SELECT test.trim_oracle(); -- FUNCTION test.trim_oracle does not exist +-------- +SELECT test.ascii(); -- FUNCTION test.ascii does not exist. Chec +-------- +SELECT test.replace(); -- FUNCTION test.replace does not exist. Ch +-------- +SELECT test.weight_string(); -- FUNCTION test.weight_string does not exi +-------- +SELECT test.char(); -- FUNCTION test.char does not exist. Check +-------- +SELECT test.trim(); -- FUNCTION test.trim does not exist. Check +-------- +SELECT test.year(); -- FUNCTION test.year does not exist. Check +-------- +SELECT test.create(); -- FUNCTION test.create does not exist. Che +CALL p2('SELECT $(VAR) FROM t1'); +-------- +SELECT non_keyword FROM t1; -- Unknown column 'non_keyword' in 'field l +-------- +SELECT lpad FROM t1; -- Unknown column 'lpad' in 'field list' +-------- +SELECT rpad FROM t1; -- Unknown column 'rpad' in 'field list' +-------- +SELECT adddate FROM t1; -- Unknown column 'adddate' in 'field list' +-------- +SELECT substr FROM t1; -- Unknown column 'substr' in 'field list' +-------- +SELECT substring FROM t1; -- Unknown column 'substring' in 'field lis +-------- +SELECT trim_oracle FROM t1; -- Unknown column 'trim_oracle' in 'field l +-------- +SELECT ascii FROM t1; -- Unknown column 'ascii' in 'field list' +-------- +SELECT replace FROM t1; -- ..syntax.. near 'FROM t1' at line 1 +-------- +SELECT weight_string FROM t1; -- Unknown column 'weight_string' in 'field +-------- +SELECT char FROM t1; -- ..syntax.. near 'FROM t1' at line 1 +-------- +SELECT trim FROM t1; -- Unknown column 'trim' in 'field list' +-------- +SELECT year FROM t1; -- Unknown column 'year' in 'field list' +-------- +SELECT create FROM t1; -- ..syntax.. near 'create FROM t1' at line +CALL p2('SELECT t1.$(VAR) FROM t1'); +-------- +SELECT t1.non_keyword FROM t1; -- Unknown column 't1.non_keyword' in 'fiel +-------- +SELECT t1.lpad FROM t1; -- Unknown column 't1.lpad' in 'field list' +-------- +SELECT t1.rpad FROM t1; -- Unknown column 't1.rpad' in 'field list' +-------- +SELECT t1.adddate FROM t1; -- Unknown column 't1.adddate' in 'field li +-------- +SELECT t1.substr FROM t1; -- Unknown column 't1.substr' in 'field lis +-------- +SELECT t1.substring FROM t1; -- Unknown column 't1.substring' in 'field +-------- +SELECT t1.trim_oracle FROM t1; -- Unknown column 't1.trim_oracle' in 'fiel +-------- +SELECT t1.ascii FROM t1; -- Unknown column 't1.ascii' in 'field list +-------- +SELECT t1.replace FROM t1; -- Unknown column 't1.replace' in 'field li +-------- +SELECT t1.weight_string FROM t1; -- Unknown column 't1.weight_string' in 'fi +-------- +SELECT t1.char FROM t1; -- Unknown column 't1.char' in 'field list' +-------- +SELECT t1.trim FROM t1; -- Unknown column 't1.trim' in 'field list' +-------- +SELECT t1.year FROM t1; -- Unknown column 't1.year' in 'field list' +-------- +SELECT t1.create FROM t1; -- Unknown column 't1.create' in 'field lis +CALL p2('DROP TABLE $(VAR)'); +-------- +DROP TABLE non_keyword; -- Unknown table 'test.non_keyword' +-------- +DROP TABLE lpad; -- Unknown table 'test.lpad' +-------- +DROP TABLE rpad; -- Unknown table 'test.rpad' +-------- +DROP TABLE adddate; -- Unknown table 'test.adddate' +-------- +DROP TABLE substr; -- Unknown table 'test.substr' +-------- +DROP TABLE substring; -- Unknown table 'test.substring' +-------- +DROP TABLE trim_oracle; -- Unknown table 'test.trim_oracle' +-------- +DROP TABLE ascii; -- Unknown table 'test.ascii' +-------- +DROP TABLE replace; -- ..syntax.. near 'replace' at line 1 +-------- +DROP TABLE weight_string; -- Unknown table 'test.weight_string' +-------- +DROP TABLE char; -- ..syntax.. near 'char' at line 1 +-------- +DROP TABLE trim; -- Unknown table 'test.trim' +-------- +DROP TABLE year; -- Unknown table 'test.year' +-------- +DROP TABLE create; -- ..syntax.. near 'create' at line 1 +CALL p2('DROP TABLE test.$(VAR)'); +-------- +DROP TABLE test.non_keyword; -- Unknown table 'test.non_keyword' +-------- +DROP TABLE test.lpad; -- Unknown table 'test.lpad' +-------- +DROP TABLE test.rpad; -- Unknown table 'test.rpad' +-------- +DROP TABLE test.adddate; -- Unknown table 'test.adddate' +-------- +DROP TABLE test.substr; -- Unknown table 'test.substr' +-------- +DROP TABLE test.substring; -- Unknown table 'test.substring' +-------- +DROP TABLE test.trim_oracle; -- Unknown table 'test.trim_oracle' +-------- +DROP TABLE test.ascii; -- Unknown table 'test.ascii' +-------- +DROP TABLE test.replace; -- Unknown table 'test.replace' +-------- +DROP TABLE test.weight_string; -- Unknown table 'test.weight_string' +-------- +DROP TABLE test.char; -- Unknown table 'test.char' +-------- +DROP TABLE test.trim; -- Unknown table 'test.trim' +-------- +DROP TABLE test.year; -- Unknown table 'test.year' +-------- +DROP TABLE test.create; -- Unknown table 'test.create' +CALL p2('CREATE FUNCTION $(VAR)() RETURNS OOPS'); +-------- +CREATE FUNCTION non_keyword() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION lpad() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION rpad() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION adddate() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION substr() RETURNS OOPS; -- ..syntax.. near 'substr() RETURNS OOPS' +-------- +CREATE FUNCTION substring() RETURNS OOPS; -- ..syntax.. near 'substring() RETURNS OOP +-------- +CREATE FUNCTION trim_oracle() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION ascii() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION replace() RETURNS OOPS; -- ..syntax.. near 'replace() RETURNS OOPS' +-------- +CREATE FUNCTION weight_string() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION char() RETURNS OOPS; -- ..syntax.. near 'char() RETURNS OOPS' at +-------- +CREATE FUNCTION trim() RETURNS OOPS; -- ..syntax.. near 'trim() RETURNS OOPS' at +-------- +CREATE FUNCTION year() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION create() RETURNS OOPS; -- ..syntax.. near 'create() RETURNS OOPS' +CALL p2('CREATE FUNCTION test.$(VAR)() RETURNS OOPS'); +-------- +CREATE FUNCTION test.non_keyword() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.lpad() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.rpad() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.adddate() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.substr() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.substring() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.trim_oracle() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.ascii() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.replace() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.weight_string() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.char() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.trim() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.year() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +-------- +CREATE FUNCTION test.create() RETURNS OOPS; -- ..syntax.. near 'OOPS' at line 1 +CALL p2('DROP FUNCTION $(VAR)'); +-------- +DROP FUNCTION non_keyword; -- This command is not supported in the pre +-------- +DROP FUNCTION lpad; -- This command is not supported in the pre +-------- +DROP FUNCTION rpad; -- This command is not supported in the pre +-------- +DROP FUNCTION adddate; -- This command is not supported in the pre +-------- +DROP FUNCTION substr; -- This command is not supported in the pre +-------- +DROP FUNCTION substring; -- This command is not supported in the pre +-------- +DROP FUNCTION trim_oracle; -- This command is not supported in the pre +-------- +DROP FUNCTION ascii; -- This command is not supported in the pre +-------- +DROP FUNCTION replace; -- ..syntax.. near 'replace' at line 1 +-------- +DROP FUNCTION weight_string; -- This command is not supported in the pre +-------- +DROP FUNCTION char; -- ..syntax.. near 'char' at line 1 +-------- +DROP FUNCTION trim; -- This command is not supported in the pre +-------- +DROP FUNCTION year; -- This command is not supported in the pre +-------- +DROP FUNCTION create; -- ..syntax.. near 'create' at line 1 +CALL p2('DROP FUNCTION test.$(VAR)'); +-------- +DROP FUNCTION test.non_keyword; -- This command is not supported in the pre +-------- +DROP FUNCTION test.lpad; -- This command is not supported in the pre +-------- +DROP FUNCTION test.rpad; -- This command is not supported in the pre +-------- +DROP FUNCTION test.adddate; -- This command is not supported in the pre +-------- +DROP FUNCTION test.substr; -- This command is not supported in the pre +-------- +DROP FUNCTION test.substring; -- This command is not supported in the pre +-------- +DROP FUNCTION test.trim_oracle; -- This command is not supported in the pre +-------- +DROP FUNCTION test.ascii; -- This command is not supported in the pre +-------- +DROP FUNCTION test.replace; -- This command is not supported in the pre +-------- +DROP FUNCTION test.weight_string; -- This command is not supported in the pre +-------- +DROP FUNCTION test.char; -- This command is not supported in the pre +-------- +DROP FUNCTION test.trim; -- This command is not supported in the pre +-------- +DROP FUNCTION test.year; -- This command is not supported in the pre +-------- +DROP FUNCTION test.create; -- This command is not supported in the pre +DROP TABLE t1; +DROP PROCEDURE p1; +DROP PROCEDURE p2; diff --git a/mysql-test/main/keywords.test b/mysql-test/main/keywords.test index a745aada106..e6a3fc4953d 100644 --- a/mysql-test/main/keywords.test +++ b/mysql-test/main/keywords.test @@ -295,3 +295,80 @@ BEGIN NOT ATOMIC END $$ DELIMITER ;$$ + + +--echo # +--echo # Testing various keywords in various contexts +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1(query TEXT, var TEXT) +BEGIN + DECLARE errmsg TEXT DEFAULT ''; + DECLARE CONTINUE HANDLER + FOR SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 errmsg = MESSAGE_TEXT; + SET errmsg= REPLACE(errmsg, 'You have an error in your SQL ', '..'); + SET errmsg= REPLACE(errmsg, '; check the manual that corresponds to your MariaDB server version for the right syntax to use', '..'); + END; + SET query=REPLACE(query, '$(VAR)', var); + EXECUTE IMMEDIATE query; + SELECT CONCAT(query, '; -- ', LEFT(COALESCE(errmsg,''),40)) AS `--------`; +END; +$$ +CREATE PROCEDURE p2(query TEXT) +BEGIN + FOR row IN (SELECT word FROM t1 ORDER BY category, word) + DO + CALL p1(query, row.word); + END FOR; +END; +$$ +DELIMITER ;$$ + +CREATE TABLE t1 (word TEXT, category TEXT); + +INSERT INTO t1 VALUES ('non_keyword', '00 Simple identifier'); + +INSERT INTO t1 VALUES ('lpad', '01 Built-in native function'); +INSERT INTO t1 VALUES ('rpad', '01 Built-in native function'); + +INSERT INTO t1 VALUES ('adddate', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('substr', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('substring', '02 function_call_nonkeyword'); +INSERT INTO t1 VALUES ('trim_oracle', '02 function_call_nonkeyword'); + +INSERT INTO t1 VALUES ('ascii', '03 function_call_conflict'); +INSERT INTO t1 VALUES ('replace', '03 function_call_conflict'); +INSERT INTO t1 VALUES ('weight_string', '03 function_call_conflict'); + +INSERT INTO t1 VALUES ('char', '04 function_call_keyword'); +INSERT INTO t1 VALUES ('trim', '04 function_call_keyword'); +INSERT INTO t1 VALUES ('year', '04 function_call_keyword'); + +INSERT INTO t1 VALUES ('create', '05 Reserved keyword'); + +CALL p2('SELECT @@$(VAR)'); +CALL p2('SELECT @@global.$(VAR)'); +CALL p2('SELECT @@global.$(VAR)()'); + +CALL p2('SELECT $(VAR)()'); +CALL p2('SELECT test.$(VAR)()'); + +CALL p2('SELECT $(VAR) FROM t1'); +CALL p2('SELECT t1.$(VAR) FROM t1'); + +CALL p2('DROP TABLE $(VAR)'); +CALL p2('DROP TABLE test.$(VAR)'); + +CALL p2('CREATE FUNCTION $(VAR)() RETURNS OOPS'); +CALL p2('CREATE FUNCTION test.$(VAR)() RETURNS OOPS'); + +CALL p2('DROP FUNCTION $(VAR)'); +CALL p2('DROP FUNCTION test.$(VAR)'); + +DROP TABLE t1; + +DROP PROCEDURE p1; +DROP PROCEDURE p2; -- cgit v1.2.1 From 27b0030b9dc48d1e5264d084e4a917700271c8ab Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 4 Apr 2022 13:00:03 +0530 Subject: MDEV-27783 InnoDB: Failing assertion: table->get_ref_count() == 0 upon ALTER TABLE ... MODIFY COLUMN - There is a race condition occurs between purge thread and DDL. So purge thread can increment n_ref_count even after DDL does purge_sys_t::stop_FTS(). - dict_table_open_on_id for purge thread should check purge_sys.must_wait_FTS() before acquring the table. - purge_sys.stop_FTS() does acquire dict_sys.latch for setting the purge system flag and check table ref count on auxilary tables. --- storage/innobase/dict/dict0dict.cc | 26 +++++++++++++++++++++++ storage/innobase/fts/fts0fts.cc | 41 ++++++++++++++++++++++-------------- storage/innobase/include/dict0dict.h | 1 + storage/innobase/row/row0purge.cc | 6 +++++- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 4253326d46a..f64fd6f04c9 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -68,6 +68,7 @@ Created 1/8/1996 Heikki Tuuri #include "srv0mon.h" #include "srv0start.h" #include "trx0undo.h" +#include "trx0purge.h" #include #include @@ -819,12 +820,14 @@ template dict_table_t* dict_acquire_mdl_shared (dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); /** Look up a table by numeric identifier. +@tparam purge_thd Whether the function is called by purge thread @param[in] table_id table identifier @param[in] dict_locked data dictionary locked @param[in] table_op operation to perform when opening @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ +template dict_table_t* dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd, @@ -837,6 +840,12 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, if (table) { + if (purge_thd && purge_sys.must_wait_FTS()) + { + table= nullptr; + goto func_exit; + } + table->acquire(); if (thd && !dict_locked) table= dict_acquire_mdl_shared(table, thd, mdl, table_op); @@ -853,7 +862,14 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, ? DICT_ERR_IGNORE_RECOVER_LOCK : DICT_ERR_IGNORE_FK_NOKEY); if (table) + { + if (purge_thd && purge_sys.must_wait_FTS()) + { + dict_sys.unlock(); + return nullptr; + } table->acquire(); + } if (!dict_locked) { dict_sys.unlock(); @@ -867,12 +883,22 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, } } +func_exit: if (!dict_locked) dict_sys.unfreeze(); return table; } +template dict_table_t* dict_table_open_on_id +(table_id_t table_id, bool dict_locked, + dict_table_op_t table_op, THD *thd, + MDL_ticket **mdl); +template dict_table_t* dict_table_open_on_id +(table_id_t table_id, bool dict_locked, + dict_table_op_t table_op, THD *thd, + MDL_ticket **mdl); + /********************************************************************//** Looks for column n position in the clustered index. @return position in internal representation of the clustered index */ diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 964a216cd39..c3d076b81d6 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1555,12 +1555,16 @@ have any other reference count. static void fts_table_no_ref_count(const char *table_name) { dict_table_t *table= dict_table_open_on_name( - table_name, false, DICT_ERR_IGNORE_TABLESPACE); + table_name, true, DICT_ERR_IGNORE_TABLESPACE); if (!table) return; while (table->get_ref_count() > 1) + { + dict_sys.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); + dict_sys.lock(SRW_LOCK_CALL); + } table->release(); } @@ -1572,8 +1576,10 @@ and common table associated with the fts table. already stopped*/ void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped) { + dict_sys.lock(SRW_LOCK_CALL); if (!already_stopped) purge_sys.stop_FTS(); + fts_table_t fts_table; char table_name[MAX_FULL_NAME_LEN]; @@ -1582,28 +1588,31 @@ void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped) for (const char **suffix= fts_common_tables; *suffix; suffix++) { fts_table.suffix= *suffix; - fts_get_table_name(&fts_table, table_name, false); + fts_get_table_name(&fts_table, table_name, true); fts_table_no_ref_count(table_name); } - if (!table.fts) - return; - auto indexes= table.fts->indexes; - if (!indexes) - return; - for (ulint i= 0;i < ib_vector_size(indexes); ++i) + if (table.fts) { - const dict_index_t *index= static_cast( - ib_vector_getp(indexes, i)); - FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, index); - for (const fts_index_selector_t *s= fts_index_selector; - s->suffix; s++) + if (auto indexes= table.fts->indexes) { - fts_table.suffix= s->suffix; - fts_get_table_name(&fts_table, table_name, false); - fts_table_no_ref_count(table_name); + for (ulint i= 0;i < ib_vector_size(indexes); ++i) + { + const dict_index_t *index= static_cast( + ib_vector_getp(indexes, i)); + FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, index); + for (const fts_index_selector_t *s= fts_index_selector; + s->suffix; s++) + { + fts_table.suffix= s->suffix; + fts_get_table_name(&fts_table, table_name, true); + fts_table_no_ref_count(table_name); + } + } } } + + dict_sys.unlock(); } /** Lock the internal FTS_ tables for table, before fts_drop_tables(). diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 07acd0ecb74..a02f4761964 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -146,6 +146,7 @@ dict_acquire_mdl_shared(dict_table_t *table, @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ +template dict_table_t* dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd= nullptr, diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index 75d497b2cf4..e6267a2023a 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1027,10 +1027,14 @@ row_purge_parse_undo_rec( try_again: purge_sys.check_stop_FTS(); - node->table = dict_table_open_on_id( + node->table = dict_table_open_on_id( table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd, &node->mdl_ticket); + if (!node->table && purge_sys.must_wait_FTS()) { + goto try_again; + } + if (!node->table) { /* The table has been dropped: no need to do purge and release mdl happened as a part of open process itself */ -- cgit v1.2.1 From e84e134a9100f1d04f9fff56c2097ab4d020b57c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 7 Apr 2022 09:30:26 +1000 Subject: main.thread_pool_info - no threadpool on aix --- mysql-test/main/thread_pool_info.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/main/thread_pool_info.test b/mysql-test/main/thread_pool_info.test index cd906454d8c..84dce94d778 100644 --- a/mysql-test/main/thread_pool_info.test +++ b/mysql-test/main/thread_pool_info.test @@ -1,4 +1,5 @@ source include/not_embedded.inc; +source include/not_aix.inc; let $have_plugin = `SELECT COUNT(*) FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_STATUS='ACTIVE' AND PLUGIN_NAME = 'THREAD_POOL_GROUPS'`; if(!$have_plugin) -- cgit v1.2.1 From 4ee00a29e34d80555b6d1b4eb3f7b44b2f8049fa Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 7 Apr 2022 10:50:04 +1000 Subject: MDEV-28250 aix test case failure innodb_zip.innochecksum_3,4k,crc32,innodb As discovered by tracing, but also presenting in AIX fseeko documentation, seeking beyond the EOF is acceptable, as you can write there. To display the same error in AIX to other implementations that return errors on seek, we take the EFBIG error code on reading and error the same way. An AIX truss of an aspect of the test: truss extra/innochecksum --page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd statx("./mysql-test/var/log/innodb_zip.innochecksum_3-4k,crc32,innodb/mysqld.1/data//test/tab1.ibd", 0x0FFFFFFFFFFFF610, 176, 010) = 0 kopen("./mysql-test/var/log/innodb_zip.innochecksum_3-4k,crc32,innodb/mysqld.1/data//test/tab1.ibd", O_RDONLY|O_LARGEFILE) = 3 kfcntl(3, 12, 0x00000001100006C8) = 0 kfcntl(3, F_GETFL, 0x00000001100A6CF8) = 67108864 kioctl(3, 22528, 0x0000000000000000, 0x0000000000000000) Err#25 ENOTTY klseek(3, 0, 1, 0x0FFFFFFFFFFFF3F0) = 0 kioctl(3, 22528, 0x0000000000000000, 0x0000000000000000) Err#25 ENOTTY kread(3, "DEADBEEF\0\0\0\0FFFFFFFF".., 4096) = 4096 klseek(3, 0, 1, 0x0FFFFFFFFFFFF450) = 0 klseek(3, 17592186040320, 0, 0x0FFFFFFFFFFFF450) = 0 klseek(3, 0, 1, 0x0FFFFFFFFFFFF3F0) = 0 kread(3, "DEADBEEF\0\0\0\0FFFFFFFF".., 4096) Err#27 EFBIG An equivalent Linux trace: ltrace extra/innochecksum --page=18446744073709551615 $MYSQLD_DATADIR/test/tab1.ibd stat64(0x7fff10ea2dc3, 0x7fff10ea0670, 88, 0x8026be41) = 0 open64("./mysql-test/var/log/innodb_zip."..., 0, 02072403160) = 3 fcntl64(3, 6, 0x139f180, 1) = 0 fgetpos64(0x615000000080, 0x7fff10ea0760, 1, 0) = 0 fseeko64(0x615000000080, 0xffffffff000, 0, 5 pthread_getspecific(0, 0x4d0eb8, 0x7fff10ea0490, 0) = 0x7f7b2806d000 <... fseeko64 resumed> ) = 0 fgetpos64(0x615000000080, 0x7fff10ea0760, 1, 1) = 0 feof(0x615000000080) = 0 feof(0x615000000080) = 1 Error: Unable to seek to necessary offset --- extra/innochecksum.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 3c3c0275915..5ac48f57fb1 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -1893,6 +1893,18 @@ unexpected_eof: } if (ferror(fil_in)) { +#ifdef _AIX + /* + AIX fseeko can go past eof without error. + the error occurs on read, hence output the + same error here as would show up on other + platforms. This shows up in the mtr test + innodb_zip.innochecksum_3-4k,crc32,innodb + */ + if (errno == EFBIG) { + goto unexpected_eof; + } +#endif fprintf(stderr, "Error reading " ULINTPF " bytes", physical_page_size); perror(" "); -- cgit v1.2.1 From 3c99a48db31c8601a5eb0a9465dc96d8f7f72999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 6 Apr 2022 15:54:59 +0300 Subject: MDEV-28247 : Disable background ibuf merge during Galera SST This failure was caused by MDEV-25975, which removed the parameter innodb_disallow_writes. Added a check for wsrep_sst_disable_writes to the function ibuf_merge_in_background(). --- storage/innobase/ibuf/ibuf0ibuf.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 60496f20230..f530ed75b61 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -27,6 +27,13 @@ Created 7/19/1997 Heikki Tuuri #include "ibuf0ibuf.h" #include "sync0sync.h" #include "btr0sea.h" +#ifdef WITH_WSREP +extern uint32 wsrep_sst_disable_writes; +# define wsrep_sst_disable_writes \ + my_atomic_load32_explicit(&wsrep_sst_disable_writes, MY_MEMORY_ORDER_RELAXED) +#else +# define wsrep_sst_disable_writes false +#endif using st_::span; @@ -2653,6 +2660,10 @@ ibuf_merge_in_background( } #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + if (wsrep_sst_disable_writes) { + return(0); + } + if (full) { /* Caller has requested a full batch */ n_pages = PCT_IO(100); -- cgit v1.2.1 From 8990ffe62adce06001c4c950cfcc977a4d8ea4db Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 25 Mar 2022 17:25:11 +1100 Subject: MDEV-28153: Debian autobake to generate control Without doing the full build. Autobake now includes a dependency on lsb-release. As the BB CI images (https://github.com/MariaDB/mariadb.org-tools/blob/master/buildbot.mariadb.org/ci_build_images/debian.Dockerfile) have explicit dependencies, there's no point maintaining them in two places. We don't want do the full autobake-deb.sh there, just enough to have the control file containing the correct dependencies. Helps: https://github.com/MariaDB/mariadb.org-tools/pull/130 --- debian/autobake-deb.sh | 14 +++++++++++--- debian/salsa-ci.yml | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 08c83a86349..50d839439e5 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -30,9 +30,12 @@ then # build is not running on Travis or Gitlab-CI sed '/-DPLUGIN_COLUMNSTORE=NO/d' -i debian/rules # Take the files and part of control from MCS directory - cp -v storage/columnstore/columnstore/debian/mariadb-plugin-columnstore.* debian/ - echo >> debian/control - cat storage/columnstore/columnstore/debian/control >> debian/control + if [ ! -f debian/mariadb-plugin-columnstore.install ] + then + cp -v storage/columnstore/columnstore/debian/mariadb-plugin-columnstore.* debian/ + echo >> debian/control + cat storage/columnstore/columnstore/debian/control >> debian/control + fi fi # Look up distro-version specific stuff @@ -91,6 +94,11 @@ case "${CODENAME}" in exit 1 esac +if [ -n "${AUTOBAKE_PREP_CONTROL_RULES_ONLY:-}" ] +then + exit 0 +fi + # Adjust changelog, add new version echo "Incrementing changelog and starting build scripts" diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index 24f59aae221..6fc90193e06 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -34,7 +34,7 @@ build: - mv ${CCACHE_WORK_DIR} ${CCACHE_TMP_DIR} # Run Salsa-CI .build-script equivalent, with extra devscripts so autobake-deb.sh can run 'dch' - export CCACHE_DIR=${CCACHE_TMP_DIR} - - apt-get update && eatmydata apt-get install --no-install-recommends -y ccache fakeroot build-essential devscripts + - apt-get update && eatmydata apt-get install --no-install-recommends -y ccache fakeroot build-essential devscripts lsb-release - cd ${WORKING_DIR}/${SOURCE_DIR} - eatmydata apt-get build-dep --no-install-recommends -y . - update-ccache-symlinks; ccache -z # Zero out ccache counters -- cgit v1.2.1 From dea4e178fe2bbefc08133de44513ba47cb2d8bf2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 7 Apr 2022 14:55:52 +1000 Subject: deb: make --output-sync=target Rather than Debian logs containing a barely decipherable mix of build command and the output of some other command, we use the make option --output-sync=target. This make the compile line and the output stay together in the output stream. This option exists even in the make version in debian;stretch so should work everywhere. Test on debian:stretch, ubuntu:18.04, the two lowest version that use the debian/rules. --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 967dfe9c434..57636eb028a 100755 --- a/debian/rules +++ b/debian/rules @@ -108,7 +108,7 @@ override_dh_auto_build: @echo "RULES.$@" # Print build env info to help debug builds on different platforms dpkg-architecture - cd $(BUILDDIR) && $(MAKE) + cd $(BUILDDIR) && $(MAKE) --output-sync=target override_dh_auto_test: @echo "RULES.$@" -- cgit v1.2.1 From d8463b64b3f3a601ee39666fd0b758313e373519 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Fri, 21 Jan 2022 01:59:25 +0900 Subject: MDEV-27239 Spider: Assertion `thd->transaction->stmt.ha_list == __null || trans == &thd->transaction->stmt' failed in ha_commit_trans on BEGIN WORK after FTWRL The check on the SQL command type, in ha_spider::external_lock() is deleted by e954d9de. This resulted in the wrong call of spider_internal_start_trx() (and thus Ha_trx_info::register_ha()). I reverted the check and refactored ha_spider::external_lock(). --- storage/spider/ha_spider.cc | 153 ++++++++------------- .../mysql-test/spider/bugfix/r/mdev_27239.result | 20 +++ .../mysql-test/spider/bugfix/t/mdev_27239.cnf | 2 + .../mysql-test/spider/bugfix/t/mdev_27239.test | 24 ++++ 4 files changed, 105 insertions(+), 94 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27239.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27239.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27239.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 48bf8f4c664..974e096510e 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -1182,75 +1182,83 @@ int ha_spider::external_lock( int error_num = 0; SPIDER_TRX *trx; backup_error_status(); + DBUG_ENTER("ha_spider::external_lock"); DBUG_PRINT("info",("spider this=%p", this)); DBUG_PRINT("info",("spider lock_type=%x", lock_type)); -#if MYSQL_VERSION_ID < 50500 - DBUG_PRINT("info",("spider thd->options=%x", (int) thd->options)); -#endif -#ifdef WITH_PARTITION_STORAGE_ENGINE - if ( - wide_handler->stage == SPD_HND_STAGE_EXTERNAL_LOCK && - wide_handler->stage_executor != this) + DBUG_PRINT("info", ("spider sql_command=%d", thd_sql_command(thd))); + + if (wide_handler->stage == SPD_HND_STAGE_EXTERNAL_LOCK) { - DBUG_RETURN(0); + /* Only the stage executor deals with table locks. */ + if (wide_handler->stage_executor != this) + { + DBUG_RETURN(0); + } + } + else + { + /* Update the stage executor when the stage changes */ + wide_handler->stage= SPD_HND_STAGE_EXTERNAL_LOCK; + wide_handler->stage_executor= this; } - wide_handler->stage = SPD_HND_STAGE_EXTERNAL_LOCK; - wide_handler->stage_executor = this; -#endif -#ifdef HANDLER_HAS_NEED_INFO_FOR_AUTO_INC - info_auto_called = FALSE; -#endif + info_auto_called = FALSE; + wide_handler->external_lock_type= lock_type; wide_handler->sql_command = thd_sql_command(thd); + + /* We treat BEGIN as if UNLOCK TABLE. */ if (wide_handler->sql_command == SQLCOM_BEGIN) + { wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; + } + if (lock_type == F_UNLCK && + wide_handler->sql_command != SQLCOM_UNLOCK_TABLES) + { + DBUG_RETURN(0); + } trx = spider_get_trx(thd, TRUE, &error_num); if (error_num) + { DBUG_RETURN(error_num); + } wide_handler->trx = trx; - DBUG_PRINT("info",("spider sql_command=%d", wide_handler->sql_command)); -#ifdef HA_CAN_BULK_ACCESS - wide_handler->external_lock_cnt++; -#endif - if ( - lock_type == F_UNLCK && - wide_handler->sql_command != SQLCOM_UNLOCK_TABLES - ) - DBUG_RETURN(0); + /* Question: Why the following if block is necessary? Why here? */ if (store_error_num) + { DBUG_RETURN(store_error_num); - wide_handler->external_lock_type = lock_type; -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - if ((conn_kinds & SPIDER_CONN_KIND_MYSQL)) + } + + DBUG_ASSERT(wide_handler->sql_command != SQLCOM_RENAME_TABLE && + wide_handler->sql_command != SQLCOM_DROP_DB); + + if (wide_handler->sql_command == SQLCOM_DROP_TABLE || + wide_handler->sql_command == SQLCOM_ALTER_TABLE) { -#endif - if ( - /* SQLCOM_RENAME_TABLE and SQLCOM_DROP_DB don't come here */ - wide_handler->sql_command == SQLCOM_DROP_TABLE || - wide_handler->sql_command == SQLCOM_ALTER_TABLE - ) { - if (trx->locked_connections) - { - my_message(ER_SPIDER_ALTER_BEFORE_UNLOCK_NUM, - ER_SPIDER_ALTER_BEFORE_UNLOCK_STR, MYF(0)); - DBUG_RETURN(ER_SPIDER_ALTER_BEFORE_UNLOCK_NUM); - } - DBUG_RETURN(0); + if (trx->locked_connections) + { + my_message(ER_SPIDER_ALTER_BEFORE_UNLOCK_NUM, + ER_SPIDER_ALTER_BEFORE_UNLOCK_STR, MYF(0)); + DBUG_RETURN(ER_SPIDER_ALTER_BEFORE_UNLOCK_NUM); } - if (unlikely((error_num = spider_internal_start_trx(this)))) + DBUG_RETURN(0); + } + + if (lock_type != F_UNLCK) + { + if (unlikely((error_num= spider_internal_start_trx(this)))) { DBUG_RETURN(error_num); } -#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET) - } else { - trans_register_ha(trx->thd, FALSE, spider_hton_ptr); - if (thd_test_options(trx->thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) - trans_register_ha(trx->thd, TRUE, spider_hton_ptr); + if (wide_handler->sql_command != SQLCOM_SELECT && + wide_handler->sql_command != SQLCOM_HA_READ) + { + trx->updated_in_this_trx= TRUE; + DBUG_PRINT("info", ("spider trx->updated_in_this_trx=TRUE")); + } } -#endif if (wide_handler->lock_table_type > 0 || wide_handler->sql_command == SQLCOM_UNLOCK_TABLES) @@ -1263,12 +1271,10 @@ int ha_spider::external_lock( } /* lock/unlock tables */ -#ifdef WITH_PARTITION_STORAGE_ENGINE if (partition_handler && partition_handler->handlers) { - uint roop_count; - for (roop_count = 0; roop_count < partition_handler->no_parts; - ++roop_count) + for (uint roop_count= 0; roop_count < partition_handler->no_parts; + ++roop_count) { if (unlikely((error_num = partition_handler->handlers[roop_count]->lock_tables()))) @@ -1276,54 +1282,13 @@ int ha_spider::external_lock( DBUG_RETURN(error_num); } } - } else { -#endif - if (unlikely((error_num = lock_tables()))) - { - DBUG_RETURN(error_num); - } -#ifdef WITH_PARTITION_STORAGE_ENGINE } -#endif - } - - DBUG_PRINT("info",("spider trx_start=%s", - trx->trx_start ? "TRUE" : "FALSE")); - /* need to check after spider_internal_start_trx() */ - if (trx->trx_start) - { - switch (wide_handler->sql_command) + else if (unlikely((error_num= lock_tables()))) { - case SQLCOM_SELECT: - case SQLCOM_HA_READ: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_READ: -#endif - /* nothing to do */ - break; - case SQLCOM_UPDATE: - case SQLCOM_UPDATE_MULTI: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_UPDATE: -#endif - case SQLCOM_CREATE_TABLE: - case SQLCOM_INSERT: - case SQLCOM_INSERT_SELECT: - case SQLCOM_DELETE: - case SQLCOM_LOAD: - case SQLCOM_REPLACE: - case SQLCOM_REPLACE_SELECT: - case SQLCOM_DELETE_MULTI: -#ifdef HS_HAS_SQLCOM - case SQLCOM_HS_INSERT: - case SQLCOM_HS_DELETE: -#endif - default: - trx->updated_in_this_trx = TRUE; - DBUG_PRINT("info",("spider trx->updated_in_this_trx=TRUE")); - break; + DBUG_RETURN(error_num); } } + DBUG_RETURN(0); } diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27239.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27239.result new file mode 100644 index 00000000000..de135972a22 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27239.result @@ -0,0 +1,20 @@ +# +# MDEV-27239 Spider: Assertion `thd->transaction->stmt.ha_list == __null || trans == &thd->transaction->stmt' failed in ha_commit_trans on BEGIN WORK after FTWRL +# +for master_1 +for child2 +for child3 +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a (a INT) ENGINE=SPIDER; +FLUSH TABLE tbl_a WITH READ LOCK; +Warnings: +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +Error 1429 Unable to connect to foreign data source: localhost +BEGIN; +DROP DATABASE auto_test_local; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.cnf @@ -0,0 +1,2 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.test new file mode 100644 index 00000000000..3cf4bebd369 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27239.test @@ -0,0 +1,24 @@ +--echo # +--echo # MDEV-27239 Spider: Assertion `thd->transaction->stmt.ha_list == __null || trans == &thd->transaction->stmt' failed in ha_commit_trans on BEGIN WORK after FTWRL +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +CREATE DATABASE auto_test_local; +USE auto_test_local; + +CREATE TABLE tbl_a (a INT) ENGINE=SPIDER; +FLUSH TABLE tbl_a WITH READ LOCK; +BEGIN; + +DROP DATABASE auto_test_local; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log -- cgit v1.2.1 From d90c5ddd8beb961434200f7e02fac3a3a121f7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 9 Apr 2022 11:12:34 +0300 Subject: MDEV-27234 fixup: Add a result file Noticed by Monty --- .../suite/innodb/r/alter_crash_rebuild.result | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 mysql-test/suite/innodb/r/alter_crash_rebuild.result diff --git a/mysql-test/suite/innodb/r/alter_crash_rebuild.result b/mysql-test/suite/innodb/r/alter_crash_rebuild.result new file mode 100644 index 00000000000..b4d4e8ba85a --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_crash_rebuild.result @@ -0,0 +1,21 @@ +CREATE TABLE t1 (a INT NOT NULL) ENGINE=InnoDB STATS_PERSISTENT=0; +connect ddl,localhost,root; +SET DEBUG_SYNC='after_trx_committed_in_memory SIGNAL stuck WAIT_FOR ever EXECUTE 2'; +ALTER TABLE t1 ADD PRIMARY KEY(a); +connection default; +SET DEBUG_SYNC='now WAIT_FOR stuck'; +SET DEBUG_SYNC='now SIGNAL ever'; +SET DEBUG_SYNC='now WAIT_FOR stuck'; +SET GLOBAL innodb_log_checkpoint_now=ON; +# restart +disconnect ddl; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0 +SELECT * FROM t1; +a +DROP TABLE t1; +InnoDB 0 transactions not purged -- cgit v1.2.1 From cfdb621243b97e38c0ff849456d8dac0a5224ef3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 8 Apr 2022 14:17:36 +0200 Subject: MDEV-28255 "Error" instead of NULL in P_S.THREADS_CONNECTION_TYPE for background threads use vio_type_names[] values as in MySQL --- mysql-test/suite/perfschema/r/threads_mysql.result | 8 ++++++-- mysql-test/suite/perfschema/t/threads_mysql.test | 2 +- vio/viosocket.c | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/perfschema/r/threads_mysql.result b/mysql-test/suite/perfschema/r/threads_mysql.result index 40e6360fec7..d0748349af3 100644 --- a/mysql-test/suite/perfschema/r/threads_mysql.result +++ b/mysql-test/suite/perfschema/r/threads_mysql.result @@ -1,6 +1,6 @@ SET GLOBAL event_scheduler = OFF; SELECT name, type, processlist_user, processlist_host, processlist_db, -processlist_command, processlist_info, +processlist_command, processlist_info, connection_type, IF(parent_thread_id IS NULL, parent_thread_id, 'unified parent_thread_id') AS unified_parent_thread_id, role, instrumented @@ -14,6 +14,7 @@ processlist_host NULL processlist_db mysql processlist_command NULL processlist_info NULL +connection_type NULL unified_parent_thread_id NULL role NULL instrumented YES @@ -24,6 +25,7 @@ processlist_host NULL processlist_db NULL processlist_command NULL processlist_info NULL +connection_type NULL unified_parent_thread_id unified parent_thread_id role NULL instrumented YES @@ -34,13 +36,14 @@ processlist_host localhost processlist_db test processlist_command Query processlist_info SELECT name, type, processlist_user, processlist_host, processlist_db, -processlist_command, processlist_info, +processlist_command, processlist_info, connection_type, IF(parent_thread_id IS NULL, parent_thread_id, 'unified parent_thread_id') AS unified_parent_thread_id, role, instrumented FROM performance_schema.threads WHERE name LIKE 'thread/sql%' ORDER BY name +connection_type Socket unified_parent_thread_id unified parent_thread_id role NULL instrumented YES @@ -51,6 +54,7 @@ processlist_host NULL processlist_db NULL processlist_command NULL processlist_info NULL +connection_type NULL unified_parent_thread_id unified parent_thread_id role NULL instrumented YES diff --git a/mysql-test/suite/perfschema/t/threads_mysql.test b/mysql-test/suite/perfschema/t/threads_mysql.test index c33f421863e..8a021055d44 100644 --- a/mysql-test/suite/perfschema/t/threads_mysql.test +++ b/mysql-test/suite/perfschema/t/threads_mysql.test @@ -32,7 +32,7 @@ SET GLOBAL event_scheduler = OFF; # Therefore we have to disable this protocol for the next statement. --disable_ps_protocol SELECT name, type, processlist_user, processlist_host, processlist_db, - processlist_command, processlist_info, + processlist_command, processlist_info, connection_type, IF(parent_thread_id IS NULL, parent_thread_id, 'unified parent_thread_id') AS unified_parent_thread_id, role, instrumented diff --git a/vio/viosocket.c b/vio/viosocket.c index 9cad035161c..0ce351f1242 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -647,7 +647,7 @@ enum enum_vio_type vio_type(Vio* vio) static const LEX_CSTRING vio_type_names[] = { - { STRING_WITH_LEN("Error") }, // cannot happen + { STRING_WITH_LEN("") }, // internal threads { STRING_WITH_LEN("TCP/IP") }, { STRING_WITH_LEN("Socket") }, { STRING_WITH_LEN("Named Pipe") }, -- cgit v1.2.1 From 284ff64cd6618ac9f90c182d46fa6f03b301b65b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 10 Apr 2022 14:46:24 +0400 Subject: 10.6 tests for MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed The patch for MDEV-27673 (in 10.3) fixed MDEV-26507 as well. This patch only adds 10.6 specific MTR tests for MDEV-26507. --- .../suite/sysschema/r/v_innodb_lock_waits.result | 12 ++++++++++++ mysql-test/suite/sysschema/t/v_innodb_lock_waits.test | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mysql-test/suite/sysschema/r/v_innodb_lock_waits.result b/mysql-test/suite/sysschema/r/v_innodb_lock_waits.result index 7e44c334283..d8e2c496d13 100644 --- a/mysql-test/suite/sysschema/r/v_innodb_lock_waits.result +++ b/mysql-test/suite/sysschema/r/v_innodb_lock_waits.result @@ -56,3 +56,15 @@ blocking_trx_rows_modified bigint(21) unsigned NO NULL sql_kill_blocking_query varchar(32) YES NULL sql_kill_blocking_connection varchar(26) YES NULL SELECT * FROM sys.x$innodb_lock_waits; +# +# Start of 10.6 tests +# +# +# MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +# +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +SELECT * FROM sys.x$innodb_lock_waits; +SET SESSION sql_mode=DEFAULT; +# +# End of 10.6 tests +# diff --git a/mysql-test/suite/sysschema/t/v_innodb_lock_waits.test b/mysql-test/suite/sysschema/t/v_innodb_lock_waits.test index d742f599595..b784587d2a6 100644 --- a/mysql-test/suite/sysschema/t/v_innodb_lock_waits.test +++ b/mysql-test/suite/sysschema/t/v_innodb_lock_waits.test @@ -21,3 +21,21 @@ DESC sys.x$innodb_lock_waits; SELECT * FROM sys.x$innodb_lock_waits; --enable_result_log + +--echo # +--echo # Start of 10.6 tests +--echo # + +--echo # +--echo # MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +--echo # + +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +--disable_result_log +SELECT * FROM sys.x$innodb_lock_waits; +--enable_result_log +SET SESSION sql_mode=DEFAULT; + +--echo # +--echo # End of 10.6 tests +--echo # -- cgit v1.2.1 From bf70532e3d64011e0d5319317fc938539fc42c28 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 10 Apr 2022 14:36:47 +0400 Subject: 10.5 tests for MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed The fix for MDEV-27673 (in 10.3) fixed MDEV-26507 as well. This patch only adds MTR tests. --- mysql-test/main/information_schema.result | 21 +++++++++++++++++++++ mysql-test/main/information_schema.test | 24 ++++++++++++++++++++++++ mysql-test/suite/innodb_i_s/innodb_trx.result | 18 ++++++++++++++++++ mysql-test/suite/innodb_i_s/innodb_trx.test | 25 +++++++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 54307546f02..aded33a1e73 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -2400,3 +2400,24 @@ progress # # End of 10.3 tests # +# +# Start of 10.5 tests +# +# +# MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +# +CREATE TABLE t1 (a int); +CREATE ALGORITHM=TEMPTABLE VIEW i AS +SELECT a.created +FROM t1 w JOIN INFORMATION_SCHEMA.routines a +WHERE a.routine_name='not existing' + ORDER BY a.last_altered; +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +SELECT * FROM i; +created +SET SESSION sql_mode=DEFAULT; +DROP VIEW i; +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index 4c231d94160..fa27dcdf8f3 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -2110,3 +2110,27 @@ select progress from information_schema.processlist limit 1; --echo # --echo # End of 10.3 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +--echo # + +CREATE TABLE t1 (a int); +CREATE ALGORITHM=TEMPTABLE VIEW i AS + SELECT a.created + FROM t1 w JOIN INFORMATION_SCHEMA.routines a + WHERE a.routine_name='not existing' + ORDER BY a.last_altered; +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +SELECT * FROM i; +SET SESSION sql_mode=DEFAULT; +DROP VIEW i; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/suite/innodb_i_s/innodb_trx.result b/mysql-test/suite/innodb_i_s/innodb_trx.result index b9e0b05297d..cdcbe64b141 100644 --- a/mysql-test/suite/innodb_i_s/innodb_trx.result +++ b/mysql-test/suite/innodb_i_s/innodb_trx.result @@ -28,3 +28,21 @@ CREATE TEMPORARY TABLE t1 LIKE INFORMATION_SCHEMA.INNODB_TRX; DROP TEMPORARY TABLE t1; CREATE TEMPORARY TABLE t1 AS SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX LIMIT 0; DROP TEMPORARY TABLE t1; +# +# Start of 10.5 tests +# +# +# MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +# +CREATE ALGORITHM=TEMPTABLE VIEW i AS +SELECT a.trx_started +FROM INFORMATION_SCHEMA.innodb_lock_waits w +JOIN INFORMATION_SCHEMA.innodb_trx a +ORDER BY a.trx_wait_started; +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +SELECT * FROM i; +SET SESSION sql_mode=DEFAULT; +DROP VIEW i; +# +# End of 10.5 tests +# diff --git a/mysql-test/suite/innodb_i_s/innodb_trx.test b/mysql-test/suite/innodb_i_s/innodb_trx.test index 90fa3467b50..2a66750ed9f 100644 --- a/mysql-test/suite/innodb_i_s/innodb_trx.test +++ b/mysql-test/suite/innodb_i_s/innodb_trx.test @@ -7,3 +7,28 @@ DROP TEMPORARY TABLE t1; CREATE TEMPORARY TABLE t1 AS SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX LIMIT 0; DROP TEMPORARY TABLE t1; + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed +--echo # + +CREATE ALGORITHM=TEMPTABLE VIEW i AS + SELECT a.trx_started + FROM INFORMATION_SCHEMA.innodb_lock_waits w + JOIN INFORMATION_SCHEMA.innodb_trx a + ORDER BY a.trx_wait_started; +SET SESSION sql_mode='ALLOW_INVALID_DATES'; +--disable_result_log +SELECT * FROM i; +--enable_result_log +SET SESSION sql_mode=DEFAULT; +DROP VIEW i; + +--echo # +--echo # End of 10.5 tests +--echo # -- cgit v1.2.1 From 5a4a37076db1f3a77a40c9636b96eef5625b3d81 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 8 Apr 2022 18:54:26 +0200 Subject: MDEV-10183 implement service_manager_extend_timeout on Windows The implementation calls SetServiceStatus() with updated SERVICE_STATUS::dwHint and SERVICE_STATUS::dwCheckpoint --- include/my_service_manager.h | 7 ++++++- sql/mysqld.cc | 6 ++++++ sql/mysqld.h | 1 + sql/winmain.cc | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/my_service_manager.h b/include/my_service_manager.h index 3eff1253f20..498fc762048 100644 --- a/include/my_service_manager.h +++ b/include/my_service_manager.h @@ -43,7 +43,12 @@ #define SD_LISTEN_FDS_START (0) #define sd_notify(X, Y) #define sd_notifyf(E, F, ...) -#define service_manager_extend_timeout(I, FMTSTR, ...) +#ifdef _WIN32 + #define service_manager_extend_timeout(I, F, ...) \ + mysqld_win_extend_service_timeout(I) +#else + #define service_manager_extend_timeout(I, FMTSTR, ...) +#endif #endif #endif /* MY_SERVICE_MANAGER_INCLUDED */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c3f745b4aae..a4220851fb6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2752,6 +2752,12 @@ void mysqld_win_set_startup_complete() } +void mysqld_win_extend_service_timeout(DWORD sec) +{ + my_report_svc_status((DWORD)-1, 0, 2*1000*sec); +} + + void mysqld_win_set_service_name(const char *name) { if (stricmp(name, "mysql")) diff --git a/sql/mysqld.h b/sql/mysqld.h index d0a33fabb51..7d41f61c4df 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -968,6 +968,7 @@ extern int mysqld_main(int argc, char **argv); extern HANDLE hEventShutdown; extern void mysqld_win_initiate_shutdown(); extern void mysqld_win_set_startup_complete(); +extern void mysqld_win_extend_service_timeout(DWORD sec); extern void mysqld_set_service_status_callback(void (*)(DWORD, DWORD, DWORD)); extern void mysqld_win_set_service_name(const char *name); #endif diff --git a/sql/winmain.cc b/sql/winmain.cc index f999767cb27..7def0aed531 100644 --- a/sql/winmain.cc +++ b/sql/winmain.cc @@ -81,7 +81,8 @@ static void report_svc_status(DWORD current_state, DWORD exit_code, DWORD wait_h return; static DWORD check_point= 1; - svc_status.dwCurrentState= current_state; + if (current_state != (DWORD)-1) + svc_status.dwCurrentState= current_state; svc_status.dwWaitHint= wait_hint; if (exit_code) -- cgit v1.2.1 From 7bccf3dd744b6e85b69629c1e18730e77df503a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Apr 2022 10:22:40 +0300 Subject: MDEV-28274 Assertion s <= READ_FIX failed in buf_page_t::set_state buf_page_t::set_state(): Relax a debug assertion. It is fine to update a read-fixed block descriptor to be both read-fixed and buffer-fixed. buf_pool_t::watch_unset(): Fix some incorrect logic that was implemented in commit e9e6db93550aee9e6567b94ab928da9b13050e98. Thanks to Elena Stepanova for the test case. --- mysql-test/suite/innodb/r/ibuf_delete.result | 49 ++++++++++++++++++++ mysql-test/suite/innodb/t/ibuf_delete.test | 67 ++++++++++++++++++++++++++++ storage/innobase/buf/buf0buf.cc | 16 ++++--- storage/innobase/include/buf0buf.h | 3 +- 4 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/innodb/r/ibuf_delete.result create mode 100644 mysql-test/suite/innodb/t/ibuf_delete.test diff --git a/mysql-test/suite/innodb/r/ibuf_delete.result b/mysql-test/suite/innodb/r/ibuf_delete.result new file mode 100644 index 00000000000..1481fca9bf6 --- /dev/null +++ b/mysql-test/suite/innodb/r/ibuf_delete.result @@ -0,0 +1,49 @@ +SET @buffering= @@innodb_change_buffering; +SET GLOBAL innodb_change_buffering= deletes; +SET @flush= @@innodb_flush_log_at_trx_commit; +SET GLOBAL innodb_flush_log_at_trx_commit= 0; +CREATE TABLE t1 ( +a varchar(1024), +b varchar(1024), +c varchar(1024), +d varchar(1024), +e varchar(1024), +f varchar(1024), +g varchar(1024), +h varchar(1024), +key (a), +key (b), +key (c), +key (d) +) ENGINE=InnoDB; +INSERT INTO t1 +SELECT REPEAT('x',10), REPEAT('x',13), REPEAT('x',427), REPEAT('x',244), +REPEAT('x',9), REPEAT('x',112), REPEAT('x',814), REPEAT('x',633) +FROM seq_1_to_1024; +CREATE TEMPORARY TABLE t2 ( +a varchar(1024), +b varchar(1024), +c varchar(1024), +d varchar(1024), +e varchar(1024), +f varchar(1024), +g varchar(1024), +h varchar(1024), +i varchar(1024), +j varchar(1024), +k varchar(1024), +l varchar(1024), +m varchar(1024), +key (a), +key (b), +key (c), +key (d), +key (e), +key (f) +) ENGINE=InnoDB; +SET @x=REPEAT('x',512); +INSERT INTO t2 SELECT @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x +FROM seq_1_to_768; +DROP TABLE t1, t2; +SET GLOBAL innodb_change_buffering= @buffering; +SET GLOBAL innodb_flush_log_at_trx_commit= @flush; diff --git a/mysql-test/suite/innodb/t/ibuf_delete.test b/mysql-test/suite/innodb/t/ibuf_delete.test new file mode 100644 index 00000000000..82b740b6aa1 --- /dev/null +++ b/mysql-test/suite/innodb/t/ibuf_delete.test @@ -0,0 +1,67 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +SET @buffering= @@innodb_change_buffering; +SET GLOBAL innodb_change_buffering= deletes; +SET @flush= @@innodb_flush_log_at_trx_commit; +SET GLOBAL innodb_flush_log_at_trx_commit= 0; + +CREATE TABLE t1 ( + a varchar(1024), + b varchar(1024), + c varchar(1024), + d varchar(1024), + e varchar(1024), + f varchar(1024), + g varchar(1024), + h varchar(1024), + key (a), + key (b), + key (c), + key (d) +) ENGINE=InnoDB; + +INSERT INTO t1 +SELECT REPEAT('x',10), REPEAT('x',13), REPEAT('x',427), REPEAT('x',244), +REPEAT('x',9), REPEAT('x',112), REPEAT('x',814), REPEAT('x',633) +FROM seq_1_to_1024; + +CREATE TEMPORARY TABLE t2 ( + a varchar(1024), + b varchar(1024), + c varchar(1024), + d varchar(1024), + e varchar(1024), + f varchar(1024), + g varchar(1024), + h varchar(1024), + i varchar(1024), + j varchar(1024), + k varchar(1024), + l varchar(1024), + m varchar(1024), + key (a), + key (b), + key (c), + key (d), + key (e), + key (f) +) ENGINE=InnoDB; + +SET @x=REPEAT('x',512); +INSERT INTO t2 SELECT @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x +FROM seq_1_to_768; + +--disable_query_log +--let $run=1024 +while ($run) +{ + eval DELETE FROM t1 LIMIT 1 /* $run */; + --dec $run +} +--enable_query_log + +# Cleanup +DROP TABLE t1, t2; +SET GLOBAL innodb_change_buffering= @buffering; +SET GLOBAL innodb_flush_log_at_trx_commit= @flush; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index b948fefe55a..1bdbf134249 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2146,15 +2146,17 @@ void buf_pool_t::watch_unset(const page_id_t id, buf_pool_t::hash_chain &chain) if (!watch_is_sentinel(*w)) { no_watch: - ut_d(const auto s=) w->unfix(); - ut_ad(~buf_page_t::LRU_MASK & s); + w->unfix(); w= nullptr; } - const auto state= w->state(); - ut_ad(~buf_page_t::LRU_MASK & state); - ut_ad(state >= buf_page_t::UNFIXED); - if (state != buf_page_t::UNFIXED + 1) - goto no_watch; + else + { + const auto state= w->state(); + ut_ad(~buf_page_t::LRU_MASK & state); + ut_ad(state >= buf_page_t::UNFIXED + 1); + if (state != buf_page_t::UNFIXED + 1) + goto no_watch; + } } if (!w) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 7c372379ad3..9e341546c6a 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -2009,7 +2009,8 @@ inline void buf_page_t::set_state(uint32_t s) { mysql_mutex_assert_owner(&buf_pool.mutex); ut_ad(s <= REMOVE_HASH || s >= UNFIXED); - ut_ad(s <= READ_FIX); + ut_ad(s < WRITE_FIX); + ut_ad(s <= READ_FIX || zip.fix == READ_FIX); zip.fix= s; } -- cgit v1.2.1 From 840bab858b643ef6c03f1c5a47809e6e5e061499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 11 Apr 2022 14:41:24 +0300 Subject: MDEV-28289 fts_optimize_sync_table() is acquiring dict_sys.latch while holding it dict_acquire_mdl_shared(): Invoke the correct variant dict_table_t::parse_name() also when trylock=true, that is, we are being called from fts_optimize_sync_table(). Ever since commit 82b7c561b7919fa24e3d24b3f04a16046e24374f (MDEV-24258) this code was prone to a hang. If another thread requested an exclusive dict_sys.latch between the time dict_acquire_mdl_shared() acquired a shared dict_sys.latch and dict_table_t::parse_name() was trying to acquire another shared dict_sys.latch, InnoDB would get into an infinite livelock of threads, because the futex-based srw-lock implementation prioritizes exclusive latch requests. dict_table_t::parse_name(): Rename the template parameter dict_locked into dict_frozen. --- storage/innobase/dict/dict0dict.cc | 18 +++++++++--------- storage/innobase/include/dict0dict.h | 4 ++-- storage/innobase/include/dict0mem.h | 24 ++++++++++++------------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index f64fd6f04c9..12b9574ecda 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -602,13 +602,13 @@ dict_index_get_nth_field_pos( } /** Parse the table file name into table name and database name. -@tparam dict_locked whether dict_sys.lock() was called -@param[in,out] db_name database name buffer -@param[in,out] tbl_name table name buffer -@param[out] db_name_len database name length -@param[out] tbl_name_len table name length +@tparam dict_frozen whether the caller holds dict_sys.latch +@param[in,out] db_name database name buffer +@param[in,out] tbl_name table name buffer +@param[out] db_name_len database name length +@param[out] tbl_name_len table name length @return whether the table name is visible to SQL */ -template +template bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], char (&tbl_name)[NAME_LEN + 1], size_t *db_name_len, size_t *tbl_name_len) const @@ -616,7 +616,7 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], char db_buf[MAX_DATABASE_NAME_LEN + 1]; char tbl_buf[MAX_TABLE_NAME_LEN + 1]; - if (!dict_locked) + if (!dict_frozen) dict_sys.freeze(SRW_LOCK_CALL); /* protect against renaming */ ut_ad(dict_sys.frozen()); const size_t db_len= name.dblen(); @@ -636,7 +636,7 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1], memcpy(tbl_buf, mdl_name.m_name + db_len + 1, tbl_len); tbl_buf[tbl_len]= 0; - if (!dict_locked) + if (!dict_frozen) dict_sys.unfreeze(); *db_name_len= filename_to_tablename(db_buf, db_name, @@ -782,7 +782,7 @@ return_without_mdl: size_t db1_len, tbl1_len; - if (!table->parse_name(db_buf1, tbl_buf1, &db1_len, &tbl1_len)) + if (!table->parse_name(db_buf1, tbl_buf1, &db1_len, &tbl1_len)) { /* The table was renamed to #sql prefix. Release MDL (if any) for the old name and return. */ diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index a02f4761964..d84c737b0f5 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. 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 @@ -1570,7 +1570,7 @@ public: } else lock_wait(SRW_LOCK_ARGS(file, line)); - } + } #ifdef UNIV_PFS_RWLOCK /** Unlock the data dictionary cache. */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index dac738fbc68..d2f090f0ae4 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. 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 @@ -1934,17 +1934,17 @@ struct dict_table_t { /** For overflow fields returns potential max length stored inline */ inline size_t get_overflow_field_local_len() const; - /** Parse the table file name into table name and database name. - @tparam dict_locked whether dict_sys.lock() was called - @param[in,out] db_name database name buffer - @param[in,out] tbl_name table name buffer - @param[out] db_name_len database name length - @param[out] tbl_name_len table name length - @return whether the table name is visible to SQL */ - template - bool parse_name(char (&db_name)[NAME_LEN + 1], - char (&tbl_name)[NAME_LEN + 1], - size_t *db_name_len, size_t *tbl_name_len) const; + /** Parse the table file name into table name and database name. + @tparam dict_frozen whether the caller holds dict_sys.latch + @param[in,out] db_name database name buffer + @param[in,out] tbl_name table name buffer + @param[out] db_name_len database name length + @param[out] tbl_name_len table name length + @return whether the table name is visible to SQL */ + template + bool parse_name(char (&db_name)[NAME_LEN + 1], + char (&tbl_name)[NAME_LEN + 1], + size_t *db_name_len, size_t *tbl_name_len) const; /** Clear the table when rolling back TRX_UNDO_EMPTY */ void clear(que_thr_t *thr); -- cgit v1.2.1 From f61f58e7596b397a5490b3e2a87deefb81746cfb Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 8 Apr 2022 12:48:27 +0530 Subject: MDEV-26578 ERROR: AddressSanitizer: heap-use-after-free around dict_table_t::is_temporary_name - Purge thread is trying to access the table name when other thread does rename of the table name. It leads to heap use after free error by purge thread. purge thread should check whether the table name is temporary while holding dict_sys.mutex. --- storage/innobase/dict/dict0dict.cc | 11 +++++++++++ storage/innobase/include/dict0dict.h | 2 ++ storage/innobase/row/row0purge.cc | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 9c1750c588f..eb32b52db29 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -921,12 +921,14 @@ template dict_table_t* dict_acquire_mdl_shared(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t); /** Look up a table by numeric identifier. +@tparam purge_thd Whether the function is called by purge thread @param[in] table_id table identifier @param[in] dict_locked data dictionary locked @param[in] table_op operation to perform when opening @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ +template dict_table_t* dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd, @@ -948,6 +950,10 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED); if (table != NULL) { + if (purge_thd && table->name.is_temporary()) { + mutex_exit(&dict_sys.mutex); + return nullptr; + } dict_sys.acquire(table); MONITOR_INC(MONITOR_TABLE_REFERENCE); } @@ -965,6 +971,11 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked, return table; } +template dict_table_t* dict_table_open_on_id +(table_id_t, bool, dict_table_op_t, THD *, MDL_ticket **); +template dict_table_t* dict_table_open_on_id +(table_id_t, bool, dict_table_op_t, THD *, MDL_ticket **); + /********************************************************************//** Looks for column n position in the clustered index. @return position in internal representation of the clustered index */ diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 5682a10c889..14227fad3b6 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -140,12 +140,14 @@ dict_acquire_mdl_shared(dict_table_t *table, dict_table_op_t table_op= DICT_TABLE_OP_NORMAL); /** Look up a table by numeric identifier. +@tparam purge_thd Whether the function is called by purge thread @param[in] table_id table identifier @param[in] dict_locked data dictionary locked @param[in] table_op operation to perform when opening @param[in,out] thd background thread, or NULL to not acquire MDL @param[out] mdl mdl ticket, or NULL @return table, NULL if does not exist */ +template dict_table_t* dict_table_open_on_id(table_id_t table_id, bool dict_locked, dict_table_op_t table_op, THD *thd= nullptr, diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index ff19ed9830e..c00358eafa9 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -933,11 +933,11 @@ row_purge_parse_undo_rec( } try_again: - node->table = dict_table_open_on_id( + node->table = dict_table_open_on_id( table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd, &node->mdl_ticket); - if (node->table == NULL || node->table->name.is_temporary()) { + if (!node->table) { /* The table has been dropped: no need to do purge and release mdl happened as a part of open process itself */ goto err_exit; -- cgit v1.2.1 From bc75f7ed6d81138f8c2d8d2c800b9cf55bbaff7d Mon Sep 17 00:00:00 2001 From: Tuukka Pasanen Date: Thu, 10 Feb 2022 14:52:32 +0200 Subject: MDEV-28194: Remove unneeded path from MariaDB server postinst script Remove unndeeded paths from mariadb-server-10.6.postinst as it's already in export PATH and it fires 'command-with-path-in-maintainer-script' in lintian checks --- debian/mariadb-server-10.6.postinst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/mariadb-server-10.6.postinst b/debian/mariadb-server-10.6.postinst index 13800b7bce2..93a1e4e8b87 100644 --- a/debian/mariadb-server-10.6.postinst +++ b/debian/mariadb-server-10.6.postinst @@ -115,7 +115,7 @@ EOF if [ -f "$mysql_datadir"/auto.cnf ] && [ -f "$mysql_datadir"/mysql/user.MYD ] && [ ! lsof -nt "$mysql_datadir"/mysql/user.MYD > /dev/null ] && [ ! -f "$mysql_datadir"/undo_001 ]; then echo "UPDATE mysql.user SET plugin='unix_socket' WHERE plugin='auth_socket';" | - /usr/sbin/mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null + mariadbd --skip-innodb --key_buffer_size=0 --default-storage-engine=MyISAM --bootstrap 2> /dev/null fi # Ensure the existence and right permissions for the database and -- cgit v1.2.1 From e41500e4f2914af8142e06ca17925f6c03c7b7af Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 12 Apr 2022 13:57:16 +0400 Subject: MDEV-26128 type_set and type_enum are broken The problem was not with the server behavior, it was with wrong test results recorded. Enabling both type_set and type_enum. type_set.result was OK. The test did not fail. type_enum.result was incorrectly recorded in this commit: eb483c5181ab430877c135c16224284cfc517b3d Recording correct results. --- mysql-test/main/disabled.def | 2 -- mysql-test/main/type_enum.result | 12 +++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/disabled.def b/mysql-test/main/disabled.def index d3366587ee5..02104f6a680 100644 --- a/mysql-test/main/disabled.def +++ b/mysql-test/main/disabled.def @@ -18,5 +18,3 @@ file_contents : MDEV-6526 these files are not installed anymore max_statement_time : cannot possibly work, depends on timing partition_open_files_limit : open_files_limit check broken by MDEV-18360 partition_innodb : Waiting for fix MDEV-20169 -type_enum : Waiting for fix MDEV-6978 -type_set : Waiting for fix MDEV-6978 diff --git a/mysql-test/main/type_enum.result b/mysql-test/main/type_enum.result index 9b251fb414b..d17b94bbb4f 100644 --- a/mysql-test/main/type_enum.result +++ b/mysql-test/main/type_enum.result @@ -1932,14 +1932,16 @@ ALTER TABLE t2 ADD PRIMARY KEY(c1); SELECT t1.* FROM t1 JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a # t2 should NOT be eliminated EXPLAIN SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 -1 SIMPLE t2 range PRIMARY PRIMARY 1 NULL 1 Using where; Using index +1 SIMPLE t2 index PRIMARY PRIMARY 1 NULL 2 Using where; Using index DROP TABLE IF EXISTS t1,t2; CREATE TABLE t1 (c1 SET('a') CHARACTER SET latin1 PRIMARY KEY); INSERT INTO t1 VALUES ('a'); @@ -1957,14 +1959,16 @@ ALTER TABLE t2 ADD PRIMARY KEY(c1); SELECT t1.* FROM t1 JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a # t2 should NOT be eliminated EXPLAIN SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 -1 SIMPLE t2 range PRIMARY PRIMARY 1 NULL 1 Using where; Using index +1 SIMPLE t2 index PRIMARY PRIMARY 1 NULL 2 Using where; Using index DROP TABLE IF EXISTS t1,t2; CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET latin1 PRIMARY KEY); INSERT INTO t1 VALUES ('a'); @@ -1982,14 +1986,16 @@ ALTER TABLE t2 ADD PRIMARY KEY(c1); SELECT t1.* FROM t1 JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; c1 a +a # t2 should NOT be eliminated EXPLAIN SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.c1 COLLATE latin1_swedish_ci=t2.c1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 -1 SIMPLE t2 range PRIMARY PRIMARY 1 NULL 1 Using where; Using index +1 SIMPLE t2 index PRIMARY PRIMARY 1 NULL 2 Using where; Using index DROP TABLE IF EXISTS t1,t2; # # MDEV-6991 GROUP_MIN_MAX optimization is erroneously applied in some cases -- cgit v1.2.1