Extract MySQL error classification logic (Phase 3.7, #5495)

New: include/MySQLErrorClassifier.h, lib/MySQLErrorClassifier.cpp

Functions:
- classify_mysql_error(): classifies error codes as retryable (1047
  WSREP, 1053 shutdown) or fatal, checking retry conditions
- can_retry_on_new_connection(): checks if offline server retry is
  possible given connection state (reusable, no txn, no transfer)
pull/5512/head
René Cannaò 2 months ago
parent 1354b798b1
commit 5c227a3bc9

@ -0,0 +1,76 @@
/**
* @file MySQLErrorClassifier.h
* @brief Pure MySQL error classification for retry decisions.
*
* Extracted from MySQL_Session handler_ProcessingQueryError_CheckBackendConnectionStatus()
* and handler_minus1_HandleErrorCodes().
*
* @see Phase 3.7 (GitHub issue #5495)
*/
#ifndef MYSQL_ERROR_CLASSIFIER_H
#define MYSQL_ERROR_CLASSIFIER_H
/**
* @brief Action to take after a MySQL backend query error.
*/
enum MySQLErrorAction {
MYSQL_ERROR_CONTINUE, ///< Error handled, continue processing.
MYSQL_ERROR_RETRY_ON_NEW_CONN, ///< Reconnect and retry on a new server.
MYSQL_ERROR_REPORT_TO_CLIENT ///< Send error to client, no retry.
};
/**
* @brief Classify a MySQL error code to determine retry eligibility.
*
* Mirrors the logic in handler_minus1_HandleErrorCodes():
* - Error 1047 (WSREP not ready): retryable if conditions permit
* - Error 1053 (server shutdown): retryable if conditions permit
* - Other errors: report to client
*
* Retry is only possible when:
* - query_retries_on_failure > 0
* - connection is reusable
* - no active transaction
* - multiplex not disabled
*
* @param error_code MySQL error number.
* @param retries_remaining Number of retries left.
* @param connection_reusable Whether the connection can be reused.
* @param in_active_transaction Whether a transaction is in progress.
* @param multiplex_disabled Whether multiplexing is disabled.
* @return MySQLErrorAction indicating what to do.
*/
MySQLErrorAction classify_mysql_error(
unsigned int error_code,
int retries_remaining,
bool connection_reusable,
bool in_active_transaction,
bool multiplex_disabled
);
/**
* @brief Check if a backend query can be retried on a new connection.
*
* Mirrors handler_ProcessingQueryError_CheckBackendConnectionStatus().
* A retry is possible when the server is offline AND all retry
* conditions are met.
*
* @param server_offline Whether the backend server is offline.
* @param retries_remaining Number of retries left.
* @param connection_reusable Whether the connection can be reused.
* @param in_active_transaction Whether a transaction is in progress.
* @param multiplex_disabled Whether multiplexing is disabled.
* @param transfer_started Whether result transfer has already begun.
* @return true if the query should be retried on a new connection.
*/
bool can_retry_on_new_connection(
bool server_offline,
int retries_remaining,
bool connection_reusable,
bool in_active_transaction,
bool multiplex_disabled,
bool transfer_started
);
#endif // MYSQL_ERROR_CLASSIFIER_H

@ -108,6 +108,7 @@ _OBJ_CXX := ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo
MonitorHealthDecision.oo \
TransactionState.oo \
HostgroupRouting.oo \
MySQLErrorClassifier.oo \
proxy_sqlite3_symbols.oo
# TSDB object files

@ -0,0 +1,66 @@
/**
* @file MySQLErrorClassifier.cpp
* @brief Implementation of MySQL error classification.
*
* @see MySQLErrorClassifier.h
* @see Phase 3.7 (GitHub issue #5495)
*/
#include "MySQLErrorClassifier.h"
MySQLErrorAction classify_mysql_error(
unsigned int error_code,
int retries_remaining,
bool connection_reusable,
bool in_active_transaction,
bool multiplex_disabled)
{
// Check if this error code is retryable
bool retryable_error = false;
switch (error_code) {
case 1047: // ER_UNKNOWN_COM_ERROR (WSREP not ready)
case 1053: // ER_SERVER_SHUTDOWN
retryable_error = true;
break;
default:
break;
}
if (!retryable_error) {
return MYSQL_ERROR_REPORT_TO_CLIENT;
}
// Check retry conditions (mirrors handler_minus1_HandleErrorCodes)
if (retries_remaining > 0
&& connection_reusable
&& !in_active_transaction
&& !multiplex_disabled) {
return MYSQL_ERROR_RETRY_ON_NEW_CONN;
}
return MYSQL_ERROR_REPORT_TO_CLIENT;
}
bool can_retry_on_new_connection(
bool server_offline,
int retries_remaining,
bool connection_reusable,
bool in_active_transaction,
bool multiplex_disabled,
bool transfer_started)
{
if (!server_offline) {
return false; // server is fine, no retry needed
}
// Mirror handler_ProcessingQueryError_CheckBackendConnectionStatus
if (retries_remaining > 0
&& connection_reusable
&& !in_active_transaction
&& !multiplex_disabled
&& !transfer_started) {
return true;
}
return false;
}
Loading…
Cancel
Save