From f85f0950a0af0c157daf664ac2b42e21d06df9de Mon Sep 17 00:00:00 2001 From: "Kristofer.Pettersson@naruto." <> Date: Mon, 2 Apr 2007 09:51:14 +0200 Subject: [PATCH] Bug#26174 Server Crash:INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in Event - Some variables in I_S.GLOBAL_STATUS were depending on a network connection in order to evaluate. Since no network connection is present during the execution of an event, this caused the server to crash. - The variable function hooks does now verify that the vio- object is valid before attempting to use it. --- mysql-test/r/information_schema.result | 28 ++++++++++++++ mysql-test/t/information_schema.test | 40 ++++++++++++++++++++ sql/mysqld.cc | 52 +++++++++++++++++--------- sql/set_var.cc | 2 +- 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e5d6078e863..6c03ace3d27 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1408,4 +1408,32 @@ select user,db from information_schema.processlist; user db user3148 test drop user user3148@localhost; +DROP TABLE IF EXISTS thread_status; +CREATE TABLE thread_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +CREATE TABLE server_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +DROP EVENT IF EXISTS log_status; +CREATE EVENT log_status +ON SCHEDULE EVERY 1 SECOND +DO +BEGIN +INSERT INTO thread_status SELECT variable_name, variable_value FROM +information_schema.session_status; +INSERT INTO server_status SELECT variable_name, variable_value FROM +information_schema.global_status; +END$$ +SET GLOBAL event_scheduler=1; +SELECT * FROM thread_status WHERE variable_name LIKE 'SSL%' LIMIT 1,2; +variable_name variable_value +SSL_ACCEPTS 0.0000000 +SSL_CALLBACK_CACHE_HITS 0.0000000 +SELECT variable_name FROM server_status LIMIT 1,2; +variable_name +ABORTED_CONNECTS +BINLOG_CACHE_DISK_USE +DROP EVENT log_status; +DROP TABLE thread_status; +DROP TABLE server_status; +SET GLOBAL event_scheduler=0; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 09a588c9195..bd1f4271c94 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1042,5 +1042,45 @@ select user,db from information_schema.processlist; connection default; drop user user3148@localhost; + + +# +# Bug #26174 Server Crash: INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in Event +# +--disable_warnings +DROP TABLE IF EXISTS thread_status; +CREATE TABLE thread_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +CREATE TABLE server_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +DROP EVENT IF EXISTS log_status; +--enable_warnings + +DELIMITER $$; + +CREATE EVENT log_status + ON SCHEDULE EVERY 1 SECOND + DO + BEGIN + INSERT INTO thread_status SELECT variable_name, variable_value FROM +information_schema.session_status; + INSERT INTO server_status SELECT variable_name, variable_value FROM +information_schema.global_status; + END$$ + +DELIMITER ;$$ + +SET GLOBAL event_scheduler=1; +sleep 1; +SELECT * FROM thread_status WHERE variable_name LIKE 'SSL%' LIMIT 1,2; +SELECT variable_name FROM server_status LIMIT 1,2; + + + +DROP EVENT log_status; +DROP TABLE thread_status; +DROP TABLE server_status; +SET GLOBAL event_scheduler=0; + --echo End of 5.1 tests. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 83b16d9af0a..082a7c6fcbb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3803,6 +3803,8 @@ we force server id to 2, but this MySQL server will not act as a slave."); { if (Events::get_instance()->init()) unireg_abort(1); + } else { + Events::opt_event_scheduler= Events::EVENTS_DISABLED; } /* Signal threads waiting for server to be started */ @@ -6662,12 +6664,20 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *bu return 0; } -/* Functions relying on SSL */ +/* + Functions relying on SSL + Note: In the show_ssl_* functions, we need to check if we have a + valid vio-object since this isn't always true, specifically + when session_status or global_status is requested from + inside an Event. + */ static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; - var->value= const_cast(thd->net.vio->ssl_arg ? - SSL_get_version((SSL*) thd->net.vio->ssl_arg) : ""); + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + var->value= const_cast(SSL_get_version((SSL*) thd->net.vio->ssl_arg)); + else + var->value= ""; return 0; } @@ -6675,9 +6685,10 @@ static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_session_reused((SSL*) thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6685,9 +6696,10 @@ static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6695,9 +6707,10 @@ static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->net.vio && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6705,17 +6718,20 @@ static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; - var->value= const_cast(thd->net.vio->ssl_arg ? - SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : ""); + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + var->value= const_cast(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg)); + else + var->value= ""; return 0; } @@ -6723,7 +6739,7 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; var->value= buff; - if (thd->net.vio->ssl_arg) + if (thd->vio_ok() && thd->net.vio->ssl_arg) { int i; const char *p; diff --git a/sql/set_var.cc b/sql/set_var.cc index e2c90b72feb..91d2a2ec63b 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -4000,7 +4000,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var) DBUG_ENTER("sys_var_event_scheduler::update"); if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) { - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED or --skip-grant-tables"); DBUG_RETURN(TRUE); }