From 5485bb02f46975389785cbe9daf3654bfb89d912 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Fri, 5 Dec 2025 22:15:13 +0000 Subject: [PATCH] Improve fast forward replication CLIENT_DEPRECATE_EOF validation Enhance the match_ff_req_options function to better handle CLIENT_DEPRECATE_EOF flag validation in fast forward replication scenarios. The function now performs a more robust check by examining the actual MySQL command type when the initial CLIENT_DEPRECATE_EOF flags don't match between frontend and backend connections. Key improvements: - Special handling for binlog-related commands (_MYSQL_COM_BINLOG_DUMP, _MYSQL_COM_BINLOG_DUMP_GTID, _MYSQL_COM_REGISTER_SLAVE) that should be allowed even when CLIENT_DEPRECATE_EOF flags don't match - Proper packet parsing to extract and validate MySQL command types - Enhanced compatibility for fast forward replication connections with mixed deprecate EOF configurations This change ensures that ProxySQL can handle more complex replication scenarios while maintaining proper protocol validation. --- lib/mysql_connection.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 0e5367edf..6c8531575 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -738,8 +738,29 @@ bool MySQL_Connection::match_ff_req_options(const MySQL_Connection *c) { // Only required to be checked for fast_forward sessions if (frontend->myds && frontend->myds->sess->session_fast_forward) { - return (frontend->options.client_flag & CLIENT_DEPRECATE_EOF) == + bool ret = (frontend->options.client_flag & CLIENT_DEPRECATE_EOF) == (backend->mysql->server_capabilities & CLIENT_DEPRECATE_EOF); + if (ret == false) { + if (frontend->myds && frontend->myds->PSarrayIN) { + PtrSizeArray * PSarrayIN = frontend->myds->PSarrayIN; + if (PSarrayIN->len == 1) { + PtrSize_t pkt = PSarrayIN->pdata[0]; + if (pkt.size >= 5) { + unsigned char c = *reinterpret_cast(static_cast(pkt.ptr) + 4); + switch ((enum_mysql_command)c) { + case _MYSQL_COM_BINLOG_DUMP: + case _MYSQL_COM_BINLOG_DUMP_GTID: + case _MYSQL_COM_REGISTER_SLAVE: + ret = true; + break; + default: + break; + }; + } + } + } + } + return ret; } else { return true; }