Commit 3eb81136 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-22939 Server crashes in row_make_new_pathname()

The statement ALTER TABLE...DISCARD TABLESPACE is problematic,
because its designed purpose is to break the referential integrity
of the data dictionary and make a table point to nowhere.

ha_innobase::commit_inplace_alter_table(): Check whether the
table has been discarded. (This is a bit late to check it, right
before committing the change.) Previously, we performed this check
only in a specific branch of the function commit_set_autoinc().

Note: We intentionally allow non-rebuilding ALTER TABLE even if
the tablespace has been discarded, to remain compatible with MySQL.
(See the various tests with "wl5522" in the name, such as
innodb.innodb-wl5522.)

The test case would crash starting with 10.3 only, but it does not hurt
to minimize the code and test difference between 10.2 and 10.3.
parent e5e83daf
......@@ -60,3 +60,13 @@ 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;
#
# MDEV-22939 Server crashes in row_make_new_pathname()
#
CREATE TABLE t (a INT) ENGINE=INNODB;
ALTER TABLE t DISCARD TABLESPACE;
ALTER TABLE t ENGINE INNODB;
ERROR HY000: Tablespace has been discarded for table `t`
ALTER TABLE t FORCE;
ERROR HY000: Tablespace has been discarded for table `t`
DROP TABLE t;
......@@ -68,3 +68,14 @@ 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;
--echo #
--echo # MDEV-22939 Server crashes in row_make_new_pathname()
--echo #
CREATE TABLE t (a INT) ENGINE=INNODB;
ALTER TABLE t DISCARD TABLESPACE;
--error ER_TABLESPACE_DISCARDED
ALTER TABLE t ENGINE INNODB;
--error ER_TABLESPACE_DISCARDED
ALTER TABLE t FORCE;
DROP TABLE t;
......@@ -7209,12 +7209,6 @@ commit_set_autoinc(
&& (ha_alter_info->create_info->used_fields
& HA_CREATE_USED_AUTO)) {
if (dict_table_is_discarded(ctx->old_table)) {
my_error(ER_TABLESPACE_DISCARDED, MYF(0),
old_table->s->table_name.str);
DBUG_RETURN(true);
}
/* An AUTO_INCREMENT value was supplied by the user.
It must be persisted to the data file. */
const Field* ai = old_table->found_next_number_field;
......@@ -8411,9 +8405,15 @@ ha_innobase::commit_inplace_alter_table(
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
fail = commit_set_autoinc(ha_alter_info, ctx, altered_table,
table);
if (ctx->need_rebuild()
&& dict_table_is_discarded(ctx->old_table)) {
my_error(ER_TABLESPACE_DISCARDED, MYF(0),
table->s->table_name.str);
fail = true;
} else {
fail = commit_set_autoinc(ha_alter_info, ctx,
altered_table, table);
}
if (fail) {
} else if (ctx->need_rebuild()) {
......
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