-
Notifications
You must be signed in to change notification settings - Fork 977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V2.0.9 var array review #2521
V2.0.9 var array review #2521
Conversation
for (int i=0; i<SQL_NAME_LAST; i++) { | ||
if (i == SQL_CHARACTER_SET || i == SQL_CHARACTER_SET_RESULTS || | ||
i == SQL_CHARACTER_SET_CONNECTION || i == SQL_CHARACTER_SET_CLIENT || | ||
i == SQL_CHARACTER_SET_DATABASE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these variables cannot be set independently.
We either:
- only set
collation_connection
(what is that is actually exchanged in the protocol) - set
collation_connection
, and all the other variables need to be set accordingly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default character set is used when backend mysql server dose not support configured collation/charset. For example, mysql 5.7 does not support collation is greater than 254. There for it might be configured to switch to the default character set.
This code is useless. I should not add it, because default values should not be used to initialize variables.
ss << ci->nr; | ||
sess->mysql_variables->client_set_value(i, ss.str()); | ||
} else { | ||
sess->mysql_variables->client_set_value(i, mysql_thread___default_variables[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, I am not sure about this.
If the client didn't set the variable, and a default it is not required (for example, collation_connection
), probably we should not assign these variables.
To me, assigning a variable means that it needs to be tracked.
I may remove this comment after further review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed this code completely. Client character set initialization takes place in
bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned int len)
From my understanding, default values, that are configured in the global_variables
should not be used to initialize character set variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct.
As part of the handshake, in MySQL_Protocol::generate_pkt_initial_handshake()
, we have this:
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_name(mysql_thread___default_variables[SQL_CHARACTER_SET]);
if (!ci) {
proxy_error("Cannot find character set for name [%s]. Configuration error. Check [%s] global variable.\n",
mysql_thread___default_variables[SQL_CHARACTER_SET], mysql_tracked_variables[SQL_CHARACTER_SET].internal_variable_name);
assert(0);
}
uint8_t uint8_charset = ci->nr & 255;
The client can, in process_pkt_handshake_response
, either:
- accept it replying with the same collation id
- accept it replying with value 0 see Crash on mysql_connection.cpp:417:set_names_start() #810
- change it returning a different collation
@@ -3683,7 +3341,7 @@ bool MySQL_Thread::init() { | |||
|
|||
match_regexes=(Session_Regex **)malloc(sizeof(Session_Regex *)*4); | |||
match_regexes[0]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)SQL_LOG_BIN( *)(:|)=( *)"); | |||
match_regexes[1]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)(SQL_MODE|TIME_ZONE|CHARACTER_SET_RESULTS|SESSION_TRACK_GTIDS|SQL_AUTO_IS_NULL|SQL_SELECT_LIMIT|SQL_SAFE_UPDATES|COLLATION_CONNECTION|NET_WRITE_TIMEOUT|TX_ISOLATION|MAX_JOIN_SIZE( *)(:|)=( *))"); | |||
match_regexes[1]=new Session_Regex((char *)"^SET (|SESSION |@@|@@session.)(SQL_MODE|TIME_ZONE|CHARACTER_SET_RESULTS|CHARACTER_SET_CLIENT|CHARACTER_SET_DATABASE|SESSION_TRACK_GTIDS|SQL_AUTO_IS_NULL|SQL_SELECT_LIMIT|SQL_SAFE_UPDATES|COLLATION_CONNECTION|CHARACTER_SET_CONNECTION|NET_WRITE_TIMEOUT|TX_ISOLATION|MAX_JOIN_SIZE( *)(:|)=( *))"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should automatically generate this regex, so we won't forget when adding new variables.
lib/MySQL_Variables.cpp
Outdated
|
||
void print_backtrace(void); | ||
|
||
void MySQL_Variables::client_set_value(int idx, const char* value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function doesn't check if the client exists.
I see this function called by MySQL_Connection::set_charset()
, that is in turned called by MySQL_Connection::connect_start()
.
MySQL_Connection::connect_start()
creates a connection to the backend.
Some sessions do not have a client connection, for example sessions used by mirroring.
Therefore, trying to set a variable on a not existing client will cause a crash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
set_charset(c->nr, NAMES); | ||
proxy_warning("TRACE : INITIAL ACTION client %s, server %s\n", myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_ACTION), myds->sess->mysql_variables->server_get_value(SQL_CHARACTER_ACTION)); | ||
set_charset(c->nr, (charset_action)atoi(myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_ACTION))); | ||
//set_charset(c->nr, CONNECT_START); | ||
mysql_options(mysql, MYSQL_SET_CHARSET_NAME, c->csname); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to myself: the client (proxysql) send to the server (the backend) the default collation for a specific charset).
If the client is using a collation that is not the default, we may need to change it later on.
We can probably force the desired collation directly into the struct mysql
, instead of using mysql_options
5e7fcc4
to
fd02a36
Compare
This causes the automated test server to crash as ProxySQL just accumulates memory until it crashes :D try avoid submitting for build testing until it works... |
V2.0.9 web2
Fix LOAD MYSQL SERVERS FROM CONFIG
Fix galera query in maint_mode
Better handling of transactions in SQLite3
use DIGEST_STATS_FAST_1 always
Revert to auto configuration of build job num
adding MariaDB ConnectorJ test case to set parser tests
- SQL_SAFE_UPDATES - SQL_SELECT_LIMIT - SQL_SQL_MODE - automation tests
Added new array mysql_tracked_variables[] that defines the tracked variables. Ideally, tracking a new session variable will requires adding only a couple of lines of code. Removed session variables from mysql_thread_variables_names: - now both MySQL_Threads_Handler::get_variables_list() and MySQL_Threads_Handler::has_variable() rely on mysql_tracked_variables[] Simplified MySQL_Variables, as it now also uses mysql_tracked_variables[] .
Generalized code to handle two variables together: - sql_auto_is_null - sql_safe_updates
- collation_connection - net_write_timeout - max_join_size
- collation_connection - net_write_timeout - max_join_size
68df53b
to
5ad09af
Compare
5ad09af
to
0bb82bb
Compare
Automated message: PR pending admin approval for build testing |
Creating a pull request to for review purposes. Not to be merged