From ed0cb3e4ba0e16aa939199436cb7d68493690c0b Mon Sep 17 00:00:00 2001 From: "kroki/tomash@moonlight.intranet" <> Date: Tue, 12 Sep 2006 14:56:25 +0400 Subject: [PATCH 1/7] BUG#21414: SP: Procedure undroppable, to some extent The problem was that if after FLUSH TABLES WITH READ LOCK the user issued DROP/ALTER PROCEDURE/FUNCTION the operation would fail (as expected), but after UNLOCK TABLE any attempt to execute the same operation would lead to the error 1305 "PROCEDURE/FUNCTION does not exist", and an attempt to execute any stored function will also fail. This happened because under FLUSH TABLES WITH READ LOCK we couldn't open and lock mysql.proc table for update, and this fact was erroneously remembered by setting mysql_proc_table_exists to false, so subsequent statements believed that mysql.proc doesn't exist, and thus that there are no functions and procedures in the database. As a solution, we remove mysql_proc_table_exists flag completely. The reason is that this optimization didn't work most of the time anyway. Even if open of mysql.proc failed for some reason when we were trying to call a function or a procedure, we were setting mysql_proc_table_exists back to true to force table reopen for the sake of producing the same error message (the open can fail for number of reasons). The solution could have been to remember the reason why open failed, but that's a lot of code for optimization of a rare case. Hence we simply remove this optimization. --- mysql-test/r/sp.result | 8 ++++++++ mysql-test/t/sp.test | 27 ++++++++++++++++++++++----- sql/mysql_priv.h | 1 - sql/sp.cc | 27 --------------------------- sql/sql_acl.cc | 1 - 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 854935b071b..b08ce0528a3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5394,4 +5394,12 @@ Procedure sql_mode Create Procedure bug21416 CREATE DEFINER=`root`@`localhost` PROCEDURE `bug21416`() show create procedure bug21416 drop procedure bug21416| +DROP PROCEDURE IF EXISTS bug21414| +CREATE PROCEDURE bug21414() SELECT 1| +FLUSH TABLES WITH READ LOCK| +DROP PROCEDURE bug21414| +ERROR HY000: Can't execute the query because you have a conflicting read lock +UNLOCK TABLES| +The following should succeed. +DROP PROCEDURE bug21414| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 4b0f463a9e3..0d69ec95c50 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1,13 +1,9 @@ # # Basic stored PROCEDURE tests # -# Please keep this file free of --error cases and other -# things that will not run in a single debugged mysqld -# process (e.g. master-slave things). -# # Test cases for bugs are added at the end. See template there. # -# Tests that require --error go into sp-error.test +# Some tests that require --error go into sp-error.test # Tests that require inndb go into sp_trans.test # Tests that check privilege and security issues go to sp-security.test. # Tests that require multiple connections, except security/privilege tests, @@ -6322,6 +6318,27 @@ create procedure bug21416() show create procedure bug21416| call bug21416()| drop procedure bug21416| + +# +# BUG#21414: SP: Procedure undroppable, to some extent +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug21414| +--enable_warnings + +CREATE PROCEDURE bug21414() SELECT 1| + +FLUSH TABLES WITH READ LOCK| + +--error ER_CANT_UPDATE_WITH_READLOCK +DROP PROCEDURE bug21414| + +UNLOCK TABLES| + +--echo The following should succeed. +DROP PROCEDURE bug21414| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3ec9dd718e8..fa3be3173d9 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1216,7 +1216,6 @@ extern my_bool opt_log_queries_not_using_indexes; extern bool opt_disable_networking, opt_skip_show_db; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop, shutdown_in_progress, grant_option; -extern bool mysql_proc_table_exists; extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile; diff --git a/sql/sp.cc b/sql/sp.cc index fc72822c15e..43eff39a463 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -66,8 +66,6 @@ enum MYSQL_PROC_FIELD_COUNT }; -bool mysql_proc_table_exists= 1; - /* Tells what SP_DEFAULT_ACCESS should be mapped to */ #define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL @@ -119,13 +117,6 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup) bool not_used; DBUG_ENTER("open_proc_table"); - /* - Speed up things if mysql.proc doesn't exists. mysql_proc_table_exists - is set when we create or read stored procedure or on flush privileges. - */ - if (!mysql_proc_table_exists) - DBUG_RETURN(0); - thd->reset_n_backup_open_tables_state(backup); bzero((char*) &tables, sizeof(tables)); @@ -135,7 +126,6 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup) MYSQL_LOCK_IGNORE_FLUSH))) { thd->restore_backup_open_tables_state(backup); - mysql_proc_table_exists= 0; DBUG_RETURN(0); } @@ -184,15 +174,6 @@ static TABLE *open_proc_table_for_update(THD *thd) table= open_ltable(thd, &tables, TL_WRITE); - /* - Under explicit LOCK TABLES or in prelocked mode we should not - say that mysql.proc table does not exist if we are unable to - open and lock it for writing since this condition may be - transient. - */ - if (!(thd->locked_tables || thd->prelocked_mode) || table) - mysql_proc_table_exists= test(table); - DBUG_RETURN(table); } @@ -1610,14 +1591,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, case SP_KEY_NOT_FOUND: ret= SP_OK; break; - case SP_OPEN_TABLE_FAILED: - /* - Force it to attempt opening it again on subsequent calls; - otherwise we will get one error message the first time, and - then ER_SP_PROC_TABLE_CORRUPT (below) on subsequent tries. - */ - mysql_proc_table_exists= 1; - /* Fall through */ default: /* Any error when loading an existing routine is either some problem diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0c7b8626c93..bd1417b7e0d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -202,7 +202,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) DBUG_ENTER("acl_load"); grant_version++; /* Privileges updated */ - mysql_proc_table_exists= 1; // Assume mysql.proc exists acl_cache->clear(1); // Clear locked hostname cache From f6663df6d8339866f0e1ea0c83aa56be351a7b46 Mon Sep 17 00:00:00 2001 From: "petr/cps@mysql.com/owlet.local" <> Date: Fri, 15 Sep 2006 13:07:23 +0400 Subject: [PATCH 2/7] Post-review fixes for Bug #18559 "log tables cannot change engine, and gets deadlocked when dropping w/ log on": 1) Add more generic error messages 2) Add new handlerton flag for engines, which support log tables 3) Remove (log-tables related) mutex lock in myisam to improve performance --- mysql-test/r/log_tables.result | 18 +++++++++--------- mysql-test/t/log_tables.test | 18 +++++++++--------- sql/handler.h | 1 + sql/share/errmsg.txt | 4 ++++ sql/sql_table.cc | 9 ++++----- storage/csv/ha_tina.cc | 2 +- storage/myisam/ha_myisam.cc | 2 +- storage/myisam/mi_write.c | 8 ++++---- 8 files changed, 33 insertions(+), 29 deletions(-) diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index 638c05dd712..59cef29dc8f 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -73,16 +73,16 @@ select * from mysql.slow_log; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2) alter table mysql.general_log engine=myisam; -ERROR HY000: You can't alter a log table if logging is enabled +ERROR HY000: You cannot alter a log table if logging is enabled alter table mysql.slow_log engine=myisam; -ERROR HY000: You can't alter a log table if logging is enabled +ERROR HY000: You cannot alter a log table if logging is enabled drop table mysql.general_log; -ERROR HY000: Cannot drop log table if log is enabled +ERROR HY000: You cannot drop a log table if logging is enabled drop table mysql.slow_log; -ERROR HY000: Cannot drop log table if log is enabled +ERROR HY000: You cannot drop a log table if logging is enabled set global general_log='OFF'; alter table mysql.slow_log engine=myisam; -ERROR HY000: You can't alter a log table if logging is enabled +ERROR HY000: You cannot alter a log table if logging is enabled set global slow_query_log='OFF'; show create table mysql.general_log; Table Create Table @@ -173,13 +173,13 @@ unlock tables; set global general_log='OFF'; set global slow_query_log='OFF'; alter table mysql.slow_log engine=ndb; -ERROR HY000: One can use only CSV and MyISAM engines for the log tables +ERROR HY000: This storage engine cannot be used for log tables" alter table mysql.slow_log engine=innodb; -ERROR HY000: One can use only CSV and MyISAM engines for the log tables +ERROR HY000: This storage engine cannot be used for log tables" alter table mysql.slow_log engine=archive; -ERROR HY000: One can use only CSV and MyISAM engines for the log tables +ERROR HY000: This storage engine cannot be used for log tables" alter table mysql.slow_log engine=blackhole; -ERROR HY000: One can use only CSV and MyISAM engines for the log tables +ERROR HY000: This storage engine cannot be used for log tables" drop table mysql.slow_log; drop table mysql.general_log; drop table mysql.general_log; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 97c83310b4d..d9e17129799 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -178,21 +178,21 @@ select * from mysql.slow_log; # check that appropriate error messages are given when one attempts to alter # or drop a log tables, while corresponding logs are enabled ---error ER_CANT_ALTER_LOG_TABLE +--error ER_BAD_LOG_STATEMENT alter table mysql.general_log engine=myisam; ---error ER_CANT_ALTER_LOG_TABLE +--error ER_BAD_LOG_STATEMENT alter table mysql.slow_log engine=myisam; ---error ER_CANT_DROP_LOG_TABLE +--error ER_BAD_LOG_STATEMENT drop table mysql.general_log; ---error ER_CANT_DROP_LOG_TABLE +--error ER_BAD_LOG_STATEMENT drop table mysql.slow_log; # check that one can alter log tables to MyISAM set global general_log='OFF'; # cannot convert another log table ---error ER_CANT_ALTER_LOG_TABLE +--error ER_BAD_LOG_STATEMENT alter table mysql.slow_log engine=myisam; # alter both tables @@ -252,13 +252,13 @@ set global general_log='OFF'; set global slow_query_log='OFF'; # check that alter table doesn't work for other engines ---error ER_BAD_LOG_ENGINE +--error ER_UNSUPORTED_LOG_ENGINE alter table mysql.slow_log engine=ndb; ---error ER_BAD_LOG_ENGINE +--error ER_UNSUPORTED_LOG_ENGINE alter table mysql.slow_log engine=innodb; ---error ER_BAD_LOG_ENGINE +--error ER_UNSUPORTED_LOG_ENGINE alter table mysql.slow_log engine=archive; ---error ER_BAD_LOG_ENGINE +--error ER_UNSUPORTED_LOG_ENGINE alter table mysql.slow_log engine=blackhole; drop table mysql.slow_log; diff --git a/sql/handler.h b/sql/handler.h index df40a207916..6d61a6ee271 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -681,6 +681,7 @@ struct handlerton #define HTON_FLUSH_AFTER_RENAME (1 << 4) #define HTON_NOT_USER_SELECTABLE (1 << 5) #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported +#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables typedef struct st_thd_trans { diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 2228ded870b..aa85be6f551 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5960,3 +5960,7 @@ ER_HOSTNAME eng "host name" ER_WRONG_STRING_LENGTH eng "String '%-.70s' is too long for %s (should be no longer than %d)" +ER_UNSUPORTED_LOG_ENGINE + eng "This storage engine cannot be used for log tables"" +ER_BAD_LOG_STATEMENT + eng "You cannot %s a log table if logging is enabled" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f0f69676ed2..932237e98f8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1628,7 +1628,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, (!my_strcasecmp(system_charset_info, table->table_name, "slow_log") && opt_slow_log && logger.is_slow_log_table_enabled()))) { - my_error(ER_CANT_DROP_LOG_TABLE, MYF(0)); + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "drop"); DBUG_RETURN(1); } } @@ -5174,7 +5174,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (table_kind == SLOW_LOG && opt_slow_log && logger.is_slow_log_table_enabled())) { - my_error(ER_CANT_ALTER_LOG_TABLE, MYF(0)); + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "alter"); DBUG_RETURN(TRUE); } @@ -5182,10 +5182,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if ((table_kind == GENERAL_LOG || table_kind == SLOW_LOG) && (lex_create_info->used_fields & HA_CREATE_USED_ENGINE) && (!lex_create_info->db_type || /* unknown engine */ - !(lex_create_info->db_type->db_type == DB_TYPE_MYISAM || - lex_create_info->db_type->db_type == DB_TYPE_CSV_DB))) + !(lex_create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) { - my_error(ER_BAD_LOG_ENGINE, MYF(0)); + my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0)); DBUG_RETURN(TRUE); } } diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 2fe2afeb470..76544146fa1 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -162,7 +162,7 @@ static int tina_init_func() tina_hton.db_type= DB_TYPE_CSV_DB; tina_hton.create= tina_create_handler; tina_hton.panic= tina_end; - tina_hton.flags= HTON_CAN_RECREATE; + tina_hton.flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; } return 0; } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 209478ee9a5..d6939d9ccc1 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1783,7 +1783,7 @@ static int myisam_init() myisam_hton.db_type=DB_TYPE_MYISAM; myisam_hton.create=myisam_create_handler; myisam_hton.panic=mi_panic; - myisam_hton.flags=HTON_CAN_RECREATE; + myisam_hton.flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES; return 0; } diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index f16d9471afe..7080875009b 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -167,13 +167,13 @@ int mi_write(MI_INFO *info, byte *record) /* Update status of the table. We need to do so after each row write for the log tables, as we want the new row to become visible to - other threads as soon as possible. We lock mutex here to follow - pthread memory visibility rules. + other threads as soon as possible. We don't lock mutex here + (as it is required by pthread memory visibility rules) as (1) it's + not critical to use outdated share->is_log_table value (2) locking + mutex here for every write is too expensive. */ - pthread_mutex_lock(&share->intern_lock); if (share->is_log_table) mi_update_status((void*) info); - pthread_mutex_unlock(&share->intern_lock); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); From d2ebe6be036958366e56170c72c6546ccc19d1e5 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Mon, 25 Sep 2006 09:28:52 +0200 Subject: [PATCH 3/7] Bug #22379 im_daemon_life_cycle.test fails on merge of 5.1 -> 5.1-engines Remove race situations that occur when removing pidfiles. Primarily each process should remove its own pidfile, secondly it should be removed by the process that created it and _only_ if it's certain the process is dead. Third, mysql-test-run.pl will remove the pidfile when process has been killed. - Set state of an instance to STARTING _before_ calling instance->start() - Check that pidfile of instance has been created before changing STARTING => STARTED - Only remove the pidfile if IM kills an instance with SIGKILL, otherwise the instance will remove it itself --- server-tools/instance-manager/guardian.cc | 27 ++++++++++++++----- server-tools/instance-manager/instance.cc | 25 ++++++++--------- .../instance-manager/instance_options.cc | 3 ++- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc index 24844e05776..e2142c97f33 100644 --- a/server-tools/instance-manager/guardian.cc +++ b/server-tools/instance-manager/guardian.cc @@ -110,20 +110,35 @@ void Guardian_thread::process_instance(Instance *instance, if (instance->is_running()) { - /* clear status fields */ - current_node->restart_counter= 0; - current_node->crash_moment= 0; - current_node->state= STARTED; + /* The instance can be contacted on it's port */ + + /* If STARTING also check that pidfile has been created */ + if (current_node->state == STARTING && + current_node->instance->options.get_pid() == 0) + { + /* Pid file not created yet, don't go to STARTED state yet */ + } + else + { + /* clear status fields */ + log_info("guardian: instance %s is running, set state to STARTED", + instance->options.instance_name); + current_node->restart_counter= 0; + current_node->crash_moment= 0; + current_node->state= STARTED; + } } else { switch (current_node->state) { case NOT_STARTED: - instance->start(); - current_node->last_checked= current_time; log_info("guardian: starting instance %s", instance->options.instance_name); + + /* NOTE, set state to STARTING _before_ start() is called */ current_node->state= STARTING; + instance->start(); + current_node->last_checked= current_time; break; case STARTED: /* fallthrough */ case STARTING: /* let the instance start or crash */ diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 39381b457ab..5c47dc87734 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -571,18 +571,19 @@ void Instance::kill_instance(int signum) /* if there are no pid, everything seems to be fine */ if ((pid= options.get_pid()) != 0) /* get pid from pidfile */ { - /* - If we cannot kill mysqld, then it has propably crashed. - Let us try to remove staled pidfile and return successfully - as mysqld is probably stopped. - */ - if (!kill(pid, signum)) - options.unlink_pidfile(); - else if (signum == SIGKILL) /* really killed instance with SIGKILL */ - log_error("The instance %s is being stopped forsibly. Normally \ - it should not happed. Probably the instance has been \ - hanging. You should also check your IM setup", - options.instance_name); + if (kill(pid, signum) == 0) + { + /* Kill suceeded */ + if (signum == SIGKILL) /* really killed instance with SIGKILL */ + { + log_error("The instance %s is being stopped forcibly. Normally" \ + "it should not happen. Probably the instance has been" \ + "hanging. You should also check your IM setup", + options.instance_name); + /* After sucessful hard kill the pidfile need to be removed */ + options.unlink_pidfile(); + } + } } return; } diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 72621ed1662..f86f359959b 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -377,7 +377,8 @@ pid_t Instance_options::get_pid() { pid_t pid; - fscanf(pid_file_stream, "%i", &pid); + if (fscanf(pid_file_stream, "%i", &pid) != 1) + pid= -1; my_fclose(pid_file_stream, MYF(0)); return pid; } From d993720268e1d056f4dcbaac7886616bce6b6f31 Mon Sep 17 00:00:00 2001 From: "andrey@example.com" <> Date: Mon, 25 Sep 2006 15:50:49 +0200 Subject: [PATCH 4/7] cleanups - fix a test and remove unneeded declaration --- mysql-test/r/events.result | 63 +++++++++++++++----------------------- mysql-test/t/events.test | 31 +++++++------------ sql/sql_show.cc | 2 -- 3 files changed, 35 insertions(+), 61 deletions(-) diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result index 146f46edc2b..abf6879fc3c 100644 --- a/mysql-test/r/events.result +++ b/mysql-test/r/events.result @@ -38,52 +38,37 @@ drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost RECURRING NULL 10 SECOND # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -0 1 +SELECT interval_field, interval_value, body FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +interval_field interval_value body +SECOND 10 SELECT 1 +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +1 0 1 ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -1 1 +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +0 1 1 ALTER EVENT event_starts_test COMMENT "non-empty comment"; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -1 1 non-empty comment +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +0 1 1 non-empty comment ALTER EVENT event_starts_test COMMENT ""; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -1 1 +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +0 1 1 DROP EVENT event_starts_test; CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost RECURRING NULL 20 SECOND # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -0 0 +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +1 0 0 ALTER EVENT event_starts_test COMMENT "non-empty comment"; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost RECURRING NULL 20 SECOND # # ENABLED -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; -starts IS NULL ends IS NULL comment -0 0 non-empty comment +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +1 0 0 non-empty comment ALTER EVENT event_starts_test COMMENT ""; -SHOW EVENTS; -Db Name Definer Type Execute at Interval value Interval field Starts Ends Status -events_test event_starts_test root@localhost RECURRING NULL 20 SECOND # # ENABLED +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +execute_at IS NULL starts IS NULL ends IS NULL comment +1 0 0 DROP EVENT event_starts_test; create table test_nested(a int); create event e_43 on schedule every 1 second do set @a = 5; diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test index add5dbcaa24..32863308687 100644 --- a/mysql-test/t/events.test +++ b/mysql-test/t/events.test @@ -49,35 +49,26 @@ drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; +# # BUG #16537 (Events: mysql.event.starts is null) +# CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT interval_field, interval_value, body FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; DROP EVENT event_starts_test; + CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT "non-empty comment"; ---replace_column 8 # 9 # -SHOW EVENTS; -SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; ALTER EVENT event_starts_test COMMENT ""; ---replace_column 8 # 9 # -SHOW EVENTS; +SELECT execute_at IS NULL, starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; DROP EVENT event_starts_test; # # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eddba067d3a..455abde8336 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4201,8 +4201,6 @@ static interval_type get_real_interval_type(interval_type i_type) return INTERVAL_SECOND; } -extern LEX_STRING interval_type_to_name[]; - /* Loads an event from mysql.event and copies it's data to a row of From db3a25fd78a3aabf33b6074b8d73416c5f701c38 Mon Sep 17 00:00:00 2001 From: "andrey@example.com" <> Date: Mon, 25 Sep 2006 16:49:25 +0200 Subject: [PATCH 5/7] Fix for bug#22397 Events: crash with procedure which alters events ALTER EVENT in stored procedure body led to a crash during the procedure call. Affected was only ALTER EVENT which changed the interval of the event. No problems with AT, STARTS, ENDS and so on. --- mysql-test/r/events_bugs.result | 13 +++++++++++++ mysql-test/t/events_bugs.test | 19 +++++++++++++++++++ sql/event_data_objects.cc | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 458fd151130..08be6924e03 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -213,4 +213,17 @@ create event e_53 on schedule every 5 second starts (select s1 from ttx) do drop ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select s1 from ttx) do drop table t' at line 1 create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop table t; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select s1 from ttx) do drop table t' at line 1 +drop event if exists e_16; +drop procedure if exists p_16; +create event e_16 on schedule every 1 second do set @a=5; +create procedure p_16 () alter event e_16 on schedule every @a second; +set @a = null; +call p_16(); +ERROR HY000: Incorrect INTERVAL value: 'NULL' +call p_16(); +ERROR HY000: Incorrect INTERVAL value: 'NULL' +set @a= 6; +call p_16(); +drop procedure p_16; +drop event e_16; drop database events_test; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index c9a8842f8f0..60e8c78d8bb 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -234,4 +234,23 @@ create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop t # END - BUG#16394: Events: Crash if schedule contains SELECT # +# +# START - BUG#22397: Events: crash with procedure which alters events +# +--disable_warnings +drop event if exists e_16; +drop procedure if exists p_16; +--enable_warnings +create event e_16 on schedule every 1 second do set @a=5; +create procedure p_16 () alter event e_16 on schedule every @a second; +set @a = null; +--error ER_WRONG_VALUE +call p_16(); +--error ER_WRONG_VALUE +call p_16(); +set @a= 6; +call p_16(); + +drop procedure p_16; +drop event e_16; drop database events_test; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 6f865a2bcac..4b9aa43b14b 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -353,7 +353,7 @@ Event_parse_data::init_interval(THD *thd) DBUG_RETURN(0); wrong_value: - report_bad_value("INTERVAL", item_execute_at); + report_bad_value("INTERVAL", item_expression); DBUG_RETURN(ER_WRONG_VALUE); } From f7a779acfb296bcb23f59569b862d5323cc294a8 Mon Sep 17 00:00:00 2001 From: "andrey@example.com" <> Date: Mon, 25 Sep 2006 17:22:23 +0200 Subject: [PATCH 6/7] Fix for bug#22662 Inconsistent values displayed for event_scheduler when set to DISABLED It was a silly ordering number error. --- mysql-test/r/events_restart_phase0.result | 22 ++++++++++++++++++++++ mysql-test/t/events_restart_phase0.log | 22 ++++++++++++++++++++++ mysql-test/t/events_restart_phase0.result | 22 ++++++++++++++++++++++ sql/events.h | 2 +- 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/events_restart_phase0.result create mode 100644 mysql-test/t/events_restart_phase0.log create mode 100644 mysql-test/t/events_restart_phase0.result diff --git a/mysql-test/r/events_restart_phase0.result b/mysql-test/r/events_restart_phase0.result new file mode 100644 index 00000000000..218b804a302 --- /dev/null +++ b/mysql-test/r/events_restart_phase0.result @@ -0,0 +1,22 @@ +SHOW VARIABLES LIKE 'event%'; +Variable_name Value +event_scheduler DISABLED +SELECT @@global.event_scheduler; +@@global.event_scheduler +DISABLED +SET GLOBAL event_scheduler=on; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=off; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=0; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=1; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=2; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' +SET GLOBAL event_scheduler=SUSPEND; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' +SET GLOBAL event_scheduler=SUSPENDED; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' +SET GLOBAL event_scheduler=disabled; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' diff --git a/mysql-test/t/events_restart_phase0.log b/mysql-test/t/events_restart_phase0.log new file mode 100644 index 00000000000..218b804a302 --- /dev/null +++ b/mysql-test/t/events_restart_phase0.log @@ -0,0 +1,22 @@ +SHOW VARIABLES LIKE 'event%'; +Variable_name Value +event_scheduler DISABLED +SELECT @@global.event_scheduler; +@@global.event_scheduler +DISABLED +SET GLOBAL event_scheduler=on; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=off; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=0; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=1; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=2; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' +SET GLOBAL event_scheduler=SUSPEND; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' +SET GLOBAL event_scheduler=SUSPENDED; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' +SET GLOBAL event_scheduler=disabled; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' diff --git a/mysql-test/t/events_restart_phase0.result b/mysql-test/t/events_restart_phase0.result new file mode 100644 index 00000000000..218b804a302 --- /dev/null +++ b/mysql-test/t/events_restart_phase0.result @@ -0,0 +1,22 @@ +SHOW VARIABLES LIKE 'event%'; +Variable_name Value +event_scheduler DISABLED +SELECT @@global.event_scheduler; +@@global.event_scheduler +DISABLED +SET GLOBAL event_scheduler=on; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=off; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=0; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=1; +ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement +SET GLOBAL event_scheduler=2; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' +SET GLOBAL event_scheduler=SUSPEND; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' +SET GLOBAL event_scheduler=SUSPENDED; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' +SET GLOBAL event_scheduler=disabled; +ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' diff --git a/sql/events.h b/sql/events.h index b5d2866aa38..79c4a419388 100644 --- a/sql/events.h +++ b/sql/events.h @@ -55,7 +55,7 @@ public: { EVENTS_OFF= 0, EVENTS_ON= 1, - EVENTS_DISABLED= 5 + EVENTS_DISABLED= 4 }; static enum_opt_event_scheduler opt_event_scheduler; From 6cb96bb8b4b23a86a38ebb691654e296e6505fc5 Mon Sep 17 00:00:00 2001 From: "petr/cps@mysql.com/owlet.local" <> Date: Wed, 27 Sep 2006 17:48:00 +0400 Subject: [PATCH 7/7] Remove unused error messages (no release contains them at the moment, so we can safely do that). Update an error mesage to make it translateable. --- mysql-test/r/log_tables.result | 10 +++++----- sql/share/errmsg.txt | 9 ++------- sql/sql_table.cc | 4 ++-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index 59cef29dc8f..33f6c0c7af2 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -73,16 +73,16 @@ select * from mysql.slow_log; start_time user_host query_time lock_time rows_sent rows_examined db last_insert_id insert_id server_id sql_text TIMESTAMP USER_HOST QUERY_TIME 00:00:00 1 0 test 0 0 1 select sleep(2) alter table mysql.general_log engine=myisam; -ERROR HY000: You cannot alter a log table if logging is enabled +ERROR HY000: You cannot 'ALTER' a log table if logging is enabled alter table mysql.slow_log engine=myisam; -ERROR HY000: You cannot alter a log table if logging is enabled +ERROR HY000: You cannot 'ALTER' a log table if logging is enabled drop table mysql.general_log; -ERROR HY000: You cannot drop a log table if logging is enabled +ERROR HY000: You cannot 'DROP' a log table if logging is enabled drop table mysql.slow_log; -ERROR HY000: You cannot drop a log table if logging is enabled +ERROR HY000: You cannot 'DROP' a log table if logging is enabled set global general_log='OFF'; alter table mysql.slow_log engine=myisam; -ERROR HY000: You cannot alter a log table if logging is enabled +ERROR HY000: You cannot 'ALTER' a log table if logging is enabled set global slow_query_log='OFF'; show create table mysql.general_log; Table Create Table diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 2b382317253..d53cb477615 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5972,12 +5972,6 @@ ER_RBR_NOT_AVAILABLE ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ger "Trigger können nicht auf Systemtabellen erzeugt werden" -ER_CANT_ALTER_LOG_TABLE - eng "You can't alter a log table if logging is enabled" -ER_BAD_LOG_ENGINE - eng "One can use only CSV and MyISAM engines for the log tables" -ER_CANT_DROP_LOG_TABLE - eng "Cannot drop log table if log is enabled" ER_EVENT_RECURSIVITY_FORBIDDEN eng "Recursivity of EVENT DDL statements is forbidden when body is present" ER_EVENTS_DB_ERROR @@ -5993,4 +5987,5 @@ ER_WRONG_STRING_LENGTH ER_UNSUPORTED_LOG_ENGINE eng "This storage engine cannot be used for log tables"" ER_BAD_LOG_STATEMENT - eng "You cannot %s a log table if logging is enabled" + eng "You cannot '%s' a log table if logging is enabled" + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 25de19b20b2..78a67eddf9e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1628,7 +1628,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, (!my_strcasecmp(system_charset_info, table->table_name, "slow_log") && opt_slow_log && logger.is_slow_log_table_enabled()))) { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "drop"); + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); DBUG_RETURN(1); } } @@ -5179,7 +5179,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (table_kind == SLOW_LOG && opt_slow_log && logger.is_slow_log_table_enabled())) { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "alter"); + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER"); DBUG_RETURN(TRUE); }