Skip to content

Commit 3eb8113

Browse files
committed
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.
1 parent e5e83da commit 3eb8113

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

mysql-test/suite/innodb/r/alter_table.result

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,13 @@ CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
6060
INSERT INTO t1 SELECT * FROM seq_1_to_128;
6161
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
6262
DROP TABLE t1;
63+
#
64+
# MDEV-22939 Server crashes in row_make_new_pathname()
65+
#
66+
CREATE TABLE t (a INT) ENGINE=INNODB;
67+
ALTER TABLE t DISCARD TABLESPACE;
68+
ALTER TABLE t ENGINE INNODB;
69+
ERROR HY000: Tablespace has been discarded for table `t`
70+
ALTER TABLE t FORCE;
71+
ERROR HY000: Tablespace has been discarded for table `t`
72+
DROP TABLE t;

mysql-test/suite/innodb/t/alter_table.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,14 @@ CREATE TABLE t1(a INT NOT NULL UNIQUE) ENGINE=InnoDB;
6868
INSERT INTO t1 SELECT * FROM seq_1_to_128;
6969
ALTER TABLE t1 ADD b TINYINT AUTO_INCREMENT PRIMARY KEY, DROP KEY a;
7070
DROP TABLE t1;
71+
72+
--echo #
73+
--echo # MDEV-22939 Server crashes in row_make_new_pathname()
74+
--echo #
75+
CREATE TABLE t (a INT) ENGINE=INNODB;
76+
ALTER TABLE t DISCARD TABLESPACE;
77+
--error ER_TABLESPACE_DISCARDED
78+
ALTER TABLE t ENGINE INNODB;
79+
--error ER_TABLESPACE_DISCARDED
80+
ALTER TABLE t FORCE;
81+
DROP TABLE t;

storage/innobase/handler/handler0alter.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7209,12 +7209,6 @@ commit_set_autoinc(
72097209
&& (ha_alter_info->create_info->used_fields
72107210
& HA_CREATE_USED_AUTO)) {
72117211

7212-
if (dict_table_is_discarded(ctx->old_table)) {
7213-
my_error(ER_TABLESPACE_DISCARDED, MYF(0),
7214-
old_table->s->table_name.str);
7215-
DBUG_RETURN(true);
7216-
}
7217-
72187212
/* An AUTO_INCREMENT value was supplied by the user.
72197213
It must be persisted to the data file. */
72207214
const Field* ai = old_table->found_next_number_field;
@@ -8411,9 +8405,15 @@ ha_innobase::commit_inplace_alter_table(
84118405
= static_cast<ha_innobase_inplace_ctx*>(*pctx);
84128406

84138407
DBUG_ASSERT(new_clustered == ctx->need_rebuild());
8414-
8415-
fail = commit_set_autoinc(ha_alter_info, ctx, altered_table,
8416-
table);
8408+
if (ctx->need_rebuild()
8409+
&& dict_table_is_discarded(ctx->old_table)) {
8410+
my_error(ER_TABLESPACE_DISCARDED, MYF(0),
8411+
table->s->table_name.str);
8412+
fail = true;
8413+
} else {
8414+
fail = commit_set_autoinc(ha_alter_info, ctx,
8415+
altered_table, table);
8416+
}
84178417

84188418
if (fail) {
84198419
} else if (ctx->need_rebuild()) {

0 commit comments

Comments
 (0)