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.
137 lines
4.5 KiB
137 lines
4.5 KiB
#ifndef CLASS_BASE_THREAD_H
|
|
#define CLASS_BASE_THREAD_H
|
|
|
|
#include "proxysql.h"
|
|
|
|
typedef struct _thr_id_username_t {
|
|
uint32_t id;
|
|
char *username;
|
|
} thr_id_usr;
|
|
|
|
typedef struct _kill_queue_t {
|
|
pthread_mutex_t m;
|
|
std::vector<thr_id_usr *> conn_ids;
|
|
std::vector<thr_id_usr *> query_ids;
|
|
} kill_queue_t;
|
|
|
|
/**
|
|
* @class Session_Regex
|
|
* @brief Encapsulates regex operations for session handling.
|
|
*
|
|
* This class is used for matching patterns in SQL queries, specifically for
|
|
* settings like sql_log_bin, sql_mode, and time_zone.
|
|
* See issues #509 , #815 and #816
|
|
*/
|
|
class Session_Regex {
|
|
private:
|
|
void* opt;
|
|
void* re;
|
|
char* s;
|
|
public:
|
|
Session_Regex(const char* p);
|
|
~Session_Regex();
|
|
bool match(const char* m);
|
|
};
|
|
|
|
class MySQL_Thread;
|
|
class PgSQL_Thread;
|
|
|
|
class Base_Thread {
|
|
public:
|
|
#ifdef DEBUG
|
|
// This block is only used for Watchdog unit tests:
|
|
// Specifically for PROXYSQLTEST cases 55 0 and 55 1.
|
|
std::atomic<unsigned int> watchdog_test__simulated_delay_ms {0};
|
|
std::atomic<unsigned int> watchdog_test__missed_heartbeats {0};
|
|
#endif // DEBUG
|
|
|
|
private:
|
|
bool maintenance_loop;
|
|
|
|
// Partition-gate state. note_pool_attempt() bumps the counters from the
|
|
// get_MyConn_from_pool() call site; update_partition_gate() consumes them
|
|
// once per outer process_all_sessions iteration. Single-threaded per worker.
|
|
unsigned int partition_pool_attempts = 0;
|
|
unsigned int partition_pool_nulls = 0;
|
|
unsigned int partition_streak = 0;
|
|
bool partition_active = false;
|
|
|
|
public:
|
|
// Gate thresholds: NULL-ratio (NUM/DEN) classifies a tick as "stressed";
|
|
// STREAK is the number of consecutive disagreeing ticks required to flip
|
|
// the gate state (hysteresis filter against transient bursts).
|
|
static constexpr unsigned int PARTITION_GATE_NULL_RATIO_NUM = 1;
|
|
static constexpr unsigned int PARTITION_GATE_NULL_RATIO_DEN = 20; // 5%
|
|
static constexpr unsigned int PARTITION_GATE_STREAK = 3;
|
|
// Below this attempt count a tick carries no signal: gate state and
|
|
// streak are left untouched. Avoids "2/2 NULL = 100% stressed" noise.
|
|
static constexpr unsigned int PARTITION_GATE_MIN_ATTEMPTS = 4;
|
|
static constexpr unsigned int PARTITION_FAIRNESS_MIN_B = 4;
|
|
|
|
// Called by sessions inside this worker at the get_MyConn_from_pool()
|
|
// call site to feed the gate.
|
|
inline void note_pool_attempt(bool was_null) {
|
|
++partition_pool_attempts;
|
|
if (was_null) ++partition_pool_nulls;
|
|
}
|
|
|
|
// Runs the hysteresis state machine from per-tick counters, resets them,
|
|
// and returns whether the partition pass should run. MUST be called every
|
|
// outer iteration of process_all_sessions (even when the partition path
|
|
// is otherwise skipped) so the counters don't accumulate stale.
|
|
bool update_partition_gate();
|
|
|
|
unsigned long long curtime;
|
|
unsigned long long last_move_to_idle_thread_time;
|
|
bool epoll_thread;
|
|
int shutdown;
|
|
PtrArray *mysql_sessions;
|
|
Session_Regex **match_regexes;
|
|
Base_Thread();
|
|
~Base_Thread();
|
|
template<typename T, typename S>
|
|
S create_new_session_and_client_data_stream(int _fd);
|
|
template<typename T, typename S>
|
|
void register_session(T, S, bool up_start = true);
|
|
template<typename T>
|
|
void check_timing_out_session(unsigned int n);
|
|
template<typename T>
|
|
void check_for_invalid_fd(unsigned int n);
|
|
template<typename S>
|
|
void ProcessAllSessions_Partition();
|
|
template<typename T>
|
|
void ProcessAllMyDS_AfterPoll();
|
|
template<typename T>
|
|
void read_one_byte_from_pipe(unsigned int n);
|
|
template<typename T, typename DS>
|
|
void tune_timeout_for_myds_needs_pause(DS * myds);
|
|
template<typename T, typename DS>
|
|
void tune_timeout_for_session_needs_pause(DS * myds);
|
|
template<typename T, typename DS>
|
|
void configure_pollout(DS * myds, unsigned int n);
|
|
template<typename T, typename DS>
|
|
bool set_backend_to_be_skipped_if_frontend_is_slow(DS * myds, unsigned int n);
|
|
#ifdef IDLE_THREADS
|
|
template<typename T, typename DS> bool move_session_to_idle_mysql_sessions(DS * myds, unsigned int n);
|
|
#endif // IDLE_THREADS
|
|
template<typename T, typename S> unsigned int find_session_idx_in_mysql_sessions(S * sess);
|
|
template<typename T> void ProcessAllMyDS_BeforePoll();
|
|
template<typename T, typename S> void run_SetAllSession_ToProcess0();
|
|
|
|
|
|
#if ENABLE_TIMER
|
|
// for now this is not accessible via Admin/Prometheus , thus useful only with gdb
|
|
struct {
|
|
TimerCount Sessions_Handlers;
|
|
TimerCount Connections_Handlers;
|
|
} Timers;
|
|
#endif // ENABLE_TIMER
|
|
|
|
friend class MySQL_Thread;
|
|
friend class PgSQL_Thread;
|
|
};
|
|
|
|
std::string proxysql_session_type_str(enum proxysql_session_type session_type);
|
|
|
|
#endif // CLASS_BASE_THREAD_H
|