mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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.
This commit is contained in:
@@ -219,7 +219,7 @@ xb_fil_cur_open(
|
|||||||
return(XB_FIL_CUR_SKIP);
|
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);
|
ulint cflags = fsp_flags_convert_from_101(flags);
|
||||||
if (cflags == ULINT_UNDEFINED) {
|
if (cflags == ULINT_UNDEFINED) {
|
||||||
msg("[%02u] xtrabackup: Error: Invalid "
|
msg("[%02u] xtrabackup: Error: Invalid "
|
||||||
|
@@ -11,7 +11,7 @@ sub convert_to_mariadb_101
|
|||||||
# FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start
|
# FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start
|
||||||
my($flags) = unpack "x[54]N", $_;
|
my($flags) = unpack "x[54]N", $_;
|
||||||
my $badflags = ($flags & 0x3f);
|
my $badflags = ($flags & 0x3f);
|
||||||
my $compression_level=6;
|
my $compression_level=3;
|
||||||
$badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
|
$badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16);
|
||||||
$badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
|
$badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ SET INNODB_STRICT_MODE=OFF;
|
|||||||
CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
||||||
SET INNODB_STRICT_MODE=ON;
|
SET INNODB_STRICT_MODE=ON;
|
||||||
CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='MYSQL_TMP_DIR';
|
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;
|
CREATE TABLE ti(a INT) ENGINE=InnoDB;
|
||||||
FLUSH TABLES ti FOR EXPORT;
|
FLUSH TABLES ti FOR EXPORT;
|
||||||
backup: ti
|
backup: ti
|
||||||
|
@@ -29,7 +29,7 @@ SET INNODB_STRICT_MODE=ON;
|
|||||||
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
|
||||||
EVAL CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='$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;
|
CREATE TABLE ti(a INT) ENGINE=InnoDB;
|
||||||
FLUSH TABLES ti FOR EXPORT;
|
FLUSH TABLES ti FOR EXPORT;
|
||||||
perl;
|
perl;
|
||||||
|
@@ -659,7 +659,7 @@ buf_dblwr_process()
|
|||||||
if (page_no == 0) {
|
if (page_no == 0) {
|
||||||
/* Check the FSP_SPACE_FLAGS. */
|
/* Check the FSP_SPACE_FLAGS. */
|
||||||
ulint flags = fsp_header_get_flags(page);
|
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)
|
&& fsp_flags_convert_from_101(flags)
|
||||||
== ULINT_UNDEFINED) {
|
== ULINT_UNDEFINED) {
|
||||||
ib::warn() << "Ignoring a doublewrite copy"
|
ib::warn() << "Ignoring a doublewrite copy"
|
||||||
|
@@ -663,7 +663,7 @@ retry:
|
|||||||
ut_free(buf2);
|
ut_free(buf2);
|
||||||
os_file_close(node->handle);
|
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);
|
ulint cflags = fsp_flags_convert_from_101(flags);
|
||||||
if (cflags == ULINT_UNDEFINED) {
|
if (cflags == ULINT_UNDEFINED) {
|
||||||
ib::error()
|
ib::error()
|
||||||
@@ -1601,7 +1601,7 @@ fil_space_create(
|
|||||||
fil_space_t* space;
|
fil_space_t* space;
|
||||||
|
|
||||||
ut_ad(fil_system);
|
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
|
ut_ad(purpose == FIL_TYPE_LOG
|
||||||
|| srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0);
|
|| srv_page_size == UNIV_PAGE_SIZE_ORIG || flags != 0);
|
||||||
|
|
||||||
@@ -2388,7 +2388,7 @@ fil_op_write_log(
|
|||||||
ulint len;
|
ulint len;
|
||||||
|
|
||||||
ut_ad(first_page_no == 0);
|
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
|
/* fil_name_parse() requires that there be at least one path
|
||||||
separator and that the file path end with ".ibd". */
|
separator and that the file path end with ".ibd". */
|
||||||
@@ -3794,7 +3794,7 @@ fil_ibd_create(
|
|||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
|
ut_a(space_id < SRV_LOG_SPACE_FIRST_ID);
|
||||||
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
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
|
/* Create the subdirectories in the path, if they are
|
||||||
not there already. */
|
not there already. */
|
||||||
@@ -4089,7 +4089,7 @@ fil_ibd_open(
|
|||||||
return(DB_CORRUPTION);
|
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_default.init(space_name, flags);
|
||||||
df_dict.init(space_name, flags);
|
df_dict.init(space_name, flags);
|
||||||
df_remote.init(space_name, flags);
|
df_remote.init(space_name, flags);
|
||||||
@@ -4737,7 +4737,7 @@ void
|
|||||||
fsp_flags_try_adjust(ulint space_id, ulint flags)
|
fsp_flags_try_adjust(ulint space_id, ulint flags)
|
||||||
{
|
{
|
||||||
ut_ad(!srv_read_only_mode);
|
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_t mtr;
|
||||||
mtr.start();
|
mtr.start();
|
||||||
|
@@ -353,7 +353,7 @@ Datafile::read_first_page(bool read_only_mode)
|
|||||||
if (m_order == 0) {
|
if (m_order == 0) {
|
||||||
m_space_id = fsp_header_get_space_id(m_first_page);
|
m_space_id = fsp_header_get_space_id(m_first_page);
|
||||||
m_flags = fsp_header_get_flags(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);
|
ulint cflags = fsp_flags_convert_from_101(m_flags);
|
||||||
if (cflags == ULINT_UNDEFINED) {
|
if (cflags == ULINT_UNDEFINED) {
|
||||||
ib::error()
|
ib::error()
|
||||||
@@ -524,9 +524,7 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the whole page is blank. */
|
/* Check if the whole page is blank. */
|
||||||
if (error_txt == NULL
|
if (error_txt == NULL && !m_space_id && !m_flags) {
|
||||||
&& m_space_id == srv_sys_space.space_id()
|
|
||||||
&& !m_flags) {
|
|
||||||
const byte* b = m_first_page;
|
const byte* b = m_first_page;
|
||||||
ulint nonzero_bytes = UNIV_PAGE_SIZE;
|
ulint nonzero_bytes = UNIV_PAGE_SIZE;
|
||||||
|
|
||||||
@@ -558,7 +556,7 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
|
|||||||
free_first_page();
|
free_first_page();
|
||||||
|
|
||||||
return(DB_ERROR);
|
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. */
|
/* Tablespace flags must be valid. */
|
||||||
error_txt = "Tablespace flags are invalid";
|
error_txt = "Tablespace flags are invalid";
|
||||||
} else if (page_get_page_no(m_first_page) != 0) {
|
} else if (page_get_page_no(m_first_page) != 0) {
|
||||||
@@ -799,7 +797,7 @@ Datafile::restore_from_doublewrite()
|
|||||||
ulint flags = mach_read_from_4(
|
ulint flags = mach_read_from_4(
|
||||||
FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
|
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);
|
ulint cflags = fsp_flags_convert_from_101(flags);
|
||||||
if (cflags == ULINT_UNDEFINED) {
|
if (cflags == ULINT_UNDEFINED) {
|
||||||
ib::warn()
|
ib::warn()
|
||||||
|
@@ -682,7 +682,7 @@ fsp_header_init_fields(
|
|||||||
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */
|
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */
|
||||||
{
|
{
|
||||||
flags &= ~FSP_FLAGS_MEM_MASK;
|
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,
|
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page,
|
||||||
space_id);
|
space_id);
|
||||||
|
@@ -878,7 +878,7 @@ dict_tf_to_fsp_flags(ulint table_flags)
|
|||||||
fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION;
|
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)) {
|
if (DICT_TF_HAS_DATA_DIR(table_flags)) {
|
||||||
fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;
|
fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR;
|
||||||
|
@@ -779,7 +779,7 @@ fsp_flags_convert_from_101(ulint flags)
|
|||||||
flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
|
flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
|
||||||
| FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
|
| FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
|
||||||
<< FSP_FLAGS_POS_PAGE_COMPRESSION);
|
<< FSP_FLAGS_POS_PAGE_COMPRESSION);
|
||||||
ut_ad(fsp_flags_is_valid(flags));
|
ut_ad(fsp_flags_is_valid(flags, false));
|
||||||
return(flags);
|
return(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,7 +793,7 @@ bool
|
|||||||
fsp_flags_match(ulint expected, ulint actual)
|
fsp_flags_match(ulint expected, ulint actual)
|
||||||
{
|
{
|
||||||
expected &= ~FSP_FLAGS_MEM_MASK;
|
expected &= ~FSP_FLAGS_MEM_MASK;
|
||||||
ut_ad(fsp_flags_is_valid(expected));
|
ut_ad(fsp_flags_is_valid(expected, false));
|
||||||
|
|
||||||
if (actual == expected) {
|
if (actual == expected) {
|
||||||
return(true);
|
return(true);
|
||||||
|
@@ -129,7 +129,7 @@ public:
|
|||||||
@param[in] fsp_flags tablespace flags */
|
@param[in] fsp_flags tablespace flags */
|
||||||
void set_flags(ulint fsp_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;
|
m_flags = fsp_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
/** Validate the tablespace flags, which are stored in the
|
||||||
tablespace header at offset FSP_SPACE_FLAGS.
|
tablespace header at offset FSP_SPACE_FLAGS.
|
||||||
@param[in] flags the contents of 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 */
|
@return whether the flags are correct (not in the buggy 10.1) format */
|
||||||
MY_ATTRIBUTE((warn_unused_result, const))
|
MY_ATTRIBUTE((warn_unused_result, const))
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
bool
|
bool
|
||||||
fsp_flags_is_valid(ulint flags)
|
fsp_flags_is_valid(ulint flags, bool is_ibd)
|
||||||
{
|
{
|
||||||
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
|
DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
|
||||||
return(false););
|
return(false););
|
||||||
@@ -422,7 +423,12 @@ fsp_flags_is_valid(ulint flags)
|
|||||||
return(false);
|
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 */
|
#endif /* fsp0types_h */
|
||||||
|
@@ -527,7 +527,7 @@ AbstractCallback::init(
|
|||||||
const page_t* page = block->frame;
|
const page_t* page = block->frame;
|
||||||
|
|
||||||
m_space_flags = fsp_header_get_flags(page);
|
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);
|
ulint cflags = fsp_flags_convert_from_101(m_space_flags);
|
||||||
if (cflags == ULINT_UNDEFINED) {
|
if (cflags == ULINT_UNDEFINED) {
|
||||||
ib::error() << "Invalid FSP_SPACE_FLAGS="
|
ib::error() << "Invalid FSP_SPACE_FLAGS="
|
||||||
|
Reference in New Issue
Block a user