diff options
-rw-r--r-- | mysql-test/suite/parts/r/partition_alter_instant.result | 34 | ||||
-rw-r--r-- | mysql-test/suite/parts/t/partition_alter_instant.test | 43 | ||||
-rw-r--r-- | sql/ha_partition.cc | 53 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 1 |
4 files changed, 106 insertions, 25 deletions
diff --git a/mysql-test/suite/parts/r/partition_alter_instant.result b/mysql-test/suite/parts/r/partition_alter_instant.result new file mode 100644 index 00000000000..e5ef57db992 --- /dev/null +++ b/mysql-test/suite/parts/r/partition_alter_instant.result @@ -0,0 +1,34 @@ +CREATE TABLE t1 ( +id INT NOT NULL, +name VARCHAR(30))ENGINE=InnoDB ROW_FORMAT=COMPACT CHARACTER SET=latin1 +PARTITION BY RANGE (id) ( +PARTITION p0 VALUES LESS THAN (50), +PARTITION p1 VALUES LESS THAN (MAXVALUE) +); +INSERT INTO t1(id, name) VALUES(16, 'Me'), (337, 'ROFL'); +# Add and drop 31 Instant columns +CREATE TABLE t2 LIKE t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `name` varchar(30) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT + PARTITION BY RANGE (`id`) +(PARTITION `p0` VALUES LESS THAN (50) ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN MAXVALUE ENGINE = InnoDB) +ALTER TABLE t2 REMOVE PARTITIONING; +ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `name` varchar(30) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +SET ALTER_ALGORITHM=INSTANT; +ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255); +ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE +SET ALTER_ALGORITHM=INPLACE; +ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255); +DROP TABLE t1, t2; +SET ALTER_ALGORITHM=DEFAULT; diff --git a/mysql-test/suite/parts/t/partition_alter_instant.test b/mysql-test/suite/parts/t/partition_alter_instant.test new file mode 100644 index 00000000000..3d798791517 --- /dev/null +++ b/mysql-test/suite/parts/t/partition_alter_instant.test @@ -0,0 +1,43 @@ +--source include/have_partition.inc +--source include/have_innodb.inc +--source include/have_innodb_16k.inc + +# MDEV-21832 FORCE all partition to rebuild if any one of the +# partition does rebuild +CREATE TABLE t1 ( + id INT NOT NULL, + name VARCHAR(30))ENGINE=InnoDB ROW_FORMAT=COMPACT CHARACTER SET=latin1 + PARTITION BY RANGE (id) ( + PARTITION p0 VALUES LESS THAN (50), + PARTITION p1 VALUES LESS THAN (MAXVALUE) +); + +INSERT INTO t1(id, name) VALUES(16, 'Me'), (337, 'ROFL'); + +--echo # Add and drop 31 Instant columns +--disable_query_log +let $i = 1; +while ($i < 32) { +--eval ALTER TABLE t1 ADD COLUMN col$i VARCHAR(255) NOT NULL DEFAULT repeat('a', 255); +inc $i; +} + +let $i = 31; +while ($i > 0) { +--eval ALTER TABLE t1 DROP COLUMN col$i +dec $i; +} +--enable_query_log + +CREATE TABLE t2 LIKE t1; +SHOW CREATE TABLE t2; +ALTER TABLE t2 REMOVE PARTITIONING; +ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2; +SHOW CREATE TABLE t2; +SET ALTER_ALGORITHM=INSTANT; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255); +SET ALTER_ALGORITHM=INPLACE; +ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255); +DROP TABLE t1, t2; +SET ALTER_ALGORITHM=DEFAULT; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index d65a4963905..e8a62438e02 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -10071,7 +10071,8 @@ ha_partition::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { uint index= 0; - enum_alter_inplace_result result= HA_ALTER_INPLACE_NO_LOCK; + enum_alter_inplace_result result; + alter_table_operations orig_ops; ha_partition_inplace_ctx *part_inplace_ctx; bool first_is_set= false; THD *thd= ha_thd(); @@ -10098,33 +10099,35 @@ ha_partition::check_if_supported_inplace_alter(TABLE *altered_table, if (!part_inplace_ctx->handler_ctx_array) DBUG_RETURN(HA_ALTER_ERROR); - /* Set all to NULL, including the terminating one. */ - for (index= 0; index <= m_tot_parts; index++) - part_inplace_ctx->handler_ctx_array[index]= NULL; + do { + result= HA_ALTER_INPLACE_NO_LOCK; + /* Set all to NULL, including the terminating one. */ + for (index= 0; index <= m_tot_parts; index++) + part_inplace_ctx->handler_ctx_array[index]= NULL; - ha_alter_info->handler_flags |= ALTER_PARTITIONED; - for (index= 0; index < m_tot_parts; index++) - { - enum_alter_inplace_result p_result= - m_file[index]->check_if_supported_inplace_alter(altered_table, - ha_alter_info); - part_inplace_ctx->handler_ctx_array[index]= ha_alter_info->handler_ctx; - - if (index == 0) + ha_alter_info->handler_flags |= ALTER_PARTITIONED; + orig_ops= ha_alter_info->handler_flags; + for (index= 0; index < m_tot_parts; index++) { - first_is_set= (ha_alter_info->handler_ctx != NULL); - } - else if (first_is_set != (ha_alter_info->handler_ctx != NULL)) - { - /* Either none or all partitions must set handler_ctx! */ - DBUG_ASSERT(0); - DBUG_RETURN(HA_ALTER_ERROR); + enum_alter_inplace_result p_result= + m_file[index]->check_if_supported_inplace_alter(altered_table, + ha_alter_info); + part_inplace_ctx->handler_ctx_array[index]= ha_alter_info->handler_ctx; + + if (index == 0) + first_is_set= (ha_alter_info->handler_ctx != NULL); + else if (first_is_set != (ha_alter_info->handler_ctx != NULL)) + { + /* Either none or all partitions must set handler_ctx! */ + DBUG_ASSERT(0); + DBUG_RETURN(HA_ALTER_ERROR); + } + if (p_result < result) + result= p_result; + if (result == HA_ALTER_ERROR) + break; } - if (p_result < result) - result= p_result; - if (result == HA_ALTER_ERROR) - break; - } + } while (orig_ops != ha_alter_info->handler_flags); ha_alter_info->handler_ctx= part_inplace_ctx; /* diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 4200e87fa7f..0f1d519b42b 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2488,6 +2488,7 @@ cannot_create_many_fulltext_index: } if (need_rebuild || fts_need_rebuild) { + ha_alter_info->handler_flags |= ALTER_RECREATE_TABLE; DBUG_RETURN(online ? HA_ALTER_INPLACE_COPY_NO_LOCK : HA_ALTER_INPLACE_COPY_LOCK); |