diff options
-rw-r--r-- | mysql-test/r/events_trans.result | 19 | ||||
-rw-r--r-- | mysql-test/t/events_trans.test | 25 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 19 | ||||
-rw-r--r-- | sql/events.cc | 3 |
4 files changed, 58 insertions, 8 deletions
diff --git a/mysql-test/r/events_trans.result b/mysql-test/r/events_trans.result index 16ec64b4c50..37951c30787 100644 --- a/mysql-test/r/events_trans.result +++ b/mysql-test/r/events_trans.result @@ -116,3 +116,22 @@ OK: create event: database does not exist delete from t1; commit work; drop database events_test; +# +# Bug#54105 assert in MDL_context::release_locks_stored_before +# +USE test; +DROP TABLE IF EXISTS t1, t2; +DROP EVENT IF EXISTS e1; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT); +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1; +START TRANSACTION; +INSERT INTO t1 VALUES (1); +SAVEPOINT A; +SHOW CREATE EVENT e1; +Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation +e1 SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `e1` ON SCHEDULE EVERY 1 DAY STARTS '#' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 1 latin1 latin1_swedish_ci latin1_swedish_ci +SELECT * FROM t2; +a +ROLLBACK WORK TO SAVEPOINT A; +DROP TABLE t1, t2; diff --git a/mysql-test/t/events_trans.test b/mysql-test/t/events_trans.test index a94b75bb812..4cf2583ac96 100644 --- a/mysql-test/t/events_trans.test +++ b/mysql-test/t/events_trans.test @@ -121,3 +121,28 @@ let $wait_condition= drop database events_test; + +--echo # +--echo # Bug#54105 assert in MDL_context::release_locks_stored_before +--echo # + +USE test; + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +DROP EVENT IF EXISTS e1; +--enable_warnings + +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT); +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT 1; + +START TRANSACTION; +INSERT INTO t1 VALUES (1); +SAVEPOINT A; +--replace_regex /STARTS '[^']+'/STARTS '#'/ +SHOW CREATE EVENT e1; +SELECT * FROM t2; +ROLLBACK WORK TO SAVEPOINT A; + +DROP TABLE t1, t2; diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index d47f1641bb0..db508e4ea41 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -996,24 +996,33 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *etn) { bool ret; - TABLE *table= NULL; ulong saved_mode= thd->variables.sql_mode; + Open_tables_backup open_tables_backup; + TABLE_LIST event_table; DBUG_ENTER("Event_db_repository::load_named_event"); DBUG_PRINT("enter",("thd: 0x%lx name: %*s", (long) thd, (int) name.length, name.str)); + event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ); + /* Reset sql_mode during data dictionary operations. */ thd->variables.sql_mode= 0; - if (!(ret= open_event_table(thd, TL_READ, &table))) + /* + We don't use open_event_table() here to make sure that SHOW + CREATE EVENT works properly in transactional context, and + does not release transactional metadata locks when the + event table is closed. + */ + if (!(ret= open_system_tables_for_read(thd, &event_table, &open_tables_backup))) { - if ((ret= find_named_event(dbname, name, table))) + if ((ret= find_named_event(dbname, name, event_table.table))) my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name.str); - else if ((ret= etn->load_from_row(thd, table))) + else if ((ret= etn->load_from_row(thd, event_table.table))) my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "event"); - close_mysql_tables(thd); + close_system_tables(thd, &open_tables_backup); } thd->variables.sql_mode= saved_mode; diff --git a/sql/events.cc b/sql/events.cc index 5379ec2c9eb..3dc6a46bb66 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -699,7 +699,6 @@ send_show_create_event(THD *thd, Event_timed *et, Protocol *protocol) bool Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) { - Open_tables_backup open_tables_backup; Event_timed et; bool ret; @@ -722,9 +721,7 @@ Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) deadlock can occur please refer to the description of 'system table' flag. */ - thd->reset_n_backup_open_tables_state(&open_tables_backup); ret= db_repository->load_named_event(thd, dbname, name, &et); - thd->restore_backup_open_tables_state(&open_tables_backup); if (!ret) ret= send_show_create_event(thd, &et, thd->protocol); |