From 9ec045ca74b9a1e67be253fa594ab143b74a0a5e Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Thu, 15 Jan 2026 13:03:18 +0500 Subject: [PATCH] Fix PostgreSQL deadlock with Close Statement flood exceeding threshold_resultset_size Bug Description: ProxySQL would deadlock when processing extended query frames where: 1. Many Close Statement messages accumulate responses in PSarrayOUT 2. Total response size exceeds pgsql-threshold_resultset_size 3. A backend operation (Describe/Execute) follows in the same frame Root Cause: - Close Statement operations are handled locally by ProxySQL (no backend routing) - Their CloseComplete responses accumulate in PSarrayOUT - When threshold_resultset_size is exceeded, ProxySQL stops reading from backend - Subsequent backend operations (Describe/Execute) need backend responses to complete - This creates a deadlock: ProxySQL won't read, backend operation can't complete - Extended query frame never finishes, query times out The Fix: When PSarrayOUT exceeds threshold_resultset_size and a backend operation is pending, ProxySQL now flushes all accumulated data in PSarrayOUT to the client first, then continues processing backend operations. This breaks the deadlock by clearing the buffer before attempting to read more data from the backend. --- lib/PgSQL_Session.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/PgSQL_Session.cpp b/lib/PgSQL_Session.cpp index 919bfd882..33b109a4d 100644 --- a/lib/PgSQL_Session.cpp +++ b/lib/PgSQL_Session.cpp @@ -3094,7 +3094,17 @@ handler_again: if (myconn->query_result && myconn->query_result->get_resultset_size() > (unsigned int)pgsql_thread___threshold_resultset_size) { myconn->query_result->get_resultset(client_myds->PSarrayOUT); } else { - in_pending_state = true; + + if (processing_extended_query && client_myds && mirror == false) { + const unsigned int buffered_data = client_myds->PSarrayOUT->len * PGSQL_RESULTSET_BUFLEN; + if (buffered_data > overflow_safe_multiply<4, unsigned int>(pgsql_thread___threshold_resultset_size)) { + // Don't enter pending state when PSarrayOUT exceeds threshold. This allows ProxySQL + // to flush accumulated data to the client before attempting to read backend responses. + // Prevents deadlock. Issue#5300 + } else { + in_pending_state = true; + } + } } break; // rc==2 : a multi-resultset (or multi statement) was detected, and the current statement is completed