Commit 18f7dfed authored by Michael Widenius's avatar Michael Widenius

Allow mysql_upgrade to enable event after table is corrected

new features:
set event_scheduler=ON|OFF will now try to init event scheduler
if it's not enabled
set event_scheduler=default will try to enable it based on
the value of the event_scheduler when mysqld was started
parent 95faf34d
...@@ -865,6 +865,7 @@ static const char *expected_errors[]= ...@@ -865,6 +865,7 @@ static const char *expected_errors[]=
"ERROR 1060", /* Duplicate column name */ "ERROR 1060", /* Duplicate column name */
"ERROR 1061", /* Duplicate key name */ "ERROR 1061", /* Duplicate key name */
"ERROR 1054", /* Unknown column */ "ERROR 1054", /* Unknown column */
"ERROR 1290", /* RR_OPTION_PREVENTS_STATEMENT */
0 0
}; };
......
...@@ -18,7 +18,7 @@ change column body body longtext character set utf8 collate utf8_bin; ...@@ -18,7 +18,7 @@ change column body body longtext character set utf8 collate utf8_bin;
use events_test; use events_test;
select @@event_scheduler; select @@event_scheduler;
@@event_scheduler @@event_scheduler
DISABLED OFF
show events; show events;
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
select event_name from information_schema.events; select event_name from information_schema.events;
...@@ -40,12 +40,12 @@ ERROR HY000: Cannot proceed because system tables used by Event Scheduler were f ...@@ -40,12 +40,12 @@ ERROR HY000: Cannot proceed because system tables used by Event Scheduler were f
drop event intact_check; drop event intact_check;
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
set global event_scheduler=on; set global event_scheduler=on;
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start ERROR HY000: Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.
set global event_scheduler=off; set global event_scheduler=off;
ERROR HY000: Cannot proceed because system tables used by Event Scheduler were found damaged at server start ERROR HY000: Event Scheduler: An error occurred when initializing system tables. Disabling the Event Scheduler.
show variables like 'event_scheduler'; show variables like 'event_scheduler';
Variable_name Value Variable_name Value
event_scheduler DISABLED event_scheduler OFF
Make sure that we still can create and drop databases, Make sure that we still can create and drop databases,
and no warnings are produced. and no warnings are produced.
drop database if exists mysqltest_database_not_exists; drop database if exists mysqltest_database_not_exists;
...@@ -58,6 +58,22 @@ Error 1545 Failed to open mysql.event ...@@ -58,6 +58,22 @@ Error 1545 Failed to open mysql.event
Restore the original mysql.event table Restore the original mysql.event table
drop table mysql.event; drop table mysql.event;
rename table event_like to mysql.event; rename table event_like to mysql.event;
check that we can now enable events without restart
set global event_scheduler=original;
Warnings:
Note 1408 Event Scheduler: Loaded 3 events
select @@global.event_scheduler;
@@global.event_scheduler
ON
set global event_scheduler=on;
select @@global.event_scheduler;
@@global.event_scheduler
ON
show events;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
events_test abc1 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
events_test abc2 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
events_test abc3 root@localhost SYSTEM RECURRING # 1 SECOND # # ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
Now let's restart the server again Now let's restart the server again
use events_test; use events_test;
select @@event_scheduler; select @@event_scheduler;
......
...@@ -57,3 +57,4 @@ Phase 6/6: Running 'FLUSH PRIVILEGES' ...@@ -57,3 +57,4 @@ Phase 6/6: Running 'FLUSH PRIVILEGES'
OK OK
update mysql.user set password='' where user='root'; update mysql.user set password='' where user='root';
flush privileges; flush privileges;
set global event_scheduler=OFF;
...@@ -59,7 +59,9 @@ DROP FUNCTION f1; ...@@ -59,7 +59,9 @@ DROP FUNCTION f1;
DROP FUNCTION f2; DROP FUNCTION f2;
DROP FUNCTION f3; DROP FUNCTION f3;
set global event_scheduler=1; set global event_scheduler=1;
ERROR HY000: The MariaDB server is running with the --event-scheduler=DISABLED or --skip-grant-tables option so it cannot execute this statement Warnings:
Note 1408 Event Scheduler: Loaded 0 events
set global event_scheduler=0;
select count(*) from information_schema.COLUMN_PRIVILEGES; select count(*) from information_schema.COLUMN_PRIVILEGES;
count(*) count(*)
0 0
......
...@@ -71,9 +71,9 @@ drop event intact_check_1; ...@@ -71,9 +71,9 @@ drop event intact_check_1;
drop event intact_check_2; drop event intact_check_2;
--error ER_EVENTS_DB_ERROR --error ER_EVENTS_DB_ERROR
drop event intact_check; drop event intact_check;
--error ER_EVENTS_DB_ERROR --error ER_STARTUP
set global event_scheduler=on; set global event_scheduler=on;
--error ER_EVENTS_DB_ERROR --error ER_STARTUP
set global event_scheduler=off; set global event_scheduler=off;
show variables like 'event_scheduler'; show variables like 'event_scheduler';
--echo Make sure that we still can create and drop databases, --echo Make sure that we still can create and drop databases,
...@@ -84,6 +84,16 @@ drop database mysqltest_db1; ...@@ -84,6 +84,16 @@ drop database mysqltest_db1;
--echo Restore the original mysql.event table --echo Restore the original mysql.event table
drop table mysql.event; drop table mysql.event;
rename table event_like to mysql.event; rename table event_like to mysql.event;
--echo check that we can now enable events without restart
set global event_scheduler=original;
select @@global.event_scheduler;
set global event_scheduler=on;
select @@global.event_scheduler;
--sorted_result
--replace_column 6 # 9 # 10 #
show events;
--echo Now let's restart the server again --echo Now let's restart the server again
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
......
...@@ -19,4 +19,5 @@ connect(con1,localhost,root,foo,,,); ...@@ -19,4 +19,5 @@ connect(con1,localhost,root,foo,,,);
update mysql.user set password='' where user='root'; update mysql.user set password='' where user='root';
flush privileges; flush privileges;
# Load event table
set global event_scheduler=OFF;
...@@ -112,8 +112,8 @@ DROP FUNCTION f3; ...@@ -112,8 +112,8 @@ DROP FUNCTION f3;
# #
# Bug #26807 "set global event_scheduler=1" and --skip-grant-tables crashes server # Bug #26807 "set global event_scheduler=1" and --skip-grant-tables crashes server
# #
--error ER_OPTION_PREVENTS_STATEMENT
set global event_scheduler=1; set global event_scheduler=1;
set global event_scheduler=0;
# #
# Bug#26285 Selecting information_schema crahes server # Bug#26285 Selecting information_schema crahes server
......
...@@ -597,6 +597,8 @@ ALTER TABLE event ADD body_utf8 longblob DEFAULT NULL ...@@ -597,6 +597,8 @@ ALTER TABLE event ADD body_utf8 longblob DEFAULT NULL
AFTER db_collation; AFTER db_collation;
ALTER TABLE event MODIFY body_utf8 longblob DEFAULT NULL; ALTER TABLE event MODIFY body_utf8 longblob DEFAULT NULL;
# Enable event scheduler if the event table was not up to date before.
set global event_scheduler=original;
# #
# TRIGGER privilege # TRIGGER privilege
......
This diff is collapsed.
...@@ -79,9 +79,11 @@ class Events ...@@ -79,9 +79,11 @@ class Events
and the @@global.event_scheduler SQL variable. and the @@global.event_scheduler SQL variable.
See sys_var.cc See sys_var.cc
*/ */
enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED }; enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED,
EVENTS_ORIGINAL };
/* Protected using LOCK_global_system_variables only. */ /* Protected using LOCK_global_system_variables only. */
static ulong opt_event_scheduler; static ulong opt_event_scheduler, startup_state;
static ulong inited;
static bool check_if_system_tables_error(); static bool check_if_system_tables_error();
static bool start(int *err_no); static bool start(int *err_no);
static bool stop(); static bool stop();
...@@ -91,8 +93,7 @@ class Events ...@@ -91,8 +93,7 @@ class Events
static Event_db_repository * static Event_db_repository *
get_db_repository() { return db_repository; } get_db_repository() { return db_repository; }
static bool static bool init(THD *thd, bool opt_noacl);
init(bool opt_noacl);
static void static void
deinit(); deinit();
...@@ -130,6 +131,11 @@ class Events ...@@ -130,6 +131,11 @@ class Events
static void static void
dump_internal_status(); dump_internal_status();
static void set_original_state(ulong startup_state_org)
{
startup_state= startup_state_org;
}
private: private:
static bool static bool
...@@ -139,8 +145,6 @@ class Events ...@@ -139,8 +145,6 @@ class Events
static Event_queue *event_queue; static Event_queue *event_queue;
static Event_scheduler *scheduler; static Event_scheduler *scheduler;
static Event_db_repository *db_repository; static Event_db_repository *db_repository;
/* Set to TRUE if an error at start up */
static bool check_system_tables_error;
private: private:
/* Prevent use of these */ /* Prevent use of these */
......
...@@ -5507,7 +5507,15 @@ int mysqld_main(int argc, char **argv) ...@@ -5507,7 +5507,15 @@ int mysqld_main(int argc, char **argv)
execute_ddl_log_recovery(); execute_ddl_log_recovery();
if (Events::init(opt_noacl || opt_bootstrap)) /*
Change EVENTS_ORIGINAL to EVENTS_OFF (the default value) as there is no
point in using ORIGINAL during startup
*/
if (Events::opt_event_scheduler == Events::EVENTS_ORIGINAL)
Events::opt_event_scheduler= Events::EVENTS_OFF;
Events::set_original_state(Events::opt_event_scheduler);
if (Events::init((THD*) 0, opt_noacl || opt_bootstrap))
unireg_abort(1); unireg_abort(1);
if (opt_bootstrap) if (opt_bootstrap)
......
...@@ -510,8 +510,10 @@ Diagnostics_area::set_error_status(uint sql_errno, ...@@ -510,8 +510,10 @@ Diagnostics_area::set_error_status(uint sql_errno,
void void
Diagnostics_area::disable_status() Diagnostics_area::disable_status()
{ {
DBUG_ENTER("disable_status");
DBUG_ASSERT(! is_set()); DBUG_ASSERT(! is_set());
m_status= DA_DISABLED; m_status= DA_DISABLED;
DBUG_VOID_RETURN;
} }
Warning_info::Warning_info(ulonglong warn_id_arg, Warning_info::Warning_info(ulonglong warn_id_arg,
......
...@@ -815,30 +815,26 @@ static Sys_var_ulong Sys_delayed_queue_size( ...@@ -815,30 +815,26 @@ static Sys_var_ulong Sys_delayed_queue_size(
VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1)); VALID_RANGE(1, UINT_MAX), DEFAULT(DELAYED_QUEUE_SIZE), BLOCK_SIZE(1));
#ifdef HAVE_EVENT_SCHEDULER #ifdef HAVE_EVENT_SCHEDULER
static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED", NullS }; static const char *event_scheduler_names[]= { "OFF", "ON", "DISABLED",
"ORIGINAL", NullS };
static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var) static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var)
{ {
/* DISABLED is only accepted on the command line */
if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED)
return true;
/*
If the scheduler was disabled because there are no/bad
system tables, produce a more meaningful error message
than ER_OPTION_PREVENTS_STATEMENT
*/
if (Events::check_if_system_tables_error())
return true;
if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) if (Events::opt_event_scheduler == Events::EVENTS_DISABLED)
{ {
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--event-scheduler=DISABLED or --skip-grant-tables"); "--event-scheduler=DISABLED or --skip-grant-tables");
return true; return true;
} }
/* DISABLED is only accepted on the command line */
if (var->save_result.ulonglong_value == Events::EVENTS_DISABLED)
return true;
return false; return false;
} }
static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type) static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type)
{ {
int err_no= 0; int err_no= 0;
bool ret;
uint opt_event_scheduler_value= Events::opt_event_scheduler; uint opt_event_scheduler_value= Events::opt_event_scheduler;
mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_unlock(&LOCK_global_system_variables);
/* /*
...@@ -857,9 +853,25 @@ static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type) ...@@ -857,9 +853,25 @@ static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type)
rare and it's difficult to avoid it without opening up possibilities rare and it's difficult to avoid it without opening up possibilities
for deadlocks. See bug#51160. for deadlocks. See bug#51160.
*/ */
bool ret= opt_event_scheduler_value == Events::EVENTS_ON
? Events::start(&err_no) /* EVENTS_ORIGINAL means we should revert back to the startup state */
: Events::stop(); if (opt_event_scheduler_value == Events::EVENTS_ORIGINAL)
{
opt_event_scheduler_value= Events::opt_event_scheduler=
Events::startup_state;
}
/*
If the scheduler was not properly inited (because of wrong system tables),
try to init it again. This is needed for mysql_upgrade to work properly if
the event tables where upgraded.
*/
if (!Events::inited && (Events::init(thd, 0) || !Events::inited))
ret= 1;
else
ret= opt_event_scheduler_value == Events::EVENTS_ON ?
Events::start(&err_no) :
Events::stop();
mysql_mutex_lock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_global_system_variables);
if (ret) if (ret)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment