Commit 031c695b authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-16594 ALTER DATA DIRECTORY in PARTITIONS of InnoDB storage does nothing silently

InnoDB intentionally (it's a documented behavior) ignores changing of
DATA DIRECTORY and INDEX DIRECTORY for partitions. Though we should
issue warning when this happens.
parent 0e38cd37
...@@ -53,6 +53,9 @@ ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO ( ...@@ -53,6 +53,9 @@ ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB, PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB
); );
Warnings:
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
SHOW CREATE TABLE t; SHOW CREATE TABLE t;
Table Create Table Table Create Table
t CREATE TABLE `t` ( t CREATE TABLE `t` (
......
#
# MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir
#
CREATE TABLE t (
a INT NOT NULL
) ENGINE=INNODB
PARTITION BY HASH (a) (
PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB
);
INSERT INTO t VALUES (1);
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE;
SET GLOBAL INNODB_FILE_PER_TABLE=OFF;
ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE;
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
SET GLOBAL INNODB_FILE_PER_TABLE=@TMP;
ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB
);
Warnings:
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/',
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
);
Warnings:
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB,
PARTITION p2 INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB
);
Warnings:
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
(PARTITION p1 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB,
PARTITION p2 DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here' ENGINE = InnoDB) */
DROP TABLE t;
CREATE TABLE t (
a INT NOT NULL
) ENGINE=INNODB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
SUBPARTITIONS 2
(
PARTITION p1 VALUES LESS THAN (7)
DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/'
INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/'
ENGINE = INNODB,
PARTITION p2 VALUES LESS THAN MAXVALUE
DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/'
INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_here/'
ENGINE = INNODB
);
Warnings:
Warning 1618 <INDEX DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
ALTER TABLE t
REORGANIZE PARTITION p1,p2 INTO
(
PARTITION p1 VALUES LESS THAN (7)
DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
ENGINE = INNODB,
PARTITION p2 VALUES LESS THAN MAXVALUE
DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
ENGINE = INNODB
);
Warnings:
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
Warning 1982 <DATA DIRECTORY> option ignored for InnoDB partition
Warning 1982 <INDEX DIRECTORY> option ignored for InnoDB partition
SHOW CREATE TABLE t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
SUBPARTITIONS 2
(PARTITION p1 VALUES LESS THAN (7) DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN MAXVALUE DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = InnoDB) */
DROP TABLE t;
--source include/have_innodb.inc
--source include/have_partition.inc
--echo #
--echo # MDEV-15953 Alter InnoDB Partitioned Table Moves Files (which were originally not in the datadir) to the datadir
--echo #
mkdir $MYSQLTEST_VARDIR/tmp/partitions_here;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval CREATE TABLE t (
a INT NOT NULL
) ENGINE=INNODB
PARTITION BY HASH (a) (
PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB,
PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/' ENGINE = INNODB
);
INSERT INTO t VALUES (1);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
ALTER TABLE t DROP PRIMARY KEY, ALGORITHM=COPY;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
SET @TMP = @@GLOBAL.INNODB_FILE_PER_TABLE;
SET GLOBAL INNODB_FILE_PER_TABLE=OFF;
ALTER TABLE t ADD PRIMARY KEY pk(a), ALGORITHM=INPLACE;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
SET GLOBAL INNODB_FILE_PER_TABLE=@TMP;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB,
PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB
);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/',
PARTITION p2 DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t REORGANIZE PARTITION p1,p2 INTO (
PARTITION p1 INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB,
PARTITION p2 INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/' ENGINE = INNODB
);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
DROP TABLE t;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval CREATE TABLE t (
a INT NOT NULL
) ENGINE=INNODB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
SUBPARTITIONS 2
(
PARTITION p1 VALUES LESS THAN (7)
DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/'
INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/'
ENGINE = INNODB,
PARTITION p2 VALUES LESS THAN MAXVALUE
DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/'
INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_here/'
ENGINE = INNODB
);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval ALTER TABLE t
REORGANIZE PARTITION p1,p2 INTO
(
PARTITION p1 VALUES LESS THAN (7)
DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
ENGINE = INNODB,
PARTITION p2 VALUES LESS THAN MAXVALUE
DATA DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
INDEX DIRECTORY = '$MYSQLTEST_VARDIR/tmp/partitions_somewhere_else/'
ENGINE = INNODB
);
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
SHOW CREATE TABLE t;
DROP TABLE t;
rmdir $MYSQLTEST_VARDIR/tmp/partitions_here/test;
rmdir $MYSQLTEST_VARDIR/tmp/partitions_here;
...@@ -7142,3 +7142,5 @@ ER_NO_EIS_FOR_FIELD ...@@ -7142,3 +7142,5 @@ ER_NO_EIS_FOR_FIELD
ER_WARN_AGGFUNC_DEPENDENCE ER_WARN_AGGFUNC_DEPENDENCE
eng "Aggregate function '%-.192s)' of SELECT #%d belongs to SELECT #%d" eng "Aggregate function '%-.192s)' of SELECT #%d belongs to SELECT #%d"
ukr "Агрегатна функція '%-.192s)' з SELECTу #%d належить до SELECTу #%d" ukr "Агрегатна функція '%-.192s)' з SELECTу #%d належить до SELECTу #%d"
WARN_INNODB_PARTITION_OPTION_IGNORED
eng "<%-.64s> option ignored for InnoDB partition"
...@@ -4660,6 +4660,69 @@ bool compare_partition_options(HA_CREATE_INFO *table_create_info, ...@@ -4660,6 +4660,69 @@ bool compare_partition_options(HA_CREATE_INFO *table_create_info,
} }
/**
Check if the ALTER command tries to change DATA DIRECTORY
or INDEX DIRECTORY for its partitions and warn if so.
@param thd THD
@param part_elem partition_element to check
*/
static void warn_if_datadir_altered(THD *thd,
const partition_element *part_elem)
{
DBUG_ASSERT(part_elem);
if (part_elem->engine_type &&
part_elem->engine_type->db_type != DB_TYPE_INNODB)
return;
if (part_elem->data_file_name)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
WARN_INNODB_PARTITION_OPTION_IGNORED,
ER(WARN_INNODB_PARTITION_OPTION_IGNORED),
"DATA DIRECTORY");
}
if (part_elem->index_file_name)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
WARN_INNODB_PARTITION_OPTION_IGNORED,
ER(WARN_INNODB_PARTITION_OPTION_IGNORED),
"INDEX DIRECTORY");
}
}
/**
Currently changing DATA DIRECTORY and INDEX DIRECTORY for InnoDB partitions is
not possible. This function checks it and warns on that case.
@param thd THD
@param tab_part_info old partition info
@param alt_part_info new partition info
*/
static void check_datadir_altered_for_innodb(THD *thd,
partition_info *tab_part_info,
partition_info *alt_part_info)
{
if (tab_part_info->default_engine_type->db_type != DB_TYPE_INNODB)
return;
for (List_iterator_fast<partition_element> it(alt_part_info->partitions);
partition_element *part_elem= it++;)
{
if (alt_part_info->is_sub_partitioned())
{
for (List_iterator_fast<partition_element> it2(part_elem->subpartitions);
const partition_element *sub_part_elem= it2++;)
{
warn_if_datadir_altered(thd, sub_part_elem);
}
}
else
warn_if_datadir_altered(thd, part_elem);
}
}
/* /*
Prepare for ALTER TABLE of partition structure Prepare for ALTER TABLE of partition structure
...@@ -5389,6 +5452,8 @@ state of p1. ...@@ -5389,6 +5452,8 @@ state of p1.
{ {
goto err; goto err;
} }
check_datadir_altered_for_innodb(thd, tab_part_info, alt_part_info);
/* /*
Online handling: Online handling:
REORGANIZE PARTITION: REORGANIZE PARTITION:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment