From 75f781f0d27d73dce4c7570e5b94b9482903c907 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Fri, 5 Mar 2021 17:51:17 +0000 Subject: [PATCH 1/4] MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns optimize_schema_tables_memory_usage() crashed when its argument included TABLE struct that was not fully initialized. To prevent such a crash, we check if a table is an information schema table at the beginning of each iteration. Closes #1768 --- mysql-test/main/information_schema.result | 7 +++++++ mysql-test/main/information_schema.test | 8 ++++++++ sql/sql_show.cc | 11 ++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index c65a10cbd4b..28c1122ac03 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -2316,5 +2316,12 @@ count(*) 2 DROP TABLE t1; # +# MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns +# +create table t1 ( name varchar(64) character set utf8, len int); +select * from t1 where (name, len) in (select name, len from information_schema.innodb_sys_columns having len = 8); +name len +drop table t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index 4468eb18e45..71e700f3f18 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -2044,6 +2044,14 @@ INSERT INTO t1 VALUES ('2012-12-12'),('2021-11-11'); SELECT count(*) FROM t1 AS t1a LEFT JOIN (t1 AS t1b JOIN INFORMATION_SCHEMA.ROUTINES) ON (t1b.a IS NULL); SELECT count(*) FROM t1 AS t1a LEFT JOIN (t1 AS t1b JOIN INFORMATION_SCHEMA.PROFILING) ON (t1b.a IS NULL); DROP TABLE t1; + +--echo # +--echo # MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns +--echo # +create table t1 ( name varchar(64) character set utf8, len int); +select * from t1 where (name, len) in (select name, len from information_schema.innodb_sys_columns having len = 8); +drop table t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e6b5461e5af..469f28acf6c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8672,14 +8672,19 @@ end: bool optimize_schema_tables_memory_usage(List &tables) { + DBUG_ENTER("optimize_schema_tables_memory_usage"); + List_iterator tli(tables); while (TABLE_LIST *table_list= tli++) { + if (!table_list->schema_table) + continue; + TABLE *table= table_list->table; THD *thd=table->in_use; - if (!table_list->schema_table || !thd->fill_information_schema_tables()) + if (!thd->fill_information_schema_tables()) continue; if (!table->is_created()) @@ -8726,10 +8731,10 @@ bool optimize_schema_tables_memory_usage(List &tables) // TODO switch from Aria to Memory if all blobs were optimized away? if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo, table_list->select_lex->options | thd->variables.option_bits)) - return 1; + DBUG_RETURN(1); } } - return 0; + DBUG_RETURN(0); } From cc9c303a450bf9cbb9bda51638d0c435fe755336 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 10 Mar 2021 16:46:42 +0530 Subject: [PATCH 2/4] MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table InnoDB set the space in dict_table_t as NULL when table is discarded. So InnoDB shouldn't use the space present in table to detect whether the given tablespace is temporary tablespace. --- mysql-test/suite/innodb_fts/r/fulltext.result | 16 ++++++++++++++++ mysql-test/suite/innodb_fts/t/fulltext.test | 9 +++++++++ storage/innobase/fts/fts0fts.cc | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index 0e30dd0be05..f41b938604d 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -689,3 +689,19 @@ FTS_DOC_ID t 2 foo bar 3 foo DROP TABLE t; +# +# MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table +# +CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 ADD FULLTEXT INDEX (a); +Warnings: +Warning 1814 Tablespace has been discarded for table `t1` +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) DEFAULT NULL, + FULLTEXT KEY `a` (`a`), + FULLTEXT KEY `a_2` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 663b202265b..560ee8f96f2 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -717,3 +717,12 @@ while ($N) } DROP TABLE t; + +--echo # +--echo # MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table +--echo # +CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 ADD FULLTEXT INDEX (a); +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 859ec5051f2..cf76e3c83cd 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1730,7 +1730,7 @@ fts_create_in_mem_aux_table( dict_table_t* new_table = dict_mem_table_create( aux_table_name, NULL, n_cols, 0, table->flags, table->space_id == TRX_SYS_SPACE - ? 0 : table->space->purpose == FIL_TYPE_TEMPORARY + ? 0 : table->space_id == SRV_TMP_SPACE_ID ? DICT_TF2_TEMPORARY : DICT_TF2_USE_FILE_PER_TABLE); if (DICT_TF_HAS_DATA_DIR(table->flags)) { From 6e7ac4060d28a35e12d6a34450e5624734d3a9be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 12:34:56 +0200 Subject: [PATCH 3/4] MDEV-25070 fixup: Correct the result --- mysql-test/suite/innodb_fts/r/fulltext.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index f41b938604d..c3345548c0d 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -691,7 +691,7 @@ FTS_DOC_ID t DROP TABLE t; # # MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table -# +# CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 ADD FULLTEXT INDEX (a); From 08e8ad7c717302a77db91cfa06909eb8c10006fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 12:50:04 +0200 Subject: [PATCH 4/4] MDEV-25106 Deprecation warning for innodb_checksum_algorithm=none,innodb,... MDEV-25105 (commit 7a4fbb55b02b449a135fe935f624422eaacfdd7c) in MariaDB 10.6 will refuse the innodb_checksum_algorithm values none, innodb, strict_none, strict_innodb. We will issue a deprecation warning if innodb_checksum_algorithm is set to any of these non-default unsafe values. innodb_checksum_algorithm=crc32 was made the default in MySQL 5.7 and MariaDB Server 10.2, and given that older versions of the server have reached their end of life, there is no valid reason to use anything else than innodb_checksum_algorithm=crc32 or innodb_checksum_algorithm=strict_crc32 in MariaDB 10.3. Reviewed by: Sergei Golubchik --- .../r/innodb-checksum-algorithm.result | 18 ++++++++++ .../r/innodb_checksum_algorithm_basic.result | 8 +++++ storage/innobase/handler/ha_innodb.cc | 33 +++++++++++++++++-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result index ff42e975b8d..a43676dcebe 100644 --- a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result @@ -8,6 +8,8 @@ SET GLOBAL innodb_encrypt_tables = ON; SET GLOBAL innodb_encryption_threads = 4; call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_(crc32|none|innodb)\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"(innodb|none|crc32)\""); SET GLOBAL innodb_checksum_algorithm = innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SET GLOBAL innodb_default_encryption_key_id=4; SET GLOBAL innodb_checksum_algorithm=crc32; create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb @@ -90,6 +92,8 @@ update tpe_crc32 set b=substr(b,1); ALTER TABLE tp_crc32 IMPORT TABLESPACE; update tp_crc32 set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_crc32 DISCARD TABLESPACE; ALTER TABLE tc_crc32 DISCARD TABLESPACE; ALTER TABLE te_crc32 DISCARD TABLESPACE; @@ -115,6 +119,8 @@ update tpe_crc32 set b=substr(b,1); ALTER TABLE tp_crc32 IMPORT TABLESPACE; update tp_crc32 set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_crc32 DISCARD TABLESPACE; ALTER TABLE tc_crc32 DISCARD TABLESPACE; ALTER TABLE te_crc32 DISCARD TABLESPACE; @@ -151,6 +157,8 @@ test.tp_crc32 check status OK DROP TABLE tce_crc32, tc_crc32, te_crc32, t_crc32, tpe_crc32, tp_crc32; SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb ROW_FORMAT=COMPRESSED encrypted=yes; create table tc_innodb(a serial, b blob, index(b(10))) engine=innodb @@ -231,6 +239,8 @@ update tpe_innodb set b=substr(b,1); ALTER TABLE tp_innodb IMPORT TABLESPACE; update tp_innodb set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_innodb DISCARD TABLESPACE; ALTER TABLE tc_innodb DISCARD TABLESPACE; ALTER TABLE te_innodb DISCARD TABLESPACE; @@ -256,6 +266,8 @@ update tpe_innodb set b=substr(b,1); ALTER TABLE tp_innodb IMPORT TABLESPACE; update tp_innodb set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_innodb DISCARD TABLESPACE; ALTER TABLE tc_innodb DISCARD TABLESPACE; ALTER TABLE te_innodb DISCARD TABLESPACE; @@ -292,6 +304,8 @@ test.tp_innodb check status OK DROP TABLE tce_innodb, tc_innodb, te_innodb, t_innodb, tpe_innodb, tp_innodb; SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. create table tce_none(a serial, b blob, index(b(10))) engine=innodb ROW_FORMAT=COMPRESSED encrypted=yes; create table tc_none(a serial, b blob, index(b(10))) engine=innodb @@ -372,6 +386,8 @@ update tpe_none set b=substr(b,1); ALTER TABLE tp_none IMPORT TABLESPACE; update tp_none set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_none DISCARD TABLESPACE; ALTER TABLE tc_none DISCARD TABLESPACE; ALTER TABLE te_none DISCARD TABLESPACE; @@ -397,6 +413,8 @@ update tpe_none set b=substr(b,1); ALTER TABLE tp_none IMPORT TABLESPACE; update tp_none set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_none DISCARD TABLESPACE; ALTER TABLE tc_none DISCARD TABLESPACE; ALTER TABLE te_none DISCARD TABLESPACE; diff --git a/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result b/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result index 9c2e95b3c7c..912acb69ab0 100644 --- a/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result @@ -11,18 +11,26 @@ SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_crc32 SET GLOBAL innodb_checksum_algorithm = 'innodb'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm innodb SET GLOBAL innodb_checksum_algorithm = 'strict_innodb'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_innodb SET GLOBAL innodb_checksum_algorithm = 'none'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm none SET GLOBAL innodb_checksum_algorithm = 'strict_none'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_none diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b0b7a96116a..5074855af64 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3509,6 +3509,11 @@ static int innodb_init_abort() static const char* deprecated_idle_flush_pct = "innodb_idle_flush_pct is DEPRECATED and has no effect."; +static const char* deprecated_innodb_checksum_algorithm + = "Setting innodb_checksum_algorithm to values other than" + " crc32 or strict_crc32 is UNSAFE and DEPRECATED." + " These deprecated values will be disallowed in MariaDB 10.6."; + static ulong innodb_idle_flush_pct; /** If applicable, emit a message that log checksums cannot be disabled. @@ -3537,6 +3542,21 @@ innodb_log_checksums_func_update(THD* thd, bool check) return(check); } +static void innodb_checksum_algorithm_update(THD *thd, st_mysql_sys_var*, + void *, const void *save) +{ + srv_checksum_algorithm= *static_cast(save); + switch (srv_checksum_algorithm) { + case SRV_CHECKSUM_ALGORITHM_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + break; + default: + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_UNSUPPORTED, + deprecated_innodb_checksum_algorithm); + } +} + /****************************************************************//** Gives the file extension of an InnoDB single-table tablespace. */ static const char* ha_innobase_exts[] = { @@ -3953,9 +3973,16 @@ static int innodb_init_params() if (!innobase_use_checksums) { ib::warn() << "Setting innodb_checksums to OFF is DEPRECATED." - " This option may be removed in future releases. You" - " should set innodb_checksum_algorithm=NONE instead."; + " This option was removed in MariaDB 10.5."; srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_NONE; + } else { + switch (srv_checksum_algorithm) { + case SRV_CHECKSUM_ALGORITHM_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + break; + default: + ib::warn() << deprecated_innodb_checksum_algorithm; + } } innodb_log_checksums = innodb_log_checksums_func_update( @@ -19111,7 +19138,7 @@ static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm, " magic number when reading;" " Files updated when this option is set to crc32 or strict_crc32 will" " not be readable by MariaDB versions older than 10.0.4", - NULL, NULL, SRV_CHECKSUM_ALGORITHM_CRC32, + NULL, innodb_checksum_algorithm_update, SRV_CHECKSUM_ALGORITHM_CRC32, &innodb_checksum_algorithm_typelib); static MYSQL_SYSVAR_BOOL(log_checksums, innodb_log_checksums,