From b06e8167a7b8f9ae9cf2f7c19054ecc9c0c78398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Oct 2021 15:54:25 +0300 Subject: [PATCH] MDEV-22627 Failing assertion: dict_tf2_is_valid(flags, flags2) create_table_info_t::innobase_table_flags(): Refuse to create a PAGE_COMPRESSED table with PAGE_COMPRESSION_LEVEL=0 if also innodb_compression_level=0. The parameter value innodb_compression_level=0 was only somewhat meaningful for testing or debugging ROW_FORMAT=COMPRESSED tables. For the page_compressed format, it never made any sense, and the check in dict_tf_is_valid_not_redundant() that was added in 72378a25830184f91005be7e80cfb28381c79f23 (MDEV-12873) would cause the server to crash. --- .../default_row_format_create,redundant.rdiff | 9 +++++++ .../innodb/r/default_row_format_create.result | 15 ++++++++++++ .../innodb/t/default_row_format_create.test | 16 +++++++++++++ storage/innobase/handler/ha_innodb.cc | 24 ++++++++++++------- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/innodb/r/default_row_format_create,redundant.rdiff b/mysql-test/suite/innodb/r/default_row_format_create,redundant.rdiff index 29bc560907e..0e94bfd1c0f 100644 --- a/mysql-test/suite/innodb/r/default_row_format_create,redundant.rdiff +++ b/mysql-test/suite/innodb/r/default_row_format_create,redundant.rdiff @@ -20,3 +20,12 @@ SET @save_format = @@GLOBAL.innodb_default_row_format; SET GLOBAL innodb_default_row_format = redundant; CREATE TABLE t1 (c1 INT) ENGINE=InnoDB; +@@ -49,7 +49,7 @@ + ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options") + SHOW WARNINGS; + Level Code Message +-Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0 ++Warning 140 InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=REDUNDANT + Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options") + Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB + CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1; diff --git a/mysql-test/suite/innodb/r/default_row_format_create.result b/mysql-test/suite/innodb/r/default_row_format_create.result index d51a63dbd01..d85fed35d92 100644 --- a/mysql-test/suite/innodb/r/default_row_format_create.result +++ b/mysql-test/suite/innodb/r/default_row_format_create.result @@ -42,3 +42,18 @@ SHOW TABLE STATUS LIKE 't1'; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment t1 InnoDB # Redundant # # # # # # NULL # NULL NULL latin1_swedish_ci NULL DROP TABLE t1; +SET @save_level=@@GLOBAL.innodb_compression_level; +SET GLOBAL innodb_compression_level=0; +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1; +ERROR HY000: Can't create table `test`.`t` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: PAGE_COMPRESSED requires PAGE_COMPRESSION_LEVEL or innodb_compression_level > 0 +Error 1005 Can't create table `test`.`t` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1; +DROP TABLE IF EXISTS t; +SET GLOBAL innodb_compression_level=1; +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1; +DROP TABLE IF EXISTS t; +SET GLOBAL innodb_compression_level=@save_level; diff --git a/mysql-test/suite/innodb/t/default_row_format_create.test b/mysql-test/suite/innodb/t/default_row_format_create.test index 03a7ebd3752..a1c6ff0d588 100644 --- a/mysql-test/suite/innodb/t/default_row_format_create.test +++ b/mysql-test/suite/innodb/t/default_row_format_create.test @@ -44,3 +44,19 @@ TRUNCATE TABLE t1; --replace_column 3 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # SHOW TABLE STATUS LIKE 't1'; DROP TABLE t1; + +SET @save_level=@@GLOBAL.innodb_compression_level; +SET GLOBAL innodb_compression_level=0; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1; +SHOW WARNINGS; +--disable_warnings +--error 0,ER_CANT_CREATE_TABLE +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1 page_compression_level=1; +DROP TABLE IF EXISTS t; +SET GLOBAL innodb_compression_level=1; +--error 0,ER_CANT_CREATE_TABLE +CREATE TABLE t(c INT) ENGINE=InnoDB page_compressed=1; +DROP TABLE IF EXISTS t; +--enable_warnings +SET GLOBAL innodb_compression_level=@save_level; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index fefd0bdde00..592492cac60 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11991,10 +11991,6 @@ bool create_table_info_t::innobase_table_flags() modified by another thread while the table is being created. */ const ulint file_format_allowed = srv_file_format; - /* Cache the value of innobase_compression_level, in case it is - modified by another thread while the table is being created. */ - const ulint default_compression_level = page_zip_level; - ha_table_option_struct *options= m_form->s->option_struct; m_flags = 0; @@ -12199,13 +12195,23 @@ index_bad: m_flags2 |= DICT_TF2_USE_FILE_PER_TABLE; } + ulint level = options->page_compression_level; + if (!level) { + level = page_zip_level; + if (!level && options->page_compressed) { + push_warning_printf( + m_thd, Sql_condition::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: PAGE_COMPRESSED requires" + " PAGE_COMPRESSION_LEVEL or" + " innodb_compression_level > 0"); + DBUG_RETURN(false); + } + } + /* Set the table flags */ dict_tf_set(&m_flags, innodb_row_format, zip_ssize, - m_use_data_dir, - options->page_compressed, - options->page_compression_level == 0 ? - default_compression_level : static_cast(options->page_compression_level), - 0); + m_use_data_dir, options->page_compressed, level, 0); /* Set the flags2 when create table or alter tables */ m_flags2 |= DICT_TF2_FTS_AUX_HEX_NAME;