diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2016-08-09 15:49:30 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2016-08-31 17:17:46 +0200 |
commit | 6dfa1d374e8c4d3a06e25ceb78cc6571418363ab (patch) | |
tree | e41520848e0ffdefb24a7fbe4cfe1c7249163125 | |
parent | 0ee3e64c55664332e8e92eda55b43692159fe4fe (diff) | |
download | mariadb-git-6dfa1d374e8c4d3a06e25ceb78cc6571418363ab.tar.gz |
MDEV-8931: (server part of) session state tracking
Postreview fixes.
New MySQL tests fixes.
-rw-r--r-- | include/mysql.h.pp | 2 | ||||
-rw-r--r-- | include/mysql_com.h | 4 | ||||
-rw-r--r-- | libmysqld/lib_sql.cc | 3 | ||||
-rw-r--r-- | mysql-test/r/mysqld--help.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result | 22 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result | 8 | ||||
-rw-r--r-- | sql/session_tracker.cc | 276 | ||||
-rw-r--r-- | sql/session_tracker.h | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 6 | ||||
-rw-r--r-- | sql/sql_string.h | 10 | ||||
-rw-r--r-- | sql/sys_vars.cc | 8 |
11 files changed, 198 insertions, 153 deletions
diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 0ef3403626c..e1a0901cee8 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -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); diff --git a/include/mysql_com.h b/include/mysql_com.h index 16af9849759..82f3b9f62ba 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -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) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index aeee99ebe4d..097cde04b43 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -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; diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 176e8186798..ad57cc6fe5e 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -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 diff --git a/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result b/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result index 78ca8ca4ad1..7162e40ef6b 100644 --- a/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result +++ b/mysql-test/suite/sys_vars/r/session_track_system_variables_basic.result @@ -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; diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 3a73ca07402..e422be7287e 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -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 diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index bd641ab8d03..3272d2a41f0 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -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,76 +732,102 @@ 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; - - /* As its always system variable. */ - show.type= SHOW_SYS; - - while ((node= (sysvar_node_st *) (*orig_list)[idx])) + THD *thd; + String *buf; +}; + +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) { - 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_lock(&LOCK_plugin); - if (!*node->test_load) - { - mysql_mutex_unlock(&LOCK_plugin); - continue; - } - sys_var *svar= node->m_svar; - show.name= svar->name.str; - show.value= (char *) svar; + mysql_mutex_unlock(&LOCK_plugin); + return false; + } + sys_var *svar= node->m_svar; + bool is_plugin= svar->cast_pluginvar(); + if (!is_plugin) + mysql_mutex_unlock(&LOCK_plugin); - value= get_one_variable(thd, &show, OPT_SESSION, SHOW_SYS, NULL, - &charset, val_buf, &val_length); + /* As its always system variable. */ + show.type= SHOW_SYS; + show.name= svar->name.str; + show.value= (char *) svar; + + 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) + - svar->name.length + - net_length_size(val_length) + - val_length; + length= net_length_size(svar->name.length) + + svar->name.length + + net_length_size(val_length) + + val_length; - 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, - EXTRA_ALLOC))) - return true; + compile_time_assert(SESSION_TRACK_SYSTEM_VARIABLES < 251); + if (unlikely((1 + net_length_size(length) + length + buf->length() >= + MAX_PACKET_LENGTH) || + buf->reserve(1 + net_length_size(length) + length, + EXTRA_ALLOC))) + return true; - /* Session state type (SESSION_TRACK_SYSTEM_VARIABLES) */ - buf->q_append((char)SESSION_TRACK_SYSTEM_VARIABLES); + /* Session state type (SESSION_TRACK_SYSTEM_VARIABLES) */ + buf->q_append((char)SESSION_TRACK_SYSTEM_VARIABLES); - /* Length of the overall entity. */ - buf->q_net_store_length((ulonglong)length); + /* Length of the overall entity. */ + buf->q_net_store_length((ulonglong)length); - /* System variable's name (length-encoded string). */ - buf->q_net_store_data((const uchar*)svar->name.str, svar->name.length); + /* System variable's name (length-encoded string). */ + buf->q_net_store_data((const uchar*)svar->name.str, svar->name.length); - /* System variable's value (length-encoded string). */ - buf->q_net_store_data((const uchar*)value, val_length); - } - ++ idx; + /* System variable's value (length-encoded string). */ + buf->q_net_store_data((const uchar*)value, val_length); } + 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; - - to= net_store_length((uchar *) to, (ulonglong) 9); - to= net_store_length((uchar *) to, (ulonglong) 8); - - *(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)SESSION_TRACK_TRANSACTION_STATE); + + buf->q_append((char)9); // whole packet length + buf->q_append((char)8); // results length + + 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; diff --git a/sql/session_tracker.h b/sql/session_tracker.h index 431726f03ed..3f73b5dc705 100644 --- a/sql/session_tracker.h +++ b/sql/session_tracker.h @@ -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; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c344a6c6ed8..41006f07a0a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -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)) diff --git a/sql/sql_string.h b/sql/sql_string.h index feab8070cd2..f53015fbd6b 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -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) { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 462bfe52741..a047823551b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -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, |