Skip to content
Permalink
Browse files
MDEV-14119 Assertion cmp_rec_rec() in ALTER TABLE
innobase_pk_order_preserved(): Treat an added AUTO_INCREMENT
column in the same way as an added existing column.
In either case, the column values are not guaranteed to
be constant, and thus the ordering may change if such a column
is added before any existing PRIMARY KEY columns.

prepare_inplace_alter_table_dict(): Initialize
dict_table_t::persistent_autoinc before invoking
innobase_pk_order_preserved().
  • Loading branch information
dr-m committed Aug 11, 2020
1 parent de8d57e commit c96be84
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 7 deletions.
@@ -263,3 +263,10 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;

# pk(o1,o2) to pk(o1,o2,autoinc) must not sort
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
@@ -53,3 +53,10 @@ ALTER TABLE t1 DROP a;
ERROR HY000: Cannot drop index 'a': needed in a foreign key constraint
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;
#
# MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
#
CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_128;
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
DROP TABLE t1;
@@ -323,4 +323,9 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
SET DEBUG_DBUG = @saved_debug_dbug;
@@ -1903,6 +1903,11 @@ create table t1(o1 int, o2 int, o3 int, primary key(o1,o2,o3)) engine = innodb;
insert into t1 values(1,1,2),(2,2,1);
alter table t1 drop primary key, add primary key(o1), lock=none;
drop table t1;
create table t1(o1 int, o2 int, primary key(o1,o2)) engine = innodb;
insert into t1 values(1,1),(2,1);
alter table t1 drop primary key, add column a int unique auto_increment,
add primary key(o1,o2,a), algorithm=inplace;
drop table t1;
#
# MDEV-15325 Incomplete validation of missing tablespace during recovery
#
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
#
# MDEV-11995 ALTER TABLE proceeds despite reporting ER_TOO_LONG_KEY error
#
@@ -59,3 +60,11 @@ ALTER TABLE t1 ADD b INT;
ALTER TABLE t1 DROP a;
ALTER TABLE t1 ADD c INT;
DROP TABLE t1, tx;

--echo #
--echo # MDEV-14119 Assertion cmp_rec_rec() on ALTER TABLE
--echo #
CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
INSERT INTO t1 SELECT * FROM seq_1_to_128;
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
DROP TABLE t1;
@@ -3362,7 +3362,11 @@ innobase_pk_order_preserved(
if (old_pk_column) {
new_field_order = old_field;
} else if (innobase_pk_col_is_existing(new_col_no, col_map,
old_n_cols)) {
old_n_cols)
|| new_clust_index->table->persistent_autoinc
== new_field + 1) {
/* Adding an existing column or an AUTO_INCREMENT
column may change the existing ordering. */
new_field_order = old_n_uniq + existing_field_count++;
} else {
/* Skip newly added column. */
@@ -4913,12 +4917,6 @@ prepare_inplace_alter_table_dict(
user_table);
dict_index_t* new_clust_index = dict_table_get_first_index(
ctx->new_table);
ctx->skip_pk_sort = innobase_pk_order_preserved(
ctx->col_map, clust_index, new_clust_index);

DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
DBUG_ASSERT(ctx->skip_pk_sort););

DBUG_ASSERT(!ctx->new_table->persistent_autoinc);
if (const Field* ai = altered_table->found_next_number_field) {
const unsigned col_no = innodb_col_no(ai);
@@ -4937,6 +4935,12 @@ prepare_inplace_alter_table_dict(
}
}

ctx->skip_pk_sort = innobase_pk_order_preserved(
ctx->col_map, clust_index, new_clust_index);

DBUG_EXECUTE_IF("innodb_alter_table_pk_assert_no_sort",
DBUG_ASSERT(ctx->skip_pk_sort););

if (ctx->online) {
/* Allocate a log for online table rebuild. */
rw_lock_x_lock(&clust_index->lock);

0 comments on commit c96be84

Please sign in to comment.