mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
9.4 KiB
278 lines
9.4 KiB
#ifndef __CLASS_MYSQL_CONNECTION_H
|
|
#define __CLASS_MYSQL_CONNECTION_H
|
|
|
|
#include "proxysql.h"
|
|
#include "cpp.h"
|
|
|
|
//#include "../deps/json/json.hpp"
|
|
//using json = nlohmann::json;
|
|
|
|
#ifndef PROXYJSON
|
|
#define PROXYJSON
|
|
#include "../deps/json/json_fwd.hpp"
|
|
#endif // PROXYJSON
|
|
|
|
//#define STATUS_MYSQL_CONNECTION_TRANSACTION 0x00000001 // DEPRECATED
|
|
#define STATUS_MYSQL_CONNECTION_COMPRESSION 0x00000002
|
|
#define STATUS_MYSQL_CONNECTION_USER_VARIABLE 0x00000004
|
|
#define STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT 0x00000008
|
|
#define STATUS_MYSQL_CONNECTION_LOCK_TABLES 0x00000010
|
|
#define STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE 0x00000020
|
|
#define STATUS_MYSQL_CONNECTION_GET_LOCK 0x00000040
|
|
#define STATUS_MYSQL_CONNECTION_NO_MULTIPLEX 0x00000080
|
|
#define STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0 0x00000100
|
|
#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 MySQLServers_SslParams;
|
|
|
|
class Variable {
|
|
public:
|
|
char *value = (char*)"";
|
|
void fill_server_internal_session(nlohmann::json &j, int idx);
|
|
void fill_client_internal_session(nlohmann::json &j, int idx);
|
|
};
|
|
|
|
enum charset_action {
|
|
UNKNOWN,
|
|
NAMES,
|
|
CHARSET,
|
|
CONNECT_START
|
|
};
|
|
|
|
class MySQL_Connection_userinfo {
|
|
private:
|
|
uint64_t compute_hash();
|
|
public:
|
|
uint64_t hash;
|
|
char *username;
|
|
char *password;
|
|
PASSWORD_TYPE::E passtype;
|
|
char *schemaname;
|
|
char *sha1_pass;
|
|
char *fe_username;
|
|
MySQL_Connection_userinfo();
|
|
~MySQL_Connection_userinfo();
|
|
void set(char *, char *, char *, char *);
|
|
void set(MySQL_Connection_userinfo *);
|
|
bool set_schemaname(char *, int);
|
|
};
|
|
|
|
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;
|
|
void connect_start_SetAttributes();
|
|
void connect_start_SetCharset();
|
|
void connect_start_SetClientFlag(unsigned long&);
|
|
char * connect_start_DNS_lookup();
|
|
void connect_start_SetSslSettings();
|
|
void ProcessQueryAndSetStatusFlags_Warnings(char *);
|
|
void ProcessQueryAndSetStatusFlags_UserVariables(char *, int);
|
|
void ProcessQueryAndSetStatusFlags_Savepoint(char *);
|
|
void ProcessQueryAndSetStatusFlags_SetBackslashEscapes();
|
|
public:
|
|
struct {
|
|
char *server_version;
|
|
uint32_t session_track_gtids_int;
|
|
uint32_t max_allowed_pkt;
|
|
uint32_t server_capabilities;
|
|
uint32_t client_flag;
|
|
unsigned int compression_min_length;
|
|
char *init_connect;
|
|
bool init_connect_sent;
|
|
char * session_track_gtids;
|
|
char *ldap_user_variable;
|
|
char *ldap_user_variable_value;
|
|
bool session_track_gtids_sent;
|
|
bool ldap_user_variable_sent;
|
|
uint8_t protocol_version;
|
|
int8_t last_set_autocommit;
|
|
bool autocommit;
|
|
bool no_backslash_escapes;
|
|
} options;
|
|
|
|
Variable variables[SQL_NAME_LAST_HIGH_WM];
|
|
uint32_t var_hash[SQL_NAME_LAST_HIGH_WM];
|
|
// for now we store possibly missing variables in the lower range
|
|
// we may need to fix that, but this will cost performance
|
|
bool var_absent[SQL_NAME_LAST_HIGH_WM] = {false};
|
|
|
|
std::vector<uint32_t> dynamic_variables_idx;
|
|
unsigned int reorder_dynamic_variables_idx();
|
|
|
|
struct {
|
|
unsigned long length;
|
|
char *ptr;
|
|
MYSQL_STMT *stmt;
|
|
MYSQL_RES *stmt_result;
|
|
stmt_execute_metadata_t *stmt_meta;
|
|
} query;
|
|
char scramble_buff[40];
|
|
unsigned long long creation_time;
|
|
unsigned long long last_time_used;
|
|
unsigned long long timeout;
|
|
int auto_increment_delay_token;
|
|
int fd;
|
|
MySQL_STMTs_local_v14 *local_stmts; // local view of prepared statements
|
|
MYSQL *mysql;
|
|
MYSQL *ret_mysql;
|
|
MYSQL_RES *mysql_result;
|
|
MYSQL_ROW mysql_row;
|
|
MySQL_ResultSet *MyRS;
|
|
MySQL_ResultSet *MyRS_reuse;
|
|
MySrvC *parent;
|
|
MySQL_Connection_userinfo *userinfo;
|
|
MySQL_Data_Stream *myds;
|
|
|
|
struct {
|
|
char* hostname;
|
|
char* ip;
|
|
} connected_host_details;
|
|
/**
|
|
* @brief Keeps tracks of the 'server_status'. Do not confuse with the 'server_status' from the
|
|
* 'MYSQL' connection itself. This flag keeps track of the configured server status from the
|
|
* parent 'MySrvC'.
|
|
*/
|
|
enum MySerStatus server_status; // this to solve a side effect of #774
|
|
|
|
bytes_stats_t bytes_info; // bytes statistics
|
|
struct {
|
|
unsigned long long questions;
|
|
unsigned long long myconnpoll_get;
|
|
unsigned long long myconnpoll_put;
|
|
} 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.
|
|
*/
|
|
uint32_t status_flags;
|
|
int async_exit_status; // exit status of MariaDB Client Library Non blocking API
|
|
int interr; // integer return
|
|
MDB_ASYNC_ST async_state_machine; // Async state machine
|
|
short wait_events;
|
|
uint8_t compression_pkt_id;
|
|
my_bool ret_bool;
|
|
bool async_fetch_row_start;
|
|
bool send_quit;
|
|
bool reusable;
|
|
bool processing_multi_statement;
|
|
bool multiplex_delayed;
|
|
bool unknown_transaction_status;
|
|
void compute_unknown_transaction_status();
|
|
char gtid_uuid[128];
|
|
|
|
MySQLServers_SslParams * ssl_params = NULL;
|
|
|
|
MySQL_Connection();
|
|
~MySQL_Connection();
|
|
bool set_autocommit(bool);
|
|
bool set_no_backslash_escapes(bool);
|
|
unsigned int set_charset(unsigned int, enum charset_action);
|
|
|
|
void set_status(bool set, uint32_t status_flag);
|
|
void set_status_sql_log_bin0(bool);
|
|
bool get_status(uint32_t status_flag);
|
|
bool get_status_sql_log_bin0();
|
|
void connect_start();
|
|
void connect_cont(short event);
|
|
void change_user_start();
|
|
void change_user_cont(short event);
|
|
void ping_start();
|
|
void ping_cont(short event);
|
|
void set_autocommit_start();
|
|
void set_autocommit_cont(short event);
|
|
void set_names_start();
|
|
void set_names_cont(short event);
|
|
void real_query_start();
|
|
void real_query_cont(short event);
|
|
#ifndef PROXYSQL_USE_RESULT
|
|
void store_result_start();
|
|
void store_result_cont(short event);
|
|
#endif // PROXYSQL_USE_RESULT
|
|
void initdb_start();
|
|
void initdb_cont(short event);
|
|
void set_option_start();
|
|
void set_option_cont(short event);
|
|
void set_query(char *stmt, unsigned long length);
|
|
MDB_ASYNC_ST handler(short event);
|
|
void next_event(MDB_ASYNC_ST new_st);
|
|
|
|
int async_connect(short event);
|
|
int async_change_user(short event);
|
|
int async_select_db(short event);
|
|
int async_set_autocommit(short event, bool);
|
|
int async_set_names(short event, unsigned int nr);
|
|
int async_send_simple_command(short event, char *stmt, unsigned long length); // no result set expected
|
|
int async_query(short event, char *stmt, unsigned long length, MYSQL_STMT **_stmt=NULL, stmt_execute_metadata_t *_stmt_meta=NULL);
|
|
int async_ping(short event);
|
|
int async_set_option(short event, bool mask);
|
|
|
|
void stmt_prepare_start();
|
|
void stmt_prepare_cont(short event);
|
|
void stmt_execute_start();
|
|
void stmt_execute_cont(short event);
|
|
void stmt_execute_store_result_start();
|
|
void stmt_execute_store_result_cont(short event);
|
|
|
|
/**
|
|
* @brief Process the rows returned by 'async_stmt_execute_store_result'. Extracts all the received
|
|
* rows from 'query.stmt->result.data' but the last one, adds them to 'MyRS', frees the buffer
|
|
* used by 'query.stmt' and allocates a new one with the last row, leaving it ready for being filled
|
|
* with the new rows to be received.
|
|
* @param processed_bytes Reference to the already processed bytes to be updated with the rows
|
|
* that are being read and added to 'MyRS'.
|
|
*/
|
|
void process_rows_in_ASYNC_STMT_EXECUTE_STORE_RESULT_CONT(unsigned long long& processed_bytes);
|
|
|
|
void async_free_result();
|
|
/**
|
|
* @brief Returns if the connection is **for sure**, known to be in an active transaction.
|
|
* @details The function considers two things:
|
|
* 1. If 'server_status' is flagged with 'SERVER_STATUS_IN_TRANS'.
|
|
* 2. If the connection has 'autcommit=0' and 'autocommit_false_is_transaction' is set.
|
|
* @return True if the connection is known to be in a transaction, or equivalent state.
|
|
*/
|
|
bool IsKnownActiveTransaction();
|
|
/**
|
|
* @brief Returns if the connection is in a **potential transaction**.
|
|
* @details This function is a more strict version of 'IsKnownActiveTransaction', which also considers
|
|
* connections which holds 'unknown_transaction_status' as potentially active transactions.
|
|
* @return True if the connection is in potentially in an active transaction.
|
|
*/
|
|
bool IsActiveTransaction();
|
|
bool IsServerOffline();
|
|
bool IsAutoCommit();
|
|
bool AutocommitFalse_AndSavepoint();
|
|
bool MultiplexDisabled(bool check_delay_token = true);
|
|
bool IsKeepMultiplexEnabledVariables(char *query_digest_text);
|
|
void ProcessQueryAndSetStatusFlags(char *query_digest_text);
|
|
void optimize();
|
|
void close_mysql();
|
|
|
|
void set_is_client(); // used for local_stmts
|
|
|
|
void reset();
|
|
|
|
bool get_gtid(char *buff, uint64_t *trx_id);
|
|
void reduce_auto_increment_delay_token() { if (auto_increment_delay_token) auto_increment_delay_token--; };
|
|
|
|
bool match_ff_req_options(const MySQL_Connection *c);
|
|
bool match_tracked_options(const MySQL_Connection *c);
|
|
bool requires_CHANGE_USER(const MySQL_Connection *client_conn);
|
|
unsigned int number_of_matching_session_variables(const MySQL_Connection *client_conn, unsigned int& not_matching);
|
|
unsigned long get_mysql_thread_id() { return mysql ? mysql->thread_id : 0; }
|
|
static void set_ssl_params(MYSQL *mysql, MySQLServers_SslParams *ssl_params);
|
|
|
|
void get_mysql_info_json(nlohmann::json&);
|
|
void get_backend_conn_info_json(nlohmann::json&);
|
|
};
|
|
#endif /* __CLASS_MYSQL_CONNECTION_H */
|