Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2097 06/01/31 12:05:14 andrey@lmy004. +6 -0
- fix for bug #16414 (Events: Crash or hang if event drops itself)
WL#1034 (Internal CRON)
sql/sql_parse.cc
1.516 06/01/31 12:05:05 andrey@lmy004. +2 -0
- some debug info about the status code returned.
sql/event_timed.cc
1.24 06/01/31 12:05:05 andrey@lmy004. +2 -12
- use db_drop_event() and don't implement the dropping ourselves
sql/event_priv.h
1.16 06/01/31 12:05:05 andrey@lmy004. +3 -0
- export the new function db_drop_event()
sql/event.cc
1.24 06/01/31 12:05:05 andrey@lmy004. +57 -12
- evex_remove_from_cache reports back whether the in_memory
object was deleted or was scheduled. In case scheduling then
don't delete it from outside but let it do it itself
- move out db interaction code out of evex_drop_event to db_drop_event
so it can be called from outter space :)
mysql-test/t/events.test
1.13 06/01/31 12:05:05 andrey@lmy004. +67 -44
use --sleep instead of select sleep()
enable some scheduler related tests. They were disabled because of a hang that
happened. The hang is fixed with this bugfix.
mysql-test/r/events.result
1.12 06/01/31 12:05:04 andrey@lmy004. +67 -9
update the result
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: andrey
# Host: lmy004.
# Root: /work/mysql-5.1-events_i_s
--- 1.515/sql/sql_parse.cc 2006-01-30 13:31:20 +01:00
+++ 1.516/sql/sql_parse.cc 2006-01-31 12:05:05 +01:00
@@ -3723,6 +3723,8 @@
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);
--- 1.11/mysql-test/r/events.result 2006-01-30 17:11:41 +01:00
+++ 1.12/mysql-test/r/events.result 2006-01-31 12:05:04 +01:00
@@ -15,20 +15,11 @@
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 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 @@
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;
--- 1.12/mysql-test/t/events.test 2006-01-30 17:11:42 +01:00
+++ 1.13/mysql-test/t/events.test 2006-01-31 12:05:05 +01:00
@@ -17,12 +17,12 @@
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 @@
##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 @@
--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;
-#
-#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 "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;
+
+#
+#
+#
+--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 @@
## 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 @@
##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;
--- 1.23/sql/event.cc 2006-01-30 13:31:16 +01:00
+++ 1.24/sql/event.cc 2006-01-31 12:05:05 +01:00
@@ -704,11 +704,17 @@
}
+/*
+ 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 @@
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 @@
if (use_lock)
VOID(pthread_mutex_unlock(&LOCK_event_arrays));
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
@@ -866,21 +873,25 @@
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 @@
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 @@
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);
}
--- 1.15/sql/event_priv.h 2006-01-30 13:31:17 +01:00
+++ 1.16/sql/event_priv.h 2006-01-31 12:05:05 +01:00
@@ -40,6 +40,9 @@
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
--- 1.23/sql/event_timed.cc 2006-01-30 17:11:42 +01:00
+++ 1.24/sql/event_timed.cc 2006-01-31 12:05:05 +01:00
@@ -877,20 +877,10 @@
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));
}
| Thread |
|---|
| • bk commit into 5.1 tree (andrey:1.2097) BUG#16414 | ahristov | 31 Jan |