mirror of https://github.com/sysown/proxysql
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
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
|
||||
@ -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…
Reference in new issue