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:55:56 +0300 |
commit | e555540ab6b9c3e0d4fdd00af093b115a9401d0a (patch) | |
tree | 84467ec02335ca26faeaffd416bfc552faea6b22 | |
parent | 8ae9c86f2a79f1301f5428542fc7f53feed7d4f4 (diff) | |
download | mariadb-git-e555540ab6b9c3e0d4fdd00af093b115a9401d0a.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-- | 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 | 14 | ||||
-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 | 16 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0dblwr.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 14 | ||||
-rw-r--r-- | storage/xtradb/fsp/fsp0fsp.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/include/dict0dict.ic | 2 | ||||
-rw-r--r-- | storage/xtradb/include/fsp0fsp.h | 16 | ||||
-rw-r--r-- | storage/xtradb/row/row0import.cc | 2 |
15 files changed, 47 insertions, 35 deletions
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 bf613c1b3b1..7ec8bb19c10 100644 --- a/mysql-test/suite/innodb/r/101_compatibility.result +++ b/mysql-test/suite/innodb/r/101_compatibility.result @@ -7,7 +7,7 @@ CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT; CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC; CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; 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 25567b939c7..df3261cebd1 100644 --- a/mysql-test/suite/innodb/t/101_compatibility.test +++ b/mysql-test/suite/innodb/t/101_compatibility.test @@ -28,7 +28,7 @@ CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; --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 8ff5428d3a5..f35a34e5e98 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -616,7 +616,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_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index d78a8b20f33..6abc7f0e1c2 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -662,7 +662,7 @@ fil_node_open_file( 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_logf(IB_LOG_LEVEL_ERROR, @@ -2366,7 +2366,7 @@ fil_read_first_page( FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); } - 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_logf(IB_LOG_LEVEL_ERROR, @@ -2497,7 +2497,7 @@ fil_op_write_log( ulint len; log_ptr = mlog_open(mtr, 11 + 2 + 1); - ut_ad(fsp_flags_is_valid(flags)); + ut_ad(fsp_flags_is_valid(flags, space_id)); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery: @@ -3718,7 +3718,7 @@ fil_create_new_single_table_tablespace( 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)); if (is_temp) { /* Temporary table filepath */ @@ -3979,7 +3979,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(&mtr); @@ -4061,7 +4061,7 @@ fil_open_single_table_tablespace( 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)); atomic_writes = fsp_flags_get_atomic_writes(flags); memset(&def, 0, sizeof(def)); @@ -4601,7 +4601,7 @@ fil_user_tablespace_restore_page( flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (!fsp_flags_is_valid(flags)) { + if (!fsp_flags_is_valid(flags, fsp->id)) { ulint cflags = fsp_flags_convert_from_101(flags); if (cflags == ULINT_UNDEFINED) { ib_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 9d5e2e984fc..ab96befb700 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -661,7 +661,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 6044f992d82..147968a343a 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -934,7 +934,7 @@ dict_tf_to_fsp_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 d8d044ba2ec..275a5785ce2 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -788,11 +788,12 @@ fseg_print( /** 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);); @@ -816,7 +817,7 @@ fsp_flags_is_valid(ulint flags) bits 10..14 would be nonzero 0bsssaa where sss is nonzero PAGE_SSIZE (3, 4, 6, or 7) and aa is ATOMIC_WRITES (not 0b11). */ - if (FSP_FLAGS_GET_RESERVED(flags) & ~1) { + if (FSP_FLAGS_GET_RESERVED(flags) & ~1U) { return(false); } @@ -839,7 +840,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); } /** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format. @@ -948,7 +954,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); } @@ -962,7 +968,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/row/row0import.cc b/storage/innobase/row/row0import.cc index 43830725978..4375d491ba7 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -548,7 +548,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_logf(IB_LOG_LEVEL_ERROR, diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 49371f9a6f1..d6e738f15fa 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -616,7 +616,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_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index fdd09a6034e..dbf6501b183 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -670,7 +670,7 @@ fil_node_open_file( 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_logf(IB_LOG_LEVEL_ERROR, @@ -2426,7 +2426,7 @@ fil_read_first_page( FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); } - 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_logf(IB_LOG_LEVEL_ERROR, @@ -2541,7 +2541,7 @@ fil_op_write_log( ulint len; log_ptr = mlog_open(mtr, 11 + 2 + 1); - ut_ad(fsp_flags_is_valid(flags)); + ut_ad(fsp_flags_is_valid(flags, space_id)); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery: @@ -3778,7 +3778,7 @@ fil_create_new_single_table_tablespace( 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)); if (is_temp) { /* Temporary table filepath */ @@ -4172,7 +4172,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(&mtr); @@ -4254,7 +4254,7 @@ fil_open_single_table_tablespace( 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)); atomic_writes = fsp_flags_get_atomic_writes(flags); memset(&def, 0, sizeof(def)); @@ -4795,7 +4795,7 @@ fil_user_tablespace_restore_page( flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (!fsp_flags_is_valid(flags)) { + if (!fsp_flags_is_valid(flags, fsp->id)) { ulint cflags = fsp_flags_convert_from_101(flags); if (cflags == ULINT_UNDEFINED) { ib_logf(IB_LOG_LEVEL_WARN, diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index df8c6ffe222..b5491ac6550 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -664,7 +664,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/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index f68d4e176da..4db6a73bbc2 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -934,7 +934,7 @@ dict_tf_to_fsp_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/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index 715572199ab..7395a248bed 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -787,11 +787,12 @@ fseg_print( /** 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);); @@ -815,7 +816,7 @@ fsp_flags_is_valid(ulint flags) bits 10..14 would be nonzero 0bsssaa where sss is nonzero PAGE_SSIZE (3, 4, 6, or 7) and aa is ATOMIC_WRITES (not 0b11). */ - if (FSP_FLAGS_GET_RESERVED(flags) & ~1) { + if (FSP_FLAGS_GET_RESERVED(flags) & ~1U) { return(false); } @@ -838,7 +839,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); } /** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format. @@ -947,7 +953,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); } @@ -961,7 +967,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/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 86b2d782b7b..a99c72c01b5 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -549,7 +549,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_logf(IB_LOG_LEVEL_ERROR, |