mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-8931: (server part of) session state tracking
Postreview fixes. New MySQL tests fixes.
This commit is contained in:
@ -95,7 +95,7 @@ enum enum_session_state_type
|
||||
SESSION_TRACK_GTIDS,
|
||||
SESSION_TRACK_TRANSACTION_CHARACTERISTICS,
|
||||
SESSION_TRACK_TRANSACTION_STATE,
|
||||
SESSION_TRACK_END
|
||||
SESSION_TRACK_always_at_the_end
|
||||
};
|
||||
my_bool my_net_init(NET *net, Vio* vio, void *thd, unsigned int my_flags);
|
||||
void my_net_local_init(NET *net);
|
||||
|
@ -559,13 +559,13 @@ enum enum_session_state_type
|
||||
SESSION_TRACK_GTIDS,
|
||||
SESSION_TRACK_TRANSACTION_CHARACTERISTICS, /* Transaction chistics */
|
||||
SESSION_TRACK_TRANSACTION_STATE, /* Transaction state */
|
||||
SESSION_TRACK_END /* must be last */
|
||||
SESSION_TRACK_always_at_the_end /* must be last */
|
||||
};
|
||||
|
||||
#define SESSION_TRACK_BEGIN SESSION_TRACK_SYSTEM_VARIABLES
|
||||
|
||||
#define IS_SESSION_STATE_TYPE(T) \
|
||||
(((int)(T) >= SESSION_TRACK_BEGIN) && ((T) < SESSION_TRACK_END))
|
||||
(((int)(T) >= SESSION_TRACK_BEGIN) && ((T) < SESSION_TRACK_always_at_the_end))
|
||||
|
||||
#define net_new_transaction(net) ((net)->pkt_nr=0)
|
||||
|
||||
|
@ -1172,8 +1172,7 @@ bool
|
||||
net_send_ok(THD *thd,
|
||||
uint server_status, uint statement_warn_count,
|
||||
ulonglong affected_rows, ulonglong id, const char *message,
|
||||
bool unused1,
|
||||
bool unused2)
|
||||
bool, bool)
|
||||
{
|
||||
DBUG_ENTER("emb_net_send_ok");
|
||||
MYSQL_DATA *data;
|
||||
|
@ -909,7 +909,11 @@ The following options may be given as the first argument:
|
||||
--session-track-state-change
|
||||
Track changes to the session state.
|
||||
--session-track-system-variables=name
|
||||
Track changes in registered system variables.
|
||||
Track changes in registered system variables. For
|
||||
compatibility with MySQL defaults this variable should be
|
||||
set to "autocommit, character_set_client,
|
||||
character_set_connection, character_set_results,
|
||||
time_zone"
|
||||
--session-track-transaction-info=name
|
||||
Track changes to the transaction attributes. OFF to
|
||||
disable; STATE to track just transaction state (Is there
|
||||
@ -1403,7 +1407,7 @@ secure-file-priv (No default value)
|
||||
server-id 1
|
||||
session-track-schema TRUE
|
||||
session-track-state-change FALSE
|
||||
session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
session-track-system-variables
|
||||
session-track-transaction-info OFF
|
||||
show-slave-auth-info FALSE
|
||||
silent-startup FALSE
|
||||
|
@ -5,25 +5,25 @@
|
||||
# Global - default
|
||||
SELECT @@global.session_track_system_variables;
|
||||
@@global.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
# Session - default
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
|
||||
# via INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'session_track%' ORDER BY VARIABLE_NAME;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
SESSION_TRACK_SCHEMA ON
|
||||
SESSION_TRACK_STATE_CHANGE OFF
|
||||
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
SESSION_TRACK_SYSTEM_VARIABLES
|
||||
SESSION_TRACK_TRANSACTION_INFO OFF
|
||||
# via INFORMATION_SCHEMA.SESSION_VARIABLES
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'session_track%' ORDER BY VARIABLE_NAME;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
SESSION_TRACK_SCHEMA ON
|
||||
SESSION_TRACK_STATE_CHANGE OFF
|
||||
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
SESSION_TRACK_SYSTEM_VARIABLES
|
||||
SESSION_TRACK_TRANSACTION_INFO OFF
|
||||
SET @global_saved_tmp = @@global.session_track_system_variables;
|
||||
|
||||
@ -34,7 +34,7 @@ SELECT @@global.session_track_system_variables;
|
||||
autocommit
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
|
||||
# Altering session variable's value
|
||||
SET @@session.session_track_system_variables='autocommit';
|
||||
@ -72,25 +72,25 @@ SET @@session.session_track_system_variables = DEFAULT;
|
||||
|
||||
SELECT @@global.session_track_system_variables;
|
||||
@@global.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
|
||||
# Variables' values in a new session (con2).
|
||||
connect con2,"127.0.0.1",root,,test,$MASTER_MYPORT,;
|
||||
SELECT @@global.session_track_system_variables;
|
||||
@@global.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
|
||||
# Altering session should not affect global.
|
||||
SET @@session.session_track_system_variables = 'sql_mode';
|
||||
SELECT @@global.session_track_system_variables;
|
||||
@@global.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
sql_mode
|
||||
@ -104,7 +104,7 @@ SELECT @@global.session_track_system_variables;
|
||||
sql_mode
|
||||
SELECT @@session.session_track_system_variables;
|
||||
@@session.session_track_system_variables
|
||||
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
|
||||
|
||||
# Switching to the default connection.
|
||||
connection default;
|
||||
|
@ -3818,13 +3818,13 @@ ENUM_VALUE_LIST OFF,ON
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||
VARIABLE_NAME SESSION_TRACK_SYSTEM_VARIABLES
|
||||
SESSION_VALUE autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
GLOBAL_VALUE autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
SESSION_VALUE
|
||||
GLOBAL_VALUE
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE autocommit,character_set_client,character_set_connection,character_set_results,time_zone
|
||||
DEFAULT_VALUE
|
||||
VARIABLE_SCOPE SESSION
|
||||
VARIABLE_TYPE VARCHAR
|
||||
VARIABLE_COMMENT Track changes in registered system variables.
|
||||
VARIABLE_COMMENT Track changes in registered system variables. For compatibility with MySQL defaults this variable should be set to "autocommit, character_set_client, character_set_connection, character_set_results, time_zone"
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
|
@ -144,16 +144,18 @@ private:
|
||||
return res;
|
||||
}
|
||||
|
||||
uchar* operator[](ulong idx)
|
||||
{
|
||||
return my_hash_element(&m_registered_sysvars, idx);
|
||||
}
|
||||
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 session_created);
|
||||
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
|
||||
@ -217,9 +219,13 @@ public:
|
||||
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 session_created);
|
||||
CHARSET_INFO *char_set, bool take_mutex);
|
||||
};
|
||||
|
||||
|
||||
@ -284,7 +290,7 @@ public:
|
||||
static const unsigned int EXTRA_ALLOC= 1024;
|
||||
|
||||
|
||||
void Session_sysvars_tracker::vars_list::reset()
|
||||
void Session_sysvars_tracker::vars_list::reinit()
|
||||
{
|
||||
buffer_length= 0;
|
||||
track_all= 0;
|
||||
@ -304,7 +310,7 @@ void Session_sysvars_tracker::vars_list::reset()
|
||||
|
||||
void Session_sysvars_tracker::vars_list::copy(vars_list* from, THD *thd)
|
||||
{
|
||||
reset();
|
||||
reinit();
|
||||
track_all= from->track_all;
|
||||
free_hash();
|
||||
buffer_length= from->buffer_length;
|
||||
@ -331,7 +337,7 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
|
||||
if (!(node= (sysvar_node_st *) my_malloc(sizeof(sysvar_node_st),
|
||||
MYF(MY_WME | mem_flag))))
|
||||
{
|
||||
reset();
|
||||
reinit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -345,7 +351,7 @@ bool Session_sysvars_tracker::vars_list::insert(sysvar_node_st *node,
|
||||
if (!search((sys_var *)svar))
|
||||
{
|
||||
//EOF (error is already reported)
|
||||
reset();
|
||||
reinit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -367,9 +373,7 @@ 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 session_created [IN] bool variable which says if the parse is
|
||||
already executed once. The mutex on variables
|
||||
is not acquired if this variable is false.
|
||||
@param take_mutex [IN] take LOCK_plugin
|
||||
|
||||
@return
|
||||
true Error
|
||||
@ -379,11 +383,12 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
|
||||
LEX_STRING var_list,
|
||||
bool throw_error,
|
||||
CHARSET_INFO *char_set,
|
||||
bool session_created)
|
||||
bool take_mutex)
|
||||
{
|
||||
const char separator= ',';
|
||||
char *token, *lasts= NULL;
|
||||
size_t rest= var_list.length;
|
||||
reinit();
|
||||
|
||||
if (!var_list.str || var_list.length == 0)
|
||||
{
|
||||
@ -408,7 +413,7 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
|
||||
token value. Hence the mutex is handled here to avoid a performance
|
||||
overhead.
|
||||
*/
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
for (;;)
|
||||
{
|
||||
@ -429,12 +434,17 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
|
||||
/* Remove leading/trailing whitespace. */
|
||||
trim_whitespace(char_set, &var);
|
||||
|
||||
if ((svar= find_sys_var_ex(thd, var.str, var.length, throw_error, true)))
|
||||
if(!strcmp(var.str,(const char *)"*"))
|
||||
{
|
||||
track_all= true;
|
||||
}
|
||||
else if ((svar=
|
||||
find_sys_var_ex(thd, var.str, var.length, throw_error, true)))
|
||||
{
|
||||
if (insert(NULL, svar, m_mem_flag) == TRUE)
|
||||
goto error;
|
||||
}
|
||||
else if (throw_error && session_created && thd)
|
||||
else if (throw_error && thd)
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_VALUE_FOR_VAR,
|
||||
@ -449,13 +459,13 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd,
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
return false;
|
||||
|
||||
error:
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
return true;
|
||||
}
|
||||
@ -465,7 +475,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
|
||||
LEX_STRING var_list,
|
||||
bool throw_error,
|
||||
CHARSET_INFO *char_set,
|
||||
bool session_created)
|
||||
bool take_mutex)
|
||||
{
|
||||
const char separator= ',';
|
||||
char *token, *lasts= NULL;
|
||||
@ -485,11 +495,10 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
|
||||
token value. Hence the mutex is handled here to avoid a performance
|
||||
overhead.
|
||||
*/
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
for (;;)
|
||||
{
|
||||
sys_var *svar;
|
||||
LEX_STRING var;
|
||||
|
||||
lasts= (char *) memchr(token, separator, rest);
|
||||
@ -506,9 +515,10 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
|
||||
/* Remove leading/trailing whitespace. */
|
||||
trim_whitespace(char_set, &var);
|
||||
|
||||
if (!(svar= find_sys_var_ex(thd, var.str, var.length, throw_error, true)))
|
||||
if(!strcmp(var.str,(const char *)"*") &&
|
||||
!find_sys_var_ex(thd, var.str, var.length, throw_error, true))
|
||||
{
|
||||
if (throw_error && session_created && thd)
|
||||
if (throw_error && take_mutex && thd)
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_WRONG_VALUE_FOR_VAR,
|
||||
@ -517,7 +527,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
return true;
|
||||
}
|
||||
@ -528,7 +538,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd,
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!thd || session_created)
|
||||
if (!thd || take_mutex)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
return false;
|
||||
@ -605,7 +615,10 @@ bool Session_sysvars_tracker::vars_list::construct_var_list(char *buf,
|
||||
my_hash_iterate(&m_registered_sysvars, &name_array_filler, &data);
|
||||
DBUG_ASSERT(data.idx <= m_registered_sysvars.records);
|
||||
|
||||
|
||||
/*
|
||||
We check number of records again here because number of variables
|
||||
could be reduced in case of plugin unload.
|
||||
*/
|
||||
if (m_registered_sysvars.records == 0)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
@ -710,7 +723,7 @@ 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->reset();
|
||||
tool_list->reinit();
|
||||
if (tool_list->parse_var_list(thd, var->save_result.string_value, true,
|
||||
thd->charset(), true))
|
||||
return true;
|
||||
@ -719,47 +732,47 @@ bool Session_sysvars_tracker::update(THD *thd, set_var *var)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Store the data for changed system variables in the specified buffer.
|
||||
Once the data is stored, we reset the flags related to state-change
|
||||
(see reset()).
|
||||
|
||||
@param thd [IN] The thd handle.
|
||||
@paran buf [INOUT] Buffer to store the information to.
|
||||
|
||||
@retval true Error
|
||||
@retval false Success
|
||||
/*
|
||||
Function and structure to support storing variables from hash to the buffer.
|
||||
*/
|
||||
|
||||
bool Session_sysvars_tracker::store(THD *thd, String *buf)
|
||||
struct st_store_variable_param
|
||||
{
|
||||
char val_buf[SHOW_VAR_FUNC_BUFF_SIZE];
|
||||
SHOW_VAR show;
|
||||
const char *value;
|
||||
sysvar_node_st *node;
|
||||
CHARSET_INFO *charset;
|
||||
size_t val_length, length;
|
||||
int idx= 0;
|
||||
THD *thd;
|
||||
String *buf;
|
||||
};
|
||||
|
||||
/* As its always system variable. */
|
||||
show.type= SHOW_SYS;
|
||||
|
||||
while ((node= (sysvar_node_st *) (*orig_list)[idx]))
|
||||
{
|
||||
my_bool Session_sysvars_tracker::store_variable(void *ptr, void *data_ptr)
|
||||
{
|
||||
Session_sysvars_tracker::sysvar_node_st *node=
|
||||
(Session_sysvars_tracker::sysvar_node_st *)ptr;
|
||||
if (node->m_changed)
|
||||
{
|
||||
THD *thd= ((st_store_variable_param *)data_ptr)->thd;
|
||||
String *buf= ((st_store_variable_param *)data_ptr)->buf;
|
||||
char val_buf[SHOW_VAR_FUNC_BUFF_SIZE];
|
||||
SHOW_VAR show;
|
||||
CHARSET_INFO *charset;
|
||||
size_t val_length, length;
|
||||
mysql_mutex_lock(&LOCK_plugin);
|
||||
if (!*node->test_load)
|
||||
{
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
sys_var *svar= node->m_svar;
|
||||
bool is_plugin= svar->cast_pluginvar();
|
||||
if (!is_plugin)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
/* As its always system variable. */
|
||||
show.type= SHOW_SYS;
|
||||
show.name= svar->name.str;
|
||||
show.value= (char *) svar;
|
||||
|
||||
value= get_one_variable(thd, &show, OPT_SESSION, SHOW_SYS, NULL,
|
||||
const char *value= get_one_variable(thd, &show, OPT_SESSION, SHOW_SYS, NULL,
|
||||
&charset, val_buf, &val_length);
|
||||
if (is_plugin)
|
||||
mysql_mutex_unlock(&LOCK_plugin);
|
||||
|
||||
length= net_length_size(svar->name.length) +
|
||||
@ -770,7 +783,7 @@ bool Session_sysvars_tracker::store(THD *thd, String *buf)
|
||||
compile_time_assert(SESSION_TRACK_SYSTEM_VARIABLES < 251);
|
||||
if (unlikely((1 + net_length_size(length) + length + buf->length() >=
|
||||
MAX_PACKET_LENGTH) ||
|
||||
buf->prep_alloc(1 + net_length_size(length) + length,
|
||||
buf->reserve(1 + net_length_size(length) + length,
|
||||
EXTRA_ALLOC)))
|
||||
return true;
|
||||
|
||||
@ -787,8 +800,34 @@ bool Session_sysvars_tracker::store(THD *thd, String *buf)
|
||||
/* System variable's value (length-encoded string). */
|
||||
buf->q_net_store_data((const uchar*)value, val_length);
|
||||
}
|
||||
++ idx;
|
||||
}
|
||||
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.
|
||||
Once the data is stored, we reset the flags related to state-change
|
||||
(see reset()).
|
||||
|
||||
@param thd [IN] The thd handle.
|
||||
@paran buf [INOUT] Buffer to store the information to.
|
||||
|
||||
@retval true Error
|
||||
@retval false Success
|
||||
*/
|
||||
|
||||
bool Session_sysvars_tracker::store(THD *thd, String *buf)
|
||||
{
|
||||
if (!orig_list->is_enabled())
|
||||
return false;
|
||||
|
||||
if (orig_list->store(thd, buf))
|
||||
return true;
|
||||
|
||||
reset();
|
||||
|
||||
@ -811,7 +850,8 @@ void Session_sysvars_tracker::mark_as_changed(THD *thd,
|
||||
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 ((node= (sysvar_node_st *) (orig_list->insert_or_search(node, svar))))
|
||||
if (orig_list->is_enabled() &&
|
||||
(node= (sysvar_node_st *) (orig_list->insert_or_search(node, svar))))
|
||||
{
|
||||
node->m_changed= true;
|
||||
State_tracker::mark_as_changed(thd, var);
|
||||
@ -838,20 +878,28 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
Prepare/reset the m_registered_sysvars hash for next statement.
|
||||
*/
|
||||
|
||||
void Session_sysvars_tracker::reset()
|
||||
{
|
||||
sysvar_node_st *node;
|
||||
int idx= 0;
|
||||
|
||||
while ((node= (sysvar_node_st *) (*orig_list)[idx]))
|
||||
{
|
||||
node->m_changed= false;
|
||||
++ idx;
|
||||
}
|
||||
orig_list->reset();
|
||||
m_changed= false;
|
||||
}
|
||||
|
||||
@ -931,7 +979,7 @@ bool Current_schema_tracker::store(THD *thd, String *buf)
|
||||
compile_time_assert(NAME_LEN < 251);
|
||||
DBUG_ASSERT(length < 251);
|
||||
if (unlikely((1 + 1 + length + buf->length() >= MAX_PACKET_LENGTH) ||
|
||||
buf->prep_alloc(1 + 1 + length, EXTRA_ALLOC)))
|
||||
buf->reserve(1 + 1 + length, EXTRA_ALLOC)))
|
||||
return true;
|
||||
|
||||
/* Session state type (SESSION_TRACK_SCHEMA) */
|
||||
@ -1034,26 +1082,25 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
|
||||
/* STATE */
|
||||
if (tx_changed & TX_CHG_STATE)
|
||||
{
|
||||
uchar *to;
|
||||
if (unlikely((11 + buf->length() >= MAX_PACKET_LENGTH) ||
|
||||
((to= (uchar *) buf->prep_append(11, EXTRA_ALLOC)) == NULL)))
|
||||
buf->reserve(11, EXTRA_ALLOC)))
|
||||
return true;
|
||||
|
||||
*(to++)= (char)SESSION_TRACK_TRANSACTION_STATE;
|
||||
buf->q_append((char)SESSION_TRACK_TRANSACTION_STATE);
|
||||
|
||||
to= net_store_length((uchar *) to, (ulonglong) 9);
|
||||
to= net_store_length((uchar *) to, (ulonglong) 8);
|
||||
buf->q_append((char)9); // whole packet length
|
||||
buf->q_append((char)8); // results length
|
||||
|
||||
*(to++)= (tx_curr_state & TX_EXPLICIT) ? 'T' :
|
||||
((tx_curr_state & TX_IMPLICIT) ? 'I' : '_');
|
||||
*(to++)= (tx_curr_state & TX_READ_UNSAFE) ? 'r' : '_';
|
||||
*(to++)= ((tx_curr_state & TX_READ_TRX) ||
|
||||
(tx_curr_state & TX_WITH_SNAPSHOT)) ? 'R' : '_';
|
||||
*(to++)= (tx_curr_state & TX_WRITE_UNSAFE) ? 'w' : '_';
|
||||
*(to++)= (tx_curr_state & TX_WRITE_TRX) ? 'W' : '_';
|
||||
*(to++)= (tx_curr_state & TX_STMT_UNSAFE) ? 's' : '_';
|
||||
*(to++)= (tx_curr_state & TX_RESULT_SET) ? 'S' : '_';
|
||||
*(to++)= (tx_curr_state & TX_LOCKED_TABLES) ? 'L' : '_';
|
||||
buf->q_append((char)((tx_curr_state & TX_EXPLICIT) ? 'T' :
|
||||
((tx_curr_state & TX_IMPLICIT) ? 'I' : '_')));
|
||||
buf->q_append((char)((tx_curr_state & TX_READ_UNSAFE) ? 'r' : '_'));
|
||||
buf->q_append((char)(((tx_curr_state & TX_READ_TRX) ||
|
||||
(tx_curr_state & TX_WITH_SNAPSHOT)) ? 'R' : '_'));
|
||||
buf->q_append((char)((tx_curr_state & TX_WRITE_UNSAFE) ? 'w' : '_'));
|
||||
buf->q_append((char)((tx_curr_state & TX_WRITE_TRX) ? 'W' : '_'));
|
||||
buf->q_append((char)((tx_curr_state & TX_STMT_UNSAFE) ? 's' : '_'));
|
||||
buf->q_append((char)((tx_curr_state & TX_RESULT_SET) ? 'S' : '_'));
|
||||
buf->q_append((char)((tx_curr_state & TX_LOCKED_TABLES) ? 'L' : '_'));
|
||||
}
|
||||
|
||||
/* CHARACTERISTICS -- How to restart the transaction */
|
||||
@ -1066,7 +1113,7 @@ bool Transaction_state_tracker::store(THD *thd, String *buf)
|
||||
|
||||
/* 2 length by 1 byte and code */
|
||||
if (unlikely((1 + 1 + 1 + 110 + buf->length() >= MAX_PACKET_LENGTH) ||
|
||||
buf->prep_alloc(1 + 1 + 1, EXTRA_ALLOC)))
|
||||
buf->reserve(1 + 1 + 1, EXTRA_ALLOC)))
|
||||
return true;
|
||||
|
||||
compile_time_assert(SESSION_TRACK_TRANSACTION_CHARACTERISTICS < 251);
|
||||
@ -1503,7 +1550,7 @@ bool Session_state_change_tracker::update(THD *thd, set_var *)
|
||||
bool Session_state_change_tracker::store(THD *thd, String *buf)
|
||||
{
|
||||
if (unlikely((1 + 1 + 1 + buf->length() >= MAX_PACKET_LENGTH) ||
|
||||
buf->prep_alloc(1 + 1 + 1, EXTRA_ALLOC)))
|
||||
buf->reserve(1 + 1 + 1, EXTRA_ALLOC)))
|
||||
return true;
|
||||
|
||||
compile_time_assert(SESSION_TRACK_STATE_CHANGE < 251);
|
||||
@ -1550,9 +1597,10 @@ bool Session_state_change_tracker::is_state_changed(THD *)
|
||||
Session_tracker::Session_tracker()
|
||||
{
|
||||
/* track data ID fit into one byte in net coding */
|
||||
compile_time_assert(SESSION_TRACK_END < 251);
|
||||
compile_time_assert(SESSION_TRACK_always_at_the_end < 251);
|
||||
/* one tracker could serv several tracking data */
|
||||
compile_time_assert((uint)SESSION_TRACK_END >= (uint)SESSION_TRACKER_END);
|
||||
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;
|
||||
@ -1648,7 +1696,7 @@ void Session_tracker::store(THD *thd, String *buf)
|
||||
|
||||
if ((size= net_length_size(length)) != 1)
|
||||
{
|
||||
if (buf->prep_alloc(size - 1, EXTRA_ALLOC))
|
||||
if (buf->reserve(size - 1, EXTRA_ALLOC))
|
||||
{
|
||||
buf->length(start); // it is safer to have 0-length block in case of error
|
||||
return;
|
||||
|
@ -62,8 +62,8 @@ protected:
|
||||
/**
|
||||
Is tracking enabled for a particular session state type ?
|
||||
|
||||
@note: It is cache to avoid virtual functions and checking thd
|
||||
when we want mark tracker as changed.
|
||||
@note: it is a cache of the corresponding thd->variables.session_track_xxx
|
||||
variable
|
||||
*/
|
||||
bool m_enabled;
|
||||
|
||||
|
@ -2981,8 +2981,10 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/*
|
||||
if there was instruction which changed tracking state before, result
|
||||
can go with this command OK packet, so better do not cache the result.
|
||||
If there was instruction which changed tracking state,
|
||||
the result of changed tracking state send to client in OK packed.
|
||||
So it changes result sent to client and probably can be different
|
||||
independent on query text. So we can't cache such results.
|
||||
*/
|
||||
if ((thd->client_capabilities & CLIENT_SESSION_TRACK) &&
|
||||
(thd->server_status & SERVER_SESSION_STATE_CHANGED))
|
||||
|
@ -566,16 +566,6 @@ public:
|
||||
return Ptr+ old_length; /* Area to use */
|
||||
}
|
||||
|
||||
inline bool prep_alloc(uint32 arg_length, uint32 step_alloc)
|
||||
{
|
||||
uint32 new_length= arg_length + str_length;
|
||||
if (new_length > Alloced_length)
|
||||
{
|
||||
if (realloc(new_length + step_alloc))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool append(const char *s, uint32 arg_length, uint32 step_alloc)
|
||||
{
|
||||
|
@ -5393,10 +5393,12 @@ static Sys_var_ulong Sys_log_tc_size(
|
||||
|
||||
static Sys_var_sesvartrack Sys_track_session_sys_vars(
|
||||
"session_track_system_variables",
|
||||
"Track changes in registered system variables.",
|
||||
"Track changes in registered system variables. "
|
||||
"For compatibility with MySQL defaults this variable should be set to "
|
||||
"\"autocommit, character_set_client, character_set_connection, "
|
||||
"character_set_results, time_zone\"",
|
||||
CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET,
|
||||
DEFAULT("autocommit,character_set_client,character_set_connection,"
|
||||
"character_set_results,time_zone"),
|
||||
DEFAULT(""),
|
||||
NO_MUTEX_GUARD);
|
||||
|
||||
static bool update_session_track_schema(sys_var *self, THD *thd,
|
||||
|
Reference in New Issue
Block a user