diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-07-05 14:35:55 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-07-05 14:35:55 +0300 |
commit | e3d3147792ebe56cbdd8ab52f123bed36e85e00c (patch) | |
tree | 19b0b32c398d1b578a693d0bcdc7ccda09cd9071 | |
parent | f2931b1e3acbd4d7ffdfac75e27efce1ea19583b (diff) | |
download | mariadb-git-e3d3147792ebe56cbdd8ab52f123bed36e85e00c.tar.gz |
MDEV-13105 InnoDB fails to load a table with PAGE_COMPRESSION_LEVEL after upgrade from 10.1.20
When using innodb_page_size=16k, InnoDB tables
that were created in MariaDB 10.1.0 to 10.1.20 with
PAGE_COMPRESSED=1 and
PAGE_COMPRESSION_LEVEL=2 or PAGE_COMPRESSION_LEVEL=3
would fail to load.
fsp_flags_is_valid(): When using innodb_page_size=16k, use a
more strict check for .ibd files, with the assumption that
nobody would try to use different-page-size files.
-rw-r--r-- | extra/mariabackup/fil_cur.cc | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/include/ibd_convert.pl | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/101_compatibility.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/101_compatibility.test | 2 | ||||
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 2 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 12 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0file.cc | 10 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 2 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.ic | 2 | ||||
-rw-r--r-- | storage/innobase/include/fsp0fsp.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/fsp0space.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/fsp0types.h | 10 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 2 |
13 files changed, 29 insertions, 25 deletions
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc index 9df5f8e8fa3..b733f98457e 100644 --- a/extra/mariabackup/fil_cur.cc +++ b/extra/mariabackup/fil_cur.cc @@ -219,7 +219,7 @@ xb_fil_cur_open( return(XB_FIL_CUR_SKIP); } - if (!fsp_flags_is_valid(flags)) { + if (!fsp_flags_is_valid(flags, cursor->space_id)) { ulint cflags = fsp_flags_convert_from_101(flags); if (cflags == ULINT_UNDEFINED) { msg("[%02u] xtrabackup: Error: Invalid " diff --git a/mysql-test/suite/innodb/include/ibd_convert.pl b/mysql-test/suite/innodb/include/ibd_convert.pl index 9c7e829f455..bb9dfbe74b8 100644 --- a/mysql-test/suite/innodb/include/ibd_convert.pl +++ b/mysql-test/suite/innodb/include/ibd_convert.pl @@ -11,7 +11,7 @@ sub convert_to_mariadb_101 # FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start my($flags) = unpack "x[54]N", $_; my $badflags = ($flags & 0x3f); - my $compression_level=6; + my $compression_level=3; $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE diff --git a/mysql-test/suite/innodb/r/101_compatibility.result b/mysql-test/suite/innodb/r/101_compatibility.result index bc4d37916df..a1ca493a6b2 100644 --- a/mysql-test/suite/innodb/r/101_compatibility.result +++ b/mysql-test/suite/innodb/r/101_compatibility.result @@ -9,7 +9,7 @@ SET INNODB_STRICT_MODE=OFF; CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; SET INNODB_STRICT_MODE=ON; CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='MYSQL_TMP_DIR'; -CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1; +CREATE TABLE tp(a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1; CREATE TABLE ti(a INT) ENGINE=InnoDB; FLUSH TABLES ti FOR EXPORT; backup: ti diff --git a/mysql-test/suite/innodb/t/101_compatibility.test b/mysql-test/suite/innodb/t/101_compatibility.test index 78dee53e52f..eb3d3b0c014 100644 --- a/mysql-test/suite/innodb/t/101_compatibility.test +++ b/mysql-test/suite/innodb/t/101_compatibility.test @@ -29,7 +29,7 @@ SET INNODB_STRICT_MODE=ON; --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR EVAL CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='$MYSQL_TMP_DIR'; -CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1; +CREATE TABLE tp(a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC PAGE_COMPRESSED=1; CREATE TABLE ti(a INT) ENGINE=InnoDB; FLUSH TABLES ti FOR EXPORT; perl; diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index b770e8483d9..17b2229f1da 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -659,7 +659,7 @@ buf_dblwr_process() if (page_no == 0) { /* Check the FSP_SPACE_FLAGS. */ ulint flags = fsp_header_get_flags(page); - if (!fsp_flags_is_valid(flags) + if (!fsp_flags_is_valid(flags, space_id) && fsp_flags_convert_from_101(flags) == ULINT_UNDEFINED) { ib::warn() << "Ignoring a doublewrite copy" diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 2ec76017ba0..fec7405cb6d 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -663,7 +663,7 @@ retry: ut_free(buf2); os_file_close(node->handle); - if (!fsp_flags_is_valid(flags)) { + if (!fsp_flags_is_valid(flags, space->id)) { ulint cflags = fsp_flags_convert_from_101(flags); if (cflags == ULINT_UNDEFINED) { ib::error() @@ -1601,7 +1601,7 @@ fil_space_create( fil_space_t* space; ut_ad(fil_system); - ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); + ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, id)); ut_ad(purpose == FIL_TYPE_LOG || srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0); @@ -2388,7 +2388,7 @@ fil_op_write_log( ulint len; ut_ad(first_page_no == 0); - ut_ad(fsp_flags_is_valid(flags)); + ut_ad(fsp_flags_is_valid(flags, space_id)); /* fil_name_parse() requires that there be at least one path separator and that the file path end with ".ibd". */ @@ -3794,7 +3794,7 @@ fil_ibd_create( ut_ad(!srv_read_only_mode); ut_a(space_id < SRV_LOG_SPACE_FIRST_ID); ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE); - ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); + ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, space_id)); /* Create the subdirectories in the path, if they are not there already. */ @@ -4089,7 +4089,7 @@ fil_ibd_open( return(DB_CORRUPTION); } - ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); + ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK, id)); df_default.init(space_name, flags); df_dict.init(space_name, flags); df_remote.init(space_name, flags); @@ -4737,7 +4737,7 @@ void fsp_flags_try_adjust(ulint space_id, ulint flags) { ut_ad(!srv_read_only_mode); - ut_ad(fsp_flags_is_valid(flags)); + ut_ad(fsp_flags_is_valid(flags, space_id)); mtr_t mtr; mtr.start(); diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 1b3bb93c488..4f03ace9d8e 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -353,7 +353,7 @@ Datafile::read_first_page(bool read_only_mode) if (m_order == 0) { m_space_id = fsp_header_get_space_id(m_first_page); m_flags = fsp_header_get_flags(m_first_page); - if (!fsp_flags_is_valid(m_flags)) { + if (!fsp_flags_is_valid(m_flags, m_space_id)) { ulint cflags = fsp_flags_convert_from_101(m_flags); if (cflags == ULINT_UNDEFINED) { ib::error() @@ -524,9 +524,7 @@ Datafile::validate_first_page(lsn_t* flush_lsn) } /* Check if the whole page is blank. */ - if (error_txt == NULL - && m_space_id == srv_sys_space.space_id() - && !m_flags) { + if (error_txt == NULL && !m_space_id && !m_flags) { const byte* b = m_first_page; ulint nonzero_bytes = UNIV_PAGE_SIZE; @@ -558,7 +556,7 @@ Datafile::validate_first_page(lsn_t* flush_lsn) free_first_page(); return(DB_ERROR); - } else if (!fsp_flags_is_valid(m_flags)) { + } else if (!fsp_flags_is_valid(m_flags, m_space_id)) { /* Tablespace flags must be valid. */ error_txt = "Tablespace flags are invalid"; } else if (page_get_page_no(m_first_page) != 0) { @@ -799,7 +797,7 @@ Datafile::restore_from_doublewrite() ulint flags = mach_read_from_4( FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (!fsp_flags_is_valid(flags)) { + if (!fsp_flags_is_valid(flags, m_space_id)) { ulint cflags = fsp_flags_convert_from_101(flags); if (cflags == ULINT_UNDEFINED) { ib::warn() diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index bf86d83a8c7..33b237bd488 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -682,7 +682,7 @@ fsp_header_init_fields( ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */ { flags &= ~FSP_FLAGS_MEM_MASK; - ut_a(fsp_flags_is_valid(flags)); + ut_a(fsp_flags_is_valid(flags, space_id)); mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page, space_id); diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 0244bb784e0..9aaf506b2e3 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -878,7 +878,7 @@ dict_tf_to_fsp_flags(ulint table_flags) fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION; } - ut_a(fsp_flags_is_valid(fsp_flags)); + ut_a(fsp_flags_is_valid(fsp_flags, false)); if (DICT_TF_HAS_DATA_DIR(table_flags)) { fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 63fc211c88d..f9167e0462e 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -779,7 +779,7 @@ fsp_flags_convert_from_101(ulint flags) flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) << FSP_FLAGS_POS_PAGE_COMPRESSION); - ut_ad(fsp_flags_is_valid(flags)); + ut_ad(fsp_flags_is_valid(flags, false)); return(flags); } @@ -793,7 +793,7 @@ bool fsp_flags_match(ulint expected, ulint actual) { expected &= ~FSP_FLAGS_MEM_MASK; - ut_ad(fsp_flags_is_valid(expected)); + ut_ad(fsp_flags_is_valid(expected, false)); if (actual == expected) { return(true); diff --git a/storage/innobase/include/fsp0space.h b/storage/innobase/include/fsp0space.h index 2c28ecc5c7b..9f869fda158 100644 --- a/storage/innobase/include/fsp0space.h +++ b/storage/innobase/include/fsp0space.h @@ -129,7 +129,7 @@ public: @param[in] fsp_flags tablespace flags */ void set_flags(ulint fsp_flags) { - ut_ad(fsp_flags_is_valid(fsp_flags)); + ut_ad(fsp_flags_is_valid(fsp_flags, false)); m_flags = fsp_flags; } diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h index 129fd102f0f..c6dbe52def4 100644 --- a/storage/innobase/include/fsp0types.h +++ b/storage/innobase/include/fsp0types.h @@ -371,11 +371,12 @@ these are only used in MySQL 5.7 and used for compatibility. */ /** Validate the tablespace flags, which are stored in the tablespace header at offset FSP_SPACE_FLAGS. @param[in] flags the contents of FSP_SPACE_FLAGS +@param[in] is_ibd whether this is an .ibd file (not system tablespace) @return whether the flags are correct (not in the buggy 10.1) format */ MY_ATTRIBUTE((warn_unused_result, const)) UNIV_INLINE bool -fsp_flags_is_valid(ulint flags) +fsp_flags_is_valid(ulint flags, bool is_ibd) { DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false);); @@ -422,7 +423,12 @@ fsp_flags_is_valid(ulint flags) return(false); } - return(true); + /* The flags do look valid. But, avoid misinterpreting + buggy MariaDB 10.1 format flags for + PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL={0,2,3} + as valid-looking PAGE_SSIZE if this is known to be + an .ibd file and we are using the default innodb_page_size=16k. */ + return(ssize == 0 || !is_ibd || srv_page_size != UNIV_PAGE_SIZE_ORIG); } #endif /* fsp0types_h */ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index b2ac33a209b..45ca1582e49 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -527,7 +527,7 @@ AbstractCallback::init( const page_t* page = block->frame; m_space_flags = fsp_header_get_flags(page); - if (!fsp_flags_is_valid(m_space_flags)) { + if (!fsp_flags_is_valid(m_space_flags, true)) { ulint cflags = fsp_flags_convert_from_101(m_space_flags); if (cflags == ULINT_UNDEFINED) { ib::error() << "Invalid FSP_SPACE_FLAGS=" |