mariadb/sql/events.h

152 lines
4.2 KiB
C
Raw Normal View History

#ifndef _EVENT_H_
#define _EVENT_H_
Bug #51160 Deadlock around SET GLOBAL EVENT_SCHEDULER = ON|OFF This deadlock could occour betweeen one connection executing SET GLOBAL EVENT_SCHEDULER= ON and another executing SET GLOBAL EVENT_SCHEDULER= OFF. The bug was introduced by WL#4738. The first connection would hold LOCK_event_metadata (protecting the global variable) while trying to lock LOCK_global_system_variables starting the event scheduler thread (in THD:init()). The second connection would hold LOCK_global_system_variables while trying to get LOCK_event_scheduler after stopping the event scheduler inside event_scheduler_update(). This patch fixes the problem by not using LOCK_event_metadata to protect the event_scheduler variable. It is still protected using LOCK_global_system_variables. This fixes the deadlock as it removes one of the two mutexes used to produce it. However, this patch opens up the possibility that the event_scheduler variable and the real event_scheduler state can become out of sync (e.g. variable = OFF, but scheduler running). But this can only happen under very unlikely conditions - two concurrent SET GLOBAL statments, with one thread interrupted at the exact wrong moment. This is preferable to having the possibility of a deadlock. This patch also fixes a bug where it was possible to exit create_event() without releasing LOCK_event_metadata if running out of memory during its exection. No test case added since a repeatable test case would have required excessive use of new sync points. Instead we rely on the fact that this bug was easily reproduceable using RGQ tests.
2010-03-15 14:52:25 +01:00
/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Bug #51160 Deadlock around SET GLOBAL EVENT_SCHEDULER = ON|OFF This deadlock could occour betweeen one connection executing SET GLOBAL EVENT_SCHEDULER= ON and another executing SET GLOBAL EVENT_SCHEDULER= OFF. The bug was introduced by WL#4738. The first connection would hold LOCK_event_metadata (protecting the global variable) while trying to lock LOCK_global_system_variables starting the event scheduler thread (in THD:init()). The second connection would hold LOCK_global_system_variables while trying to get LOCK_event_scheduler after stopping the event scheduler inside event_scheduler_update(). This patch fixes the problem by not using LOCK_event_metadata to protect the event_scheduler variable. It is still protected using LOCK_global_system_variables. This fixes the deadlock as it removes one of the two mutexes used to produce it. However, this patch opens up the possibility that the event_scheduler variable and the real event_scheduler state can become out of sync (e.g. variable = OFF, but scheduler running). But this can only happen under very unlikely conditions - two concurrent SET GLOBAL statments, with one thread interrupted at the exact wrong moment. This is preferable to having the possibility of a deadlock. This patch also fixes a bug where it was possible to exit create_event() without releasing LOCK_event_metadata if running out of memory during its exection. No test case added since a repeatable test case would have required excessive use of new sync points. Instead we rely on the fact that this bug was easily reproduceable using RGQ tests.
2010-03-15 14:52:25 +01:00
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
2007-08-15 15:43:08 +02:00
/**
@defgroup Event_Scheduler Event Scheduler
@ingroup Runtime_Environment
2007-08-15 15:43:08 +02:00
@{
@file events.h
A public interface of Events_Scheduler module.
*/
#ifdef HAVE_PSI_INTERFACE
Patch that refactors global read lock implementation and fixes bug #57006 "Deadlock between HANDLER and FLUSH TABLES WITH READ LOCK" and bug #54673 "It takes too long to get readlock for 'FLUSH TABLES WITH READ LOCK'". The first bug manifested itself as a deadlock which occurred when a connection, which had some table open through HANDLER statement, tried to update some data through DML statement while another connection tried to execute FLUSH TABLES WITH READ LOCK concurrently. What happened was that FTWRL in the second connection managed to perform first step of GRL acquisition and thus blocked all upcoming DML. After that it started to wait for table open through HANDLER statement to be flushed. When the first connection tried to execute DML it has started to wait for GRL/the second connection creating deadlock. The second bug manifested itself as starvation of FLUSH TABLES WITH READ LOCK statements in cases when there was a constant stream of concurrent DML statements (in two or more connections). This has happened because requests for protection against GRL which were acquired by DML statements were ignoring presence of pending GRL and thus the latter was starved. This patch solves both these problems by re-implementing GRL using metadata locks. Similar to the old implementation acquisition of GRL in new implementation is two-step. During the first step we block all concurrent DML and DDL statements by acquiring global S metadata lock (each DML and DDL statement acquires global IX lock for its duration). During the second step we block commits by acquiring global S lock in COMMIT namespace (commit code acquires global IX lock in this namespace). Note that unlike in old implementation acquisition of protection against GRL in DML and DDL is semi-automatic. We assume that any statement which should be blocked by GRL will either open and acquires write-lock on tables or acquires metadata locks on objects it is going to modify. For any such statement global IX metadata lock is automatically acquired for its duration. The first problem is solved because waits for GRL become visible to deadlock detector in metadata locking subsystem and thus deadlocks like one in the first bug become impossible. The second problem is solved because global S locks which are used for GRL implementation are given preference over IX locks which are acquired by concurrent DML (and we can switch to fair scheduling in future if needed). Important change: FTWRL/GRL no longer blocks DML and DDL on temporary tables. Before this patch behavior was not consistent in this respect: in some cases DML/DDL statements on temporary tables were blocked while in others they were not. Since the main use cases for FTWRL are various forms of backups and temporary tables are not preserved during backups we have opted for consistently allowing DML/DDL on temporary tables during FTWRL/GRL. Important change: This patch changes thread state names which are used when DML/DDL of FTWRL is waiting for global read lock. It is now either "Waiting for global read lock" or "Waiting for commit lock" depending on the stage on which FTWRL is. Incompatible change: To solve deadlock in events code which was exposed by this patch we have to replace LOCK_event_metadata mutex with metadata locks on events. As result we have to prohibit DDL on events under LOCK TABLES. This patch also adds extensive test coverage for interaction of DML/DDL and FTWRL. Performance of new and old global read lock implementations in sysbench tests were compared. There were no significant difference between new and old implementations.
2010-11-11 18:11:05 +01:00
extern PSI_mutex_key key_event_scheduler_LOCK_scheduler_state;
extern PSI_cond_key key_event_scheduler_COND_state;
extern PSI_thread_key key_thread_event_scheduler, key_thread_event_worker;
#endif /* HAVE_PSI_INTERFACE */
#include "sql_string.h" /* LEX_STRING */
#include "my_time.h" /* interval_type */
class Event_db_repository;
class Event_parse_data;
class Event_queue;
class Event_scheduler;
struct TABLE_LIST;
class THD;
typedef class Item COND;
typedef struct charset_info_st CHARSET_INFO;
int
sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs);
/**
2007-08-15 15:43:08 +02:00
@brief A facade to the functionality of the Event Scheduler.
Every public operation against the scheduler has to be executed via the
interface provided by a static method of this class. No instance of this
class is ever created and it has no non-static data members.
The life cycle of the Events module is the following:
At server start up:
WL#4738 streamline/simplify @@variable creation process Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables Bug#20415 Output of mysqld --help --verbose is incomplete Bug#25430 variable not found in SELECT @@global.ft_max_word_len; Bug#32902 plugin variables don't know their names Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#34829 No default value for variable and setting default does not raise error Bug#34834 ? Is accepted as a valid sql mode Bug#34878 Few variables have default value according to documentation but error occurs Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var. Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status Bug#40988 log_output_basic.test succeeded though syntactically false. Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails) Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#44797 plugins w/o command-line options have no disabling option in --help Bug#46314 string system variables don't support expressions Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds Bug#49417 some complaints about mysqld --help --verbose output Bug#49540 DEFAULT value of binlog_format isn't the default value Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters Bug#49646 mysql --show-warnings crashes when server dies
2009-12-22 10:35:56 +01:00
init_mutexes() -> init()
When the server is running:
create_event(), drop_event(), start_or_stop_event_scheduler(), etc
At shutdown:
deinit(), destroy_mutexes().
The peculiar initialization and shutdown cycle is an adaptation to the
outside server startup/shutdown framework and mimics the rest of MySQL
subsystems (ACL, time zone tables, etc).
*/
class Events
{
public:
WL#4738 streamline/simplify @@variable creation process Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables Bug#20415 Output of mysqld --help --verbose is incomplete Bug#25430 variable not found in SELECT @@global.ft_max_word_len; Bug#32902 plugin variables don't know their names Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#34829 No default value for variable and setting default does not raise error Bug#34834 ? Is accepted as a valid sql mode Bug#34878 Few variables have default value according to documentation but error occurs Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var. Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status Bug#40988 log_output_basic.test succeeded though syntactically false. Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails) Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#44797 plugins w/o command-line options have no disabling option in --help Bug#46314 string system variables don't support expressions Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds Bug#49417 some complaints about mysqld --help --verbose output Bug#49540 DEFAULT value of binlog_format isn't the default value Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters Bug#49646 mysql --show-warnings crashes when server dies
2009-12-22 10:35:56 +01:00
/*
the following block is to support --event-scheduler command line option
and the @@global.event_scheduler SQL variable.
See sys_var.cc
*/
enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED };
Bug #51160 Deadlock around SET GLOBAL EVENT_SCHEDULER = ON|OFF This deadlock could occour betweeen one connection executing SET GLOBAL EVENT_SCHEDULER= ON and another executing SET GLOBAL EVENT_SCHEDULER= OFF. The bug was introduced by WL#4738. The first connection would hold LOCK_event_metadata (protecting the global variable) while trying to lock LOCK_global_system_variables starting the event scheduler thread (in THD:init()). The second connection would hold LOCK_global_system_variables while trying to get LOCK_event_scheduler after stopping the event scheduler inside event_scheduler_update(). This patch fixes the problem by not using LOCK_event_metadata to protect the event_scheduler variable. It is still protected using LOCK_global_system_variables. This fixes the deadlock as it removes one of the two mutexes used to produce it. However, this patch opens up the possibility that the event_scheduler variable and the real event_scheduler state can become out of sync (e.g. variable = OFF, but scheduler running). But this can only happen under very unlikely conditions - two concurrent SET GLOBAL statments, with one thread interrupted at the exact wrong moment. This is preferable to having the possibility of a deadlock. This patch also fixes a bug where it was possible to exit create_event() without releasing LOCK_event_metadata if running out of memory during its exection. No test case added since a repeatable test case would have required excessive use of new sync points. Instead we rely on the fact that this bug was easily reproduceable using RGQ tests.
2010-03-15 14:52:25 +01:00
/* Protected using LOCK_global_system_variables only. */
2010-08-05 14:34:19 +02:00
static ulong opt_event_scheduler;
WL#4738 streamline/simplify @@variable creation process Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables Bug#20415 Output of mysqld --help --verbose is incomplete Bug#25430 variable not found in SELECT @@global.ft_max_word_len; Bug#32902 plugin variables don't know their names Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#34829 No default value for variable and setting default does not raise error Bug#34834 ? Is accepted as a valid sql mode Bug#34878 Few variables have default value according to documentation but error occurs Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var. Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status Bug#40988 log_output_basic.test succeeded though syntactically false. Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails) Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#44797 plugins w/o command-line options have no disabling option in --help Bug#46314 string system variables don't support expressions Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds Bug#49417 some complaints about mysqld --help --verbose output Bug#49540 DEFAULT value of binlog_format isn't the default value Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters Bug#49646 mysql --show-warnings crashes when server dies
2009-12-22 10:35:56 +01:00
static bool check_if_system_tables_error();
static bool start();
static bool stop();
WL#4738 streamline/simplify @@variable creation process Bug#16565 mysqld --help --verbose does not order variablesBug#20413 sql_slave_skip_counter is not shown in show variables Bug#20415 Output of mysqld --help --verbose is incomplete Bug#25430 variable not found in SELECT @@global.ft_max_word_len; Bug#32902 plugin variables don't know their names Bug#34599 MySQLD Option and Variable Reference need to be consistent in formatting! Bug#34829 No default value for variable and setting default does not raise error Bug#34834 ? Is accepted as a valid sql mode Bug#34878 Few variables have default value according to documentation but error occurs Bug#34883 ft_boolean_syntax cant be assigned from user variable to global var. Bug#37187 `INFORMATION_SCHEMA`.`GLOBAL_VARIABLES`: inconsistent status Bug#40988 log_output_basic.test succeeded though syntactically false. Bug#41010 enum-style command-line options are not honoured (maria.maria-recover fails) Bug#42103 Setting key_buffer_size to a negative value may lead to very large allocations Bug#44691 Some plugins configured as MYSQL_PLUGIN_MANDATORY in can be disabled Bug#44797 plugins w/o command-line options have no disabling option in --help Bug#46314 string system variables don't support expressions Bug#46470 sys_vars.max_binlog_cache_size_basic_32 is broken Bug#46586 When using the plugin interface the type "set" for options caused a crash. Bug#47212 Crash in DBUG_PRINT in mysqltest.cc when trying to print octal number Bug#48758 mysqltest crashes on sys_vars.collation_server_basic in gcov builds Bug#49417 some complaints about mysqld --help --verbose output Bug#49540 DEFAULT value of binlog_format isn't the default value Bug#49640 ambiguous option '--skip-skip-myisam' (double skip prefix) Bug#49644 init_connect and \0 Bug#49645 init_slave and multi-byte characters Bug#49646 mysql --show-warnings crashes when server dies
2009-12-22 10:35:56 +01:00
public:
/* A hack needed for Event_queue_element */
static Event_db_repository *
get_db_repository() { return db_repository; }
static bool
init(my_bool opt_noacl);
static void
deinit();
static void
init_mutexes();
static void
destroy_mutexes();
static bool
create_event(THD *thd, Event_parse_data *parse_data, bool if_exists);
static bool
update_event(THD *thd, Event_parse_data *parse_data,
LEX_STRING *new_dbname, LEX_STRING *new_name);
static bool
drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists);
static void
drop_schema_events(THD *thd, char *db);
static bool
show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name);
/* Needed for both SHOW CREATE EVENT and INFORMATION_SCHEMA */
static int
reconstruct_interval_expression(String *buf, interval_type interval,
longlong expression);
static int
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
static void
dump_internal_status();
private:
static bool
load_events_from_db(THD *thd);
private:
static Event_queue *event_queue;
static Event_scheduler *scheduler;
static Event_db_repository *db_repository;
/* Set to TRUE if an error at start up */
static bool check_system_tables_error;
private:
/* Prevent use of these */
Events(const Events &);
void operator=(Events &);
};
2007-08-15 15:43:08 +02:00
/**
@} (end of group Event Scheduler)
*/
#endif /* _EVENT_H_ */