diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index 81fe415cf6f..3bb2bce8052 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -1456,6 +1456,68 @@ connection default; set old_mode= @old_old_mode; drop table t1; set debug_sync= reset; +# +# MDEV-32100 Online ALTER TABLE ends with 1032 under some isolation levels +# +create table iso_levels(id int, level text); +INSERT iso_levels VALUES (0, "READ UNCOMMITTED"), +(1, "READ COMMITTED"), +(2, "REPEATABLE READ"), +(3, "SERIALIZABLE"); +create table t1 (a int, b int, key(b)) engine=innodb; +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level SERIALIZABLE; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)) engine=innodb; +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level REPEATABLE READ; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)) engine=innodb; +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level READ COMMITTED; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +create table t1 (a int, b int, key(b)) engine=innodb; +connection con2; +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); +connection default; +set session transaction isolation level READ UNCOMMITTED; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; +alter table t1 force, algorithm=copy; +connection con2; +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; +connection default; +drop table t1; +set debug_sync= reset; +drop table iso_levels; disconnect con1; disconnect con2; # diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index e054c0218f5..a52e95f69ed 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -1695,6 +1695,47 @@ set old_mode= @old_old_mode; drop table t1; set debug_sync= reset; +--echo # +--echo # MDEV-32100 Online ALTER TABLE ends with 1032 under some isolation levels +--echo # + +let $tx_iso_id=4; + +create table iso_levels(id int, level text); +INSERT iso_levels VALUES (0, "READ UNCOMMITTED"), + (1, "READ COMMITTED"), + (2, "REPEATABLE READ"), + (3, "SERIALIZABLE"); + +while($tx_iso_id) { +dec $tx_iso_id; +let tx_iso= `select level from iso_levels where id = $tx_iso_id`; + +create table t1 (a int, b int, key(b)) engine=innodb; + +--connection con2 +insert into t1 values (1,1),(null,null),(3,3),(4,null),(null,5); + +--connection default + +eval set session transaction isolation level $tx_iso; +set debug_sync= "alter_table_online_downgraded signal downgraded wait_for goalters"; + +send alter table t1 force, algorithm=copy; + +--connection con2 +set debug_sync= "now wait_for downgraded"; +delete from t1 where b is null; +set debug_sync= "now signal goalters"; + +--connection default +--reap +drop table t1; +} +set debug_sync= reset; +drop table iso_levels; + + --disconnect con1 --disconnect con2 diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 25d72cfb2fb..453237dbb65 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -65,6 +65,7 @@ #include "rpl_rli.h" #include "log.h" #include "sql_debug.h" +#include "scope.h" #ifdef _WIN32 #include @@ -10236,6 +10237,12 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, table_list->lock_type= TL_READ; } + enum_tx_isolation iso_level_initial= thd->tx_isolation; + SCOPE_EXIT([thd, iso_level_initial](){ + thd->tx_isolation= iso_level_initial; + }); + thd->tx_isolation= ISO_REPEATABLE_READ; + DEBUG_SYNC(thd, "alter_table_before_open_tables"); thd->open_options|= HA_OPEN_FOR_ALTER;