diff options
author | Daniel Black <daniel@mariadb.org> | 2022-11-07 15:58:40 +1100 |
---|---|---|
committer | Daniel Black <daniel@mariadb.org> | 2022-11-11 10:21:28 +1100 |
commit | dc6a0171110741d633cef7877013d8e29d5e6def (patch) | |
tree | d5217f68d475e7cb034a8a6ac8b0448520393d20 | |
parent | 0235a528e3c2cf8c3197e4817596c9fa1947d2b8 (diff) | |
download | mariadb-git-dc6a0171110741d633cef7877013d8e29d5e6def.tar.gz |
MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message
Per fsp0types.h, SDI is on tablespace flags position 14 where MariaDB
stores its pagesize. Flag at position 13, also in MariaDB pagesize
flags, is a MySQL encryption flag.
These are checked only if fsp_flags_is_valid fails, so valid MariaDB
pages sizes don't become errors.
The error message "Cannot reset LSNs in table" was rather specific and
not always true to replaced with more generic error.
ALTER TABLE tbl IMPORT TABLESPACE now reports Unsupported on MySQL
tablespace (rather than index corrupted) along with a server error
message.
MySQL innodb Errors are with with UNSUPPORTED rather than CORRUPTED
to avoid user anxiety.
Reviewer: Marko Mäkelä
17 files changed, 170 insertions, 21 deletions
diff --git a/mysql-test/std_data/mysql80/ibdata1_16384 b/mysql-test/std_data/mysql80/ibdata1_16384 Binary files differnew file mode 100644 index 00000000000..7eeea4fdaf1 --- /dev/null +++ b/mysql-test/std_data/mysql80/ibdata1_16384 diff --git a/mysql-test/std_data/mysql80/ibdata1_32768 b/mysql-test/std_data/mysql80/ibdata1_32768 Binary files differnew file mode 100644 index 00000000000..ebcaef08d39 --- /dev/null +++ b/mysql-test/std_data/mysql80/ibdata1_32768 diff --git a/mysql-test/std_data/mysql80/ibdata1_4096 b/mysql-test/std_data/mysql80/ibdata1_4096 Binary files differnew file mode 100644 index 00000000000..67834106f48 --- /dev/null +++ b/mysql-test/std_data/mysql80/ibdata1_4096 diff --git a/mysql-test/std_data/mysql80/ibdata1_65536 b/mysql-test/std_data/mysql80/ibdata1_65536 Binary files differnew file mode 100644 index 00000000000..3d3d3043b4c --- /dev/null +++ b/mysql-test/std_data/mysql80/ibdata1_65536 diff --git a/mysql-test/std_data/mysql80/ibdata1_8192 b/mysql-test/std_data/mysql80/ibdata1_8192 Binary files differnew file mode 100644 index 00000000000..5082eff5ee2 --- /dev/null +++ b/mysql-test/std_data/mysql80/ibdata1_8192 diff --git a/mysql-test/std_data/mysql80/t1.ibd b/mysql-test/std_data/mysql80/t1.ibd Binary files differnew file mode 100644 index 00000000000..5cfd9b54496 --- /dev/null +++ b/mysql-test/std_data/mysql80/t1.ibd diff --git a/mysql-test/suite/encryption/r/encryption_key_corruption.result b/mysql-test/suite/encryption/r/encryption_key_corruption.result index f467207d0f7..349b530b474 100644 --- a/mysql-test/suite/encryption/r/encryption_key_corruption.result +++ b/mysql-test/suite/encryption/r/encryption_key_corruption.result @@ -9,5 +9,5 @@ DROP TABLE src; CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; ALTER TABLE dst DISCARD TABLESPACE; ALTER TABLE dst IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`dst` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`dst` : Data structure corruption DROP TABLE dst; diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 5070fa33a2e..00cddd4c370 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -38,7 +38,7 @@ tab InnoDB # Compact # # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N ALTER TABLE tab DISCARD TABLESPACE; call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0"); ALTER TABLE tab IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`tab` : I/O error +ERROR HY000: Internal error: Error importing tablespace for table `test`.`tab` : I/O error ALTER TABLE tab IMPORT TABLESPACE; SELECT * FROM tab; a diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-1.result b/mysql-test/suite/innodb/r/innodb-wl5522-1.result index 55557a8fb99..0f7ef6b2865 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-1.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-1.result @@ -795,3 +795,19 @@ DROP DATABASE testdb_wl5522; call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); +# +# MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +# +# +CREATE TABLE `t1` (`i` int(11) NOT NULL, PRIMARY KEY (`i`) ) ENGINE=InnoDB; +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; +call mtr.add_suppression("InnoDB: unsupported MySQL tablespace"); +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Unsupported +DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 9415d3c119a..f2209f9ca91 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -448,7 +448,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Too many concurrent transactions +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Too many concurrent transactions restore: t1 .ibd and .cfg files SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -873,7 +873,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -885,7 +885,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -957,7 +957,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb/r/restart.result b/mysql-test/suite/innodb/r/restart.result index 606e94d81db..ee2450a9270 100644 --- a/mysql-test/suite/innodb/r/restart.result +++ b/mysql-test/suite/innodb/r/restart.result @@ -3,7 +3,8 @@ # # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files # of tables with .isl file or DATA DIRECTORY attribute. -call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); # FIXME: This is much more noisy than MariaDB 10.1! call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); @@ -39,3 +40,10 @@ Warning 1210 innodb_buffer_pool_size must be at least MIN_VAL for innodb_page_si Error 1231 Variable 'innodb_buffer_pool_size' can't be set to the value of 'WRONG_VALUE' EXECUTE IMMEDIATE 'SET GLOBAL innodb_buffer_pool_size = ?' USING (@min_pool_size); SET GLOBAL innodb_buffer_pool_size = @innodb_buffer_pool_size_orig; +# +# MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +# +FOUND 1 /InnoDB: MySQL-8\.0 tablespace in \./ibdata1/ in attempted_start.err +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-1.test b/mysql-test/suite/innodb/t/innodb-wl5522-1.test index 0d59df11c44..bccf670a1c9 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-1.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-1.test @@ -932,3 +932,34 @@ call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tabl --remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd --remove_file $MYSQLTEST_VARDIR/tmp/t1_fk.cfg --remove_file $MYSQLTEST_VARDIR/tmp/t1_fk.ibd + +--echo # +--echo # MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +--echo # +--echo # + +CREATE TABLE `t1` (`i` int(11) NOT NULL, PRIMARY KEY (`i`) ) ENGINE=InnoDB; +FLUSH TABLES t1 FOR EXPORT; + +# We use the cfg file of ours. +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; + +--move_file $MYSQLTEST_VARDIR/tmp/t1.cfg $MYSQLD_DATADIR/test/t1.cfg +--copy_file std_data/mysql80/t1.ibd $MYSQLD_DATADIR/test/t1.ibd + +call mtr.add_suppression("InnoDB: unsupported MySQL tablespace"); +--error ER_INTERNAL_ERROR +ALTER TABLE t1 IMPORT TABLESPACE; + +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/innodb/t/restart.test b/mysql-test/suite/innodb/t/restart.test index 16c6d20f621..eecb62ad464 100644 --- a/mysql-test/suite/innodb/t/restart.test +++ b/mysql-test/suite/innodb/t/restart.test @@ -15,7 +15,9 @@ let page_size= `select @@innodb_page_size`; --echo # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files --echo # of tables with .isl file or DATA DIRECTORY attribute. -call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); + --echo # FIXME: This is much more noisy than MariaDB 10.1! call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); @@ -47,7 +49,7 @@ die unless open OUT, ">", "$ENV{datadir}/test/tc.ibd"; print OUT "bar " x $ENV{page_size}; close OUT or die; die unless open OUT, ">", "$ENV{MYSQL_TMP_DIR}/test/td.ibd"; -print OUT "xyz " x $ENV{page_size}; +print OUT "Xyz " x $ENV{page_size}; close OUT or die; EOF @@ -101,3 +103,60 @@ EXECUTE IMMEDIATE 'SET GLOBAL innodb_buffer_pool_size = ?' USING (@min_pool_size --source include/wait_condition.inc SET GLOBAL innodb_buffer_pool_size = @innodb_buffer_pool_size_orig; + +--echo # +--echo # MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +--echo # + +--let MYSQLD_DATADIR= `SELECT @@datadir` +--let SERVER_ID= `SELECT @@server_id` +--let EXPECT_FILE_NAME= $MYSQLTEST_VARDIR/tmp/mysqld.$SERVER_ID.expect + +--source include/shutdown_mysqld.inc + +--move_file $MYSQLD_DATADIR/ibdata1 $MYSQLD_DATADIR/ibdata1.bak +--copy_file std_data/mysql80/ibdata1_$page_size $MYSQLD_DATADIR/ibdata1 + +perl; +use IO::Handle; +my $size = 9 * 1048576; +if ($ENV{MTR_COMBINATION_32K}) { + $size *= 2; +} +if ($ENV{MTR_COMBINATION_64K}) { + $size *= 4; +} +$size -= $ENV{page_size}; +die unless open(FILE, ">>", "$ENV{MYSQLD_DATADIR}/ibdata1"); +binmode FILE; + +print FILE chr(0) x $size; +close(FILE); +EOF + +--let ibdata_size='9M' +if ($MTR_COMBINATION_32K) +{ +--let ibdata_size='18M' +} +if ($MTR_COMBINATION_64K) +{ +--let ibdata_size='36M' +} + +--error 1 +exec $MYSQLD --no-defaults --skip-networking --innodb_data_file_path=ibdata1:$ibdata_size --innodb-page-size=$page_size --datadir=$MYSQLD_DATADIR --log-error=$MYSQL_TMP_DIR/attempted_start.err; + +let SEARCH_FILE= $MYSQL_TMP_DIR/attempted_start.err; +let SEARCH_PATTERN= InnoDB: MySQL-8\.0 tablespace in \./ibdata1; +source include/search_pattern_in_file.inc; + +--remove_file $MYSQL_TMP_DIR/attempted_start.err +--remove_file $MYSQLD_DATADIR/ibdata1 +--move_file $MYSQLD_DATADIR/ibdata1.bak $MYSQLD_DATADIR/ibdata1 + +--source include/start_mysqld.inc + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index bce37b6bdc0..42ccc70cd5b 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -78,7 +78,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Too many concurrent transactions +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Too many concurrent transactions restore: t1 .ibd and .cfg files SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -322,7 +322,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -335,7 +335,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -413,7 +413,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 90ddca77549..a320b16d636 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -29,6 +29,7 @@ Created 2013-7-26 by Kevin Lewis #include "os0file.h" #include "page0page.h" #include "srv0start.h" +#include "log.h" /** Initialize the name, size and order of this datafile @param[in] name tablespace name, will be copied @@ -346,10 +347,23 @@ Datafile::read_first_page(bool read_only_mode) 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() - << "Invalid flags " << ib::hex(m_flags) - << " in " << m_filepath; - return(DB_CORRUPTION); + switch (fsp_flags_is_incompatible_mysql(m_flags)) { + case 0: + sql_print_error("InnoDB: Invalid flags 0x%zx in %s", + m_flags, m_filepath); + return(DB_CORRUPTION); + case 3: + case 2: + sql_print_error("InnoDB: MySQL-8.0 tablespace in %s", + m_filepath); + break; + case 1: + sql_print_error("InnoDB: MySQL Encrypted tablespace in %s", + m_filepath); + break; + } + sql_print_error("InnoDB: Restart in MySQL for migration/recovery."); + return(DB_UNSUPPORTED); } else { m_flags = cflags; } diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index eff1b4ab4ae..d8057e8e4bf 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -755,6 +755,20 @@ fsp_flags_match(ulint expected, ulint actual) return(actual == expected); } +/** Determine if FSP_SPACE_FLAGS are from an incompatible MySQL format. +@param flags the contents of FSP_SPACE_FLAGS +@return MySQL flags shifted. +@retval 0, if not a MySQL incompatible format. */ +MY_ATTRIBUTE((warn_unused_result, const)) +inline ulint fsp_flags_is_incompatible_mysql(ulint flags) +{ + /* + MySQL-8.0 SDI flag (bit 14), + or MySQL 5.7 Encyption flag (bit 13) + */ + return flags >> 13 & 3; +} + /** Calculates the descriptor index within a descriptor page. @param[in] page_size page size @param[in] offset page offset diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index db4c22b4969..77d027e44d3 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -46,6 +46,7 @@ Created 2012-02-08 by Sunny Bains. #ifdef HAVE_SNAPPY #include "snappy-c.h" #endif +#include "log.h" #include <vector> @@ -571,9 +572,15 @@ AbstractCallback::init( 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=" - << ib::hex(m_space_flags); - return(DB_CORRUPTION); + switch (fsp_flags_is_incompatible_mysql(m_space_flags)) { + case 0: + sql_print_error("InnoDB: Invalid FSP_SPACE_FLAGS=0x%zx", + m_space_flags); + return(DB_CORRUPTION); + default: + sql_print_error("InnoDB: unsupported MySQL tablespace"); + return(DB_UNSUPPORTED); + } } m_space_flags = cflags; } @@ -4171,7 +4178,7 @@ row_import_for_mysql( ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, - "Cannot reset LSNs in table %s : %s", + "Error importing tablespace for table %s : %s", table_name, ut_strerr(err)); } |