Skip to content

Commit

Permalink
MDEV-19491 update query stopped working after mariadb upgrade 10.2.23…
Browse files Browse the repository at this point in the history
… -> 10.2.24

as well as

MDEV-19500 Update with join stopped worked if there is a call to a procedure in a trigger
MDEV-19521 Update Table Fails with Trigger and Stored Function
MDEV-19497 Replication stops because table not found
MDEV-19527 UPDATE + JOIN + TRIGGERS = table doesn't exists error

Reimplement the fix for (5d510fd)

MDEV-18507 can't update temporary table when joined with table with triggers on read-only

instead of calling open_tables() twice, put multi-update
prepare code inside open_tables() loop.

Add a test for a MDL backoff-and-retry loop inside open_tables()
across multi-update prepare code.
  • Loading branch information
vuvova committed Jun 1, 2019
1 parent 1d4ac3d commit 6660c07
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 97 deletions.
18 changes: 18 additions & 0 deletions mysql-test/r/multi_update.result
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,24 @@ triggered
triggered
drop table t1,t2, t3;
drop user foo;
create table t1 (a int, b int);
create table t2 (c int, d int);
insert t1 values (1,2),(3,4);
insert t2 values (5,6),(7,8);
create table t0 (x int);
insert t0 values (11), (22);
create trigger tr1 before update on t2 for each row insert t0 values (new.c);
lock table t0 write;
update t1 join t2 on (a=c+4) set b=d;
drop table t1, t2, t0;
create table t1 (a int, b varchar(50), c varchar(50));
insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3');
create function f1() returns varchar(50) return 'result';
create trigger tr before update on t1 for each row set new.c = (select f1());
create table t2 select a, b from t1;
update t1 join t2 using (a) set t1.b = t2.b;
drop table t1, t2;
drop function f1;
#
# end of 5.5 tests
#
13 changes: 13 additions & 0 deletions mysql-test/r/multi_update_debug.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
create table t1 (a int, b int);
create table t2 (c int, d int);
insert t1 values (1,2),(3,4);
insert t2 values (5,6),(7,8);
create table t0 (x int);
insert t0 values (11), (22);
create trigger tr1 before update on t1 for each row insert t0 values (new.b);
set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont';
update t1 join t2 on (a=c+4) set b=d;
set debug_sync='mdl_acquire_lock_wait SIGNAL cont';
lock table t1 write, t0 write;
drop table t1, t2, t0;
set debug_sync='reset';
14 changes: 14 additions & 0 deletions mysql-test/r/multi_update_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ SELECT * FROM t2;
col_int_key pk_1 pk_2 col_int
1 2 3 4
DROP TABLE t1,t2;
create table t1 (id serial, size int(11)) engine=innodb;
create table t2 (id serial, size int, account_id int) engine=innodb;
create table t3 (id serial, size int, article_id int) engine=innodb;
create table t4 (id serial, file_id int, article_id int) engine=innodb;
insert t1 values(null, 400);
insert t2 values(null, 0, 1), (null, 1, 1);
insert t3 values(null, 100, 1);
insert t4 values(null, 1, 2);
create trigger file_update_article before update on t3 for each row
update t2 set t2.size = new.size where t2.id = new.article_id;
create trigger article_update_account before update on t2 for each row
update t1 set t1.size = t1.size + new.size where t1.id = new.account_id;
update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2;
drop table t1, t2, t3, t4;
#
# end of 5.5 tests
#
29 changes: 29 additions & 0 deletions mysql-test/t/multi_update.test
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,35 @@ select * from t2;
drop table t1,t2, t3;
drop user foo;

#
# Another test on not-opening tables unnecessary
#
create table t1 (a int, b int);
create table t2 (c int, d int);
insert t1 values (1,2),(3,4);
insert t2 values (5,6),(7,8);
create table t0 (x int);
insert t0 values (11), (22);
create trigger tr1 before update on t2 for each row insert t0 values (new.c);
connect con1, localhost, root;
lock table t0 write;
connection default;
update t1 join t2 on (a=c+4) set b=d;
disconnect con1;
drop table t1, t2, t0;

#
# MDEV-19521 Update Table Fails with Trigger and Stored Function
#
create table t1 (a int, b varchar(50), c varchar(50));
insert t1 (a,b) values (1,'1'), (2,'2'), (3,'3');
create function f1() returns varchar(50) return 'result';
create trigger tr before update on t1 for each row set new.c = (select f1());
create table t2 select a, b from t1;
update t1 join t2 using (a) set t1.b = t2.b;
drop table t1, t2;
drop function f1;

--echo #
--echo # end of 5.5 tests
--echo #
Expand Down
27 changes: 27 additions & 0 deletions mysql-test/t/multi_update_debug.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# test MDL backoff-and-retry during multi-update
#
source include/have_debug_sync.inc;
create table t1 (a int, b int);
create table t2 (c int, d int);
insert t1 values (1,2),(3,4);
insert t2 values (5,6),(7,8);
create table t0 (x int);
insert t0 values (11), (22);
create trigger tr1 before update on t1 for each row insert t0 values (new.b);

set debug_sync='open_tables_after_open_and_process_table WAIT_FOR cont';
send update t1 join t2 on (a=c+4) set b=d;

connect con1, localhost, root;
let $wait_condition= select count(*) from information_schema.processlist where state = ' debug sync point: open_tables_after_open_and_process_table'
source include/wait_condition.inc;
set debug_sync='mdl_acquire_lock_wait SIGNAL cont';
lock table t1 write, t0 write;
let $wait_condition= select count(*) from information_schema.processlist where state = 'Waiting for table metadata lock'
source include/wait_condition.inc;
disconnect con1;
connection default;
reap;
drop table t1, t2, t0;
set debug_sync='reset';
18 changes: 18 additions & 0 deletions mysql-test/t/multi_update_innodb.test
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@ SELECT * FROM t2;

DROP TABLE t1,t2;

#
# MDEV-19491 update query stopped working after mariadb upgrade 10.2.23 -> 10.2.24
#
create table t1 (id serial, size int(11)) engine=innodb;
create table t2 (id serial, size int, account_id int) engine=innodb;
create table t3 (id serial, size int, article_id int) engine=innodb;
create table t4 (id serial, file_id int, article_id int) engine=innodb;
insert t1 values(null, 400);
insert t2 values(null, 0, 1), (null, 1, 1);
insert t3 values(null, 100, 1);
insert t4 values(null, 1, 2);
create trigger file_update_article before update on t3 for each row
update t2 set t2.size = new.size where t2.id = new.article_id;
create trigger article_update_account before update on t2 for each row
update t1 set t1.size = t1.size + new.size where t1.id = new.account_id;
update t3 join t4 on t4.file_id =t3.id and t4.article_id=2 set t3.size=t3.size + 2;
drop table t1, t2, t3, t4;

--echo #
--echo # end of 5.5 tests
--echo #
3 changes: 3 additions & 0 deletions sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5055,6 +5055,7 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
sroutine_to_open= &thd->lex->sroutines_list.first;
*counter= 0;
thd_proc_info(thd, "Opening tables");
prelocking_strategy->reset(thd);

/*
If we are executing LOCK TABLES statement or a DDL statement
Expand Down Expand Up @@ -5218,6 +5219,8 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
}
}
}
if ((error= prelocking_strategy->handle_end(thd)))
goto err;
}

/*
Expand Down
2 changes: 2 additions & 0 deletions sql/sql_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,13 +426,15 @@ class Prelocking_strategy
public:
virtual ~Prelocking_strategy() { }

virtual void reset(THD *thd) { };
virtual bool handle_routine(THD *thd, Query_tables_list *prelocking_ctx,
Sroutine_hash_entry *rt, sp_head *sp,
bool *need_prelocking) = 0;
virtual bool handle_table(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list, bool *need_prelocking) = 0;
virtual bool handle_view(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list, bool *need_prelocking)= 0;
virtual bool handle_end(THD *thd) { return 0; };
};


Expand Down
Loading

0 comments on commit 6660c07

Please sign in to comment.