Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
zsoltparal-mollie committed May 1, 2024
1 parent 5b87e89 commit 50b98cb
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/MySQL_Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ class MySQL_Session
PtrArray *mybes;
MySQL_Data_Stream *client_myds;
MySQL_Data_Stream *server_myds;

// Storage for per-hostgroup backend server hints
std::map<unsigned int, MySrvC *> sticky_backend_hint;

int sticky_backend;

/*
* @brief Store the hostgroups that hold connections that have been flagged as 'expired' by the
* maintenance thread. These values will be used to release the retained connections in the specific
Expand Down
2 changes: 2 additions & 0 deletions include/query_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class Query_Processor_Output {
int timeout;
int retries;
int delay;
int sticky_backend;
char *error_msg;
char *OK_msg;
int sticky_conn;
Expand Down Expand Up @@ -170,6 +171,7 @@ class Query_Processor_Output {
timeout=-1;
retries=-1;
delay=-1;
sticky_backend=-1;
sticky_conn=-1;
multiplex=-1;
gtid_from_hostgroup=-1;
Expand Down
39 changes: 39 additions & 0 deletions lib/MyHGC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,37 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
k++;
New_sum=0;

// @todo: Move this stuff to the appropriate place
// This is promoting the stickyness value in the query hint to be a session variable
if (sess->qpo->sticky_backend != -1 && 0 <= sess->qpo->sticky_backend && sess->qpo->sticky_backend <= 2) {
// proxy_info("promoting sticky_backend with value %d\n", sess->qpo->sticky_backend);
sess->sticky_backend = sess->qpo->sticky_backend;
}

if (sess->sticky_backend > 0) {
if (auto my_srv_hint = sess->sticky_backend_hint.find(this->hid); my_srv_hint != sess->sticky_backend_hint.end()) {
// proxy_info("found prefered sticky backend\n");
for (j=0; j<num_candidates; j++) {
mysrvc = mysrvcCandidates[j];
if(mysrvc == my_srv_hint->second) {
// proxy_info("matched prefered sticky backend\n");
return mysrvc;
}
}

//Abort if we can't find the backend in candidates and we are in strict mode.
if (sess->sticky_backend==2) {
// proxy_info("didn't match prefered sticky backend in strict mode\n");
return NULL;
}

// We are clearing the server because .insert doesn't replace...
// proxy_info("clearing prefered sticky\n");
sess->sticky_backend_hint.erase(this->hid);
}
}


for (j=0; j<num_candidates; j++) {
mysrvc = mysrvcCandidates[j];
New_sum+=mysrvc->weight;
Expand All @@ -366,6 +397,14 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
#ifdef TEST_AURORA
array_mysrvc_cands += num_candidates;
#endif // TEST_AURORA
if (sess->sticky_backend > 0) {
// proxy_info("insert prefered sticky backend\n");
sess->sticky_backend_hint.insert({this->hid, mysrvc});
} else {
// proxy_info("erase prefered sticky backend\n");
sess->sticky_backend_hint.erase(this->hid);
}

return mysrvc;
}
}
Expand Down
6 changes: 6 additions & 0 deletions lib/MySQL_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,12 @@ MySQL_Session::MySQL_Session() {
use_ssl = false;
change_user_auth_switch = false;

// Session-level status of the sticky_backend
// 0 means non-sticky
// 1 means sticky, fallback to new server in case of server failure
// 2 means strictly sticky, throw an error in case of server failure
sticky_backend=0;

//gtid_trxid = 0;
gtid_hid = -1;
memset(gtid_buf,0,sizeof(gtid_buf));
Expand Down
7 changes: 7 additions & 0 deletions lib/Query_Processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2600,6 +2600,13 @@ bool Query_Processor::query_parser_first_comment(Query_Processor_Output *qpo, ch
remove_spaces(value);
if (strlen(key)) {
char c=value[0];
if (!strcasecmp(key,"sticky_backend")) {
// proxy_info("sticky_backend hint detected with value %c\n", c);
if (c >= '0' && c <= '9') { // it is a digit
int t=atoi(value);
qpo->sticky_backend=t;
}
}
if (!strcasecmp(key,"cache_ttl")) {
if (c >= '0' && c <= '9') { // it is a digit
int t=atoi(value);
Expand Down
140 changes: 140 additions & 0 deletions sticky-backend.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h
index a657dc85..60bc8ec1 100644
--- a/include/MySQL_Session.h
+++ b/include/MySQL_Session.h
@@ -225,6 +225,12 @@ class MySQL_Session
PtrArray *mybes;
MySQL_Data_Stream *client_myds;
MySQL_Data_Stream *server_myds;
+
+ // Storage for per-hostgroup backend server hints
+ std::map<unsigned int, MySrvC *> sticky_backend_hint;
+
+ int sticky_backend;
+
/*
* @brief Store the hostgroups that hold connections that have been flagged as 'expired' by the
* maintenance thread. These values will be used to release the retained connections in the specific
diff --git a/include/query_processor.h b/include/query_processor.h
index 5e17903c..358dc89a 100644
--- a/include/query_processor.h
+++ b/include/query_processor.h
@@ -130,6 +130,7 @@ class Query_Processor_Output {
int timeout;
int retries;
int delay;
+ int sticky_backend;
char *error_msg;
char *OK_msg;
int sticky_conn;
@@ -169,6 +170,7 @@ class Query_Processor_Output {
timeout=-1;
retries=-1;
delay=-1;
+ sticky_backend=-1;
sticky_conn=-1;
multiplex=-1;
gtid_from_hostgroup=-1;
diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp
index 09e86503..9d07b625 100644
--- a/lib/MySQL_HostGroups_Manager.cpp
+++ b/lib/MySQL_HostGroups_Manager.cpp
@@ -2937,6 +2937,36 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
k++;
New_sum=0;

+ // @todo: Move this stuff to the appropriate place
+ // This is promoting the stickyness value in the query hint to be a session variable
+ if (sess->qpo->sticky_backend != -1 && 0 <= sess->qpo->sticky_backend && sess->qpo->sticky_backend <= 2) {
+ // proxy_info("promoting sticky_backend with value %d\n", sess->qpo->sticky_backend);
+ sess->sticky_backend = sess->qpo->sticky_backend;
+ }
+
+ if (sess->sticky_backend > 0) {
+ if (auto my_srv_hint = sess->sticky_backend_hint.find(this->hid); my_srv_hint != sess->sticky_backend_hint.end()) {
+ // proxy_info("found prefered sticky backend\n");
+ for (j=0; j<num_candidates; j++) {
+ mysrvc = mysrvcCandidates[j];
+ if(mysrvc == my_srv_hint->second) {
+ // proxy_info("matched prefered sticky backend\n");
+ return mysrvc;
+ }
+ }
+
+ //Abort if we can't find the backend in candidates and we are in strict mode.
+ if (sess->sticky_backend==2) {
+ // proxy_info("didn't match prefered sticky backend in strict mode\n");
+ return NULL;
+ }
+
+ // We are clearing the server because .insert doesn't replace...
+ // proxy_info("clearing prefered sticky\n");
+ sess->sticky_backend_hint.erase(this->hid);
+ }
+ }
+
for (j=0; j<num_candidates; j++) {
mysrvc = mysrvcCandidates[j];
New_sum+=mysrvc->weight;
@@ -2948,6 +2978,14 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_
#ifdef TEST_AURORA
array_mysrvc_cands += num_candidates;
#endif // TEST_AURORA
+ if (sess->sticky_backend > 0) {
+ // proxy_info("insert prefered sticky backend\n");
+ sess->sticky_backend_hint.insert({this->hid, mysrvc});
+ } else {
+ // proxy_info("erase prefered sticky backend\n");
+ sess->sticky_backend_hint.erase(this->hid);
+ }
+
return mysrvc;
}
}
diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp
index 60e3e49f..7faa3037 100644
--- a/lib/MySQL_Session.cpp
+++ b/lib/MySQL_Session.cpp
@@ -592,6 +592,12 @@ MySQL_Session::MySQL_Session() {
use_ssl = false;
change_user_auth_switch = false;

+ // Session-level status of the sticky_backend
+ // 0 means non-sticky
+ // 1 means sticky, fallback to new server in case of server failure
+ // 2 means strictly sticky, throw an error in case of server failure
+ sticky_backend=0;
+
//gtid_trxid = 0;
gtid_hid = -1;
memset(gtid_buf,0,sizeof(gtid_buf));
diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp
index 3169d1ea..48301a00 100644
--- a/lib/ProxySQL_Admin.cpp
+++ b/lib/ProxySQL_Admin.cpp
@@ -12506,6 +12506,7 @@ void ProxySQL_Admin::flush_error_log() {
struct utsname unameData;
int rc;
proxy_info("ProxySQL version %s\n", PROXYSQL_VERSION);
+ proxy_info("Using Mollie patched version\n");
rc=uname(&unameData);
if (rc==0) {
proxy_info("Detected OS: %s %s %s %s %s\n", unameData.sysname, unameData.nodename, unameData.release, unameData.version, unameData.machine);
diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp
index 22cc0367..29a536cc 100644
--- a/lib/Query_Processor.cpp
+++ b/lib/Query_Processor.cpp
@@ -2750,6 +2750,13 @@ bool Query_Processor::query_parser_first_comment(Query_Processor_Output *qpo, ch
remove_spaces(value);
if (strlen(key)) {
char c=value[0];
+ if (!strcasecmp(key,"sticky_backend")) {
+ // proxy_info("sticky_backend hint detected with value %c\n", c);
+ if (c >= '0' && c <= '9') { // it is a digit
+ int t=atoi(value);
+ qpo->sticky_backend=t;
+ }
+ }
if (!strcasecmp(key,"cache_ttl")) {
if (c >= '0' && c <= '9') { // it is a digit
int t=atoi(value);
101 changes: 101 additions & 0 deletions test-config.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
datadir="/var/lib/proxysql"
admin_variables=
{
admin_credentials="admin:temp;cluster:XXXXX"
mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
# refresh_interval=2000
# debug=true
}
mysql_variables=
{
threads=4
max_connections=2048
default_query_delay=0
default_query_timeout=36000000
have_compress=true
poll_timeout=2000
interfaces="0.0.0.0:3306;/tmp/proxysql.sock"
default_schema="information_schema"
stacksize=1048576
server_version="5.7" # match the server version
connect_timeout_server=3000
# make sure to configure monitor username and password
# https://github.com/sysown/proxysql/wiki/Global-variables#mysql-monitor_username-mysql-monitor_password
monitor_username="monitor"
monitor_password="xxxxxxxx"
monitor_history=600000
monitor_connect_interval=60000
monitor_ping_interval=10000
monitor_read_only_interval=1500
monitor_read_only_timeout=500
ping_interval_server_msec=120000
ping_timeout_server=500
commands_stats=true
sessions_sort=true
connect_retries_on_failure=10
}
# defines all the MySQL servers
mysql_servers =
(
# {
# address = "127.0.0.1" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# port = 3306 # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# hostgroup = 100 # no default, required
# status = "ONLINE" # default: ONLINE
# weight = 1 # default: 1
# compression = 0 # default: 0
# max_replication_lag = 10 # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
# },
# {
# address = "/var/lib/mysql/mysql.sock"
# port = 0
# hostgroup = 100
# },
# {
# address="127.0.0.1"
# port=21891
# hostgroup=100
# max_connections=200
# },
{ address="10.32.30.72" , port =3306 , hostgroup = 100 },
{ address="10.32.30.73" , port =3306 , hostgroup = 101 }
)
# defines all the MySQL users
mysql_users:
(
{
username ="mollie" # no default , required
password ="mollie" # default: ''
default_hostgroup = 100 # default: 0
active = 1 # default: 1
}
)
#defines MySQL Query Rules
mysql_query_rules:
(
{
rule_id=100
active=1
match_pattern="^SELECT .* FOR UPDATE$"
destination_hostgroup=100
apply=1
},
{
rule_id=101
active=1
match_pattern="^SELECT"
destination_hostgroup=101
apply=1
}
)
scheduler=
(
)
mysql_replication_hostgroups=
(
{
writer_hostgroup=100
reader_hostgroup=101
comment=""
}
)

0 comments on commit 50b98cb

Please sign in to comment.