Skip to content

Commit

Permalink
MDEV-27065 Partitioning tables with custom data directories moves dat…
Browse files Browse the repository at this point in the history
…a back to default directory

The partitioning engine does not support the table-level DATA/INDEX
DIRECTORY specification.

If one create a non-partitioned table with the DATA/INDEX DIRECTORY
option and then performs ALTER TABLE ... PARTITION BY on it, the
DATA/INDEX DIRECTORY specification of the old schema is ignored.

The behavior might be a bit surprising for users because the value
of a usual table option applies to all the partitions. Thus, we raise
a warning on such ALTER TABLE ... PARTITION BY.
  • Loading branch information
nayuta-yanagisawa committed Apr 8, 2022
1 parent 5a8766a commit 27b5d81
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 4 deletions.
37 changes: 34 additions & 3 deletions mysql-test/suite/parts/inc/part_alter_values.inc
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,43 @@ ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
);
DROP TABLE t1;

#
# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
#
--echo #
--echo # MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
--echo #
--eval create table t1 (i int) engine=$engine partition by range(i) (partition p0 values less than (10))
lock table t1 write;
--error ER_SAME_NAME_PARTITION
alter table t1 add partition (partition p0 values less than (20));
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;

--echo #
--echo # MDEV-27065 Partitioning tables with custom data directories moves data back to default directory
--echo #

--mkdir $MYSQLTEST_VARDIR/tmp/mdev_27065

--disable_query_log
--eval CREATE TABLE t1 (id INT) ENGINE=$engine DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp/mdev_27065'
--enable_query_log
ALTER TABLE t1 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
DROP TABLE t1;

# InnoDB doesn't support INDEX DIRECTORY.
if (`SELECT IF('$engine' != 'InnoDB', 1, 0)`)
{
--disable_query_log
--eval CREATE TABLE t2 (id INT) ENGINE=$engine INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp/mdev_27065'
--enable_query_log
ALTER TABLE t2 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
DROP TABLE t2;
}

--remove_files_wildcard $MYSQLTEST_VARDIR/tmp/mdev_27065 *
--rmdir $MYSQLTEST_VARDIR/tmp/mdev_27065
13 changes: 13 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,22 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
#
# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
#
create table t1 (i int) engine=InnoDB partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
#
# MDEV-27065 Partitioning tables with custom data directories moves data back to default directory
#
ALTER TABLE t1 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
Warnings:
Warning 1618 <DATA DIRECTORY> table option of old schema is ignored
DROP TABLE t1;
20 changes: 20 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_maria.result
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,29 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
#
# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
#
create table t1 (i int) engine=Aria partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
#
# MDEV-27065 Partitioning tables with custom data directories moves data back to default directory
#
ALTER TABLE t1 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
Warnings:
Warning 1618 <DATA DIRECTORY> table option of old schema is ignored
DROP TABLE t1;
ALTER TABLE t2 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
Warnings:
Warning 1618 <INDEX DIRECTORY> table option of old schema is ignored
DROP TABLE t2;
20 changes: 20 additions & 0 deletions mysql-test/suite/parts/r/partition_alter_myisam.result
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,32 @@ PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
#
# MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION
#
create table t1 (i int) engine=MyISAM partition by range(i) (partition p0 values less than (10));
lock table t1 write;
alter table t1 add partition (partition p0 values less than (20));
ERROR HY000: Duplicate partition name p0
alter table t1 add partition (partition p1 values less than (20)) /* comment */;
drop table t1;
#
# MDEV-27065 Partitioning tables with custom data directories moves data back to default directory
#
ALTER TABLE t1 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
Warnings:
Warning 1618 <DATA DIRECTORY> table option of old schema is ignored
DROP TABLE t1;
ALTER TABLE t2 PARTITION BY RANGE(id)(
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN MAXVALUE
);
Warnings:
Warning 1618 <INDEX DIRECTORY> table option of old schema is ignored
DROP TABLE t2;
create table t1 ( c1 int, c2 int, c3 varchar(100)) delay_key_write=1
partition by key(c1) (
partition p01 data directory = 'MYSQL_TMP_DIR'
Expand Down
22 changes: 21 additions & 1 deletion sql/ha_partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
int error;
THD *thd= ha_thd();
char name_buff[FN_REFLEN + 1], name_lc_buff[FN_REFLEN];
char *name_buffer_ptr;
const char *path;
Expand All @@ -695,8 +696,27 @@ int ha_partition::create(const char *name, TABLE *table_arg,
my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
DBUG_RETURN(TRUE);
}
/*
The following block should be removed once the table-level data directory
specification is supported by the partitioning engine (MDEV-28108).
*/
if (thd_sql_command(thd) == SQLCOM_ALTER_TABLE && create_info)
{
if (create_info->data_file_name)
{
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN, WARN_OPTION_IGNORED,
"<DATA DIRECTORY> table option of old schema is ignored");
}
if (create_info->index_file_name)
{
push_warning_printf(
thd, Sql_condition::WARN_LEVEL_WARN, WARN_OPTION_IGNORED,
"<INDEX DIRECTORY> table option of old schema is ignored");
}
}

if (get_from_handler_file(name, ha_thd()->mem_root, false))
if (get_from_handler_file(name, thd->mem_root, false))
DBUG_RETURN(TRUE);
DBUG_ASSERT(m_file_buffer);
DBUG_PRINT("enter", ("name: (%s)", name));
Expand Down

0 comments on commit 27b5d81

Please sign in to comment.