summaryrefslogtreecommitdiff
path: root/sql/set_var.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r--sql/set_var.cc149
1 files changed, 117 insertions, 32 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 5dd438ba95a..04c80576887 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2,8 +2,7 @@
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; either version 2 of the License, or
- (at your option) any later version.
+ 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
@@ -81,7 +80,8 @@ extern my_bool innobase_log_archive,
innobase_use_doublewrite,
innobase_use_checksums,
innobase_file_per_table,
- innobase_locks_unsafe_for_binlog;
+ innobase_locks_unsafe_for_binlog,
+ innobase_rollback_on_timeout;
extern "C" {
extern ulong srv_max_buf_pool_modified_pct;
@@ -119,9 +119,6 @@ TYPELIB delay_key_write_typelib=
delay_key_write_type_names, NULL
};
-static int sys_check_charset(THD *thd, set_var *var);
-static bool sys_update_charset(THD *thd, set_var *var);
-static void sys_set_default_charset(THD *thd, enum_var_type type);
static int sys_check_ftb_syntax(THD *thd, set_var *var);
static bool sys_update_ftb_syntax(THD *thd, set_var * var);
static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
@@ -392,7 +389,7 @@ sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size",
&SV::preload_buff_size);
sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
&SV::read_buff_size);
-sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
+sys_var_opt_readonly sys_readonly("read_only", &opt_readonly);
sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
&SV::read_rnd_buff_size);
sys_var_thd_ulong sys_div_precincrement("div_precision_increment",
@@ -422,6 +419,10 @@ sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size",
sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size",
&SV::trans_prealloc_size,
0, fix_trans_mem_root);
+sys_var_thd_enum sys_thread_handling("thread_handling",
+ &SV::thread_handling,
+ &thread_handling_typelib,
+ NULL);
#ifdef HAVE_QUERY_CACHE
sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
@@ -490,6 +491,10 @@ sys_var_long_ptr sys_table_lock_wait_timeout("table_lock_wait_timeout",
&table_lock_wait_timeout);
sys_var_long_ptr sys_thread_cache_size("thread_cache_size",
&thread_cache_size);
+#if HAVE_POOL_OF_THREADS == 1
+sys_var_long_ptr sys_thread_pool_size("thread_pool_size",
+ &thread_pool_size);
+#endif
sys_var_thd_enum sys_tx_isolation("tx_isolation",
&SV::tx_isolation,
&tx_isolation_typelib,
@@ -694,7 +699,6 @@ sys_var_have_variable sys_have_query_cache("have_query_cache",
&have_query_cache);
sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys);
sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink);
-sys_var_have_variable sys_have_row_based_replication("have_row_based_replication",&have_row_based_replication);
/* Global read-only variable describing server license */
sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
@@ -817,7 +821,6 @@ SHOW_VAR init_vars[]= {
{sys_have_openssl.name, (char*) &have_openssl, SHOW_HAVE},
{sys_have_partition_db.name,(char*) &have_partition_db, SHOW_HAVE},
{sys_have_query_cache.name, (char*) &have_query_cache, SHOW_HAVE},
- {sys_have_row_based_replication.name, (char*) &have_row_based_replication, SHOW_HAVE},
{sys_have_rtree_keys.name, (char*) &have_rtree_keys, SHOW_HAVE},
{sys_have_symlink.name, (char*) &have_symlink, SHOW_HAVE},
{"init_connect", (char*) &sys_init_connect, SHOW_SYS},
@@ -850,6 +853,7 @@ SHOW_VAR init_vars[]= {
{sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS},
{"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG},
{"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG },
+ {"innodb_rollback_on_timeout", (char*) &innobase_rollback_on_timeout, SHOW_MY_BOOL},
{sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS},
{sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS},
{sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
@@ -1051,6 +1055,10 @@ SHOW_VAR init_vars[]= {
#ifdef HAVE_THR_SETCONCURRENCY
{"thread_concurrency", (char*) &concurrency, SHOW_LONG},
#endif
+ {sys_thread_handling.name, (char*) &sys_thread_handling, SHOW_SYS},
+#if HAVE_POOL_OF_THREADS == 1
+ {sys_thread_pool_size.name, (char*) &sys_thread_pool_size, SHOW_SYS},
+#endif
{"thread_stack", (char*) &my_thread_stack_size, SHOW_LONG},
{sys_time_format.name, (char*) &sys_time_format, SHOW_SYS},
{"time_zone", (char*) &sys_time_zone, SHOW_SYS},
@@ -1272,14 +1280,14 @@ static int check_completion_type(THD *thd, set_var *var)
static void fix_net_read_timeout(THD *thd, enum_var_type type)
{
if (type != OPT_GLOBAL)
- thd->net.read_timeout=thd->variables.net_read_timeout;
+ net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
}
static void fix_net_write_timeout(THD *thd, enum_var_type type)
{
if (type != OPT_GLOBAL)
- thd->net.write_timeout=thd->variables.net_write_timeout;
+ net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
}
static void fix_net_retry_count(THD *thd, enum_var_type type)
@@ -1356,10 +1364,6 @@ bool sys_var_thd_binlog_format::is_readonly() const
If we don't have row-based replication compiled in, the variable
is always read-only.
*/
-#ifndef HAVE_ROW_BASED_REPLICATION
- my_error(ER_RBR_NOT_AVAILABLE, MYF(0));
- return 1;
-#else
if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
thd->temporary_tables)
{
@@ -1384,16 +1388,13 @@ bool sys_var_thd_binlog_format::is_readonly() const
return 1;
}
#endif /* HAVE_NDB_BINLOG */
-#endif /* HAVE_ROW_BASED_REPLICATION */
return sys_var_thd_enum::is_readonly();
}
void fix_binlog_format_after_update(THD *thd, enum_var_type type)
{
-#ifdef HAVE_ROW_BASED_REPLICATION
thd->reset_current_stmt_binlog_row_based();
-#endif /*HAVE_ROW_BASED_REPLICATION*/
}
@@ -1472,9 +1473,9 @@ static void fix_server_id(THD *thd, enum_var_type type)
sys_var_long_ptr::
-sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
+sys_var_long_ptr(const char *name_arg, ulong *value_ptr_arg,
sys_after_update_func after_update_arg)
- :sys_var_long_ptr_global(name_arg, value_ptr,
+ :sys_var_long_ptr_global(name_arg, value_ptr_arg,
&LOCK_global_system_variables, after_update_arg)
{}
@@ -1824,7 +1825,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
/* As there was no local variable, return the global value */
var_type= OPT_GLOBAL;
}
- switch (type()) {
+ switch (show_type()) {
case SHOW_INT:
{
uint value;
@@ -2730,7 +2731,7 @@ bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
file_log= logger.get_log_file_handler();
break;
default:
- DBUG_ASSERT(0);
+ assert(0); // Impossible
}
if (!old_value)
@@ -3117,17 +3118,39 @@ byte *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
return (byte*) &(max_user_connections);
}
+
bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
{
- char *locale_str =var->value->str_value.c_ptr();
- MY_LOCALE *locale_match= my_locale_by_name(locale_str);
+ MY_LOCALE *locale_match;
- if (locale_match == NULL)
+ if (var->value->result_type() == INT_RESULT)
{
- my_printf_error(ER_UNKNOWN_ERROR,
- "Unknown locale: '%s'", MYF(0), locale_str);
- return 1;
+ if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
+ {
+ char buf[20];
+ int10_to_str((int) var->value->val_int(), buf, -10);
+ my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
+ return 1;
+ }
}
+ else // STRING_RESULT
+ {
+ char buff[6];
+ String str(buff, sizeof(buff), &my_charset_latin1), *res;
+ if (!(res=var->value->val_str(&str)))
+ {
+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
+ return 1;
+ }
+ const char *locale_str= res->c_ptr();
+ if (!(locale_match= my_locale_by_name(locale_str)))
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "Unknown locale: '%s'", MYF(0), locale_str);
+ return 1;
+ }
+ }
+
var->save_result.locale_value= locale_match;
return 0;
}
@@ -3747,7 +3770,7 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
*/
byte *sys_var_thd_sql_mode::symbolic_mode_representation(THD *thd,
- ulong val,
+ ulonglong val,
ulong *len)
{
char buff[256];
@@ -4062,6 +4085,70 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
return sys_var_bool_ptr::update(thd, var);
}
+bool sys_var_opt_readonly::update(THD *thd, set_var *var)
+{
+ bool result;
+
+ DBUG_ENTER("sys_var_opt_readonly::update");
+
+ /* Prevent self dead-lock */
+ if (thd->locked_tables || thd->active_transaction())
+ {
+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
+ DBUG_RETURN(true);
+ }
+
+ if (thd->global_read_lock)
+ {
+ /*
+ This connection already holds the global read lock.
+ This can be the case with:
+ - FLUSH TABLES WITH READ LOCK
+ - SET GLOBAL READ_ONLY = 1
+ */
+ result= sys_var_bool_ptr::update(thd, var);
+ DBUG_RETURN(result);
+ }
+
+ /*
+ Perform a 'FLUSH TABLES WITH READ LOCK'.
+ This is a 3 step process:
+ - [1] lock_global_read_lock()
+ - [2] close_cached_tables()
+ - [3] make_global_read_lock_block_commit()
+ [1] prevents new connections from obtaining tables locked for write.
+ [2] waits until all existing connections close their tables.
+ [3] prevents transactions from being committed.
+ */
+
+ if (lock_global_read_lock(thd))
+ DBUG_RETURN(true);
+
+ /*
+ This call will be blocked by any connection holding a READ or WRITE lock.
+ Ideally, we want to wait only for pending WRITE locks, but since:
+ con 1> LOCK TABLE T FOR READ;
+ con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
+ con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
+ can cause to wait on a read lock, it's required for the client application
+ to unlock everything, and acceptable for the server to wait on all locks.
+ */
+ if (result= close_cached_tables(thd, true, NULL, false))
+ goto end_with_read_lock;
+
+ if (result= make_global_read_lock_block_commit(thd))
+ goto end_with_read_lock;
+
+ /* Change the opt_readonly system variable, safe because the lock is held */
+ result= sys_var_bool_ptr::update(thd, var);
+
+end_with_read_lock:
+ /* Release the lock */
+ unlock_global_read_lock(thd);
+ DBUG_RETURN(result);
+}
+
+
/* even session variable here requires SUPER, because of -#o,file */
bool sys_var_thd_dbug::check(THD *thd, set_var *var)
{
@@ -4127,15 +4214,13 @@ sys_var_event_scheduler::update(THD *thd, set_var *var)
DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
- Item_result var_type= var->value->result_type();
-
if (var->save_result.ulong_value == Events::EVENTS_ON)
res= Events::get_instance()->start_execution_of_events();
else if (var->save_result.ulong_value == Events::EVENTS_OFF)
res= Events::get_instance()->stop_execution_of_events();
else
{
- DBUG_ASSERT(0);
+ assert(0); // Impossible
}
if (res)
my_error(ER_EVENT_SET_VAR_ERROR, MYF(0));