diff options
author | unknown <andrey@lmy004.> | 2006-07-17 16:52:45 +0200 |
---|---|---|
committer | unknown <andrey@lmy004.> | 2006-07-17 16:52:45 +0200 |
commit | e69e640f2eedfe1247f2a5f536d8dc1cf8a48300 (patch) | |
tree | 94cf5b188a961ae9067df17d09d62247d263ea81 | |
parent | d65ab09c4dad097f0c8c5b9bf3856b6fdaf290fa (diff) | |
download | mariadb-git-e69e640f2eedfe1247f2a5f536d8dc1cf8a48300.tar.gz |
WL#3337 (Events new architecture)
Small updates before patch submit.
client/mysqltest.c:
allow --valgrind option to mysqltest so one can be able to detect
whether the test is running under valgrind by having $VALGRIND_TEST,
similar to BIG_TEST, in the test file.
mysql-test/mysql-test-run.pl:
If the test suite is running under valgrind start mysqltest with --valgrind
to inform that we run valgrind. mysqltest will provide $VALGRIND_TEST for the
test cases.
mysql-test/r/events_bugs.result:
update result
mysql-test/r/events_scheduling.result:
update result
mysql-test/t/events.test:
Increase times or the test will fail under valgrind
mysql-test/t/events_bugs.test:
Increase times or the test will fail under valgrind
mysql-test/t/events_scheduling.test:
Remove faulty test
Disable the test case for valgrind
sql/event_data_objects.cc:
count the number of executions
sql/event_data_objects.h:
flags is not used at all
add execution_count to count the number of executions
sql/event_db_repository.cc:
Initialize wherever needed.
Add a comment regarding valgrind warning.
sql/event_queue.cc:
more debug info in the trace log
sql/event_scheduler.cc:
Use macro COND_STATE_WAIT() in all cases we need waiting
on condition. Hence, we can trace locking, attemption to lock
and more with SHOW SCHEDULER STATUS
sql/event_scheduler.h:
Change the declaration of cond_wait to accept THD
sql/events.cc:
fix memory leak. Destroy event_queue
mysql-test/include/not_valgrind.inc:
New BitKeeper file ``mysql-test/include/not_valgrind.inc''
mysql-test/r/not_valgrind.require:
New BitKeeper file ``mysql-test/r/not_valgrind.require''
-rw-r--r-- | client/mysqltest.c | 6 | ||||
-rw-r--r-- | mysql-test/include/not_valgrind.inc | 4 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 5 | ||||
-rw-r--r-- | mysql-test/r/events_bugs.result | 42 | ||||
-rw-r--r-- | mysql-test/r/events_scheduling.result | 6 | ||||
-rw-r--r-- | mysql-test/r/not_valgrind.require | 2 | ||||
-rw-r--r-- | mysql-test/t/events.test | 28 | ||||
-rw-r--r-- | mysql-test/t/events_bugs.test | 20 | ||||
-rw-r--r-- | mysql-test/t/events_scheduling.test | 4 | ||||
-rw-r--r-- | sql/event_data_objects.cc | 4 | ||||
-rw-r--r-- | sql/event_data_objects.h | 8 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 29 | ||||
-rw-r--r-- | sql/event_queue.cc | 34 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 67 | ||||
-rw-r--r-- | sql/event_scheduler.h | 3 | ||||
-rw-r--r-- | sql/events.cc | 3 |
16 files changed, 162 insertions, 103 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index b21e3883631..ca14be2e135 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -157,6 +157,7 @@ static my_bool ps_protocol= 0, ps_protocol_enabled= 0; static my_bool sp_protocol= 0, sp_protocol_enabled= 0; static my_bool view_protocol= 0, view_protocol_enabled= 0; static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0; +static my_bool opt_valgrind_test= 0; static int parsing_disabled= 0; const char *manager_user="root",*manager_host=0; char *manager_pass=0; @@ -3343,6 +3344,8 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"valgrind", 'N', "Define VALGRIND_TEST to 1.", (gptr*) &opt_valgrind_test, + (gptr*) &opt_valgrind_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"verbose", 'v', "Write more.", (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", @@ -5108,6 +5111,9 @@ static void init_var_hash(MYSQL *mysql) die("Variable hash initialization failed"); my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0, (opt_big_test) ? "1" : "0", 0)); + my_hash_insert(&var_hash, (byte*) var_init(0,"VALGRIND_TEST", 0, + (opt_valgrind_test) ? "1" : "0", + 0)); v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); diff --git a/mysql-test/include/not_valgrind.inc b/mysql-test/include/not_valgrind.inc new file mode 100644 index 00000000000..bdddaf534ca --- /dev/null +++ b/mysql-test/include/not_valgrind.inc @@ -0,0 +1,4 @@ +--require r/not_valgrind.require +--disable_query_log +eval select $VALGRIND_TEST as using_valgrind; +--enable_query_log diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 21e3fceba0c..6536681b0e1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3461,6 +3461,11 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--big-test"); } + if ( $opt_valgrind ) + { + mtr_add_arg($args, "--valgrind"); + } + if ( $opt_compress ) { mtr_add_arg($args, "--compress"); diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index e6115161cbb..3c51621d06b 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -50,10 +50,10 @@ select get_lock('test_bug16407', 60); drop table "hashed_num"; end| "Now if everything is fine the event has compiled and is locked -select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; -user host db command state info -event_scheduler localhost NULL Daemon Waiting for next activation NULL -root localhost events_test Connect User lock select get_lock('test_bug16407', 60) +select /*1*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +user host db info +event_scheduler localhost NULL NULL +root localhost events_test select get_lock('test_bug16407', 60) select release_lock('test_bug16407'); release_lock('test_bug16407') 1 @@ -106,18 +106,18 @@ event_schema event_name sql_mode events_test ee_16407_2 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER events_test ee_16407_3 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER events_test ee_16407_4 -select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; -user host db command state info -event_scheduler localhost NULL Daemon Waiting for next activation NULL -root localhost events_test Connect User lock select get_lock('ee_16407_2', 60) /*ee_16407_2*/ -root localhost events_test Connect User lock select get_lock('ee_16407_2', 60) /*ee_16407_3*/ -root localhost events_test Connect User lock select get_lock('ee_16407_2', 60) /*ee_16407_4*/ +select /*2*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +user host db info +event_scheduler localhost NULL NULL +root localhost events_test select get_lock('ee_16407_2', 60) /*ee_16407_2*/ +root localhost events_test select get_lock('ee_16407_2', 60) /*ee_16407_3*/ +root localhost events_test select get_lock('ee_16407_2', 60) /*ee_16407_4*/ select release_lock('ee_16407_2'); release_lock('ee_16407_2') 1 -select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; -user host db command state info -event_scheduler localhost NULL Daemon Waiting for next activation NULL +select /*3*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +user host db info +event_scheduler localhost NULL NULL set global event_scheduler= 2; select * from events_smode_test order by ev_name, a; ev_name a @@ -156,18 +156,18 @@ select release_lock('ee_16407_5'); call events_test.ee_16407_6_pendant(); end| "Should have 2 locked processes" -select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; -user host db command state info -event_scheduler localhost NULL Daemon Waiting for next activation NULL -root localhost events_test Connect User lock select get_lock('ee_16407_5', 60) /*ee_16407_5*/ -root localhost events_test Connect User lock select get_lock('ee_16407_5', 60) /*ee_16407_6*/ +select /*4*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +user host db info +event_scheduler localhost NULL NULL +root localhost events_test select get_lock('ee_16407_5', 60) /*ee_16407_5*/ +root localhost events_test select get_lock('ee_16407_5', 60) /*ee_16407_6*/ select release_lock('ee_16407_5'); release_lock('ee_16407_5') 1 "Should have 0 processes locked" -select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; -user host db command state info -event_scheduler localhost NULL Daemon Waiting for next activation NULL +select /*5*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +user host db info +event_scheduler localhost NULL NULL select * from events_smode_test order by ev_name, a; ev_name a ee_16407_6 2004-02-29 diff --git a/mysql-test/r/events_scheduling.result b/mysql-test/r/events_scheduling.result index d7b7241db51..a068f7f19bc 100644 --- a/mysql-test/r/events_scheduling.result +++ b/mysql-test/r/events_scheduling.result @@ -6,7 +6,6 @@ CREATE TABLE table_3(a int); CREATE TABLE table_4(a int); CREATE TABLE T19170(s1 TIMESTAMP); SET GLOBAL event_scheduler=1; -CREATE EVENT E19170 ON SCHEDULE EVERY 2 SECOND DO INSERT INTO T19170 VALUES(CURRENT_TIMESTAMP); CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1); CREATE EVENT start_n_end ON SCHEDULE EVERY 1 SECOND @@ -41,15 +40,10 @@ ERROR HY000: Unknown event 'only_one_time' "Should be preserved" SELECT EVENT_NAME, STATUS FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_NAME; EVENT_NAME STATUS -E19170 ENABLED two_time DISABLED DROP EVENT two_time; DROP TABLE table_1; DROP TABLE table_2; DROP TABLE table_3; DROP TABLE table_4; -"Checking for multiple executions in one second, should not happen -> 0 as result" -SELECT COUNT(*) FROM (SELECT s1, COUNT(*) AS cnt FROM T19170 GROUP BY s1) AS tmp WHERE tmp.cnt > 1; -COUNT(*) -0 DROP DATABASE events_test; diff --git a/mysql-test/r/not_valgrind.require b/mysql-test/r/not_valgrind.require new file mode 100644 index 00000000000..5d779c6bfcb --- /dev/null +++ b/mysql-test/r/not_valgrind.require @@ -0,0 +1,2 @@ +using_valgrind +0 diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test index d45b5906f28..2a27144bc27 100644 --- a/mysql-test/t/events.test +++ b/mysql-test/t/events.test @@ -18,7 +18,7 @@ CREATE EVENT e_x2 ON SCHEDULE EVERY 1 SECOND DO DROP TABLE x_table; connection default; SHOW DATABASES LIKE 'db_x'; SET GLOBAL event_scheduler=1; ---sleep 0.8 +--sleep 1.2 SHOW DATABASES LIKE 'db_x'; SHOW TABLES FROM db_x; SET GLOBAL event_scheduler=2; @@ -101,7 +101,7 @@ drop table test_nested; --echo "Let's check whether we can use non-qualified names" create table non_qualif(a int); create event non_qualif_ev on schedule every 10 minute do insert into non_qualif values (800219); ---sleep 0.5 +--sleep 1.1 select * from non_qualif; drop event non_qualif_ev; drop table non_qualif; @@ -224,34 +224,34 @@ SHOW EVENTS; CREATE TABLE event_like LIKE mysql.event; INSERT INTO event_like SELECT * FROM mysql.event; #sleep a bit or we won't catch the change of time ---sleep 1 +--sleep 1.1 ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; --error ER_CANNOT_LOAD_FROM_TABLE SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; #wait a bit or we won't see the difference because of seconds resolution ---sleep 1 +--sleep 1.1 SHOW CREATE TABLE mysql.event; --error ER_CANNOT_LOAD_FROM_TABLE SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; ---sleep 1 +--sleep 1.1 ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default ''; ---sleep 1 +--sleep 1.1 --echo "This should work" --replace_column 8 # 9 # SHOW EVENTS; ---sleep 1 +--sleep 1.1 ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; --error ER_CANNOT_LOAD_FROM_TABLE SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; ---sleep 1 +--sleep 1.1 ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default ''; ---sleep 1 +--sleep 1.1 --error ER_CANNOT_LOAD_FROM_TABLE SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; ---sleep 1 +--sleep 1.1 ALTER TABLE mysql.event DROP comment, DROP starts; ---sleep 1 +--sleep 1.1 --error ER_COL_COUNT_DOESNT_MATCH_CORRUPTED SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; DROP TABLE mysql.event; @@ -308,7 +308,7 @@ 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 0.5 +--sleep 1 --echo "Should have only 2 processes: the scheduler and the locked event" select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info;--echo "Release the mutex, the event worker should finish." --echo "Release the mutex, the event worker should finish." @@ -326,11 +326,11 @@ drop event закачка; 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 0.5 +--sleep 1 --echo "Should have only 3 processes: the scheduler, our conn and the locked event" select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; set global event_scheduler=2; ---sleep 0.3 +--sleep 0.8 --echo "Should have only our process now:" select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; drop event закачка21; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 7fd4c684b4b..692e85255ef 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -78,9 +78,9 @@ begin drop table "hashed_num"; end| delimiter ;| ---sleep 0.5 +--sleep 0.8 --echo "Now if everything is fine the event has compiled and is locked -select /*1*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +select /*1*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; select release_lock('test_bug16407'); set global event_scheduler= 2; @@ -127,11 +127,11 @@ begin end| delimiter ;| select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; ---sleep 0.5 -select /*2*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +--sleep 1 +select /*2*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; select release_lock('ee_16407_2'); ---sleep 0.8 -select /*3*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +--sleep 1.2 +select /*3*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; set global event_scheduler= 2; select * from events_smode_test order by ev_name, a; --echo "OK, last check before we drop them" @@ -165,13 +165,13 @@ begin call events_test.ee_16407_6_pendant(); end| delimiter ;| ---sleep 0.5 +--sleep 1 --echo "Should have 2 locked processes" -select /*4*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +select /*4*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; select release_lock('ee_16407_5'); ---sleep 0.8 +--sleep 1.3 --echo "Should have 0 processes locked" -select /*5*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; +select /*5*/ user, host, db, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; select * from events_smode_test order by ev_name, a; --echo "And here we check one more time before we drop the events" select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name; diff --git a/mysql-test/t/events_scheduling.test b/mysql-test/t/events_scheduling.test index dc4460999a7..7a7502fab7e 100644 --- a/mysql-test/t/events_scheduling.test +++ b/mysql-test/t/events_scheduling.test @@ -1,5 +1,6 @@ # Can't test with embedded server that doesn't support grants -- source include/not_embedded.inc +-- source include/not_valgrind.inc CREATE DATABASE IF NOT EXISTS events_test; USE events_test; @@ -11,7 +12,6 @@ CREATE TABLE T19170(s1 TIMESTAMP); SET GLOBAL event_scheduler=1; # We need to have 2 to make it safe with valgrind. This is probably because # of when we calculate the timestamp value -CREATE EVENT E19170 ON SCHEDULE EVERY 2 SECOND DO INSERT INTO T19170 VALUES(CURRENT_TIMESTAMP); CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1); CREATE EVENT start_n_end ON SCHEDULE EVERY 1 SECOND @@ -40,6 +40,4 @@ DROP TABLE table_1; DROP TABLE table_2; DROP TABLE table_3; DROP TABLE table_4; ---echo "Checking for multiple executions in one second, should not happen -> 0 as result" -SELECT COUNT(*) FROM (SELECT s1, COUNT(*) AS cnt FROM T19170 GROUP BY s1) AS tmp WHERE tmp.cnt > 1; DROP DATABASE events_test; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 5f879c6bea0..5cf8ec53a4d 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -676,7 +676,7 @@ Event_basic::load_string_fields(Field **fields, ...) Event_queue_element::Event_queue_element(): status_changed(FALSE), last_executed_changed(FALSE), on_completion(ON_COMPLETION_DROP), status(ENABLED), - expression(0), dropped(FALSE), flags(0) + expression(0), dropped(FALSE), execution_count(0) { DBUG_ENTER("Event_queue_element::Event_queue_element"); @@ -1413,6 +1413,8 @@ Event_queue_element::mark_last_executed(THD *thd) last_executed= time_now; /* was execute_at */ last_executed_changed= TRUE; + + execution_count++; } diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index cf1bd5e390a..a912953c927 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -74,9 +74,9 @@ public: enum enum_status status; TIME last_executed; + TIME execute_at; TIME starts; TIME ends; - TIME execute_at; my_bool starts_null; my_bool ends_null; my_bool execute_at_null; @@ -84,10 +84,10 @@ public: longlong expression; interval_type interval; - uint flags;//all kind of purposes - bool dropped; + uint execution_count; + Event_queue_element(); virtual ~Event_queue_element(); @@ -170,6 +170,8 @@ public: ulong sql_mode; + uint execution_count; + Event_job_data(); virtual ~Event_job_data(); diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index ecf8d68e788..69bbaeeae03 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -523,7 +523,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, { int ret= 0; CHARSET_INFO *scs= system_charset_info; - TABLE *table; + TABLE *table= NULL; char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged= FALSE; @@ -621,8 +621,29 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, ok: if (dbchanged) (void) mysql_change_db(thd, old_db.str, 1); - if (table) - close_thread_tables(thd); + /* + When valgrinded, the following call may lead to the following error: + + Syscall param pwrite64(buf) points to uninitialised byte(s) + at 0x406003B: do_pwrite64 (in /lib/tls/libpthread.so.0) + by 0x40600EF: pwrite64 (in /lib/tls/libpthread.so.0) + by 0x856FF74: my_pwrite (my_pread.c:146) + by 0x85734E1: flush_cached_blocks (mf_keycache.c:2280) + .... + Address 0x6618110 is 56 bytes inside a block of size 927,772 alloc'd + at 0x401C451: malloc (vg_replace_malloc.c:149) + by 0x8578CDC: _mymalloc (safemalloc.c:138) + by 0x858E5E2: my_large_malloc (my_largepage.c:65) + by 0x8570634: init_key_cache (mf_keycache.c:343) + by 0x82EDA51: ha_init_key_cache(char const*, st_key_cache*) (handler.cc:2509) + by 0x8212071: process_key_caches(int (*)(char const*, st_key_cache*)) + (set_var.cc:3824) + by 0x8206D75: init_server_components() (mysqld.cc:3304) + by 0x8207163: main (mysqld.cc:3578) + + I think it is safe not to think about it. + */ + close_thread_tables(thd); DBUG_RETURN(0); err: @@ -900,7 +921,7 @@ Event_db_repository::drop_events_by_field(THD *thd, LEX_STRING field_value) { int ret= 0; - TABLE *table; + TABLE *table= NULL; Open_tables_state backup; READ_RECORD read_record_info; DBUG_ENTER("Event_db_repository::drop_events_by_field"); diff --git a/sql/event_queue.cc b/sql/event_queue.cc index c6c7d7f14ac..39b237987e9 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -98,7 +98,6 @@ event_queue_loader_thread(void *arg) end: deinit_event_thread(thd); - DBUG_RETURN(0); // Against gcc warnings } @@ -177,7 +176,7 @@ Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched) scheduler= sched; if (init_queue_ex(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/, - 0 /*smallest_on_top*/, event_queue_element_compare_q, + 0 /*max_on_top*/, event_queue_element_compare_q, NULL, EVENT_QUEUE_EXTENT)) { sql_print_error("SCHEDULER: Can't initialize the execution queue"); @@ -196,6 +195,7 @@ Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched) goto err; pre_init_event_thread(new_thd); + new_thd->security_ctx->set_user((char*)"event_scheduler_loader"); event_queue_param_value= (struct event_queue_param *) my_malloc(sizeof(struct event_queue_param), MYF(0)); @@ -285,6 +285,7 @@ Event_queue::create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) LOCK_QUEUE_DATA(); DBUG_PRINT("info", ("new event in the queue 0x%lx", new_element)); queue_insert_safe(&queue, (byte *) new_element); + dbug_dump_queue(thd->query_start()); UNLOCK_QUEUE_DATA(); notify_observers(); @@ -356,6 +357,7 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name, new_element, old_element)); queue_insert_safe(&queue, (byte *) new_element); } + dbug_dump_queue(thd->query_start()); UNLOCK_QUEUE_DATA(); if (new_element) @@ -389,6 +391,7 @@ Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name) LOCK_QUEUE_DATA(); element= find_n_remove_event(dbname, name); + dbug_dump_queue(thd->query_start()); UNLOCK_QUEUE_DATA(); if (element) @@ -427,7 +430,7 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern, bool (*comparator)(LEX_STRING, Event_basic *)) { DBUG_ENTER("Event_queue::drop_matching_events"); - DBUG_PRINT("enter", ("pattern=%*s state=%d", pattern.length, pattern.str)); + DBUG_PRINT("enter", ("pattern=%s", pattern.str)); uint i= 0; while (i < queue.elements) @@ -808,26 +811,29 @@ Event_queue::empty_queue() now Current timestamp */ -inline void +void Event_queue::dbug_dump_queue(time_t now) { #ifndef DBUG_OFF Event_queue_element *et; uint i; + DBUG_ENTER("Event_queue::dbug_dump_queue"); DBUG_PRINT("info", ("Dumping queue . Elements=%u", queue.elements)); for (i = 0; i < queue.elements; i++) { et= ((Event_queue_element*)queue_element(&queue, i)); DBUG_PRINT("info",("et=0x%lx db=%s name=%s",et, et->dbname.str, et->name.str)); - DBUG_PRINT("info", ("exec_at=%llu starts=%llu ends=%llu " + DBUG_PRINT("info", ("exec_at=%llu starts=%llu ends=%llu execs_so_far=%u" " expr=%lld et.exec_at=%d now=%d (et.exec_at - now)=%d if=%d", TIME_to_ulonglong_datetime(&et->execute_at), TIME_to_ulonglong_datetime(&et->starts), TIME_to_ulonglong_datetime(&et->ends), + et->execution_count, et->expression, sec_since_epoch_TIME(&et->execute_at), now, (int)(sec_since_epoch_TIME(&et->execute_at) - now), sec_since_epoch_TIME(&et->execute_at) <= now)); } + DBUG_VOID_RETURN; #endif } @@ -838,7 +844,7 @@ Event_queue::dbug_dump_queue(time_t now) `now` is compared against `execute_at` of the top element in the queue. SYNOPSIS - Event_queue::dbug_dump_queue() + Event_queue::get_top_for_execution_if_time() thd [in] Thread now [in] Current timestamp job_data [out] The object to execute @@ -873,7 +879,6 @@ Event_queue::get_top_for_execution_if_time(THD *thd, time_t now, abstime->tv_sec= 0; break; } - dbug_dump_queue(now); Event_queue_element *top= ((Event_queue_element*) queue_element(&queue, 0)); @@ -889,7 +894,11 @@ Event_queue::get_top_for_execution_if_time(THD *thd, time_t now, DBUG_PRINT("info", ("Ready for execution")); abstime->tv_sec= 0; - *job_data= new Event_job_data(); + if (!(*job_data= new Event_job_data())) + { + ret= TRUE; + break; + } if ((res= db_repository->load_named_event(thd, top->dbname, top->name, *job_data))) { @@ -902,13 +911,18 @@ Event_queue::get_top_for_execution_if_time(THD *thd, time_t now, top->mark_last_executed(thd); if (top->compute_next_execution_time()) top->status= Event_queue_element::DISABLED; - DBUG_PRINT("info", ("event's status is %d", top->status)); + DBUG_PRINT("info", ("event %s status is %d", top->name.str, top->status)); + + (*job_data)->execution_count= top->execution_count; top->update_timing_fields(thd); if (((top->execute_at.year && !top->expression) || top->execute_at_null) || (top->status == Event_queue_element::DISABLED)) { DBUG_PRINT("info", ("removing from the queue")); + sql_print_information("SCHEDULER: Last execution of %s.%s. %s", + top->dbname.str, top->name.str, + top->dropped? "Dropping.":""); if (top->dropped) top->drop(thd); delete top; @@ -916,6 +930,8 @@ Event_queue::get_top_for_execution_if_time(THD *thd, time_t now, } else queue_replaced(&queue); + + dbug_dump_queue(now); } while (0); UNLOCK_QUEUE_DATA(); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 0c39c1a512b..6e3a7ec2be8 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -28,9 +28,10 @@ #define SCHED_FUNC "<unknown>" #endif -#define LOCK_DATA() lock_data(SCHED_FUNC, __LINE__) -#define UNLOCK_DATA() unlock_data(SCHED_FUNC, __LINE__) -#define COND_STATE_WAIT(timer) cond_wait(timer, SCHED_FUNC, __LINE__) +#define LOCK_DATA() lock_data(SCHED_FUNC, __LINE__) +#define UNLOCK_DATA() unlock_data(SCHED_FUNC, __LINE__) +#define COND_STATE_WAIT(mythd, abstime, msg) \ + cond_wait(mythd, abstime, msg, SCHED_FUNC, __LINE__) extern pthread_attr_t connection_attrib; @@ -140,7 +141,7 @@ deinit_event_thread(THD *thd) thd->proc_info= "Clearing"; DBUG_ASSERT(thd->net.buff != 0); net_end(&thd->net); - DBUG_PRINT("exit", ("Scheduler thread finishing")); + DBUG_PRINT("exit", ("Event thread finishing")); pthread_mutex_lock(&LOCK_thread_count); thread_count--; thread_running--; @@ -262,9 +263,11 @@ event_worker_thread(void *arg) DBUG_PRINT("info", ("Baikonur, time is %d, BURAN reporting and operational." "THD=0x%lx", time(NULL), thd)); - sql_print_information("SCHEDULER: [%s.%s of %s] executing in thread %lu", + sql_print_information("SCHEDULER: [%s.%s of %s] executing in thread %lu. " + "Execution %u", event->dbname.str, event->name.str, - event->definer.str, thd->thread_id); + event->definer.str, thd->thread_id, + event->execution_count); thd->enable_slow_log= TRUE; @@ -272,9 +275,8 @@ event_worker_thread(void *arg) evex_print_warnings(thd, event); - sql_print_information("SCHEDULER: [%s.%s of %s] executed " - " in thread thread %lu. RetCode=%d", - event->dbname.str, event->name.str, + sql_print_information("SCHEDULER: [%s.%s of %s] executed in thread %lu. " + "RetCode=%d", event->dbname.str, event->name.str, event->definer.str, thd->thread_id, ret); if (ret == EVEX_COMPILE_ERROR) sql_print_information("SCHEDULER: COMPILE ERROR for event %s.%s of %s", @@ -456,7 +458,7 @@ Event_scheduler::run(THD *thd) thd->end_time(); /* Gets a minimized version */ if (queue->get_top_for_execution_if_time(thd, thd->query_start(), - &job_data, &abstime)) + &job_data, &abstime)) { sql_print_information("SCHEDULER: Serious error during getting next" " event to execute. Stopping."); @@ -469,31 +471,22 @@ Event_scheduler::run(THD *thd) if (!job_data && !abstime.tv_sec) { DBUG_PRINT("info", ("The queue is empty. Going to sleep")); - thd->enter_cond(&COND_state, &LOCK_scheduler_state, - "Waiting on empty queue"); - COND_STATE_WAIT(NULL); - thd->exit_cond(""); + COND_STATE_WAIT(thd, NULL, "Waiting on empty queue"); DBUG_PRINT("info", ("Woke up. Got COND_state")); - LOCK_DATA(); } else if (abstime.tv_sec) { - DBUG_PRINT("info", ("Have to sleep some time %u till", + DBUG_PRINT("info", ("Have to sleep some time %u s. till %u", abstime.tv_sec - thd->query_start(), abstime.tv_sec)); - thd->enter_cond(&COND_state, &LOCK_scheduler_state, - "Waiting for next activation"); - COND_STATE_WAIT(&abstime); + COND_STATE_WAIT(thd, &abstime, "Waiting for next activation"); /* If we get signal we should recalculate the whether it's the right time because there could be : 1. Spurious wake-up 2. The top of the queue was changed (new one becase of create/update) */ - /* This will do implicit UNLOCK_DATA() */ - thd->exit_cond(""); DBUG_PRINT("info", ("Woke up. Got COND_stat or time for execution.")); - LOCK_DATA(); } else { @@ -610,7 +603,7 @@ Event_scheduler::stop() "workers count=%d", scheduler_states_names[state].str, workers_count())); /* thd could be 0x0, when shutting down */ - COND_STATE_WAIT(NULL); + COND_STATE_WAIT(thd, NULL, "Waiting scheduler to stop"); } while (state == STOPPING); DBUG_PRINT("info", ("Manager thread has cleaned up. Set state to INIT")); @@ -720,29 +713,43 @@ Event_scheduler::unlock_data(const char *func, uint line) SYNOPSIS Event_scheduler::cond_wait() - cond Conditional to wait for - mutex Mutex of the conditional - - RETURN VALUE - Error code of pthread_cond_wait() + thd Thread (Could be NULL during shutdown procedure) + abstime If not null then call pthread_cond_timedwait() + func Which function is requesting cond_wait + line On which line cond_wait is requested */ void -Event_scheduler::cond_wait(struct timespec *abstime, const char *func, - uint line) +Event_scheduler::cond_wait(THD *thd, struct timespec *abstime, const char* msg, + const char *func, uint line) { + DBUG_ENTER("Event_scheduler::cond_wait"); waiting_on_cond= TRUE; mutex_last_unlocked_at_line= line; mutex_scheduler_data_locked= FALSE; mutex_last_unlocked_in_func= func; + if (thd) + thd->enter_cond(&COND_state, &LOCK_scheduler_state, msg); + + DBUG_PRINT("info", ("pthread_cond_%swait", abstime? "timed":"")); if (!abstime) pthread_cond_wait(&COND_state, &LOCK_scheduler_state); else pthread_cond_timedwait(&COND_state, &LOCK_scheduler_state, abstime); + if (thd) + { + /* + This will free the lock so we need to relock. Not the best thing to + do but we need to obey cond_wait() + */ + thd->exit_cond(""); + LOCK_DATA(); + } mutex_last_locked_in_func= func; mutex_last_locked_at_line= line; mutex_scheduler_data_locked= TRUE; waiting_on_cond= FALSE; + DBUG_VOID_RETURN; } diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h index b5c3dae49f8..cc6d0f7a20a 100644 --- a/sql/event_scheduler.h +++ b/sql/event_scheduler.h @@ -95,7 +95,8 @@ private: unlock_data(const char *func, uint line); void - cond_wait(struct timespec *abstime, const char *func, uint line); + cond_wait(THD *thd, struct timespec *abstime, const char* msg, + const char *func, uint line); pthread_mutex_t LOCK_scheduler_state; diff --git a/sql/events.cc b/sql/events.cc index 94ef8faa83d..f75a362f947 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -622,7 +622,7 @@ Events::init_mutexes() event_queue= new Event_queue; event_queue->init_mutexes(); - scheduler= new Event_scheduler(); + scheduler= new Event_scheduler; scheduler->init_mutexes(); } @@ -642,6 +642,7 @@ Events::destroy_mutexes() delete scheduler; delete db_repository; + delete event_queue; pthread_mutex_destroy(&LOCK_event_metadata); } |