mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MDEV-36236 Instant alter aborts when InnoDB fails to rollback instant operation
Problem: ======== - InnoDB does consecutive instant alter operation, first instant DDL fails, it fails to reset the old instant information in table during rollback. This lead to consecutive instant alter to have wrong assumption about the exisitng instant column information. Fix: ==== dict_table_t::instant_column(): Duplicate the instant information field of the table. By doing this, InnoDB alter retains the old instant information and reset it during rollback operation
This commit is contained in:
parent
e7442e5eb9
commit
0d7ef4f478
4 changed files with 40 additions and 5 deletions
|
|
@ -1,8 +1,9 @@
|
|||
@@ -527,6 +527,6 @@
|
||||
@@ -576,7 +576,7 @@
|
||||
FROM information_schema.global_status
|
||||
WHERE variable_name = 'innodb_instant_alter_column';
|
||||
instants
|
||||
-37
|
||||
+38
|
||||
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
|
||||
# End of 10.6 tests
|
||||
CREATE TABLE t1(f1 INT, f2 TEXT)ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(1, 'a');
|
||||
ALTER TABLE t1 ADD COLUMN f3 TEXT FIRST;
|
||||
|
|
|
|||
|
|
@ -577,5 +577,16 @@ FROM information_schema.global_status
|
|||
WHERE variable_name = 'innodb_instant_alter_column';
|
||||
instants
|
||||
37
|
||||
CREATE TABLE t1(f1 INT, f2 TEXT)ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(1, 'a');
|
||||
ALTER TABLE t1 ADD COLUMN f3 TEXT FIRST;
|
||||
SET STATEMENT DEBUG_DBUG="+d,instant_insert_fail" FOR
|
||||
ALTER TABLE t1 DROP COLUMN f1;
|
||||
ERROR HY000: Internal error: InnoDB: Insert into SYS_COLUMNS failed
|
||||
ALTER TABLE t1 DROP COLUMN f1;
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
DROP TABLE t1;
|
||||
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
|
||||
# End of 10.6 tests
|
||||
|
|
|
|||
|
|
@ -657,11 +657,19 @@ DROP TABLE t1;
|
|||
SET DEBUG_SYNC=RESET;
|
||||
|
||||
--echo # End of 10.5 tests
|
||||
|
||||
SELECT variable_value-@old_instant instants
|
||||
FROM information_schema.global_status
|
||||
WHERE variable_name = 'innodb_instant_alter_column';
|
||||
|
||||
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
|
||||
CREATE TABLE t1(f1 INT, f2 TEXT)ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(1, 'a');
|
||||
ALTER TABLE t1 ADD COLUMN f3 TEXT FIRST;
|
||||
--error ER_INTERNAL_ERROR
|
||||
SET STATEMENT DEBUG_DBUG="+d,instant_insert_fail" FOR
|
||||
ALTER TABLE t1 DROP COLUMN f1;
|
||||
ALTER TABLE t1 DROP COLUMN f1;
|
||||
CHECK TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
|
||||
--echo # End of 10.6 tests
|
||||
|
|
|
|||
|
|
@ -621,6 +621,16 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
|
|||
}
|
||||
|
||||
dict_index_t* index = dict_table_get_first_index(this);
|
||||
if (instant) {
|
||||
instant->field_map= static_cast<field_map_element_t*>(
|
||||
mem_heap_dup(heap, instant->field_map,
|
||||
(index->n_fields -
|
||||
index->first_user_field()) *
|
||||
sizeof *instant->field_map));
|
||||
instant= static_cast<dict_instant_t*>(
|
||||
mem_heap_dup(heap, instant, sizeof *instant));
|
||||
}
|
||||
|
||||
bool metadata_changed;
|
||||
{
|
||||
const dict_index_t& i = *dict_table_get_first_index(&table);
|
||||
|
|
@ -5515,6 +5525,11 @@ static bool innodb_insert_sys_columns(
|
|||
return false;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("instant_insert_fail",
|
||||
my_error(ER_INTERNAL_ERROR, MYF(0),
|
||||
"InnoDB: Insert into SYS_COLUMNS failed");
|
||||
return true;);
|
||||
|
||||
if (DB_SUCCESS != que_eval_sql(
|
||||
info,
|
||||
"PROCEDURE ADD_COL () IS\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue