mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-28930 ALTER TABLE Deadlocks with parallel TL_WRITE
ALTER ONLINE TABLE acquires table with TL_READ. Myisam normally acquires TL_WRITE for DML, which makes it hang until table is freed. We deadlock once ALTER upgrades its MDL lock. Solution: Unlock table earlier. We don't need to hold TL_READ once we finished copying. Relay log replication requires no data locks on `from` table.
This commit is contained in:
committed by
Sergei Golubchik
parent
8fbdc76038
commit
2ed03a41e6
@ -579,6 +579,27 @@ drop table t1;
|
|||||||
drop table t2;
|
drop table t2;
|
||||||
drop table t3;
|
drop table t3;
|
||||||
#
|
#
|
||||||
|
# MDEV-28930 ALTER TABLE Deadlocks with parallel TL_WRITE
|
||||||
|
#
|
||||||
|
create table t1(a int) engine=myisam select 1;
|
||||||
|
set debug_sync='alter_table_online_before_lock SIGNAL ready WAIT_FOR go_for_locking';
|
||||||
|
alter table t1 force;
|
||||||
|
connection con2;
|
||||||
|
set debug_sync='now WAIT_FOR ready';
|
||||||
|
set debug_sync='thr_multi_lock_before_thr_lock SIGNAL go_for_locking';
|
||||||
|
update t1 set a=2;
|
||||||
|
connection default;
|
||||||
|
set debug_sync='alter_table_online_before_lock SIGNAL ready WAIT_FOR go_for_locking';
|
||||||
|
alter table mysql.global_priv force;
|
||||||
|
connection con2;
|
||||||
|
set debug_sync='now WAIT_FOR ready';
|
||||||
|
set debug_sync='thr_multi_lock_before_thr_lock SIGNAL go_for_locking';
|
||||||
|
create user user1@localhost;
|
||||||
|
connection default;
|
||||||
|
set debug_sync=reset;
|
||||||
|
drop user user1@localhost;
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
# MDEV-28959 Online alter ignores strict table mode
|
# MDEV-28959 Online alter ignores strict table mode
|
||||||
#
|
#
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
|
@ -717,6 +717,39 @@ drop table t1;
|
|||||||
drop table t2;
|
drop table t2;
|
||||||
drop table t3;
|
drop table t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-28930 ALTER TABLE Deadlocks with parallel TL_WRITE
|
||||||
|
--echo #
|
||||||
|
create table t1(a int) engine=myisam select 1;
|
||||||
|
|
||||||
|
set debug_sync='alter_table_online_before_lock SIGNAL ready WAIT_FOR go_for_locking';
|
||||||
|
--send
|
||||||
|
alter table t1 force;
|
||||||
|
|
||||||
|
--connection con2
|
||||||
|
set debug_sync='now WAIT_FOR ready';
|
||||||
|
set debug_sync='thr_multi_lock_before_thr_lock SIGNAL go_for_locking';
|
||||||
|
update t1 set a=2;
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
--reap
|
||||||
|
|
||||||
|
set debug_sync='alter_table_online_before_lock SIGNAL ready WAIT_FOR go_for_locking';
|
||||||
|
--send
|
||||||
|
alter table mysql.global_priv force;
|
||||||
|
|
||||||
|
--connection con2
|
||||||
|
set debug_sync='now WAIT_FOR ready';
|
||||||
|
set debug_sync='thr_multi_lock_before_thr_lock SIGNAL go_for_locking';
|
||||||
|
create user user1@localhost;
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
--reap
|
||||||
|
|
||||||
|
set debug_sync=reset;
|
||||||
|
drop user user1@localhost;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-28959 Online alter ignores strict table mode
|
--echo # MDEV-28959 Online alter ignores strict table mode
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -75,17 +75,15 @@ stage/sql/table lock NULL NULL
|
|||||||
stage/sql/After create NULL NULL
|
stage/sql/After create NULL NULL
|
||||||
stage/sql/copy to tmp table 5 5
|
stage/sql/copy to tmp table 5 5
|
||||||
stage/sql/Enabling keys NULL NULL
|
stage/sql/Enabling keys NULL NULL
|
||||||
|
stage/sql/Unlocking tables NULL NULL
|
||||||
|
stage/sql/Enabling keys NULL NULL
|
||||||
stage/sql/Apply log event NULL NULL
|
stage/sql/Apply log event NULL NULL
|
||||||
stage/sql/After apply log event NULL NULL
|
stage/sql/After apply log event NULL NULL
|
||||||
stage/sql/Rename result table NULL NULL
|
stage/sql/Rename result table NULL NULL
|
||||||
stage/sql/Unlocking tables NULL NULL
|
|
||||||
stage/sql/Rename result table NULL NULL
|
|
||||||
stage/sql/End of update loop NULL NULL
|
stage/sql/End of update loop NULL NULL
|
||||||
stage/sql/Query end NULL NULL
|
stage/sql/Query end NULL NULL
|
||||||
stage/sql/Commit NULL NULL
|
stage/sql/Commit NULL NULL
|
||||||
stage/sql/closing tables NULL NULL
|
stage/sql/closing tables NULL NULL
|
||||||
stage/sql/Unlocking tables NULL NULL
|
|
||||||
stage/sql/closing tables NULL NULL
|
|
||||||
stage/sql/Commit implicit NULL NULL
|
stage/sql/Commit implicit NULL NULL
|
||||||
stage/sql/Starting cleanup NULL NULL
|
stage/sql/Starting cleanup NULL NULL
|
||||||
stage/sql/Freeing items NULL NULL
|
stage/sql/Freeing items NULL NULL
|
||||||
|
@ -4781,12 +4781,11 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
|
|||||||
thd->set_query_timer();
|
thd->set_query_timer();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If there is no locks taken, this is the first binrow event seen
|
If there are no tables open, this must be the first row event seen
|
||||||
after the table map events. We should then lock all the tables
|
after the table map events. We should then open and lock all tables
|
||||||
used in the transaction and proceed with execution of the actual
|
used in the transaction and proceed with execution of the actual event.
|
||||||
event.
|
|
||||||
*/
|
*/
|
||||||
if (!thd->lock)
|
if (!thd->open_tables)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Lock_tables() reads the contents of thd->lex, so they must be
|
Lock_tables() reads the contents of thd->lex, so they must be
|
||||||
|
@ -11998,6 +11998,11 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
|||||||
// We restore bitmaps, because update event is going to mess up with them.
|
// We restore bitmaps, because update event is going to mess up with them.
|
||||||
to->default_column_bitmaps();
|
to->default_column_bitmaps();
|
||||||
|
|
||||||
|
end_read_record(&info);
|
||||||
|
init_read_record_done= false;
|
||||||
|
mysql_unlock_tables(thd, thd->lock);
|
||||||
|
thd->lock= NULL;
|
||||||
|
|
||||||
error= online_alter_read_from_binlog(thd, &rgi, binlog);
|
error= online_alter_read_from_binlog(thd, &rgi, binlog);
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "alter_table_online_before_lock");
|
DEBUG_SYNC(thd, "alter_table_online_before_lock");
|
||||||
|
Reference in New Issue
Block a user