@@ -1915,10 +1915,12 @@ bool MySQL_Session::handler_again___verify_backend_session_track_gtids() {
19151915 proxy_debug (PROXY_DEBUG_MYSQL_CONNECTION, 5 , " Session %p , client: %s , backend: %s\n " , this , client_myds->myconn ->options .session_track_gtids , mybe->server_myds ->myconn ->options .session_track_gtids );
19161916 // we first verify that the backend supports it
19171917 // if backend is old (or if it is not mysql) ignore this setting
1918- if ((mybe->server_myds ->myconn ->mysql ->server_capabilities & CLIENT_SESSION_TRACKING) == 0 ) {
1919- // the backend doesn't support CLIENT_SESSION_TRACKING
1920- return ret; // exit immediately
1918+ if ((mybe->server_myds ->myconn ->mysql ->server_capabilities & CLIENT_SESSION_TRACKING) == 0
1919+ || (mybe->server_myds ->myconn ->mysql ->server_capabilities & CLIENT_DEPRECATE_EOF) == 0
1920+ || mysql_thread___enable_server_deprecate_eof == false ) {
1921+ return ret;
19211922 }
1923+
19221924 uint32_t b_int = mybe->server_myds ->myconn ->options .session_track_gtids_int ;
19231925 uint32_t f_int = client_myds->myconn ->options .session_track_gtids_int ;
19241926
@@ -1965,16 +1967,26 @@ bool MySQL_Session::handler_again___verify_backend_session_track_gtids() {
19651967}
19661968
19671969bool MySQL_Session::handler_again___verify_backend_session_track_variables () {
1968- if (mysql_thread___session_track_variables == session_track_variables::DISABLED) {
1970+ int mode = mysql_thread___session_track_variables;
1971+
1972+ // skip enabling session variable tracking in the following cases
1973+ if (mode == session_track_variables::DISABLED) {
1974+ return false ;
1975+ }
1976+ if ((mybe->server_myds ->myconn ->mysql ->server_capabilities & CLIENT_SESSION_TRACKING) == 0
1977+ || (mybe->server_myds ->myconn ->mysql ->server_capabilities & CLIENT_DEPRECATE_EOF) == 0 ) {
1978+ return false ;
1979+ }
1980+ if (!mysql_thread___enable_server_deprecate_eof && mode != session_track_variables::ENFORCED) {
19691981 return false ;
19701982 }
19711983
1984+ // enable session tracking
19721985 if (mybe->server_myds ->myconn ->options .session_track_variables_sent == false ) {
19731986 mybe->server_myds ->myconn ->options .session_track_variables_sent = true ;
19741987 set_previous_status_mode3 ();
19751988 NEXT_IMMEDIATE_NEW (SETTING_SESSION_TRACK_VARIABLES);
19761989 }
1977-
19781990 if (mybe->server_myds ->myconn ->options .session_track_state_sent == false ) {
19791991 mybe->server_myds ->myconn ->options .session_track_state_sent = true ;
19801992 set_previous_status_mode3 ();
@@ -2944,6 +2956,11 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) {
29442956 }
29452957 enum session_status st=status;
29462958 if (mybe->server_myds ->myconn ->async_state_machine ==ASYNC_IDLE) {
2959+ if (handle_session_track_capabilities () == false ) {
2960+ pause_until = thread->curtime + mysql_thread___connect_retries_delay*1000 ;
2961+ return false ;
2962+ }
2963+
29472964 st=previous_status.top ();
29482965 previous_status.pop ();
29492966 NEXT_IMMEDIATE_NEW (st);
@@ -2973,6 +2990,13 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) {
29732990 previous_status.pop ();
29742991 myds->wait_until =0 ;
29752992
2993+ if (handle_session_track_capabilities () == false ) {
2994+ previous_status.push (st);
2995+ pause_until = thread->curtime + mysql_thread___connect_retries_delay * 1000 ;
2996+ set_status (CONNECTING_SERVER);
2997+ return false ;
2998+ }
2999+
29763000 // NOTE: Even if a connection has correctly been created, since the CLIENT_DEPRECATE_EOF
29773001 // capability isn't always enforced to match for backend conns (no direct propagation), a
29783002 // mismatch can take place after the creation. Right now this is only true for
@@ -8377,3 +8401,57 @@ char* MySQL_Session::get_current_query(int max_length) {
83778401
83788402 return res;
83798403}
8404+
8405+ /* *
8406+ * @brief Handle session track capabilities validation.
8407+ *
8408+ * This function validates whether the backend connection has capabilities such as 'CLIENT_DEPRECATE_EOF'
8409+ * and 'CLIENT_SESSION_TRACKING' which are required to enable 'session_track_system_variables' in a MySQL session.
8410+ *
8411+ * If the connection lacks the capabilities and ProxySQL configuration is set in 'ENFORCED' mode, it returns the
8412+ * connection to the pool and set a backoff time for the backend server. This backoff time prevents the server from
8413+ * being selected again during connection pooling.
8414+ *
8415+ * @return 'true' if backend connection has required capabilities, otherwise returns 'false'.
8416+ */
8417+ bool MySQL_Session::handle_session_track_capabilities () {
8418+ if (mysql_thread___session_track_variables != session_track_variables::ENFORCED) {
8419+ return true ;
8420+ }
8421+
8422+ // this function should not be called in these states
8423+ if (client_myds == NULL
8424+ || client_myds->myconn == NULL
8425+ || mybe == NULL
8426+ || mybe->server_myds == NULL
8427+ || mybe->server_myds ->myconn == NULL
8428+ || mybe->server_myds ->myconn ->mysql == NULL ) {
8429+ return true ;
8430+ }
8431+
8432+ MySQL_Connection *be_conn = mybe->server_myds ->myconn ;
8433+ unsigned long srv_cap = be_conn->mysql ->server_capabilities ;
8434+ uint32_t client_flag = client_myds->myconn ->options .client_flag ;
8435+
8436+ bool client_support_session_track = ((client_flag & CLIENT_SESSION_TRACKING) != 0 && (client_flag & CLIENT_DEPRECATE_EOF) != 0 );
8437+ bool server_support_session_track = ((srv_cap & CLIENT_SESSION_TRACKING) != 0 && (srv_cap & CLIENT_DEPRECATE_EOF) != 0 );
8438+
8439+ // In fast forward, if client does not support session tracking,
8440+ // then ProxySQL do not have to enforce session track on backend connections
8441+ if ((session_fast_forward == SESSION_FORWARD_TYPE_PERMANENT) && !client_support_session_track) {
8442+ return true ;
8443+ }
8444+
8445+ if (!server_support_session_track) {
8446+ // be_conn->parent->server_backoff_time = thread->curtime + (600 * 1000000); // 10 minutes
8447+ be_conn->parent ->server_backoff_time = thread->curtime + (30 * 1000000 ); // 30 seconds
8448+ if (session_fast_forward) {
8449+ mybe->server_myds ->destroy_MySQL_Connection_From_Pool (false );
8450+ } else {
8451+ mybe->server_myds ->return_MySQL_Connection_To_Pool ();
8452+ }
8453+ return false ;
8454+ }
8455+
8456+ return true ;
8457+ }
0 commit comments