summaryrefslogtreecommitdiff
path: root/sql/session_tracker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/session_tracker.cc')
-rw-r--r--sql/session_tracker.cc790
1 files changed, 158 insertions, 632 deletions
diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc
index 7538295fcea..1b21012f09e 100644
--- a/sql/session_tracker.cc
+++ b/sql/session_tracker.cc
@@ -15,10 +15,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#ifndef EMBEDDED_LIBRARY
#include "sql_plugin.h"
-#include "session_tracker.h"
-
#include "hash.h"
#include "table.h"
#include "rpl_gtid.h"
@@ -35,264 +32,12 @@ void State_tracker::mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name)
}
-class Not_implemented_tracker : public State_tracker
-{
-public:
- bool enable(THD *thd)
- { return false; }
- bool update(THD *, set_var *)
- { return false; }
- bool store(THD *, String *)
- { return false; }
- void mark_as_changed(THD *, LEX_CSTRING *tracked_item_name)
- {}
-
-};
-
-/**
- Session_sysvars_tracker
-
- This is a tracker class that enables & manages the tracking of session
- system variables. It internally maintains a hash of user supplied variable
- references and a boolean field to store if the variable was changed by the
- last statement.
-*/
-
-class Session_sysvars_tracker : public State_tracker
-{
-private:
-
- struct sysvar_node_st {
- sys_var *m_svar;
- bool *test_load;
- bool m_changed;
- };
-
- class vars_list
- {
- private:
- /**
- Registered system variables. (@@session_track_system_variables)
- A hash to store the name of all the system variables specified by the
- user.
- */
- HASH m_registered_sysvars;
- /** Size of buffer for string representation */
- size_t buffer_length;
- myf m_mem_flag;
- /**
- If TRUE then we want to check all session variable.
- */
- bool track_all;
- void init()
- {
- my_hash_init(&m_registered_sysvars,
- &my_charset_bin,
- 4, 0, 0, (my_hash_get_key) sysvars_get_key,
- my_free, MYF(HASH_UNIQUE |
- ((m_mem_flag & MY_THREAD_SPECIFIC) ?
- HASH_THREAD_SPECIFIC : 0)));
- }
- void free_hash()
- {
- if (my_hash_inited(&m_registered_sysvars))
- {
- my_hash_free(&m_registered_sysvars);
- }
- }
-
- uchar* search(const sys_var *svar)
- {
- return (my_hash_search(&m_registered_sysvars, (const uchar *)&svar,
- sizeof(sys_var *)));
- }
-
- public:
- vars_list() :
- buffer_length(0)
- {
- m_mem_flag= current_thd ? MY_THREAD_SPECIFIC : 0;
- init();
- }
-
- size_t get_buffer_length()
- {
- DBUG_ASSERT(buffer_length != 0); // asked earlier then should
- return buffer_length;
- }
- ~vars_list()
- {
- /* free the allocated hash. */
- if (my_hash_inited(&m_registered_sysvars))
- {
- my_hash_free(&m_registered_sysvars);
- }
- }
-
- uchar* insert_or_search(sysvar_node_st *node, const sys_var *svar)
- {
- uchar *res;
- res= search(svar);
- if (!res)
- {
- if (track_all)
- {
- insert(node, svar, m_mem_flag);
- return search(svar);
- }
- }
- return res;
- }
-
- bool insert(sysvar_node_st *node, const sys_var *svar, myf mem_flag);
- void reinit();
- void reset();
- inline bool is_enabled()
- {
- return track_all || m_registered_sysvars.records;
- }
- void copy(vars_list* from, THD *thd);
- bool parse_var_list(THD *thd, LEX_STRING var_list, bool throw_error,
- CHARSET_INFO *char_set, bool take_mutex);
- bool construct_var_list(char *buf, size_t buf_len);
- bool store(THD *thd, String *buf);
- };
- /**
- Two objects of vars_list type are maintained to manage
- various operations.
- */
- vars_list *orig_list, *tool_list;
-
-public:
- Session_sysvars_tracker()
- {
- orig_list= new (std::nothrow) vars_list();
- tool_list= new (std::nothrow) vars_list();
- }
-
- ~Session_sysvars_tracker()
- {
- if (orig_list)
- delete orig_list;
- if (tool_list)
- delete tool_list;
- }
-
- size_t get_buffer_length()
- {
- return orig_list->get_buffer_length();
- }
- bool construct_var_list(char *buf, size_t buf_len)
- {
- return orig_list->construct_var_list(buf, buf_len);
- }
-
- /**
- Method used to check the validity of string provided
- for session_track_system_variables during the server
- startup.
- */
- static bool server_init_check(THD *thd, CHARSET_INFO *char_set,
- LEX_STRING var_list)
- {
- return check_var_list(thd, var_list, false, char_set, false);
- }
-
- static bool server_init_process(THD *thd, CHARSET_INFO *char_set,
- LEX_STRING var_list)
- {
- vars_list dummy;
- bool result;
- result= dummy.parse_var_list(thd, var_list, false, char_set, false);
- if (!result)
- dummy.construct_var_list(var_list.str, var_list.length + 1);
- return result;
- }
-
- void reset();
- bool enable(THD *thd);
- bool check_str(THD *thd, LEX_STRING *val);
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
- void mark_as_changed(THD *thd, LEX_CSTRING *tracked_item_name);
- /* callback */
- static uchar *sysvars_get_key(const char *entry, size_t *length,
- my_bool not_used __attribute__((unused)));
-
- // hash iterators
- static my_bool name_array_filler(void *ptr, void *data_ptr);
- static my_bool store_variable(void *ptr, void *data_ptr);
- static my_bool reset_variable(void *ptr, void *data_ptr);
-
- static bool check_var_list(THD *thd, LEX_STRING var_list, bool throw_error,
- CHARSET_INFO *char_set, bool take_mutex);
-};
-
-
-
-/**
- Current_schema_tracker,
-
- This is a tracker class that enables & manages the tracking of current
- schema for a particular connection.
-*/
-
-class Current_schema_tracker : public State_tracker
-{
-private:
- bool schema_track_inited;
- void reset();
-
-public:
-
- Current_schema_tracker()
- {
- schema_track_inited= false;
- }
-
- bool enable(THD *thd)
- { return update(thd, NULL); }
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
-};
-
-/*
- Session_state_change_tracker
-
- This is a boolean tracker class that will monitor any change that contributes
- to a session state change.
- Attributes that contribute to session state change include:
- - Successful change to System variables
- - User defined variables assignments
- - temporary tables created, altered or deleted
- - prepared statements added or removed
- - change in current database
- - change of current role
-*/
-
-class Session_state_change_tracker : public State_tracker
-{
-private:
-
- void reset();
-
-public:
- Session_state_change_tracker();
- bool enable(THD *thd)
- { return update(thd, NULL); };
- bool update(THD *thd, set_var *var);
- bool store(THD *thd, String *buf);
- bool is_state_changed(THD*);
-};
-
-
/* To be used in expanding the buffer. */
static const unsigned int EXTRA_ALLOC= 1024;
void Session_sysvars_tracker::vars_list::reinit()
{
- buffer_length= 0;
track_all= 0;
if (m_registered_sysvars.records)
my_hash_reset(&m_registered_sysvars);
@@ -310,10 +55,8 @@ void Session_sysvars_tracker::vars_list::reinit()
void Session_sysvars_tracker::vars_list::copy(vars_list* from, THD *thd)
{
- reinit();
track_all= from->track_all;
free_hash();
- buffer_length= from->buffer_length;
m_registered_sysvars= from->m_registered_sysvars;
from->init();
}
@@ -321,26 +64,20 @@ void Session_sysvars_tracker::vars_list::copy(vars_list* from, THD *thd)
/**
Inserts the variable to be tracked into m_registered_sysvars hash.
- @param node Node to be inserted.
@param svar address of the system variable
@retval false success
@retval true error
*/
-bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
- const sys_var *svar,
- myf mem_flag)
+bool Session_sysvars_tracker::vars_list::insert(const sys_var *svar)
{
- if (!node)
- {
- if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
- MYF(MY_WME | mem_flag))))
- {
- reinit();
- return true;
- }
- }
+ sysvar_node_st *node;
+ if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
+ MYF(MY_WME |
+ (mysqld_server_initialized ?
+ MY_THREAD_SPECIFIC : 0)))))
+ return true;
node->m_svar= (sys_var *)svar;
node->test_load= node->m_svar->test_load;
@@ -351,7 +88,6 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
if (!search((sys_var *)svar))
{
//EOF (error is already reported)
- reinit();
return true;
}
}
@@ -373,7 +109,6 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
in case of invalid/duplicate values.
@param char_set [IN] charecter set information used for string
manipulations.
- @param take_mutex [IN] take LOCK_plugin
@return
true Error
@@ -382,44 +117,28 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
LEX_STRING var_list,
bool throw_error,
- CHARSET_INFO *char_set,
- bool take_mutex)
+ CHARSET_INFO *char_set)
{
const char separator= ',';
char *token, *lasts= NULL;
size_t rest= var_list.length;
- reinit();
if (!var_list.str || var_list.length == 0)
- {
- buffer_length= 1;
return false;
- }
- if(!strcmp(var_list.str,(const char *)"*"))
+ if(!strcmp(var_list.str, "*"))
{
track_all= true;
- buffer_length= 2;
return false;
}
- buffer_length= var_list.length + 1;
token= var_list.str;
track_all= false;
- /*
- If Lock to the plugin mutex is not acquired here itself, it results
- in having to acquire it multiple times in find_sys_var_ex for each
- token value. Hence the mutex is handled here to avoid a performance
- overhead.
- */
- if (!thd || take_mutex)
- mysql_mutex_lock(&LOCK_plugin);
for (;;)
{
sys_var *svar;
- LEX_STRING var;
- uint not_used;
+ LEX_CSTRING var;
lasts= (char *) memchr(token, separator, rest);
@@ -433,17 +152,16 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
var.length= rest;
/* Remove leading/trailing whitespace. */
- trim_whitespace(char_set, &var, &not_used);
+ trim_whitespace(char_set, &var);
- if(!strcmp(var.str,(const char *)"*"))
+ if(!strcmp(var.str, "*"))
{
track_all= true;
}
- else if ((svar=
- find_sys_var_ex(thd, var.str, var.length, throw_error, true)))
+ else if ((svar= find_sys_var(thd, var.str, var.length, throw_error)))
{
- if (insert(NULL, svar, m_mem_flag) == TRUE)
- goto error;
+ if (insert(svar) == TRUE)
+ return true;
}
else if (throw_error && thd)
{
@@ -453,55 +171,35 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
"be ignored.", (int)var.length, token);
}
else
- goto error;
+ return true;
if (lasts)
token= lasts + 1;
else
break;
}
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
-
return false;
-
-error:
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
}
-bool Session_sysvars_tracker::check_var_list(THD *thd,
- LEX_STRING var_list,
- bool throw_error,
- CHARSET_INFO *char_set,
- bool take_mutex)
+bool sysvartrack_validate_value(THD *thd, const char *str, size_t len)
{
+ LEX_STRING var_list= { (char *) str, len };
const char separator= ',';
char *token, *lasts= NULL;
size_t rest= var_list.length;
if (!var_list.str || var_list.length == 0 ||
- !strcmp(var_list.str,(const char *)"*"))
+ !strcmp(var_list.str, "*"))
{
return false;
}
token= var_list.str;
- /*
- If Lock to the plugin mutex is not acquired here itself, it results
- in having to acquire it multiple times in find_sys_var_ex for each
- token value. Hence the mutex is handled here to avoid a performance
- overhead.
- */
- if (!thd || take_mutex)
- mysql_mutex_lock(&LOCK_plugin);
for (;;)
{
- LEX_STRING var;
- uint not_used;
+ LEX_CSTRING var;
lasts= (char *) memchr(token, separator, rest);
@@ -515,55 +213,19 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
var.length= rest;
/* Remove leading/trailing whitespace. */
- trim_whitespace(char_set, &var, &not_used);
+ trim_whitespace(system_charset_info, &var);
- if(!strcmp(var.str,(const char *)"*") &&
- !find_sys_var_ex(thd, var.str, var.length, throw_error, true))
- {
- if (throw_error && take_mutex && thd)
- {
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_VALUE_FOR_VAR,
- "%.*s is not a valid system variable and will"
- "be ignored.", (int)var.length, token);
- }
- else
- {
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
- }
- }
+ if (!strcmp(var.str, "*") && !find_sys_var(thd, var.str, var.length))
+ return true;
if (lasts)
token= lasts + 1;
else
break;
}
- if (!thd || take_mutex)
- mysql_mutex_unlock(&LOCK_plugin);
-
return false;
}
-struct name_array_filler_data
-{
- LEX_CSTRING **names;
- uint idx;
-
-};
-
-/** Collects variable references into array */
-my_bool Session_sysvars_tracker::name_array_filler(void *ptr,
- void *data_ptr)
-{
- Session_sysvars_tracker::sysvar_node_st *node=
- (Session_sysvars_tracker::sysvar_node_st *)ptr;
- name_array_filler_data *data= (struct name_array_filler_data *)data_ptr;
- if (*node->test_load)
- data->names[data->idx++]= &node->m_svar->name;
- return FALSE;
-}
/* Sorts variable references array */
static int name_array_sorter(const void *a, const void *b)
@@ -583,7 +245,8 @@ static int name_array_sorter(const void *a, const void *b)
bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
size_t buf_len)
{
- struct name_array_filler_data data;
+ LEX_CSTRING **names;
+ uint idx;
size_t left= buf_len;
size_t names_size= m_registered_sysvars.records * sizeof(LEX_CSTRING *);
const char separator= ',';
@@ -606,16 +269,19 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
return false;
}
- data.names= (LEX_CSTRING**)my_safe_alloca(names_size);
-
- if (unlikely(!data.names))
+ if (unlikely(!(names= (LEX_CSTRING**) my_safe_alloca(names_size))))
return true;
- data.idx= 0;
+ idx= 0;
mysql_mutex_lock(&LOCK_plugin);
- my_hash_iterate(&m_registered_sysvars, &name_array_filler, &data);
- DBUG_ASSERT(data.idx <= m_registered_sysvars.records);
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
+ {
+ sysvar_node_st *node= at(i);
+ if (*node->test_load)
+ names[idx++]= &node->m_svar->name;
+ }
+ DBUG_ASSERT(idx <= m_registered_sysvars.records);
/*
We check number of records again here because number of variables
@@ -628,17 +294,16 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
return false;
}
- my_qsort(data.names, data.idx, sizeof(LEX_CSTRING *),
- &name_array_sorter);
+ my_qsort(names, idx, sizeof(LEX_CSTRING*), &name_array_sorter);
- for(uint i= 0; i < data.idx; i++)
+ for(uint i= 0; i < idx; i++)
{
- LEX_CSTRING *nm= data.names[i];
+ LEX_CSTRING *nm= names[i];
size_t ln= nm->length + 1;
if (ln > left)
{
mysql_mutex_unlock(&LOCK_plugin);
- my_safe_afree(data.names, names_size);
+ my_safe_afree(names, names_size);
return true;
}
memcpy(buf, nm->str, nm->length);
@@ -649,58 +314,48 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
mysql_mutex_unlock(&LOCK_plugin);
buf--; buf[0]= '\0';
- my_safe_afree(data.names, names_size);
+ my_safe_afree(names, names_size);
return false;
}
-/**
- Enable session tracker by parsing global value of tracked variables.
- @param thd [IN] The thd handle.
+void Session_sysvars_tracker::init(THD *thd)
+{
+ mysql_mutex_assert_owner(&LOCK_global_system_variables);
+ DBUG_ASSERT(thd->variables.session_track_system_variables ==
+ global_system_variables.session_track_system_variables);
+ DBUG_ASSERT(global_system_variables.session_track_system_variables);
+ thd->variables.session_track_system_variables=
+ my_strdup(global_system_variables.session_track_system_variables,
+ MYF(MY_WME | MY_THREAD_SPECIFIC));
+}
- @retval true Error
- @retval false Success
-*/
-bool Session_sysvars_tracker::enable(THD *thd)
+void Session_sysvars_tracker::deinit(THD *thd)
{
- mysql_mutex_lock(&LOCK_plugin);
- LEX_STRING tmp;
- tmp.str= global_system_variables.session_track_system_variables;
- tmp.length= safe_strlen(tmp.str);
- if (tool_list->parse_var_list(thd, tmp,
- true, thd->charset(), false) == true)
- {
- mysql_mutex_unlock(&LOCK_plugin);
- return true;
- }
- mysql_mutex_unlock(&LOCK_plugin);
- orig_list->copy(tool_list, thd);
- m_enabled= true;
-
- return false;
+ my_free(thd->variables.session_track_system_variables);
+ thd->variables.session_track_system_variables= 0;
}
/**
- Check system variable name(s).
-
- @note This function is called from the ON_CHECK() function of the
- session_track_system_variables' sys_var class.
+ Enable session tracker by parsing global value of tracked variables.
@param thd [IN] The thd handle.
- @param var [IN] A pointer to set_var holding the specified list of
- system variable names.
@retval true Error
@retval false Success
*/
-inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
+bool Session_sysvars_tracker::enable(THD *thd)
{
- return Session_sysvars_tracker::check_var_list(thd, *val, true,
- thd->charset(), true);
+ orig_list.reinit();
+ m_parsed= false;
+ m_enabled= thd->variables.session_track_system_variables &&
+ *thd->variables.session_track_system_variables;
+ reset_changed();
+ return false;
}
@@ -710,6 +365,9 @@ inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
Session_sysvars_tracker::vars_list::copy updating the hash in orig_list
which represents the system variables to be tracked.
+ We are doing via tool list because there possible errors with memory
+ in this case value will be unchanged.
+
@note This function is called from the ON_UPDATE() function of the
session_track_system_variables' sys_var class.
@@ -721,37 +379,43 @@ inline bool Session_sysvars_tracker::check_str(THD *thd, LEX_STRING *val)
bool Session_sysvars_tracker::update(THD *thd, set_var *var)
{
- /*
- We are doing via tool list because there possible errors with memory
- in this case value will be unchanged.
- */
- tool_list->reinit();
- if (tool_list->parse_var_list(thd, var->save_result.string_value, true,
- thd->charset(), true))
+ vars_list tool_list;
+ void *copy= var->save_result.string_value.str ?
+ my_memdup(var->save_result.string_value.str,
+ var->save_result.string_value.length + 1,
+ MYF(MY_WME | MY_THREAD_SPECIFIC)) :
+ my_strdup("", MYF(MY_WME | MY_THREAD_SPECIFIC));
+
+ if (!copy)
return true;
- orig_list->copy(tool_list, thd);
- return false;
-}
+ if (tool_list.parse_var_list(thd, var->save_result.string_value, true,
+ thd->charset()))
+ {
+ my_free(copy);
+ return true;
+ }
-/*
- Function and structure to support storing variables from hash to the buffer.
-*/
+ my_free(thd->variables.session_track_system_variables);
+ thd->variables.session_track_system_variables= static_cast<char*>(copy);
+
+ m_parsed= true;
+ orig_list.copy(&tool_list, thd);
+ orig_list.construct_var_list(thd->variables.session_track_system_variables,
+ var->save_result.string_value.length + 1);
+ return false;
+}
-struct st_store_variable_param
-{
- THD *thd;
- String *buf;
-};
-my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
+bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
{
- Session_sysvars_tracker::sysvar_node_st *node=
- (Session_sysvars_tracker::sysvar_node_st *)ptr;
- if (node->m_changed)
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
{
- THD *thd= ((st_store_variable_param *)data_ptr)->thd;
- String *buf= ((st_store_variable_param *)data_ptr)->buf;
+ sysvar_node_st *node= at(i);
+
+ if (!node->m_changed)
+ continue;
+
char val_buf[SHOW_VAR_FUNC_BUFF_SIZE];
SHOW_VAR show;
CHARSET_INFO *charset;
@@ -760,7 +424,7 @@ my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
if (!*node->test_load)
{
mysql_mutex_unlock(&LOCK_plugin);
- return false;
+ continue;
}
sys_var *svar= node->m_svar;
bool is_plugin= svar->cast_pluginvar();
@@ -805,11 +469,6 @@ my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
return false;
}
-bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
-{
- st_store_variable_param data= {thd, buf};
- return my_hash_iterate(&m_registered_sysvars, &store_variable, &data);
-}
/**
Store the data for changed system variables in the specified buffer.
@@ -825,13 +484,13 @@ bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf)
bool Session_sysvars_tracker::store(THD *thd, String *buf)
{
- if (!orig_list->is_enabled())
+ if (!orig_list.is_enabled())
return false;
- if (orig_list->store(thd, buf))
+ if (orig_list.store(thd, buf))
return true;
- reset();
+ orig_list.reset();
return false;
}
@@ -846,14 +505,27 @@ bool Session_sysvars_tracker::store(THD *thd, String *buf)
void Session_sysvars_tracker::mark_as_changed(THD *thd,
LEX_CSTRING *var)
{
- sysvar_node_st *node= NULL;
+ sysvar_node_st *node;
sys_var *svar= (sys_var *)var;
+
+ if (!m_parsed)
+ {
+ DBUG_ASSERT(thd->variables.session_track_system_variables);
+ LEX_STRING tmp= { thd->variables.session_track_system_variables,
+ strlen(thd->variables.session_track_system_variables) };
+ if (orig_list.parse_var_list(thd, tmp, true, thd->charset()))
+ {
+ orig_list.reinit();
+ return;
+ }
+ m_parsed= true;
+ }
+
/*
Check if the specified system variable is being tracked, if so
mark it as changed and also set the class's m_changed flag.
*/
- if (orig_list->is_enabled() &&
- (node= (sysvar_node_st *) (orig_list->insert_or_search(node, svar))))
+ if (orig_list.is_enabled() && (node= orig_list.insert_or_search(svar)))
{
node->m_changed= true;
State_tracker::mark_as_changed(thd, var);
@@ -880,63 +552,41 @@ uchar *Session_sysvars_tracker::sysvars_get_key(const char *entry,
}
-/* Function to support resetting hash nodes for the variables */
-
-my_bool Session_sysvars_tracker::reset_variable(void *ptr,
- void *data_ptr)
-{
- ((Session_sysvars_tracker::sysvar_node_st *)ptr)->m_changed= false;
- return false;
-}
-
void Session_sysvars_tracker::vars_list::reset()
{
- my_hash_iterate(&m_registered_sysvars, &reset_variable, NULL);
+ for (ulong i= 0; i < m_registered_sysvars.records; i++)
+ at(i)->m_changed= false;
}
-/**
- Prepare/reset the m_registered_sysvars hash for next statement.
-*/
-void Session_sysvars_tracker::reset()
+bool sysvartrack_global_update(THD *thd, char *str, size_t len)
{
-
- orig_list->reset();
- m_changed= false;
+ LEX_STRING tmp= { str, len };
+ Session_sysvars_tracker::vars_list dummy;
+ if (!dummy.parse_var_list(thd, tmp, false, system_charset_info))
+ {
+ dummy.construct_var_list(str, len + 1);
+ return false;
+ }
+ return true;
}
-static Session_sysvars_tracker* sysvar_tracker(THD *thd)
-{
- return (Session_sysvars_tracker*)
- thd->session_tracker.get_tracker(SESSION_SYSVARS_TRACKER);
-}
-bool sysvartrack_validate_value(THD *thd, const char *str, size_t len)
-{
- LEX_STRING tmp= {(char *)str, len};
- return Session_sysvars_tracker::server_init_check(thd, system_charset_info,
- tmp);
-}
-bool sysvartrack_reprint_value(THD *thd, char *str, size_t len)
-{
- LEX_STRING tmp= {str, len};
- return Session_sysvars_tracker::server_init_process(thd,
- system_charset_info,
- tmp);
-}
-bool sysvartrack_update(THD *thd, set_var *var)
-{
- return sysvar_tracker(thd)->update(thd, var);
-}
-size_t sysvartrack_value_len(THD *thd)
-{
- return sysvar_tracker(thd)->get_buffer_length();
-}
-bool sysvartrack_value_construct(THD *thd, char *val, size_t len)
+int session_tracker_init()
{
- return sysvar_tracker(thd)->construct_var_list(val, len);
+ DBUG_ASSERT(global_system_variables.session_track_system_variables);
+ if (sysvartrack_validate_value(0,
+ global_system_variables.session_track_system_variables,
+ strlen(global_system_variables.session_track_system_variables)))
+ {
+ sql_print_error("The variable session_track_system_variables has "
+ "invalid values.");
+ return 1;
+ }
+ return 0;
}
+
///////////////////////////////////////////////////////////////////////////////
/**
@@ -974,7 +624,7 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
It saves length of database name and name of database name +
length of saved length of database length.
*/
- length= db_length= thd->db_length;
+ length= db_length= thd->db.length;
length += net_length_size(length);
compile_time_assert(SESSION_TRACK_SCHEMA < 251);
@@ -991,39 +641,14 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
buf->q_net_store_length(length);
/* Length and current schema name */
- buf->q_net_store_data((const uchar *)thd->db, thd->db_length);
-
- reset();
+ buf->q_net_store_data((const uchar *)thd->db.str, thd->db.length);
return false;
}
-/**
- Reset the m_changed flag for next statement.
-
- @return void
-*/
-
-void Current_schema_tracker::reset()
-{
- m_changed= false;
-}
-
-
///////////////////////////////////////////////////////////////////////////////
-
-Transaction_state_tracker::Transaction_state_tracker()
-{
- m_enabled = false;
- tx_changed = TX_CHG_NONE;
- tx_curr_state =
- tx_reported_state= TX_EMPTY;
- tx_read_flags = TX_READ_INHERIT;
- tx_isol_level = TX_ISOL_INHERIT;
-}
-
/**
Enable/disable the tracker based on @@session_track_transaction_info.
@@ -1185,7 +810,7 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
statement even for a transaction that isn't the first in an
ongoing chain. Consider
- SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED;
+ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION READ ONLY, WITH CONSISTENT SNAPSHOT;
# work
COMMIT AND CHAIN;
@@ -1193,7 +818,7 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
If we switch away at this point, the replay in the new session
needs to be
- SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED;
+ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
START TRANSACTION READ ONLY;
When a transaction ends (COMMIT/ROLLBACK sans CHAIN), all
@@ -1216,7 +841,7 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
tx_isolation_typelib as it hyphenates its items.
*/
buf->append(STRING_WITH_LEN("SET TRANSACTION ISOLATION LEVEL "));
- buf->append(isol[tx_isol_level - 1].str, isol[tx_isol_level - 1].length);
+ buf->append(&isol[tx_isol_level - 1]);
buf->append(STRING_WITH_LEN("; "));
}
@@ -1333,25 +958,14 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
}
}
- reset();
+ tx_reported_state= tx_curr_state;
+ tx_changed= TX_CHG_NONE;
return false;
}
/**
- Reset the m_changed flag for next statement.
-*/
-
-void Transaction_state_tracker::reset()
-{
- m_changed= false;
- tx_reported_state= tx_curr_state;
- tx_changed= TX_CHG_NONE;
-}
-
-
-/**
Helper function: turn table info into table access flag.
Accepts table lock type and engine type flag (transactional/
non-transactional), and returns the corresponding access flag
@@ -1520,11 +1134,6 @@ void Transaction_state_tracker::set_isol_level(THD *thd,
///////////////////////////////////////////////////////////////////////////////
-Session_state_change_tracker::Session_state_change_tracker()
-{
- m_changed= false;
-}
-
/**
@Enable/disable the tracker based on @@session_track_state_change value.
@@ -1562,106 +1171,15 @@ bool Session_state_change_tracker::store(THD *thd, String *buf)
/* Length of the overall entity (1 byte) */
buf->q_append('\1');
- DBUG_ASSERT(is_state_changed(thd));
+ DBUG_ASSERT(is_changed());
buf->q_append('1');
- reset();
-
return false;
}
-
-/**
- Reset the m_changed flag for next statement.
-*/
-
-void Session_state_change_tracker::reset()
-{
- m_changed= false;
-}
-
-
-/**
- Find if there is a session state change.
-*/
-
-bool Session_state_change_tracker::is_state_changed(THD *)
-{
- return m_changed;
-}
-
///////////////////////////////////////////////////////////////////////////////
/**
- @brief Initialize session tracker objects.
-*/
-
-Session_tracker::Session_tracker()
-{
- /* track data ID fit into one byte in net coding */
- compile_time_assert(SESSION_TRACK_always_at_the_end < 251);
- /* one tracker could serv several tracking data */
- compile_time_assert((uint)SESSION_TRACK_always_at_the_end >=
- (uint)SESSION_TRACKER_END);
-
- for (int i= 0; i < SESSION_TRACKER_END; i++)
- m_trackers[i]= NULL;
-}
-
-
-/**
- @brief Enables the tracker objects.
-
- @param thd [IN] The thread handle.
-
- @return void
-*/
-
-void Session_tracker::enable(THD *thd)
-{
- /*
- Originally and correctly this allocation was in the constructor and
- deallocation in the destructor, but in this case memory counting
- system works incorrectly (for example in INSERT DELAYED thread)
- */
- deinit();
- m_trackers[SESSION_SYSVARS_TRACKER]=
- new (std::nothrow) Session_sysvars_tracker();
- m_trackers[CURRENT_SCHEMA_TRACKER]=
- new (std::nothrow) Current_schema_tracker;
- m_trackers[SESSION_STATE_CHANGE_TRACKER]=
- new (std::nothrow) Session_state_change_tracker;
- m_trackers[SESSION_GTIDS_TRACKER]=
- new (std::nothrow) Not_implemented_tracker;
- m_trackers[TRANSACTION_INFO_TRACKER]=
- new (std::nothrow) Transaction_state_tracker;
-
- for (int i= 0; i < SESSION_TRACKER_END; i++)
- m_trackers[i]->enable(thd);
-}
-
-
-/**
- Method called during the server startup to verify the contents
- of @@session_track_system_variables.
-
- @retval false Success
- @retval true Failure
-*/
-
-bool Session_tracker::server_boot_verify(CHARSET_INFO *char_set)
-{
- bool result;
- LEX_STRING tmp;
- tmp.str= global_system_variables.session_track_system_variables;
- tmp.length= safe_strlen(tmp.str);
- result=
- Session_sysvars_tracker::server_init_check(NULL, char_set, tmp);
- return result;
-}
-
-
-/**
@brief Store all change information in the specified buffer.
@param thd [IN] The thd handle.
@@ -1673,6 +1191,12 @@ void Session_tracker::store(THD *thd, String *buf)
{
size_t start;
+ /* track data ID fit into one byte in net coding */
+ compile_time_assert(SESSION_TRACK_always_at_the_end < 251);
+ /* one tracker could serv several tracking data */
+ compile_time_assert((uint) SESSION_TRACK_always_at_the_end >=
+ (uint) SESSION_TRACKER_END);
+
/*
Probably most track result will fit in 251 byte so lets made it at
least efficient. We allocate 1 byte for length and then will move
@@ -1684,11 +1208,15 @@ void Session_tracker::store(THD *thd, String *buf)
/* Get total length. */
for (int i= 0; i < SESSION_TRACKER_END; i++)
{
- if (m_trackers[i]->is_changed() &&
- m_trackers[i]->store(thd, buf))
+ if (m_trackers[i]->is_changed())
{
- buf->length(start); // it is safer to have 0-length block in case of error
- return;
+ if (m_trackers[i]->store(thd, buf))
+ {
+ // it is safer to have 0-length block in case of error
+ buf->length(start);
+ return;
+ }
+ m_trackers[i]->reset_changed();
}
}
@@ -1716,5 +1244,3 @@ void Session_tracker::store(THD *thd, String *buf)
net_store_length(data - 1, length);
}
-
-#endif //EMBEDDED_LIBRARY