From 4312d0a827afe6cb73f6320303823ae79859c0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 20 Jan 2022 17:08:50 +0200 Subject: MDEV-26870 --skip-symbolic-links does not disallow .isl file creation The InnoDB DATA DIRECTORY attribute is not implemented via symbolic links but something similar, *.isl files that contain the names of data files. InnoDB failed to reject the DATA DIRECTORY attribute even though the server was started with --skip-symbolic-links. Because TRUNCATE TABLE cannot easily return an error, it will keep rebuilding tables even if they carry the DATA DIRECTORY attribute. --- include/my_sys.h | 4 +- mysql-test/r/information_schema_inno.result | 1 - .../suite/encryption/t/innodb-first-page-read.test | 1 + .../suite/innodb/r/skip_symbolic_links.result | 62 ++++++++++++++++++++++ mysql-test/suite/innodb/t/101_compatibility.test | 1 + .../suite/innodb/t/create_isl_with_direct.test | 1 + mysql-test/suite/innodb/t/innodb-wl5980-alter.test | 1 + mysql-test/suite/innodb/t/innodb-wl5980-debug.test | 1 + mysql-test/suite/innodb/t/restart.test | 1 + mysql-test/suite/innodb/t/skip_symbolic_links.opt | 1 + mysql-test/suite/innodb/t/skip_symbolic_links.test | 57 ++++++++++++++++++++ mysql-test/suite/innodb_zip/t/restart.test | 1 + .../create_with_data_directory_during_backup.test | 1 + mysql-test/suite/mariabackup/data_directory.test | 1 + .../suite/mariabackup/partition_datadir.test | 1 + .../suite/parts/t/alter_data_directory_innodb.test | 1 + .../suite/parts/t/reorganize_partition_innodb.test | 1 + mysql-test/t/information_schema_inno.test | 4 +- storage/innobase/handler/ha_innodb.cc | 14 +++-- 19 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/innodb/r/skip_symbolic_links.result create mode 100644 mysql-test/suite/innodb/t/skip_symbolic_links.opt create mode 100644 mysql-test/suite/innodb/t/skip_symbolic_links.test diff --git a/include/my_sys.h b/include/my_sys.h index 1d2fff0e476..d2411223841 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2021, MariaDB Corporation. + Copyright (c) 2010, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -276,7 +276,7 @@ extern int my_umask_dir, my_recived_signals, /* Signals we have got */ my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */ my_dont_interrupt; /* call remember_intr when set */ -extern my_bool my_use_symdir; +extern MYSQL_PLUGIN_IMPORT my_bool my_use_symdir; extern ulong my_default_record_cache_size; extern MYSQL_PLUGIN_IMPORT my_bool my_disable_locking; diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result index 7755d112f8e..fa81e4ef307 100644 --- a/mysql-test/r/information_schema_inno.result +++ b/mysql-test/r/information_schema_inno.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1,t2,t3; CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id, id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE, diff --git a/mysql-test/suite/encryption/t/innodb-first-page-read.test b/mysql-test/suite/encryption/t/innodb-first-page-read.test index d661e4565d2..a0b3ca3f0ff 100644 --- a/mysql-test/suite/encryption/t/innodb-first-page-read.test +++ b/mysql-test/suite/encryption/t/innodb-first-page-read.test @@ -1,6 +1,7 @@ -- source include/have_innodb.inc -- source include/have_file_key_management_plugin.inc -- source include/not_embedded.inc +-- source include/have_symlink.inc --disable_warnings SET GLOBAL innodb_file_format = `Barracuda`; diff --git a/mysql-test/suite/innodb/r/skip_symbolic_links.result b/mysql-test/suite/innodb/r/skip_symbolic_links.result new file mode 100644 index 00000000000..417d949afd4 --- /dev/null +++ b/mysql-test/suite/innodb/r/skip_symbolic_links.result @@ -0,0 +1,62 @@ +SELECT @@have_symlink; +@@have_symlink +DISABLED +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB +DATA DIRECTORY 'MYSQL_TMP_DIR'; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: DATA DIRECTORY requires HAVE_SYMLINK. +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; +ALTER TABLE t1 DATA DIRECTORY 'MYSQL_TMP_DIR'; +Warnings: +Warning 1618 option ignored +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1(a INT PRIMARY KEY, b INT) ENGINE=InnoDB +DATA DIRECTORY 'MYSQL_TMP_DIR'; +ALTER TABLE t1 FORCE; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: DATA DIRECTORY requires HAVE_SYMLINK. +Error 1478 Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +RENAME TABLE t1 TO t2; +ALTER TABLE t2 ADD UNIQUE INDEX(b), RENAME TO t1; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +ALTER TABLE t2 RENAME TO t1; +ALTER TABLE t1 ADD UNIQUE INDEX(b); +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +ALTER TABLE t1 CHANGE b c INT; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +ALTER TABLE t1 CHANGE b c INT NOT NULL; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +TRUNCATE TABLE t1; +ALTER TABLE t1 FORCE; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: DATA DIRECTORY requires HAVE_SYMLINK. +Error 1478 Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize error Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +test.t1 optimize status Operation failed +Warnings: +Warning 1478 InnoDB: DATA DIRECTORY requires HAVE_SYMLINK. +Error 1478 Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: DATA DIRECTORY requires HAVE_SYMLINK. +Error 1478 Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +ALTER TABLE t1 FORCE; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'DATA DIRECTORY' +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/101_compatibility.test b/mysql-test/suite/innodb/t/101_compatibility.test index eb3d3b0c014..8b6c971c3a4 100644 --- a/mysql-test/suite/innodb/t/101_compatibility.test +++ b/mysql-test/suite/innodb/t/101_compatibility.test @@ -1,5 +1,6 @@ --source include/innodb_page_size.inc --source include/not_embedded.inc +--source include/have_symlink.inc -- echo # -- echo # MDEV-11623 MariaDB 10.1 fails to start datadir created with diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.test b/mysql-test/suite/innodb/t/create_isl_with_direct.test index 1427264e13e..2092d03b72f 100644 --- a/mysql-test/suite/innodb/t/create_isl_with_direct.test +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.test @@ -1,5 +1,6 @@ --source include/not_embedded.inc --source include/have_innodb.inc +--source include/have_symlink.inc --disable_query_log CALL mtr.add_suppression(".*Failed to set O_DIRECT on file.*"); diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-alter.test b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test index a0d80ea8374..9b51612854f 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5980-alter.test +++ b/mysql-test/suite/innodb/t/innodb-wl5980-alter.test @@ -4,6 +4,7 @@ --echo # --source include/have_innodb.inc +--source include/have_symlink.inc --disable_query_log # These values can change during the test diff --git a/mysql-test/suite/innodb/t/innodb-wl5980-debug.test b/mysql-test/suite/innodb/t/innodb-wl5980-debug.test index 2c5e2b48870..dbb8ad33676 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5980-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5980-debug.test @@ -8,6 +8,7 @@ --source include/not_embedded.inc --source include/have_debug.inc --source include/have_innodb.inc +--source include/have_symlink.inc # These messages are expected in the log call mtr.add_suppression("Cannot find space id [0-9]+ in the tablespace memory cache"); diff --git a/mysql-test/suite/innodb/t/restart.test b/mysql-test/suite/innodb/t/restart.test index 3f28b3976c3..16c6d20f621 100644 --- a/mysql-test/suite/innodb/t/restart.test +++ b/mysql-test/suite/innodb/t/restart.test @@ -1,5 +1,6 @@ --source include/innodb_page_size.inc --source include/not_embedded.inc +--source include/have_symlink.inc let datadir= `select @@datadir`; let page_size= `select @@innodb_page_size`; diff --git a/mysql-test/suite/innodb/t/skip_symbolic_links.opt b/mysql-test/suite/innodb/t/skip_symbolic_links.opt new file mode 100644 index 00000000000..c7844699cdb --- /dev/null +++ b/mysql-test/suite/innodb/t/skip_symbolic_links.opt @@ -0,0 +1 @@ +--skip-symbolic-links diff --git a/mysql-test/suite/innodb/t/skip_symbolic_links.test b/mysql-test/suite/innodb/t/skip_symbolic_links.test new file mode 100644 index 00000000000..1f4b60f8878 --- /dev/null +++ b/mysql-test/suite/innodb/t/skip_symbolic_links.test @@ -0,0 +1,57 @@ +--source include/have_innodb.inc +--source include/not_windows.inc + +SELECT @@have_symlink; +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error ER_CANT_CREATE_TABLE +eval CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB +DATA DIRECTORY '$MYSQL_TMP_DIR'; +SHOW WARNINGS; + +CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=InnoDB; + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval ALTER TABLE t1 DATA DIRECTORY '$MYSQL_TMP_DIR'; +SHOW CREATE TABLE t1; + +DROP TABLE t1; + +--let $restart_parameters=--symbolic-links +--source include/restart_mysqld.inc + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE t1(a INT PRIMARY KEY, b INT) ENGINE=InnoDB +DATA DIRECTORY '$MYSQL_TMP_DIR'; + +--let $restart_parameters= +--source include/restart_mysqld.inc + +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 FORCE; +SHOW WARNINGS; + +RENAME TABLE t1 TO t2; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t2 ADD UNIQUE INDEX(b), RENAME TO t1; + +ALTER TABLE t2 RENAME TO t1; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 ADD UNIQUE INDEX(b); +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 CHANGE b c INT; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 CHANGE b c INT NOT NULL; + +# no error, but DATA DIRECTORY remains +TRUNCATE TABLE t1; + +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 FORCE; +SHOW WARNINGS; +OPTIMIZE TABLE t1; +SHOW WARNINGS; + +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 FORCE; + +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_zip/t/restart.test b/mysql-test/suite/innodb_zip/t/restart.test index 05ac8274278..1c4af461dfc 100644 --- a/mysql-test/suite/innodb_zip/t/restart.test +++ b/mysql-test/suite/innodb_zip/t/restart.test @@ -4,6 +4,7 @@ --source include/innodb_page_size_small.inc --source include/have_partition.inc --source include/not_embedded.inc +--source include/have_symlink.inc SET default_storage_engine=InnoDB; LET $MYSQLD_DATADIR = `select @@datadir`; LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`; diff --git a/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test b/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test index d0cb83d069f..f01028b6494 100644 --- a/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test +++ b/mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test @@ -1,4 +1,5 @@ --source include/have_debug.inc +--source include/have_symlink.inc let $table_data_dir=$MYSQLTEST_VARDIR/tmp/ddir; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; mkdir $table_data_dir; diff --git a/mysql-test/suite/mariabackup/data_directory.test b/mysql-test/suite/mariabackup/data_directory.test index 50789a34c78..a89b7bdccc4 100644 --- a/mysql-test/suite/mariabackup/data_directory.test +++ b/mysql-test/suite/mariabackup/data_directory.test @@ -1,3 +1,4 @@ +--source include/have_symlink.inc let $table_data_dir=$MYSQLTEST_VARDIR/ddir; mkdir $table_data_dir; --replace_result $table_data_dir table_data_dir diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test index c525d34a02c..36520d331bf 100644 --- a/mysql-test/suite/mariabackup/partition_datadir.test +++ b/mysql-test/suite/mariabackup/partition_datadir.test @@ -1,4 +1,5 @@ --source include/have_partition.inc +--source include/have_symlink.inc let $targetdir=$MYSQLTEST_VARDIR/backup; mkdir $targetdir; mkdir $MYSQLTEST_VARDIR/partitdata; diff --git a/mysql-test/suite/parts/t/alter_data_directory_innodb.test b/mysql-test/suite/parts/t/alter_data_directory_innodb.test index ac15e9bec6c..def04e14173 100644 --- a/mysql-test/suite/parts/t/alter_data_directory_innodb.test +++ b/mysql-test/suite/parts/t/alter_data_directory_innodb.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc --source include/have_partition.inc +--source include/have_symlink.inc --echo # --echo # MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir diff --git a/mysql-test/suite/parts/t/reorganize_partition_innodb.test b/mysql-test/suite/parts/t/reorganize_partition_innodb.test index db73650c54b..77109c38c96 100644 --- a/mysql-test/suite/parts/t/reorganize_partition_innodb.test +++ b/mysql-test/suite/parts/t/reorganize_partition_innodb.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc --source include/have_partition.inc +--source include/have_symlink.inc --echo # --echo # MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test index 9a9658e9027..89a2a8cc08e 100644 --- a/mysql-test/t/information_schema_inno.test +++ b/mysql-test/t/information_schema_inno.test @@ -1,8 +1,6 @@ -- source include/testdb_only.inc -- source include/have_innodb.inc ---disable_warnings -DROP TABLE IF EXISTS t1,t2,t3; ---enable_warnings +-- source include/have_symlink.inc # # Test for KEY_COLUMN_USAGE & TABLE_CONSTRAINTS tables diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5d78e64a06b..a8b16ba1eb0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4,7 +4,7 @@ Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -11710,9 +11710,15 @@ create_table_info_t::create_options_are_invalid() break; } - if (m_create_info->data_file_name - && m_create_info->data_file_name[0] != '\0' - && !create_option_data_directory_is_valid()) { + if (!m_create_info->data_file_name + || !m_create_info->data_file_name[0]) { + } else if (!my_use_symdir) { + push_warning( + m_thd, Sql_condition::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: DATA DIRECTORY requires HAVE_SYMLINK."); + ret = "DATA DIRECTORY"; + } else if (!create_option_data_directory_is_valid()) { ret = "DATA DIRECTORY"; } -- cgit v1.2.1