Improve fast forward replication CLIENT_DEPRECATE_EOF validation (closes #5062)#5240
Improve fast forward replication CLIENT_DEPRECATE_EOF validation (closes #5062)#5240renecannao merged 1 commit intov3.0from
Conversation
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.
Summary of ChangesHello @renecannao, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request refines the fast forward replication mechanism by improving the validation of the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request enhances the fast forward replication logic by allowing specific binlog-related commands to bypass the CLIENT_DEPRECATE_EOF flag check. The change correctly identifies these commands by inspecting the packet payload. My review includes a suggestion to refactor the implementation in lib/mysql_connection.cpp to improve readability and maintainability by flattening nested conditions and simplifying pointer casting. Overall, the change is a good improvement for replication compatibility.
| 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<unsigned char*>(static_cast<char*>(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; |
There was a problem hiding this comment.
The logic here can be refactored to improve readability and maintainability.
- The deeply nested
ifstatements form an "arrowhead" structure which can be flattened using guard clauses (early returns). This makes the code easier to follow. - The extraction of the command byte can be simplified and made safer by avoiding
reinterpret_cast. Astatic_casttoconst unsigned char*followed by array indexing is cleaner. - The
retvariable can be eliminated in favor of early returns, which simplifies control flow.
Here is a suggested refactoring:
const bool flags_match = (frontend->options.client_flag & CLIENT_DEPRECATE_EOF) ==
(backend->mysql->server_capabilities & CLIENT_DEPRECATE_EOF);
if (flags_match) {
return true;
}
if (!frontend->myds || !frontend->myds->PSarrayIN || frontend->myds->PSarrayIN->len != 1) {
return false;
}
const PtrSize_t pkt = frontend->myds->PSarrayIN->pdata[0];
if (pkt.size < 5) {
return false;
}
const auto command = static_cast<enum_mysql_command>(static_cast<const unsigned char*>(pkt.ptr)[4]);
switch (command) {
case _MYSQL_COM_BINLOG_DUMP:
case _MYSQL_COM_BINLOG_DUMP_GTID:
case _MYSQL_COM_REGISTER_SLAVE:
return true;
default:
return false;
}
|



Summary
Enhance fast forward replication CLIENT_DEPRECATE_EOF validation to improve compatibility and robustness.
Changes Made
match_ff_req_optionsfunction inlib/mysql_connection.cppTechnical Details
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. Special handling is provided for:
_MYSQL_COM_BINLOG_DUMP_MYSQL_COM_BINLOG_DUMP_GTID_MYSQL_COM_REGISTER_SLAVEThese commands are now allowed even when CLIENT_DEPRECATE_EOF flags don't match, improving compatibility for fast forward replication connections with mixed deprecate EOF configurations.
Test Coverage
This change is complemented by the new test
fast_forward_switch_replication_deprecate_eof.cppwhich validates all combinations of mysql-enable_client_deprecate_eof and mysql-enable_server_deprecate_eof settings.Closes
#5062