summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/events.result76
-rw-r--r--mysql-test/t/events.test109
-rw-r--r--sql/event.cc69
-rw-r--r--sql/event_priv.h3
-rw-r--r--sql/event_timed.cc14
-rw-r--r--sql/sql_parse.cc2
6 files changed, 197 insertions, 76 deletions
diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result
index 41f944ab089..6048dbd3012 100644
--- a/mysql-test/r/events.result
+++ b/mysql-test/r/events.result
@@ -15,20 +15,11 @@ create event event2 on schedule every 2 second starts now() ends date_add(now(),
drop event event2;
create event e_43 on schedule every 1 second do set @a = 5;
set global event_scheduler = 1;
-select sleep(2);
-sleep(2)
-0
alter event e_43 do alter event e_43 do set @a = 4;
-select sleep(3);
-sleep(3)
-0
select db, name, body, status, interval_field, interval_value from mysql.event;
db name body status interval_field interval_value
events_test e_43 set @a = 4 ENABLED SECOND 1
drop event e_43;
-select sleep(1);
-sleep(1)
-0
set global event_scheduler = 0;
create table t_event3 (a int, b float);
drop event if exists event3;
@@ -121,6 +112,7 @@ drop event two_event;
drop event three_event;
drop user ev_test@localhost;
drop event one_event;
+"Sleep a bit so the server closes the second connection"
create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
db name body definer convert_tz(execute_at, 'UTC', 'SYSTEM') on_completion
@@ -137,4 +129,70 @@ set event_scheduler=0;
ERROR HY000: Variable 'event_scheduler' is a GLOBAL variable and should be set with SET GLOBAL
set global event_scheduler=2;
ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2'
+"DISABLE the scheduler. Testing that it does not work when the variable is 0"
+set global event_scheduler=0;
+select definer, name, db from mysql.event;
+definer name db
+select get_lock("test_lock1", 20);
+get_lock("test_lock1", 20)
+1
+create event закачка on schedule every 10 hour do select get_lock("test_lock1", 20);
+"Should return 1 row"
+select definer, name, db from mysql.event;
+definer name db
+root@localhost закачка events_test
+"Should be only 1 process"
+show processlist;
+Id User Host db Command Time State Info
+# root localhost events_test Query # NULL show processlist
+select release_lock("test_lock1");
+release_lock("test_lock1")
+1
+drop event закачка;
+"Should have 0 events"
+select count(*) from mysql.event;
+count(*)
+0
+"ENABLE the scheduler and get a lock"
+set global event_scheduler=1;
+select get_lock("test_lock2", 20);
+get_lock("test_lock2", 20)
+1
+"Create an event which tries to acquire a mutex. The event locks on the mutex"
+create event закачка on schedule every 10 hour do select get_lock("test_lock2", 20);
+"Let some time pass to the event starts"
+"Should have only 3 processes: the scheduler, our conn and the locked event"
+show processlist;
+Id User Host db Command Time State Info
+# root localhost events_test Query # NULL show processlist
+# event_scheduler NULL Connect # Sleeping NULL
+# root events_test Connect # User lock select get_lock("test_lock2", 20)
+"Release the mutex, the event worker should finish."
+select release_lock("test_lock2");
+release_lock("test_lock2")
+1
+drop event закачка;
+set global event_scheduler=1;
+select get_lock("test_lock2_1", 20);
+get_lock("test_lock2_1", 20)
+1
+create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
+"Should see 2 processes, one locked on get_lock("
+"Shutting down the scheduler, it should wait for the running event"
+set global event_scheduler=0;
+"Should have only 3 processes: the scheduler, our conn and the locked event"
+show processlist;
+Id User Host db Command Time State Info
+# root localhost events_test Query # NULL show processlist
+# event_scheduler NULL Connect # Sleeping NULL
+# root events_test Connect # User lock select get_lock("test_lock2_1", 20)
+"Release the lock so the child process should finish. Hence the scheduler also"
+select release_lock("test_lock2_1");
+release_lock("test_lock2_1")
+1
+"Should have only our process now:"
+show processlist;
+Id User Host db Command Time State Info
+# root localhost events_test Query # NULL show processlist
+drop event закачка21;
drop database events_test;
diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test
index be24d490393..14acdb44038 100644
--- a/mysql-test/t/events.test
+++ b/mysql-test/t/events.test
@@ -17,12 +17,12 @@ drop event event2;
create event e_43 on schedule every 1 second do set @a = 5;
set global event_scheduler = 1;
-select sleep(2);
+--sleep 2
alter event e_43 do alter event e_43 do set @a = 4;
-select sleep(3);
+--sleep 2
select db, name, body, status, interval_field, interval_value from mysql.event;
drop event e_43;
-select sleep(1);
+--sleep 1
set global event_scheduler = 0;
create table t_event3 (a int, b float);
@@ -107,8 +107,8 @@ drop event one_event;
##INFORMATION_SCHEMA.EVENTS test end
#
-
-
+--echo "Sleep a bit so the server closes the second connection"
+--sleep 2
create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
@@ -129,23 +129,38 @@ set event_scheduler=0;
--error 1231
set global event_scheduler=2;
-#set global event_scheduler=0;
-#select count(*) from mysql.event;
-#select get_lock("test_lock1", 20);
-#create event закачка on schedule every 10 hour do select get_lock("test_lock1", 20);
-#select count(*) from mysql.event;
-##show processlist;
-#select release_lock("test_lock1");
-#drop event закачка;
-#select count(*) from mysql.event;
+--echo "DISABLE the scheduler. Testing that it does not work when the variable is 0"
+set global event_scheduler=0;
+select definer, name, db from mysql.event;
+select get_lock("test_lock1", 20);
+create event закачка on schedule every 10 hour do select get_lock("test_lock1", 20);
+--echo "Should return 1 row"
+select definer, name, db from mysql.event;
+
+--echo "Should be only 1 process"
+--replace_column 1 # 6 #
+show processlist;
+select release_lock("test_lock1");
+drop event закачка;
+--echo "Should have 0 events"
+select count(*) from mysql.event;
+
#
-#set global event_scheduler=1;
-#select get_lock("test_lock2", 20);
-#create event закачка on schedule every 10 hour do select get_lock("test_lock2", 20);
-#select sleep(2);
-#show processlist;
-#select release_lock("test_lock2");
-#drop event закачка;
+#
+#
+--echo "ENABLE the scheduler and get a lock"
+set global event_scheduler=1;
+select get_lock("test_lock2", 20);
+--echo "Create an event which tries to acquire a mutex. The event locks on the mutex"
+create event закачка on schedule every 10 hour do select get_lock("test_lock2", 20);
+--echo "Let some time pass to the event starts"
+--sleep 2
+--echo "Should have only 3 processes: the scheduler, our conn and the locked event"
+--replace_column 1 # 6 #
+show processlist;
+--echo "Release the mutex, the event worker should finish."
+select release_lock("test_lock2");
+drop event закачка;
##
## 1. get a lock
@@ -155,26 +170,33 @@ set global event_scheduler=2;
## 5. kill the scheduler, it will wait for the child to stop
## 6. both processes should be there on show processlist
## 7. release the lock and sleep, both scheduler and child should end
-#set global event_scheduler=1;
-#select get_lock("test_lock2_1", 20);
-#create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
-#select sleep(2);
-##show processlist;
-#set global event_scheduler=0;
-#select sleep(2);
-##show processlist;
-#select release_lock("test_lock2_1");
-#select sleep(2);
-##show processlist;
-#drop event закачка21;
-
-#set global event_scheduler=1;
-#select get_lock("test_lock3", 20);
-#create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20);
-#select sleep(2);
+set global event_scheduler=1;
+select get_lock("test_lock2_1", 20);
+create event закачка21 on schedule every 10 hour do select get_lock("test_lock2_1", 20);
+--sleep 1
+--echo "Should see 2 processes, one locked on get_lock("
#show processlist;
-#drop event закачка;
-#select release_lock("test_lock3");
+--echo "Shutting down the scheduler, it should wait for the running event"
+set global event_scheduler=0;
+--sleep 1
+--echo "Should have only 3 processes: the scheduler, our conn and the locked event"
+--replace_column 1 # 6 #
+show processlist;
+--echo "Release the lock so the child process should finish. Hence the scheduler also"
+select release_lock("test_lock2_1");
+--sleep 1
+--echo "Should have only our process now:"
+--replace_column 1 # 6 #
+show processlist;
+drop event закачка21;
+
+##set global event_scheduler=1;
+##select get_lock("test_lock3", 20);
+##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20);
+##select sleep(2);
+##show processlist;
+##drop event закачка;
+##select release_lock("test_lock3");
#
# test with very often occuring event
@@ -182,14 +204,15 @@ set global event_scheduler=2;
##select get_lock("test_lock4", 20);
##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20);
##select sleep(3);
+##--replace_column 1 # 6 #
##show processlist;
##drop event закачка4;
##select release_lock("test_lock4");
-#set global event_scheduler=0;
-#select sleep(2);
+##set global event_scheduler=0;
+##select sleep(2);
+##--replace_column 1 # 6 #
##show processlist;
-##the following locks for some reason and is a bug, commented for now
##select count(*) from mysql.event;
drop database events_test;
diff --git a/sql/event.cc b/sql/event.cc
index abca622835a..a7c6d48b988 100644
--- a/sql/event.cc
+++ b/sql/event.cc
@@ -704,11 +704,17 @@ done:
}
+/*
+ 0 - OK can drop from outside
+ 1 - Scheduled from dropping, don't drop from outside
+*/
+
static int
evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock,
bool is_drop)
{
uint i;
+ int ret= 0;
DBUG_ENTER("evex_remove_from_cache");
/*
@@ -738,7 +744,8 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock,
DBUG_PRINT("evex_remove_from_cache",
("running.defer mem free. is_drop=%d", is_drop));
et->flags|= EVENT_EXEC_NO_MORE;
- et->dropped= is_drop;
+ if ((et->dropped= is_drop))
+ ret= 1;
}
DBUG_PRINT("evex_remove_from_cache", ("delete from queue"));
evex_queue_delete_element(&EVEX_EQ_NAME, i);
@@ -751,7 +758,7 @@ done:
if (use_lock)
VOID(pthread_mutex_unlock(&LOCK_event_arrays));
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
@@ -866,21 +873,25 @@ done:
Drops an event
SYNOPSIS
- evex_drop_event()
+ db_drop_event()
thd THD
et event's name
drop_if_exists if set and the event not existing => warning onto the stack
+ rows_affected affected number of rows is returned heres
*/
-int
-evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
- uint *rows_affected)
+int db_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
+ uint *rows_affected)
{
TABLE *table;
- int ret= EVEX_OPEN_TABLE_FAILED;
- DBUG_ENTER("evex_drop_event");
+ Open_tables_state backup;
+ uint ret;
+
+ DBUG_ENTER("db_drop_event");
+ ret= EVEX_OPEN_TABLE_FAILED;
+ thd->reset_n_backup_open_tables_state(&backup);
if (evex_open_event_table(thd, TL_WRITE, &table))
{
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
@@ -908,10 +919,6 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
goto done;
}
- VOID(pthread_mutex_lock(&LOCK_evex_running));
- if (evex_is_running)
- ret= evex_remove_from_cache(&et->dbname, &et->name, true, true);
- VOID(pthread_mutex_unlock(&LOCK_evex_running));
done:
/*
@@ -919,6 +926,44 @@ done:
we have to close our thread tables.
*/
close_thread_tables(thd);
+ thd->restore_backup_open_tables_state(&backup);
+ DBUG_RETURN(ret);
+}
+
+
+/*
+ Drops an event
+
+ SYNOPSIS
+ evex_drop_event()
+ thd THD
+ et event's name
+ drop_if_exists if set and the event not existing => warning onto the stack
+ rows_affected affected number of rows is returned heres
+
+*/
+
+int
+evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
+ uint *rows_affected)
+{
+ TABLE *table;
+ int ret= 0;
+
+ DBUG_ENTER("evex_drop_event");
+
+
+ VOID(pthread_mutex_lock(&LOCK_evex_running));
+ if (evex_is_running)
+ ret= evex_remove_from_cache(&et->dbname, &et->name, true, true);
+ VOID(pthread_mutex_unlock(&LOCK_evex_running));
+
+ if (ret == 1)
+ ret= 0;
+ else if (ret == 0)
+ ret= db_drop_event(thd, et, drop_if_exists, rows_affected);
+ else
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
DBUG_RETURN(ret);
}
diff --git a/sql/event_priv.h b/sql/event_priv.h
index 7d1cdbcd264..b0ba205d806 100644
--- a/sql/event_priv.h
+++ b/sql/event_priv.h
@@ -40,6 +40,9 @@ evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
int
event_timed_compare_q(void *vptr, byte* a, byte *b);
+int db_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
+ uint *rows_affected);
+
#define EXEC_QUEUE_QUEUE_NAME executing_queue
#define EXEC_QUEUE_DARR_NAME evex_executing_queue
diff --git a/sql/event_timed.cc b/sql/event_timed.cc
index 28d21089b74..e585f6252ca 100644
--- a/sql/event_timed.cc
+++ b/sql/event_timed.cc
@@ -877,20 +877,10 @@ int
event_timed::drop(THD *thd)
{
TABLE *table;
- int ret= 0;
+ uint tmp= 0;
DBUG_ENTER("event_timed::drop");
- if (evex_open_event_table(thd, TL_WRITE, &table))
- DBUG_RETURN(-1);
-
- if (evex_db_find_event_aux(thd, dbname, name, definer, table))
- DBUG_RETURN(-2);
-
- if ((ret= table->file->ha_delete_row(table->record[0])))
- DBUG_RETURN(ret);
-
- close_thread_tables(thd);
- DBUG_RETURN(0);
+ DBUG_RETURN(db_drop_event(thd, this, false, &tmp));
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 279a02fa1d1..e9fb004b316 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3743,6 +3743,8 @@ end_with_restore_list:
res= evex_drop_event(thd, lex->et, lex->drop_if_exists, &rows_affected);
default:;
}
+ DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d",
+ res, rows_affected));
if (!res)
send_ok(thd, rows_affected);