Skip to content

Commit

Permalink
Merge pull request #4365 from sysown/v2.x_warning_support
Browse files Browse the repository at this point in the history
Added warnings handling
  • Loading branch information
renecannao authored Dec 8, 2023
2 parents 4b99077 + 676c6df commit 1e98de7
Show file tree
Hide file tree
Showing 23 changed files with 1,075 additions and 49 deletions.
4 changes: 3 additions & 1 deletion deps/mariadb-client-library/client_deprecate_eof.patch
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ index 0aaaf1a..229023b 100644
{
/* allocate space for rows */
if (!(current= (MYSQL_ROWS *)ma_alloc_root(&result->alloc, sizeof(MYSQL_ROWS) + packet_len)))
@@ -276,10 +284,14 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
@@ -276,10 +284,16 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
{
*pprevious= 0;
/* sace status info */
Expand All @@ -664,6 +664,8 @@ index 0aaaf1a..229023b 100644
+
+ if (stmt->mysql->server_capabilities & CLIENT_DEPRECATE_EOF && !is_data_packet) {
+ ma_read_ok_packet(stmt->mysql, p + 1, packet_len);
+ stmt->upsert_status.warning_count= stmt->mysql->warning_count;
+ stmt->upsert_status.server_status= stmt->mysql->server_status;
+ } else {
+ stmt->upsert_status.warning_count= stmt->mysql->warning_count= uint2korr(p + 1);
+ stmt->upsert_status.server_status= stmt->mysql->server_status= uint2korr(p + 3);
Expand Down
5 changes: 5 additions & 0 deletions include/MySQL_HostGroups_Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ class MyHGC { // MySQL Host Group Container
uint32_t throttle_connections_per_sec;
int8_t autocommit;
int8_t free_connections_pct;
int8_t handle_warnings;
bool multiplex;
bool connection_warming;
bool configured; // this variable controls if attributes are configured or not. If not configured, they do not apply
Expand All @@ -249,6 +250,10 @@ class MyHGC { // MySQL Host Group Container
int32_t use_ssl;
} servers_defaults;
void reset_attributes();
inline
bool handle_warnings_enabled() const {
return attributes.configured == true && attributes.handle_warnings != -1 ? attributes.handle_warnings : mysql_thread___handle_warnings;
}
MyHGC(int);
~MyHGC();
MySrvC *get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid, int max_lag_ms, MySQL_Session *sess);
Expand Down
2 changes: 1 addition & 1 deletion include/MySQL_Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class MySQL_ResultSet {
unsigned int add_row(MYSQL_ROWS *rows);
unsigned int add_row(MYSQL_ROW row);
unsigned int add_row2(MYSQL_ROWS *row, unsigned char *offset);
void add_eof();
void add_eof(bool suppress_warning_count=false);
void remove_last_eof();
void add_err(MySQL_Data_Stream *_myds);
bool get_resultset(PtrSizeArray *PSarrayFinal);
Expand Down
12 changes: 10 additions & 2 deletions include/MySQL_Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ enum proxysql_session_type {
PROXYSQL_SESSION_NONE
};

enum ps_type : uint8_t {
ps_type_not_set = 0x0,
ps_type_prepare_stmt = 0x1,
ps_type_execute_stmt = 0x2
};

std::string proxysql_session_type_str(enum proxysql_session_type session_type);

// these structs will be used for various regex hardcoded
Expand Down Expand Up @@ -121,7 +127,7 @@ class MySQL_Session
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_SET_OPTION(PtrSize_t *);
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_STATISTICS(PtrSize_t *);
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *);
bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_qpo(PtrSize_t *, bool *lock_hostgroup, bool ps=false);
bool handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_qpo(PtrSize_t *, bool *lock_hostgroup, ps_type prepare_stmt_type=ps_type_not_set);

void handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED__get_connection();

Expand Down Expand Up @@ -274,6 +280,7 @@ class MySQL_Session
int to_process;
int pending_connect;
enum proxysql_session_type session_type;
int warning_in_hg;

// bool
bool autocommit;
Expand Down Expand Up @@ -334,7 +341,7 @@ class MySQL_Session
MySQL_Backend * find_or_create_backend(int, MySQL_Data_Stream *_myds=NULL);

void SQLite3_to_MySQL(SQLite3_result *, char *, int , MySQL_Protocol *, bool in_transaction=false, bool deprecate_eof_active=false);
void MySQL_Result_to_MySQL_wire(MYSQL *mysql, MySQL_ResultSet *MyRS, MySQL_Data_Stream *_myds=NULL);
void MySQL_Result_to_MySQL_wire(MYSQL *mysql, MySQL_ResultSet *MyRS, unsigned int warning_count, MySQL_Data_Stream *_myds=NULL);
void MySQL_Stmt_Result_to_MySQL_wire(MYSQL_STMT *stmt, MySQL_Connection *myconn);
unsigned int NumActiveTransactions(bool check_savpoint=false);
bool HasOfflineBackends();
Expand Down Expand Up @@ -379,6 +386,7 @@ class MySQL_Session
bool has_any_backend();
void detected_broken_connection(const char *file, unsigned int line, const char *func, const char *action, MySQL_Connection *myconn, int myerr, const char *message, bool verbose=false);
void generate_status_one_hostgroup(int hid, std::string& s);
void reset_warning_hostgroup_flag_and_release_connection();
friend void SQLite3_Server_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt);
};

Expand Down
2 changes: 2 additions & 0 deletions include/MySQL_Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ class MySQL_Threads_Handler
char * ssl_p2s_crlpath;
int query_cache_size_MB;
int query_cache_soft_ttl_pct;
int query_cache_handle_warnings;
int min_num_servers_lantency_awareness;
int aurora_max_lag_ms_only_read_from_replicas;
bool stats_time_backend_query;
Expand All @@ -593,6 +594,7 @@ class MySQL_Threads_Handler
bool enable_load_data_local_infile;
bool log_mysql_warnings_enabled;
int data_packets_history_size;
int handle_warnings;
} variables;
struct {
unsigned int mirror_sessions_current;
Expand Down
4 changes: 4 additions & 0 deletions include/mysql_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ using json = nlohmann::json;
#define STATUS_MYSQL_CONNECTION_FOUND_ROWS 0x00000200
#define STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG 0x00000400
#define STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT 0x00000800
#define STATUS_MYSQL_CONNECTION_HAS_WARNINGS 0x00001000

class Variable {
public:
Expand Down Expand Up @@ -53,6 +54,8 @@ class MySQL_Connection_userinfo {

class MySQL_Connection {
private:
void update_warning_count_from_connection();
void update_warning_count_from_statement();
bool is_expired(unsigned long long timeout);
unsigned long long inserted_into_pool;
public:
Expand Down Expand Up @@ -128,6 +131,7 @@ class MySQL_Connection {
} statuses;

unsigned long largest_query_length;
unsigned int warning_count;
/**
* @brief This represents the internal knowledge of ProxySQL about the connection. It keeps track of those
* states which *are not reflected* into 'server_status', but are relevant for connection handling.
Expand Down
4 changes: 4 additions & 0 deletions include/proxysql_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,10 +865,12 @@ __thread bool mysql_thread___log_mysql_warnings_enabled;
__thread bool mysql_thread___enable_load_data_local_infile;
__thread int mysql_thread___client_host_cache_size;
__thread int mysql_thread___client_host_error_counts;
__thread int mysql_thread___handle_warnings;

/* variables used for Query Cache */
__thread int mysql_thread___query_cache_size_MB;
__thread int mysql_thread___query_cache_soft_ttl_pct;
__thread int mysql_thread___query_cache_handle_warnings;

/* variables used for SSL , from proxy to server (p2s) */
__thread char * mysql_thread___ssl_p2s_ca;
Expand Down Expand Up @@ -1032,10 +1034,12 @@ extern __thread bool mysql_thread___log_mysql_warnings_enabled;
extern __thread bool mysql_thread___enable_load_data_local_infile;
extern __thread int mysql_thread___client_host_cache_size;
extern __thread int mysql_thread___client_host_error_counts;
extern __thread int mysql_thread___handle_warnings;

/* variables used for Query Cache */
extern __thread int mysql_thread___query_cache_size_MB;
extern __thread int mysql_thread___query_cache_soft_ttl_pct;
extern __thread int mysql_thread___query_cache_handle_warnings;

/* variables used for SSL , from proxy to server (p2s) */
extern __thread char * mysql_thread___ssl_p2s_ca;
Expand Down
9 changes: 7 additions & 2 deletions lib/MySQL_HostGroups_Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ void MyHGC::reset_attributes() {
attributes.throttle_connections_per_sec = 1000000;
attributes.autocommit = -1;
attributes.free_connections_pct = 10;
attributes.handle_warnings = -1;
attributes.multiplex = true;
attributes.connection_warming = false;
free(attributes.init_connect);
Expand Down Expand Up @@ -6931,7 +6932,8 @@ T j_get_srv_default_int_val(
/**
* @brief Initializes the supplied 'MyHGC' with the specified 'hostgroup_settings'.
* @details Input verification is performed in the supplied 'hostgroup_settings'. It's expected to be a valid
* JSON.
* JSON that may contain the following fields:
* - handle_warnings: Value must be >= 0.
*
* In case input verification fails for a field, supplied 'MyHGC' is NOT updated for that field. An error
* message is logged specifying the source of the error.
Expand All @@ -6945,7 +6947,10 @@ void init_myhgc_hostgroup_settings(const char* hostgroup_settings, MyHGC* myhgc)
if (hostgroup_settings[0] != '\0') {
try {
nlohmann::json j = nlohmann::json::parse(hostgroup_settings);
// fields to be populated

const auto handle_warnings_check = [](int8_t handle_warnings) -> bool { return handle_warnings == 0 || handle_warnings == 1; };
int8_t handle_warnings = j_get_srv_default_int_val<int8_t>(j, hid, "handle_warnings", handle_warnings_check);
myhgc->attributes.handle_warnings = handle_warnings;
}
catch (const json::exception& e) {
proxy_error(
Expand Down
18 changes: 13 additions & 5 deletions lib/MySQL_Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2726,7 +2726,9 @@ void MySQL_ResultSet::init(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my,
// up to 2.2.0 we used to add an EOF here.
// due to bug #3547 we move the logic into add_eof() that can now handle also prepared statements
PROXY_TRACE2();
add_eof();
// if the backend server has CLIENT_DEPRECATE_EOF enabled, and the client does not support
// CLIENT_DEPRECATE_EOF, warning_count will be excluded from the intermediate EOF packet
add_eof((mysql->server_capabilities & CLIENT_DEPRECATE_EOF));
}
}

Expand Down Expand Up @@ -2990,7 +2992,7 @@ unsigned int MySQL_ResultSet::add_row2(MYSQL_ROWS *row, unsigned char *offset) {
return length;
}

void MySQL_ResultSet::add_eof() {
void MySQL_ResultSet::add_eof(bool suppress_warning_count) {
if (myprot) {
unsigned int nTrx=myds->sess->NumActiveTransactions();
uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0 );
Expand All @@ -3001,11 +3003,17 @@ void MySQL_ResultSet::add_eof() {
//PSarrayOUT->add(pkt.ptr,pkt.size);
//sid++;
//resultset_size+=pkt.size;


// Note: warnings count will only be sent to the client if mysql-query_digests is enabled
const MySQL_Backend* _mybe = myds->sess->mybe;
const MySQL_Data_Stream* _server_myds = (_mybe && _mybe->server_myds) ? _mybe->server_myds : nullptr;
const MySQL_Connection* _myconn = (_server_myds && _server_myds->myds_type == MYDS_BACKEND && _server_myds->myconn) ?
_server_myds->myconn : nullptr;
const unsigned int warning_count = (_myconn && suppress_warning_count == false) ? _myconn->warning_count : 0;
if (deprecate_eof_active) {
PtrSize_t pkt;
buffer_to_PSarrayOut();
myprot->generate_pkt_OK(false, &pkt.ptr, &pkt.size, sid, 0, 0, setStatus, 0, NULL, true);
myprot->generate_pkt_OK(false, &pkt.ptr, &pkt.size, sid, 0, 0, setStatus, warning_count, NULL, true);
PSarrayOUT.add(pkt.ptr, pkt.size);
resultset_size += pkt.size;
}
Expand All @@ -3015,7 +3023,7 @@ void MySQL_ResultSet::add_eof() {
// note that EOF is added on a packet on its own, instead of using a buffer,
// so that can be removed using remove_last_eof()
buffer_to_PSarrayOut();
myprot->generate_pkt_EOF(false, NULL, NULL, sid, 0, setStatus, this);
myprot->generate_pkt_EOF(false, NULL, NULL, sid, warning_count, setStatus, this);
resultset_size += 9;
buffer_to_PSarrayOut();
}
Expand Down
Loading

0 comments on commit 1e98de7

Please sign in to comment.