diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index b6b77101874..b0de2358777 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -3,6 +3,10 @@ drop database if exists mysqltest_db1; drop database if exists mysqltest_db2; create database events_test; use events_test; +select * from information_schema.global_variables where variable_name like 'event_scheduler'; +VARIABLE_NAME VARIABLE_VALUE +EVENT_SCHEDULER ON +SET GLOBAL event_scheduler = 'OFF'; CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1; CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2; ERROR HY000: Event 'Lower_case' already exists diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index a08be429a83..8376eb7c0de 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -125,3 +125,12 @@ drop function bug27563; drop procedure proc27563; PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 '; EXECUTE stmt; +# +# Bug#19723: kill of active connection yields different error code +# depending on platform. +# + +# Connection: con2. +KILL CONNECTION_ID(); +SELECT 1; +ERROR HY000: Lost connection to MySQL server during query diff --git a/mysql-test/r/no-threads.result b/mysql-test/r/no-threads.result index 50e52138be8..aefecd0f7bc 100644 --- a/mysql-test/r/no-threads.result +++ b/mysql-test/r/no-threads.result @@ -4,3 +4,6 @@ select 1+1; select 1+2; 1+2 3 +SHOW GLOBAL VARIABLES LIKE 'thread_handling'; +Variable_name Value +thread_handling no-threads diff --git a/mysql-test/t/events_bugs-master.opt b/mysql-test/t/events_bugs-master.opt new file mode 100644 index 00000000000..f93413a61e5 --- /dev/null +++ b/mysql-test/t/events_bugs-master.opt @@ -0,0 +1 @@ +--event-scheduler diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index ebd86f3a3d2..efdb67349ec 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -9,6 +9,21 @@ drop database if exists mysqltest_db2; create database events_test; use events_test; +# +# START: Bug #31332 --event-scheduler option misbehaving +# + +# NOTE!! this test must come first! It's testing that the --event-scheduler +# option with no argument in events_bugs-master.opt turns the scheduler on. + +select * from information_schema.global_variables where variable_name like 'event_scheduler'; + +SET GLOBAL event_scheduler = 'OFF'; + +# +# END: Bug #31332 +# + # # START - 16415: Events: event names are case sensitive # diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 1987d9d5773..55334916913 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1142,6 +1142,7 @@ END$$ DELIMITER ;$$ +let $wait_timeout= 300; let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status'; --source include/wait_condition.inc diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 5d5095f7d61..219412e5afa 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -304,3 +304,19 @@ while ($i) dec $i ; } --enable_query_log + +########################################################################### + +--echo # +--echo # Bug#19723: kill of active connection yields different error code +--echo # depending on platform. +--echo # + +--echo +--echo # Connection: con2. +--connection con2 + +KILL CONNECTION_ID(); + +--error 2013 +SELECT 1; diff --git a/mysql-test/t/no-threads.test b/mysql-test/t/no-threads.test index 806cf24e961..31ea6406ee9 100644 --- a/mysql-test/t/no-threads.test +++ b/mysql-test/t/no-threads.test @@ -3,3 +3,4 @@ # select 1+1; select 1+2; +SHOW GLOBAL VARIABLES LIKE 'thread_handling'; diff --git a/sql/events.cc b/sql/events.cc index 262c62bdbc8..73b8f2cda84 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -146,7 +146,7 @@ bool Events::set_opt_event_scheduler(char *argument) { if (argument == NULL) - opt_event_scheduler= Events::EVENTS_DISABLED; + opt_event_scheduler= Events::EVENTS_ON; else { int type; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 03c65c9d654..a7624c5bbcd 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -356,10 +356,35 @@ String *Item_func_concat::val_str(String *str) } else { // Two big const strings - if (tmp_value.alloc(max_length) || - tmp_value.copy(*res) || - tmp_value.append(*res2)) + /* + NOTE: We should be prudent in the initial allocation unit -- the + size of the arguments is a function of data distribution, which + can be any. Instead of overcommitting at the first row, we grow + the allocated amount by the factor of 2. This ensures that no + more than 25% of memory will be overcommitted on average. + */ + + uint concat_len= res->length() + res2->length(); + + if (tmp_value.alloced_length() < concat_len) + { + if (tmp_value.alloced_length() == 0) + { + if (tmp_value.alloc(concat_len)) + goto null; + } + else + { + uint new_len = max(tmp_value.alloced_length() * 2, concat_len); + + if (tmp_value.realloc(new_len)) + goto null; + } + } + + if (tmp_value.copy(*res) || tmp_value.append(*res2)) goto null; + res= &tmp_value; use_as_buff=str; } @@ -679,8 +704,33 @@ String *Item_func_concat_ws::val_str(String *str) } else { // Two big const strings - if (tmp_value.alloc(max_length) || - tmp_value.copy(*res) || + /* + NOTE: We should be prudent in the initial allocation unit -- the + size of the arguments is a function of data distribution, which can + be any. Instead of overcommitting at the first row, we grow the + allocated amount by the factor of 2. This ensures that no more than + 25% of memory will be overcommitted on average. + */ + + uint concat_len= res->length() + sep_str->length() + res2->length(); + + if (tmp_value.alloced_length() < concat_len) + { + if (tmp_value.alloced_length() == 0) + { + if (tmp_value.alloc(concat_len)) + goto null; + } + else + { + uint new_len = max(tmp_value.alloced_length() * 2, concat_len); + + if (tmp_value.realloc(new_len)) + goto null; + } + } + + if (tmp_value.copy(*res) || tmp_value.append(*sep_str) || tmp_value.append(*res2)) goto null; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4cf6e05751f..f65fee872ed 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7745,12 +7745,13 @@ mysqld_get_one_option(int optid, break; } case OPT_ONE_THREAD: - global_system_variables.thread_handling= 2; + global_system_variables.thread_handling= + SCHEDULER_ONE_THREAD_PER_CONNECTION; break; case OPT_THREAD_HANDLING: { global_system_variables.thread_handling= - find_type_or_exit(argument, &thread_handling_typelib, opt->name); + find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1; break; } case OPT_FT_BOOLEAN_SYNTAX: diff --git a/sql/scheduler.h b/sql/scheduler.h index 8351cefda4c..46bbd300cbb 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -40,7 +40,7 @@ public: enum scheduler_types { - SCHEDULER_ONE_THREAD_PER_CONNECTION=1, + SCHEDULER_ONE_THREAD_PER_CONNECTION=0, SCHEDULER_NO_THREADS, SCHEDULER_POOL_OF_THREADS }; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a904023cbff..368ed897a4d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -818,7 +818,20 @@ void THD::awake(THD::killed_state state_to_set) if (!slave_thread) thread_scheduler.post_kill_notification(this); #ifdef SIGNAL_WITH_VIO_CLOSE - close_active_vio(); + if (this != current_thd) + { + /* + In addition to a signal, let's close the socket of the thread that + is being killed. This is to make sure it does not block if the + signal is lost. This needs to be done only on platforms where + signals are not a reliable interruption mechanism. + + If we're killing ourselves, we know that we're not blocked, so this + hack is not used. + */ + + close_active_vio(); + } #endif } if (mysys_var)