diff --git a/lib/Base_Thread.cpp b/lib/Base_Thread.cpp index 263ac1004f..efd814153a 100644 --- a/lib/Base_Thread.cpp +++ b/lib/Base_Thread.cpp @@ -347,9 +347,19 @@ void Base_Thread::tune_timeout_for_myds_needs_pause(DS * myds) { template void Base_Thread::tune_timeout_for_session_needs_pause(DS * myds) { T* thr = static_cast(this); - if (thr->mypolls.poll_timeout==0 || (myds->sess->pause_until - curtime < thr->mypolls.poll_timeout) ) { - thr->mypolls.poll_timeout= myds->sess->pause_until - curtime; - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 7, "Session=%p , poll_timeout=%u , pause_until=%llu , curtime=%llu\n", myds->sess, thr->mypolls.poll_timeout, myds->sess->pause_until, curtime); + + // Only adjust poll_timeout if the pause is still in the future. If pause_until + // is stale (already <= curtime), computing (pause_until - curtime) as unsigned + // would underflow to ~1.8e19 and corrupt poll_timeout, making poll() fall back + // to the default timeout (~2s) and stalling the worker thread. The stale-pause + // case is handled by check_timing_out_session (AfterPoll) and the handler-entry + // pause checks, so doing nothing here is correct. + if (myds->sess->pause_until > curtime) { + if (thr->mypolls.poll_timeout == 0 || (myds->sess->pause_until - curtime < thr->mypolls.poll_timeout)) { + thr->mypolls.poll_timeout = myds->sess->pause_until - curtime; + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 7, "Session=%p , poll_timeout=%u , pause_until=%llu , curtime=%llu\n", myds->sess, thr->mypolls.poll_timeout, + myds->sess->pause_until, curtime); + } } } diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 892e8b2d7d..b3999aa315 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -3013,6 +3013,7 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { st=previous_status.top(); previous_status.pop(); + pause_until = 0; NEXT_IMMEDIATE_NEW(st); } assert(st==status); @@ -3039,7 +3040,7 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { st=previous_status.top(); previous_status.pop(); myds->wait_until=0; - + pause_until = 0; if (handle_session_track_capabilities() == false) { previous_status.push(st); pause_until = thread->curtime + mysql_thread___connect_retries_delay * 1000; diff --git a/lib/PgSQL_Session.cpp b/lib/PgSQL_Session.cpp index 9ca13a850a..4f32a17c03 100644 --- a/lib/PgSQL_Session.cpp +++ b/lib/PgSQL_Session.cpp @@ -1634,6 +1634,7 @@ bool PgSQL_Session::handler_again___status_CONNECTING_SERVER(int* _rc) { if (mybe->server_myds->myconn->async_state_machine == ASYNC_IDLE) { st = previous_status.top(); previous_status.pop(); + pause_until = 0; NEXT_IMMEDIATE_NEW(st); } assert(st == status); @@ -1671,6 +1672,7 @@ bool PgSQL_Session::handler_again___status_CONNECTING_SERVER(int* _rc) { st = previous_status.top(); previous_status.pop(); myds->wait_until = 0; + pause_until = 0; if (session_fast_forward) { // we have a successful connection and session_fast_forward enabled // set DSS=STATE_SLEEP or it will believe it have to use MARIADB client library