Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added warnings handling #4365

Merged
merged 22 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6b29547
Enhanced Warnings handling in ProxySQL:
rahim-kanji Oct 20, 2023
b668021
Added TAP test
rahim-kanji Oct 21, 2023
d2b8f7d
Fixed code style
rahim-kanji Oct 21, 2023
c28f88e
Added delay between query execution
rahim-kanji Oct 23, 2023
30f9897
Changed digest to match_digest
rahim-kanji Oct 23, 2023
0c85c4f
Remove *.so files from tap folder on make clean
rahim-kanji Oct 23, 2023
a47d0ef
Remove old mysql query rule entries
rahim-kanji Oct 23, 2023
b588798
Few fixes
rahim-kanji Oct 31, 2023
1807315
Merge branch 'v2.x_hostgroup_attr_settings' into v2.x_warnings_support
rahim-kanji Nov 2, 2023
743cd50
* Updated variable name from 'mysql-query_cache_with_warnings_support…
rahim-kanji Nov 6, 2023
2706b4e
Updated cluster TAP test
rahim-kanji Nov 6, 2023
8262d60
Merge branch 'v2.x_hostgroup_attr_settings' into v2.x_warnings_support
rahim-kanji Nov 6, 2023
7223ba1
Updated test_mysql_hostgroup_attributes-1-t TAP test
rahim-kanji Nov 6, 2023
05208e2
* Update warning_count as soon as query is executed.
rahim-kanji Nov 7, 2023
dae3d66
* Setting 'warning_count' as soon as query is executed.
rahim-kanji Nov 14, 2023
ffb6676
Merge branch 'v2.x_hostgroup_attr_settings' into v2.x_warnings_support
rahim-kanji Nov 14, 2023
045d6bc
* Execute all test cases with 'CLIENT_DEPRECATE_EOF' both enabled and…
rahim-kanji Nov 16, 2023
e1c489a
* If the backend server has CLIENT_DEPRECATE_EOF enabled, and the cli…
rahim-kanji Nov 20, 2023
581a095
Fixed test_wexecvp_syscall_failures-t compiling
rahim-kanji Nov 24, 2023
f26ea6b
* Overriding some of the mariadb APIs to extract the warning count an…
rahim-kanji Nov 26, 2023
8606742
Merge remote-tracking branch 'Master/v2.x' into v2.x_warning_support_…
rahim-kanji Nov 26, 2023
676c6df
Added README
rahim-kanji Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading