From e8bb94ccc80d02a9792257b971b748b389a014a1 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Fri, 30 Nov 2018 01:15:30 +0300 Subject: [PATCH 1/7] MDEV-16499 [10.1] ER_NO_SUCH_TABLE_IN_ENGINE followed by "Please drop the table and recreate" upon adding FULLTEXT key to table with virtual column There was an incorrect check for MariaDB and InnoDB tables fields count. Corruption was reported when there was no corruption. Also, a warning message had incorrect field numbers for both MariaDB and InnoDB tables. ha_innobase::open(): fixed check and message --- .../suite/innodb/r/innodb-virtual-columns.result | 15 +++++++++++++++ .../suite/innodb/t/innodb-virtual-columns.test | 11 +++++++++++ storage/innobase/handler/ha_innodb.cc | 16 +++++++++------- storage/xtradb/handler/ha_innodb.cc | 16 +++++++++------- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns.result b/mysql-test/suite/innodb/r/innodb-virtual-columns.result index 558bb23de0a..900fca8309e 100644 --- a/mysql-test/suite/innodb/r/innodb-virtual-columns.result +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns.result @@ -320,3 +320,18 @@ term uw_id plan wdraw_rsn admit_term 1035 2 CSM ACAD 1009 drop table grad_degree; drop table gso_grad_supr; +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL, FULLTEXT KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +SELECT * FROM t1; +a b c +1 foo 1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +ALTER TABLE t1 ADD FULLTEXT KEY(b); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +SELECT * FROM t1; +a b c +1 foo 1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns.test b/mysql-test/suite/innodb/t/innodb-virtual-columns.test index 368c6fc8cb1..99f550eb667 100644 --- a/mysql-test/suite/innodb/t/innodb-virtual-columns.test +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns.test @@ -300,3 +300,14 @@ select * from gso_grad_supr; drop table grad_degree; drop table gso_grad_supr; + +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL, FULLTEXT KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b CHAR(12), c INT AS (a) VIRTUAL) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1,'foo'); +ALTER TABLE t1 ADD FULLTEXT KEY(b); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 85c5529a096..33ece9c47af 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5312,19 +5312,21 @@ ha_innobase::open( ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err); if (ib_table - && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_user_cols(ib_table)) - || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && (table->s->fields - != dict_table_get_n_user_cols(ib_table) - 1)))) { + && (table->s->stored_fields != dict_table_get_n_user_cols(ib_table) + - (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0))) { ib_logf(IB_LOG_LEVEL_WARN, "table %s contains %lu user defined columns " "in InnoDB, but %lu columns in MySQL. Please " "check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html " "for how to resolve it", - norm_name, (ulong) dict_table_get_n_user_cols(ib_table), - (ulong) table->s->fields); + norm_name, + (ulong) (dict_table_get_n_user_cols(ib_table) + - DICT_TF2_FLAG_IS_SET(ib_table, + DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0), + (ulong) table->s->stored_fields); /* Mark this table as corrupted, so the drop table or force recovery can still use it, but not others. */ diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 52ef0b01534..320f7b3d088 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -5984,19 +5984,21 @@ ha_innobase::open( ib_table = dict_table_open_on_name(norm_name, FALSE, TRUE, ignore_err); if (ib_table - && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_user_cols(ib_table)) - || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && (table->s->fields - != dict_table_get_n_user_cols(ib_table) - 1)))) { + && (table->s->stored_fields != dict_table_get_n_user_cols(ib_table) + - (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0))) { ib_logf(IB_LOG_LEVEL_WARN, "table %s contains %lu user defined columns " "in InnoDB, but %lu columns in MySQL. Please " "check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html " "for how to resolve it", - norm_name, (ulong) dict_table_get_n_user_cols(ib_table), - (ulong) table->s->fields); + norm_name, + (ulong) (dict_table_get_n_user_cols(ib_table) + - DICT_TF2_FLAG_IS_SET(ib_table, + DICT_TF2_FTS_HAS_DOC_ID) + ? 1 : 0), + (ulong) table->s->stored_fields); /* Mark this table as corrupted, so the drop table or force recovery can still use it, but not others. */ From d0d0f88f2cd4da23c2c2da702da51fb533e7fb8a Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sun, 6 Jan 2019 23:15:25 +0530 Subject: [PATCH 2/7] MDEV-13784: query causes seg fault When we have a nested subquery then a subquery that was a dependent subquery may change to an independent one when we optimizer the inner subqueries. This is handled st_select_lex::optimize_unflattened_subqueries. Currently a subquery that was changed to independent from dependent after optimization phase incorrectly shows dependent in the output of Explain, this happens because we don't update used_tables for the WHERE clause, ON clause, etc after the optimization phase. --- mysql-test/r/subselect_exists2in.result | 4 +-- mysql-test/r/union.result | 38 +++++++++++++++++++++++++ mysql-test/r/view.result | 4 +-- mysql-test/t/union.test | 35 +++++++++++++++++++++++ sql/sql_lex.cc | 1 + 5 files changed, 78 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect_exists2in.result b/mysql-test/r/subselect_exists2in.result index d47e446fe8f..b6b2f5b476f 100644 --- a/mysql-test/r/subselect_exists2in.result +++ b/mysql-test/r/subselect_exists2in.result @@ -330,7 +330,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2 -Note 1003 select (select 1 from dual where (not(((1 is not null) and (1,1 in ( (select `test`.`t3`.`c` from `test`.`t3` where (`test`.`t3`.`c` is not null) ), (1 in on distinct_key where ((1 = ``.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` +Note 1003 select (select 1 from dual where (not(((1 is not null) and (1,1 in ((1 in on distinct_key where ((1 = ``.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) 1 @@ -344,7 +344,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2 -Note 1003 select (select 1 from dual where (not(((1 is not null) and (1,1 in ( (select `test`.`t3`.`c` from `test`.`t3` where (`test`.`t3`.`c` is not null) ), (1 in on distinct_key where ((1 = ``.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` +Note 1003 select (select 1 from dual where (not(((1 is not null) and (1,1 in ((1 in on distinct_key where ((1 = ``.`c`))))))))) AS `( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) )` from `test`.`t1` SELECT ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1; ( SELECT b FROM t2 WHERE NOT EXISTS ( SELECT c FROM t3 WHERE c = b ) ) 1 diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 5ea0f975a91..9b7a361fdc5 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -2049,3 +2049,41 @@ a 1000003.0 1.0 End of 5.5 tests +# +# MDEV-13784: query causes seg fault +# +CREATE TABLE t1 (`bug_id` int NOT NULL PRIMARY KEY, `product_id` int NOT NULL); +INSERT INTO t1 VALUES (45199,1184); +CREATE TABLE t2 (`product_id` int NOT NULL,`userid` int NOT NULL, PRIMARY KEY (`product_id`,`userid`)); +INSERT INTO t2 VALUES (1184,103),(1184,624),(1184,1577),(1184,1582); +CREATE TABLE t3 (`id` int NOT NULL PRIMARY KEY,`name` varchar(64)); +CREATE TABLE t4 ( `userid` int NOT NULL PRIMARY KEY, `login_name` varchar(255)); +INSERT INTO t4 VALUES (103,'foo'),(624,'foo'),(1577,'foo'),(1582,'foo'); +CREATE TABLE t5 (`id` int NOT NULL PRIMARY KEY, `name` varchar(64)); +explain select +( +select login_name from t4 where userId = ( +select userid from t2 where product_id = t1.product_id +union +select userid from t2 where product_id = ( +select id from t5 where name = (select name from t3 where id = t1.product_id)) limit 1 ) +) as x from t1 where (t1.bug_id=45199); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 +2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 func 1 Using where +3 SUBQUERY t2 ref PRIMARY PRIMARY 4 const 3 Using index +4 UNION t2 ref PRIMARY PRIMARY 4 func 1 Using where; Using index +5 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +6 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +select +( +select login_name from t4 where userId = ( +select userid from t2 where product_id = t1.product_id +union +select userid from t2 where product_id = ( +select id from t5 where name = (select name from t3 where id = t1.product_id)) limit 1 ) +) as x from t1 where (t1.bug_id=45199); +x +foo +drop table t1, t2, t3, t4, t5; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 4e3146052e9..3088704e911 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4633,7 +4633,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<10,`test`.`t1`.`a`>((10,(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond((((10) = NULL) or (isnull(NULL))))) having trigcond((NULL))))))) +Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<10,`test`.`t1`.`a`>((10,(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond((((10) = NULL) or 1))) having trigcond((NULL))))))) SELECT * FROM t1, t2 WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) WHERE t4.a >= t1.a); @@ -4649,7 +4649,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1276 Field or reference 'v1.a' of SELECT #2 was resolved in SELECT #1 -Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<10,`test`.`t1`.`a`>((10,(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond((((10) = NULL) or (isnull(NULL))))) having trigcond((NULL))))))) +Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<10,`test`.`t1`.`a`>((10,(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond((((10) = NULL) or 1))) having trigcond((NULL))))))) SELECT * FROM v1, t2 WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) WHERE t4.a >= v1.a); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 240115837c7..8ef8f7c4017 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1437,3 +1437,38 @@ SET @advertAcctId = 1000003; select @advertAcctId as a from dual union all select 1.0 from dual; --echo End of 5.5 tests + +--echo # +--echo # MDEV-13784: query causes seg fault +--echo # + +CREATE TABLE t1 (`bug_id` int NOT NULL PRIMARY KEY, `product_id` int NOT NULL); +INSERT INTO t1 VALUES (45199,1184); + +CREATE TABLE t2 (`product_id` int NOT NULL,`userid` int NOT NULL, PRIMARY KEY (`product_id`,`userid`)); +INSERT INTO t2 VALUES (1184,103),(1184,624),(1184,1577),(1184,1582); + +CREATE TABLE t3 (`id` int NOT NULL PRIMARY KEY,`name` varchar(64)); + + +CREATE TABLE t4 ( `userid` int NOT NULL PRIMARY KEY, `login_name` varchar(255)); +INSERT INTO t4 VALUES (103,'foo'),(624,'foo'),(1577,'foo'),(1582,'foo'); +CREATE TABLE t5 (`id` int NOT NULL PRIMARY KEY, `name` varchar(64)); + +explain select +( + select login_name from t4 where userId = ( + select userid from t2 where product_id = t1.product_id + union + select userid from t2 where product_id = ( + select id from t5 where name = (select name from t3 where id = t1.product_id)) limit 1 ) +) as x from t1 where (t1.bug_id=45199); +select +( + select login_name from t4 where userId = ( + select userid from t2 where product_id = t1.product_id + union + select userid from t2 where product_id = ( + select id from t5 where name = (select name from t3 where id = t1.product_id)) limit 1 ) +) as x from t1 where (t1.bug_id=45199); +drop table t1, t2, t3, t4, t5; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 891cf9987c6..08c169c5999 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3551,6 +3551,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) inner_join->select_options|= SELECT_DESCRIBE; } res= inner_join->optimize(); + sl->update_used_tables(); sl->update_correlated_cache(); is_correlated_unit|= sl->is_correlated; inner_join->select_options= save_options; From a06a3e467029cafc3c7f432fff9603fe9030c480 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 14 Jan 2019 22:14:56 +0300 Subject: [PATCH 3/7] MDEV-18233 Moving the hash_node_t to improve locality of reference When performing a hash search via HASH_SEARCH we first look at a key of a node and then at its pointer to the next node in chain. If we have those in one cache line instead of a two we reduce memory reads. I found dict_table_t, fil_space_t and buf_page_t suitable for such improvement. --- storage/innobase/include/buf0buf.h | 6 +++--- storage/innobase/include/dict0mem.h | 4 ++-- storage/innobase/include/fil0fil.h | 4 ++-- storage/xtradb/include/buf0buf.h | 6 +++--- storage/xtradb/include/dict0mem.h | 4 ++-- storage/xtradb/include/fil0fil.h | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index cddab05f84d..a5a493ab769 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1443,6 +1443,9 @@ struct buf_page_t{ by buf_pool->mutex. */ ib_uint32_t offset; /*!< page number; also protected by buf_pool->mutex. */ + buf_page_t* hash; /*!< node used in chaining to + buf_pool->page_hash or + buf_pool->zip_hash */ /** count of how manyfold this block is currently bufferfixed */ #ifdef PAGE_ATOMIC_REF_COUNT ib_uint32_t buf_fix_count; @@ -1489,9 +1492,6 @@ struct buf_page_t{ zip.data == NULL means an active buf_pool->watch */ #ifndef UNIV_HOTBACKUP - buf_page_t* hash; /*!< node used in chaining to - buf_pool->page_hash or - buf_pool->zip_hash */ #ifdef UNIV_DEBUG ibool in_page_hash; /*!< TRUE if in buf_pool->page_hash */ ibool in_zip_hash; /*!< TRUE if in buf_pool->zip_hash */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 872db7865d3..73f104fdef1 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -926,8 +926,10 @@ struct dict_table_t{ table_id_t id; /*!< id of the table */ + hash_node_t id_hash; /*!< hash chain node */ mem_heap_t* heap; /*!< memory heap */ char* name; /*!< table name */ + hash_node_t name_hash; /*!< hash chain node */ const char* dir_path_of_temp_table;/*!< NULL or the directory path where a TEMPORARY table that was explicitly created by a user should be placed if @@ -983,8 +985,6 @@ struct dict_table_t{ dictionary information and MySQL FRM information mismatch. */ #ifndef UNIV_HOTBACKUP - hash_node_t name_hash; /*!< hash chain node */ - hash_node_t id_hash; /*!< hash chain node */ UT_LIST_BASE_NODE_T(dict_index_t) indexes; /*!< list of indexes of the table */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 6e772e31772..7c0f623d890 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -245,7 +245,9 @@ struct fil_node_t { struct fil_space_t { char* name; /*!< space name = the path to the first file in it */ + hash_node_t name_hash;/*!< hash chain the name_hash table */ ulint id; /*!< space id */ + hash_node_t hash; /*!< hash chain node */ ib_int64_t tablespace_version; /*!< in DISCARD/IMPORT this timestamp is used to check if we should ignore @@ -292,8 +294,6 @@ struct fil_space_t { trying to read a block. Dropping of the tablespace is forbidden if this is positive */ - hash_node_t hash; /*!< hash chain node */ - hash_node_t name_hash;/*!< hash chain the name_hash table */ #ifndef UNIV_HOTBACKUP rw_lock_t latch; /*!< latch protecting the file space storage allocation */ diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index a5b5cc84166..0f6b8b67250 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -1477,6 +1477,9 @@ struct buf_page_t{ ib_uint32_t space; /*!< tablespace id. */ ib_uint32_t offset; /*!< page number. */ + buf_page_t* hash; /*!< node used in chaining to + buf_pool->page_hash or + buf_pool->zip_hash */ /** count of how manyfold this block is currently bufferfixed */ #ifdef PAGE_ATOMIC_REF_COUNT ib_uint32_t buf_fix_count; @@ -1530,9 +1533,6 @@ struct buf_page_t{ zip.data == NULL means an active buf_pool->watch */ #ifndef UNIV_HOTBACKUP - buf_page_t* hash; /*!< node used in chaining to - buf_pool->page_hash or - buf_pool->zip_hash */ #ifdef UNIV_DEBUG ibool in_page_hash; /*!< TRUE if in buf_pool->page_hash */ ibool in_zip_hash; /*!< TRUE if in buf_pool->zip_hash */ diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index e6c0aa1f252..0c6a84523a4 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -937,8 +937,10 @@ struct dict_table_t{ table_id_t id; /*!< id of the table */ + hash_node_t id_hash; /*!< hash chain node */ mem_heap_t* heap; /*!< memory heap */ char* name; /*!< table name */ + hash_node_t name_hash; /*!< hash chain node */ const char* dir_path_of_temp_table;/*!< NULL or the directory path where a TEMPORARY table that was explicitly created by a user should be placed if @@ -994,8 +996,6 @@ struct dict_table_t{ dictionary information and MySQL FRM information mismatch. */ #ifndef UNIV_HOTBACKUP - hash_node_t name_hash; /*!< hash chain node */ - hash_node_t id_hash; /*!< hash chain node */ UT_LIST_BASE_NODE_T(dict_index_t) indexes; /*!< list of indexes of the table */ diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 86b1c561349..1f3574d4f71 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -238,7 +238,9 @@ struct fil_node_t { struct fil_space_t { char* name; /*!< space name = the path to the first file in it */ + hash_node_t name_hash;/*!< hash chain the name_hash table */ ulint id; /*!< space id */ + hash_node_t hash; /*!< hash chain node */ ib_int64_t tablespace_version; /*!< in DISCARD/IMPORT this timestamp is used to check if we should ignore @@ -285,8 +287,6 @@ struct fil_space_t { trying to read a block. Dropping of the tablespace is forbidden if this is positive */ - hash_node_t hash; /*!< hash chain node */ - hash_node_t name_hash;/*!< hash chain the name_hash table */ #ifndef UNIV_HOTBACKUP prio_rw_lock_t latch; /*!< latch protecting the file space storage allocation */ From 71e9f0d123e201141c80a240d50347ab36ce126f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 15 Jan 2019 11:50:15 +0200 Subject: [PATCH 4/7] MDEV-17797 Add ASAN poisoning for mem_heap_t The merge commit d833bb65d53b9a4375fa71cc485b4719fdb0ee53 did not correctly merge the commit 03eb15933da9944e821bc8c787f84de50e823da0. Closes #948 --- storage/innobase/include/univ.i | 11 +++++------ storage/innobase/row/row0ftsort.cc | 7 +++---- storage/xtradb/include/univ.i | 11 +++++------ storage/xtradb/row/row0ftsort.cc | 7 +++---- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index a9d886607c0..5027b9cab5e 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -585,12 +585,14 @@ typedef void* os_thread_ret_t; #include "ut0dbg.h" #include "ut0ut.h" #include "db0err.h" +#include +/* define UNIV macros in terms of my_valgrind.h */ +#define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size) +#define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size) +#define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size) #ifdef UNIV_DEBUG_VALGRIND # include # define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size) -# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) -# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size) -# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr) # define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b) # define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do { \ @@ -625,9 +627,6 @@ typedef void* os_thread_ret_t; } while (0) #else # define UNIV_MEM_VALID(addr, size) do {} while(0) -# define UNIV_MEM_INVALID(addr, size) do {} while(0) -# define UNIV_MEM_FREE(addr, size) do {} while(0) -# define UNIV_MEM_ALLOC(addr, size) do {} while(0) # define UNIV_MEM_DESC(addr, size) do {} while(0) # define UNIV_MEM_UNDESC(b) do {} while(0) # define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do {} while(0) diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 757e268c3a7..ccc26478c72 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -741,7 +741,7 @@ loop: goto func_exit; } - UNIV_MEM_INVALID(block[t_ctx.buf_used][0], srv_sort_buf_size); + UNIV_MEM_INVALID(block[t_ctx.buf_used], srv_sort_buf_size); buf[t_ctx.buf_used] = row_merge_buf_empty(buf[t_ctx.buf_used]); mycount[t_ctx.buf_used] += t_ctx.rows_added[t_ctx.buf_used]; t_ctx.rows_added[t_ctx.buf_used] = 0; @@ -834,8 +834,7 @@ exit: goto func_exit; } - UNIV_MEM_INVALID(block[i][0], - srv_sort_buf_size); + UNIV_MEM_INVALID(block[i], srv_sort_buf_size); } buf[i] = row_merge_buf_empty(buf[i]); diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 5df8a10bcf9..e9ff9103fdd 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -607,12 +607,14 @@ typedef void* os_thread_ret_t; #include "ut0dbg.h" #include "ut0ut.h" #include "db0err.h" +#include +/* define UNIV macros in terms of my_valgrind.h */ +#define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size) +#define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size) +#define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size) #ifdef UNIV_DEBUG_VALGRIND # include # define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size) -# define UNIV_MEM_INVALID(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) -# define UNIV_MEM_FREE(addr, size) VALGRIND_MAKE_MEM_NOACCESS(addr, size) -# define UNIV_MEM_ALLOC(addr, size) VALGRIND_MAKE_MEM_UNDEFINED(addr, size) # define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr) # define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b) # define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do { \ @@ -647,9 +649,6 @@ typedef void* os_thread_ret_t; } while (0) #else # define UNIV_MEM_VALID(addr, size) do {} while(0) -# define UNIV_MEM_INVALID(addr, size) do {} while(0) -# define UNIV_MEM_FREE(addr, size) do {} while(0) -# define UNIV_MEM_ALLOC(addr, size) do {} while(0) # define UNIV_MEM_DESC(addr, size) do {} while(0) # define UNIV_MEM_UNDESC(b) do {} while(0) # define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do {} while(0) diff --git a/storage/xtradb/row/row0ftsort.cc b/storage/xtradb/row/row0ftsort.cc index bb9821d4484..d5df122c9a8 100644 --- a/storage/xtradb/row/row0ftsort.cc +++ b/storage/xtradb/row/row0ftsort.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, 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 @@ -744,7 +744,7 @@ loop: goto func_exit; } - UNIV_MEM_INVALID(block[t_ctx.buf_used][0], srv_sort_buf_size); + UNIV_MEM_INVALID(block[t_ctx.buf_used], srv_sort_buf_size); buf[t_ctx.buf_used] = row_merge_buf_empty(buf[t_ctx.buf_used]); mycount[t_ctx.buf_used] += t_ctx.rows_added[t_ctx.buf_used]; t_ctx.rows_added[t_ctx.buf_used] = 0; @@ -837,8 +837,7 @@ exit: goto func_exit; } - UNIV_MEM_INVALID(block[i][0], - srv_sort_buf_size); + UNIV_MEM_INVALID(block[i], srv_sort_buf_size); } buf[i] = row_merge_buf_empty(buf[i]); From e0633f25e8cd954197d450902f863cc824d99755 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Tue, 15 Jan 2019 14:55:12 +0300 Subject: [PATCH 5/7] MDEV-18243 incorrect ASAN instrumentation Poisoning memory after munmap() and friends is totally incorrect as this memory could be anything. os_mem_free_large(): remove memory poisoning --- storage/innobase/os/os0proc.cc | 3 --- storage/xtradb/os/os0proc.cc | 3 --- 2 files changed, 6 deletions(-) diff --git a/storage/innobase/os/os0proc.cc b/storage/innobase/os/os0proc.cc index ff6d65e4ae6..f711fbb025b 100644 --- a/storage/innobase/os/os0proc.cc +++ b/storage/innobase/os/os0proc.cc @@ -192,7 +192,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); return; } #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */ @@ -208,7 +207,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); } #elif !defined OS_MAP_ANON ut_free(ptr); @@ -226,7 +224,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); } #endif } diff --git a/storage/xtradb/os/os0proc.cc b/storage/xtradb/os/os0proc.cc index 6c9116e1397..c64c37705b5 100644 --- a/storage/xtradb/os/os0proc.cc +++ b/storage/xtradb/os/os0proc.cc @@ -247,7 +247,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); return; } #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */ @@ -263,7 +262,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); } #elif !defined OS_MAP_ANON ut_free(ptr); @@ -281,7 +279,6 @@ os_mem_free_large( ut_a(ut_total_allocated_memory >= size); ut_total_allocated_memory -= size; os_fast_mutex_unlock(&ut_list_mutex); - UNIV_MEM_FREE(ptr, size); } #endif } From db469b6907a02b1441b16eac1d464673f48f9ef4 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 11 Jan 2019 11:55:07 +0100 Subject: [PATCH 6/7] MDEV-17475: Increase maximum possible value for table_definition_cache to match table_open_cache Allow table definition cache be bigger than open table cache (due to problem with VIEWs and prepared statements). --- .../r/table_definition_cache_basic.result | 16 ++++++++-------- .../sys_vars/t/table_definition_cache_basic.test | 6 +++--- sql/sys_vars.cc | 8 ++++++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/table_definition_cache_basic.result b/mysql-test/suite/sys_vars/r/table_definition_cache_basic.result index f6befe51bc1..f7ce3f53bfc 100644 --- a/mysql-test/suite/sys_vars/r/table_definition_cache_basic.result +++ b/mysql-test/suite/sys_vars/r/table_definition_cache_basic.result @@ -28,14 +28,14 @@ Warning 1292 Truncated incorrect table_definition_cache value: '2' SELECT @@global.table_definition_cache; @@global.table_definition_cache 400 -SET @@global.table_definition_cache = 524287; +SET @@global.table_definition_cache = 2097151; SELECT @@global.table_definition_cache; @@global.table_definition_cache -524287 -SET @@global.table_definition_cache = 524288; +2097151 +SET @@global.table_definition_cache = 2097152; SELECT @@global.table_definition_cache; @@global.table_definition_cache -524288 +2097152 '#--------------------FN_DYNVARS_019_04-------------------------#' SET @@global.table_definition_cache = 0; Warnings: @@ -49,18 +49,18 @@ Warning 1292 Truncated incorrect table_definition_cache value: '-1024' SELECT @@global.table_definition_cache; @@global.table_definition_cache 400 -SET @@global.table_definition_cache = 524289; +SET @@global.table_definition_cache = 2097153; Warnings: -Warning 1292 Truncated incorrect table_definition_cache value: '524289' +Warning 1292 Truncated incorrect table_definition_cache value: '2097153' SELECT @@global.table_definition_cache; @@global.table_definition_cache -524288 +2097152 SET @@global.table_definition_cache = 42949672950; Warnings: Warning 1292 Truncated incorrect table_definition_cache value: '42949672950' SELECT @@global.table_definition_cache; @@global.table_definition_cache -524288 +2097152 SET @@global.table_definition_cache = 21221204.10; ERROR 42000: Incorrect argument type to variable 'table_definition_cache' SET @@global.table_definition_cache = ON; diff --git a/mysql-test/suite/sys_vars/t/table_definition_cache_basic.test b/mysql-test/suite/sys_vars/t/table_definition_cache_basic.test index 69f29108645..183d1d0316e 100644 --- a/mysql-test/suite/sys_vars/t/table_definition_cache_basic.test +++ b/mysql-test/suite/sys_vars/t/table_definition_cache_basic.test @@ -64,9 +64,9 @@ SET @@global.table_definition_cache = 1; SELECT @@global.table_definition_cache; SET @@global.table_definition_cache = 2; SELECT @@global.table_definition_cache; -SET @@global.table_definition_cache = 524287; +SET @@global.table_definition_cache = 2097151; SELECT @@global.table_definition_cache; -SET @@global.table_definition_cache = 524288; +SET @@global.table_definition_cache = 2097152; SELECT @@global.table_definition_cache; @@ -79,7 +79,7 @@ SET @@global.table_definition_cache = 0; SELECT @@global.table_definition_cache; SET @@global.table_definition_cache = -1024; SELECT @@global.table_definition_cache; -SET @@global.table_definition_cache = 524289; +SET @@global.table_definition_cache = 2097153; SELECT @@global.table_definition_cache; SET @@global.table_definition_cache = 42949672950; SELECT @@global.table_definition_cache; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index a21fe5df247..71fdfa8f219 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3039,11 +3039,15 @@ static Sys_var_charptr Sys_system_time_zone( NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(system_time_zone)); +/* + If One use views with prepared statements this should be bigger than + table_open_cache (now we allow 2 times bigger value) +*/ static Sys_var_ulong Sys_table_def_size( "table_definition_cache", "The number of cached table definitions", GLOBAL_VAR(tdc_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(TABLE_DEF_CACHE_MIN, 512*1024), + VALID_RANGE(TABLE_DEF_CACHE_MIN, 2*1024*1024), DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1)); @@ -3055,7 +3059,7 @@ static bool fix_table_open_cache(sys_var *, THD *, enum_var_type) return false; } - +/* Check the table_definition_cache comment if makes changes */ static Sys_var_ulong Sys_table_cache_size( "table_open_cache", "The number of cached open tables", GLOBAL_VAR(tc_size), CMD_LINE(REQUIRED_ARG), From 19a7656fb12bfae7472658056f400bb81ab99c2f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 21 May 2018 10:42:44 +1000 Subject: [PATCH 7/7] safemalloc: warn, flush after fprintf Corrects 94d722b6a43b86ee760f07915921cf58f9869a5d --- mysys/safemalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 5d19647c989..08e43d0a80a 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -282,8 +282,8 @@ static void warn(const char *format,...) va_list args; DBUG_PRINT("error", ("%s", format)); va_start(args,format); - fflush(stderr); vfprintf(stderr, format, args); + fflush(stderr); va_end(args); #ifdef HAVE_BACKTRACE