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.
1708 lines
64 KiB
1708 lines
64 KiB
#ifndef __CLASS_PGSQL_THREAD_H
|
|
#define __CLASS_PGSQL_THREAD_H
|
|
#define ____CLASS_STANDARD_PGSQL_THREAD_H
|
|
#include <prometheus/counter.h>
|
|
#include <prometheus/gauge.h>
|
|
|
|
#include "proxysql.h"
|
|
#include "proxysql_admin.h"
|
|
|
|
#include "Base_Thread.h"
|
|
#include "ProxySQL_Poll.h"
|
|
#include "PgSQL_Variables.h"
|
|
#ifdef IDLE_THREADS
|
|
#include <sys/epoll.h>
|
|
#endif // IDLE_THREADS
|
|
#include <atomic>
|
|
|
|
#include "prometheus_helpers.h"
|
|
|
|
#include "PgSQL_Set_Stmt_Parser.h"
|
|
|
|
enum class AUTHENTICATION_METHOD {
|
|
NO_PASSWORD,
|
|
CLEAR_TEXT_PASSWORD,
|
|
MD5_PASSWORD,
|
|
SASL_SCRAM_SHA_256,
|
|
SASL_SCRAM_SHA_256_PLUS
|
|
};
|
|
|
|
constexpr const char* AUTHENTICATION_METHOD_STR[] = {
|
|
"NO_PASSWORD",
|
|
"CLEAR_TEXT_PASSWORD",
|
|
"MD5_PASSWORD",
|
|
"SASL_SCRAM_SHA_256",
|
|
"SASL_SCRAM_SHA_256_PLUS"
|
|
};
|
|
|
|
/*
|
|
#define MIN_POLL_LEN 8
|
|
#define MIN_POLL_DELETE_RATIO 8
|
|
#define MY_EPOLL_THREAD_MAXEVENTS 128
|
|
*/
|
|
|
|
#define ADMIN_HOSTGROUP -2
|
|
#define STATS_HOSTGROUP -3
|
|
#define SQLITE_HOSTGROUP -4
|
|
|
|
|
|
#define MYSQL_DEFAULT_COLLATION_CONNECTION ""
|
|
#define MYSQL_DEFAULT_NET_WRITE_TIMEOUT "60"
|
|
#define MYSQL_DEFAULT_MAX_JOIN_SIZE "18446744073709551615"
|
|
|
|
extern class PgSQL_Variables pgsql_variables;
|
|
|
|
#ifdef IDLE_THREADS
|
|
typedef struct __attribute__((aligned(64))) _pgsql_conn_exchange_t {
|
|
pthread_mutex_t mutex_idles;
|
|
PtrArray* idle_mysql_sessions;
|
|
pthread_mutex_t mutex_resumes;
|
|
PtrArray* resume_mysql_sessions;
|
|
} pgsql_conn_exchange_t;
|
|
#endif // IDLE_THREADS
|
|
|
|
typedef struct PgSQL_Session_Interrupt {
|
|
uint32_t thread_id; // Target session
|
|
uint32_t secret_key; // Auth via shared secret (authentication)
|
|
std::unique_ptr<char, decltype(&free)> username; // Auth via user identity (authorization)
|
|
|
|
// Constructor for key
|
|
PgSQL_Session_Interrupt(uint32_t tid, uint32_t key)
|
|
: thread_id(tid), secret_key(key), username(nullptr, &free) {
|
|
}
|
|
|
|
// Constructor for username
|
|
PgSQL_Session_Interrupt(uint32_t tid, const char* user)
|
|
: thread_id(tid), secret_key(0), username((user ? strdup(user) : nullptr), &free) {
|
|
}
|
|
} PgSQL_Session_Interrupt_t;
|
|
|
|
typedef struct PgSQL_Session_Interrupt_Queue_t {
|
|
pthread_mutex_t m;
|
|
std::vector<PgSQL_Session_Interrupt_t> conn_ids;
|
|
std::vector<PgSQL_Session_Interrupt_t> query_ids;
|
|
} PgSQL_Session_Interrupt_Queue_t;
|
|
|
|
enum PgSQL_Thread_status_variable {
|
|
/*st_var_backend_stmt_prepare,
|
|
st_var_backend_stmt_execute,
|
|
st_var_backend_stmt_close,
|
|
st_var_frontend_stmt_prepare,
|
|
st_var_frontend_stmt_describe,
|
|
st_var_frontend_stmt_execute,
|
|
st_var_frontend_stmt_close,
|
|
st_var_queries,
|
|
st_var_queries_slow,
|
|
st_var_queries_gtid,
|
|
st_var_queries_with_max_lag_ms,
|
|
st_var_queries_with_max_lag_ms__delayed,
|
|
st_var_queries_with_max_lag_ms__total_wait_time_us,
|
|
st_var_queries_backends_bytes_sent,
|
|
st_var_queries_backends_bytes_recv,
|
|
st_var_queries_frontends_bytes_sent,
|
|
st_var_queries_frontends_bytes_recv,
|
|
st_var_query_processor_time,
|
|
st_var_backend_query_time,
|
|
st_var_mysql_backend_buffers_bytes,
|
|
st_var_mysql_frontend_buffers_bytes,
|
|
st_var_mysql_session_internal_bytes,
|
|
st_var_ConnPool_get_conn_immediate,
|
|
st_var_ConnPool_get_conn_success,
|
|
st_var_ConnPool_get_conn_failure,
|
|
st_var_ConnPool_get_conn_latency_awareness,
|
|
st_var_gtid_binlog_collected,
|
|
st_var_gtid_session_collected,
|
|
st_var_generated_pkt_err,
|
|
st_var_max_connect_timeout_err,
|
|
st_var_backend_lagging_during_query,
|
|
st_var_backend_offline_during_query,
|
|
st_var_unexpected_com_quit,
|
|
st_var_unexpected_packet,
|
|
st_var_killed_connections,
|
|
st_var_killed_queries,
|
|
st_var_hostgroup_locked,
|
|
st_var_hostgroup_locked_set_cmds,
|
|
st_var_hostgroup_locked_queries,
|
|
st_var_aws_aurora_replicas_skipped_during_query,
|
|
st_var_automatic_detected_sqli,
|
|
st_var_mysql_whitelisted_sqli_fingerprint,
|
|
st_var_client_host_error_killed_connections,
|
|
*/
|
|
PG_st_var_END = 42 // to avoid ASAN complaining. TO FIX
|
|
};
|
|
|
|
|
|
struct CopyCmdMatcher {
|
|
re2::RE2::Options options;
|
|
re2::RE2 pattern;
|
|
|
|
CopyCmdMatcher() :
|
|
options(RE2::Quiet),
|
|
pattern(
|
|
R"(((?is)(?:--.*?$|/\*[\s\S]*?\*/|\s)*\bCOPY\b\s+[^;]*?\bFROM\b\s+(?:STDIN|STDOUT)\b(?:\s+WITH\s*\([^)]*\))?))",
|
|
options) {
|
|
//((?is)(?:--.*?$|/\*[\s\S]*?\*/|\s)*\bCOPY\b\s+[^;]*?\bFROM\b\s+STDIN\b(?:\s+WITH\s*\([^)]*\))?)
|
|
}
|
|
|
|
inline
|
|
bool match(const char* query, re2::StringPiece* matched = nullptr) const {
|
|
return re2::RE2::PartialMatch(query, pattern, matched);
|
|
}
|
|
};
|
|
|
|
class __attribute__((aligned(64))) PgSQL_Thread : public Base_Thread
|
|
{
|
|
private:
|
|
unsigned int servers_table_version_previous;
|
|
unsigned int servers_table_version_current;
|
|
unsigned long long last_processing_idles;
|
|
PgSQL_Connection** my_idle_conns;
|
|
bool processing_idles;
|
|
//bool maintenance_loop;
|
|
|
|
PtrArray* cached_connections;
|
|
|
|
#ifdef IDLE_THREADS
|
|
struct epoll_event events[MY_EPOLL_THREAD_MAXEVENTS];
|
|
int efd;
|
|
unsigned int mysess_idx;
|
|
std::map<unsigned int, unsigned int> sessmap;
|
|
#endif // IDLE_THREADS
|
|
|
|
//Session_Regex** match_regexes;
|
|
|
|
#ifdef IDLE_THREADS
|
|
void worker_thread_assigns_sessions_to_idle_thread(PgSQL_Thread * thr);
|
|
void worker_thread_gets_sessions_from_idle_thread();
|
|
void idle_thread_gets_sessions_from_worker_thread();
|
|
void idle_thread_assigns_sessions_to_worker_thread(PgSQL_Thread * thr);
|
|
void idle_thread_check_if_worker_thread_has_unprocess_resumed_sessions_and_signal_it(PgSQL_Thread * thr);
|
|
void idle_thread_prepares_session_to_send_to_worker_thread(int i);
|
|
void idle_thread_to_kill_idle_sessions();
|
|
//bool move_session_to_idle_mysql_sessions(PgSQL_Data_Stream * myds, unsigned int n);
|
|
#endif // IDLE_THREADS
|
|
|
|
//unsigned int find_session_idx_in_mysql_sessions(PgSQL_Session * sess);
|
|
//bool set_backend_to_be_skipped_if_frontend_is_slow(PgSQL_Data_Stream * myds, unsigned int n);
|
|
void handle_mirror_queue_mysql_sessions();
|
|
|
|
/**
|
|
* @brief Processes kill requests from the thread's kill queues.
|
|
*
|
|
* @details This function checks the thread's kill queues (`sess_intrpt_queue.conn_ids` and `sess_intrpt_queue.query_ids`)
|
|
* for any pending kill requests. If there are any requests, it calls `Scan_Sessions_to_Kill_All()`
|
|
* to iterate through all session arrays across all threads and identify sessions that match
|
|
* the kill requests. The `killed` flag is set to true for matching sessions. After processing
|
|
* all kill requests, the kill queues are cleared.
|
|
*
|
|
* @note This function is called within the `run()` function during a maintenance loop to
|
|
* process kill requests for connections and queries. It ensures that sessions matching
|
|
* kill requests are terminated.
|
|
*
|
|
*/
|
|
void handle_kill_queues();
|
|
|
|
//void check_timing_out_session(unsigned int n);
|
|
//void check_for_invalid_fd(unsigned int n);
|
|
//void read_one_byte_from_pipe(unsigned int n);
|
|
//void tune_timeout_for_myds_needs_pause(PgSQL_Data_Stream * myds);
|
|
//void tune_timeout_for_session_needs_pause(PgSQL_Data_Stream * myds);
|
|
//void configure_pollout(PgSQL_Data_Stream * myds, unsigned int n);
|
|
|
|
protected:
|
|
int nfds;
|
|
|
|
public:
|
|
|
|
void* gen_args; // this is a generic pointer to create any sort of structure
|
|
|
|
ProxySQL_Poll<PgSQL_Data_Stream> mypolls;
|
|
pthread_t thread_id;
|
|
unsigned long long pre_poll_time;
|
|
unsigned long long last_maintenance_time;
|
|
//unsigned long long last_move_to_idle_thread_time;
|
|
std::atomic<unsigned long long> atomic_curtime;
|
|
//PtrArray* mysql_sessions;
|
|
PtrArray* mirror_queue_mysql_sessions;
|
|
PtrArray* mirror_queue_mysql_sessions_cache;
|
|
#ifdef IDLE_THREADS
|
|
PtrArray* idle_mysql_sessions;
|
|
PtrArray* resume_mysql_sessions;
|
|
CopyCmdMatcher *copy_cmd_matcher;
|
|
pgsql_conn_exchange_t myexchange;
|
|
#endif // IDLE_THREADS
|
|
|
|
int pipefd[2];
|
|
PgSQL_Session_Interrupt_Queue_t sess_intrpt_queue;
|
|
|
|
//bool epoll_thread;
|
|
bool poll_timeout_bool;
|
|
|
|
// status variables are per thread only
|
|
// in this way, there is no need for atomic operation and there is no cache miss
|
|
// when it is needed a total, all threads are checked
|
|
struct {
|
|
unsigned long long stvar[PG_st_var_END];
|
|
unsigned int active_transactions;
|
|
} status_variables;
|
|
|
|
struct {
|
|
int min_num_servers_lantency_awareness;
|
|
int aurora_max_lag_ms_only_read_from_replicas;
|
|
bool stats_time_backend_query;
|
|
bool stats_time_query_processor;
|
|
bool query_cache_stores_empty_result;
|
|
} variables;
|
|
|
|
pthread_mutex_t thread_mutex;
|
|
|
|
// if set_parser_algorithm == 2 , a single thr_SetParser is used
|
|
PgSQL_Set_Stmt_Parser *thr_SetParser;
|
|
|
|
/**
|
|
* @brief Default constructor for the PgSQL_Thread class.
|
|
*
|
|
* @details This constructor initializes various members of the PgSQL_Thread object to their
|
|
* default values. It sets up mutexes, initializes status variables, and sets up the thread's
|
|
* variables. It also sets the thread's `shutdown` flag to `false`, indicating that the thread
|
|
* is not yet in a shutdown state.
|
|
*
|
|
* @note This constructor is called when a new PgSQL_Thread object is created.
|
|
*/
|
|
PgSQL_Thread();
|
|
|
|
/**
|
|
* @brief Destructor for the PgSQL_Thread class.
|
|
*
|
|
* @details This destructor cleans up the PgSQL_Thread object, releasing resources and
|
|
* freeing allocated memory. It deletes session objects, frees cached connections, and
|
|
* destroys mutexes. It also ensures that the thread's `shutdown` flag is set to `true`
|
|
* to indicate that the thread is no longer active.
|
|
*
|
|
* @note This destructor is called automatically when the PgSQL_Thread object goes out of
|
|
* scope or is explicitly deleted.
|
|
*/
|
|
~PgSQL_Thread();
|
|
|
|
// PgSQL_Session* create_new_session_and_client_data_stream(int _fd);
|
|
|
|
/**
|
|
* @brief Initializes the PgSQL_Thread object.
|
|
*
|
|
* @return `true` if initialization is successful, `false` otherwise.
|
|
*
|
|
* @details This function performs the initial setup for the PgSQL_Thread object. It allocates
|
|
* memory for various data structures, initializes mutexes, creates a pipe for communication,
|
|
* and configures the thread's variables. It also sets up regular expressions for parsing
|
|
* certain SQL statements, such as `SET` commands.
|
|
*
|
|
* @note This function is called once during the thread's lifetime to prepare it for
|
|
* handling connections and processing queries.
|
|
*
|
|
*/
|
|
bool init();
|
|
|
|
/**
|
|
* @brief Retrieves multiple idle connections from the global connection pool.
|
|
*
|
|
* @param num_idles A reference to an integer variable that will hold the number of idle connections retrieved.
|
|
*
|
|
* @details This function requests multiple idle connections from the global connection pool (`PgHGM`)
|
|
* and stores them in the `my_idle_conns` array. It then creates new sessions for each retrieved
|
|
* connection, attaches the connection to the session's backend data stream, and registers the
|
|
* session as a connection handler. It also sets the connection's status to `PINGING_SERVER`
|
|
* and initiates the pinging process.
|
|
*
|
|
* @note This function is called within the `run()` function to acquire idle connections
|
|
* from the global pool and prepare them for use by the thread.
|
|
*
|
|
*/
|
|
void run___get_multiple_idle_connections(int& num_idles);
|
|
|
|
/**
|
|
* @brief Cleans up the mirror queue to manage concurrency.
|
|
*
|
|
* @details This function ensures that the number of mirror sessions in the `mirror_queue_mysql_sessions_cache`
|
|
* array does not exceed the maximum concurrency limit (`pgsql_thread___mirror_max_concurrency`).
|
|
* It removes sessions from the cache if the limit is exceeded.
|
|
*
|
|
* @note This function is called within the `run()` function during a maintenance loop to
|
|
* control the concurrency of mirror sessions.
|
|
*
|
|
*/
|
|
void run___cleanup_mirror_queue();
|
|
|
|
//void ProcessAllMyDS_BeforePoll();
|
|
//void ProcessAllMyDS_AfterPoll();
|
|
|
|
/**
|
|
* @brief The main loop for the PgSQL_Thread object.
|
|
*
|
|
* @details This function implements the main loop for the thread. It handles events, processes
|
|
* sessions, manages connections, and performs maintenance tasks. It continuously monitors
|
|
* the `shutdown` flag and exits the loop when it is set to true. The loop includes various
|
|
* steps such as:
|
|
*
|
|
* - Acquiring idle connections from the global pool.
|
|
* - Processing the mirror queue for completed mirror sessions.
|
|
* - Calling `ProcessAllMyDS_BeforePoll()` and `ProcessAllMyDS_AfterPoll()` functions to
|
|
* handle data stream events before and after the `poll()` call.
|
|
* - Adding and removing listeners to the polling loop.
|
|
* - Calling `poll()` to wait for events on sockets.
|
|
* - Processing all sessions using the `process_all_sessions()` function.
|
|
* - Returning unused connections to the global pool.
|
|
* - Refreshing the thread's variables.
|
|
* - Handling kill requests for connections or queries.
|
|
*
|
|
* @note This function is the entry point for the thread's execution. It is responsible for
|
|
* managing all aspects of the thread's lifecycle, including handling connections, processing
|
|
* queries, and performing maintenance tasks.
|
|
*
|
|
*/
|
|
void run();
|
|
|
|
/**
|
|
* @brief Adds a new listener socket to the polling loop.
|
|
*
|
|
* @param sock The file descriptor of the listener socket.
|
|
*
|
|
* @details This function creates a new `PgSQL_Data_Stream` object for the listener socket,
|
|
* sets its type to `MYDS_LISTENER`, and adds it to the `mypolls` array for monitoring.
|
|
*
|
|
* @note This function is called by the `run()` function when a new listener socket
|
|
* is added to the thread's monitoring list.
|
|
*
|
|
*/
|
|
void poll_listener_add(int sock);
|
|
|
|
/**
|
|
* @brief Removes a listener socket from the polling loop.
|
|
*
|
|
* @param sock The file descriptor of the listener socket to remove.
|
|
*
|
|
* @details This function finds the listener socket in the `mypolls` array based on its file
|
|
* descriptor and removes it from the array. It then deletes the associated `PgSQL_Data_Stream`
|
|
* object.
|
|
*
|
|
* @note This function is called by the `run()` function when a listener socket is
|
|
* removed from the thread's monitoring list.
|
|
*
|
|
*/
|
|
void poll_listener_del(int sock);
|
|
|
|
//void register_session(PgSQL_Session*, bool up_start = true);
|
|
|
|
/**
|
|
* @brief Unregisters a session from the thread's session array.
|
|
*
|
|
* @param idx The index of the session to unregister.
|
|
*
|
|
* @details This function removes a session from the `mysql_sessions` array at the specified index.
|
|
* It does not delete the session object itself; it is assumed that the caller will handle
|
|
* the deletion.
|
|
*
|
|
* @note This function is called by various parts of the code when a session is no longer
|
|
* active and needs to be removed from the thread's session list.
|
|
*
|
|
*/
|
|
void unregister_session(int);
|
|
|
|
/**
|
|
* @brief Returns a pointer to the `pollfd` structure for a specific data stream.
|
|
*
|
|
* @param i The index of the data stream in the `mypolls` array.
|
|
*
|
|
* @return A pointer to the `pollfd` structure for the specified data stream.
|
|
*
|
|
* @details This function provides access to the `pollfd` structure for a particular data
|
|
* stream in the `mypolls` array. This structure is used by the `poll()` function to
|
|
* monitor events on the associated socket.
|
|
*
|
|
* @note This function is used internally by the thread to obtain references to the
|
|
* `pollfd` structures for data streams when interacting with the `poll()` function.
|
|
*
|
|
*/
|
|
struct pollfd* get_pollfd(unsigned int i);
|
|
|
|
/**
|
|
* @brief Processes data on a specific data stream.
|
|
*
|
|
* @param myds A pointer to the `PgSQL_Data_Stream` object to process.
|
|
* @param n The index of the data stream in the `mypolls` array.
|
|
*
|
|
* @return `true` if processing is successful, `false` if the session should be removed.
|
|
*
|
|
* @details This function handles data events on a specific data stream. It checks for events
|
|
* such as `POLLIN`, `POLLOUT`, `POLLERR`, and `POLLHUP`. Based on the events, it reads data
|
|
* from the network, processes packets, and updates the session's status. It also handles
|
|
* timeout events and connection failures.
|
|
*
|
|
* @note This function is called by the `run()` function after the `poll()` call to process
|
|
* events on each data stream. It is responsible for managing data flow and updating
|
|
* session states.
|
|
*
|
|
*/
|
|
bool process_data_on_data_stream(PgSQL_Data_Stream * myds, unsigned int n);
|
|
|
|
//void ProcessAllSessions_SortingSessions();
|
|
|
|
/**
|
|
* @brief Processes a completed mirror session and manages its resources.
|
|
*
|
|
* @param n The index of the session in the `mysql_sessions` array.
|
|
* @param sess A pointer to the `PgSQL_Session` object representing the completed mirror session.
|
|
*
|
|
* @details This function handles the completion of a mirror session. It removes the completed
|
|
* session from the `mysql_sessions` array and decrements the `n` index to reflect the removal.
|
|
* It then checks if the `mirror_queue_mysql_sessions_cache` array is below a certain length
|
|
* (determined by `pgsql_thread___mirror_max_concurrency` and a scaling factor).
|
|
* If the cache is not full, the session is added to the cache, otherwise, it is deleted.
|
|
*
|
|
* @note This function is called within the `process_all_sessions()` function when a mirror
|
|
* session reaches the `WAITING_CLIENT_DATA` status, indicating completion.
|
|
*
|
|
*/
|
|
void ProcessAllSessions_CompletedMirrorSession(unsigned int& n, PgSQL_Session * sess);
|
|
|
|
/**
|
|
* @brief Performs maintenance tasks on a session during a maintenance loop.
|
|
*
|
|
* @param sess A pointer to the `PgSQL_Session` object to be maintained.
|
|
* @param sess_time The idle time of the session in milliseconds.
|
|
* @param total_active_transactions_ A reference to the total number of active transactions across all threads.
|
|
*
|
|
* @details This function performs various maintenance checks on a session during a maintenance
|
|
* loop. It checks for idle transactions, inactive sessions, and expired connections. It also
|
|
* handles situations where the server's table version has changed and ensures that sessions
|
|
* using offline nodes are terminated.
|
|
*
|
|
* @note This function is called within the `process_all_sessions()` function during a
|
|
* maintenance loop. It is responsible for ensuring that sessions are properly managed and
|
|
* that resources are released when necessary.
|
|
*
|
|
*/
|
|
void ProcessAllSessions_MaintenanceLoop(PgSQL_Session * sess, unsigned long long sess_time, unsigned int& total_active_transactions_);
|
|
|
|
/**
|
|
* @brief Processes all active sessions associated with the current thread.
|
|
*
|
|
* @details This function iterates through all sessions in the `mysql_sessions` array. For each
|
|
* session, it performs the following actions:
|
|
*
|
|
* - Checks for completed mirror sessions and calls `ProcessAllSessions_CompletedMirrorSession()`
|
|
* if necessary.
|
|
* - If a maintenance loop is active, it calls `ProcessAllSessions_MaintenanceLoop()` to
|
|
* perform maintenance tasks on the session.
|
|
* - If the session is healthy and needs processing, it calls the session's `handler()`
|
|
* function to handle session logic.
|
|
* - If the session is unhealthy, it closes the connection and removes the session from the
|
|
* `mysql_sessions` array.
|
|
*
|
|
* @note This function is called within the `run()` function of the `PgSQL_Thread` class. It
|
|
* is the core function responsible for managing and processing all active sessions associated
|
|
* with the thread.
|
|
*
|
|
*/
|
|
void process_all_sessions();
|
|
|
|
/**
|
|
* @brief Refreshes the thread's variables from the global variables handler.
|
|
*
|
|
* @details This function updates the thread's variables with the latest values from the
|
|
* global variables handler (`GloPTH`) to ensure consistency. It retrieves all relevant
|
|
* variables from the global handler and updates the corresponding variables in the
|
|
* thread's local scope.
|
|
*
|
|
* @note This function is called periodically by `PgSQL_Thread::run()` to ensure that
|
|
* the thread's variables are synchronized with the global variables handler.
|
|
*
|
|
*/
|
|
void refresh_variables();
|
|
|
|
/**
|
|
* @brief Registers a session as a connection handler.
|
|
*
|
|
* @param _sess A pointer to the `PgSQL_Session` object to register.
|
|
* @param _new A boolean flag indicating whether the session is newly created (true) or not (false).
|
|
*
|
|
* @details This function marks a session as a connection handler, adding it to the
|
|
* `mysql_sessions` array. It sets the session's `thread` pointer to the current thread
|
|
* and sets the `connections_handler` flag to true.
|
|
*
|
|
* @note This function is used to track sessions that are responsible for handling
|
|
* connections.
|
|
*
|
|
*/
|
|
void register_session_connection_handler(PgSQL_Session * _sess, bool _new = false);
|
|
|
|
/**
|
|
* @brief Unregisters a session as a connection handler.
|
|
*
|
|
* @param idx The index of the session in the `mysql_sessions` array.
|
|
* @param _new A boolean flag indicating whether the session is newly created (true) or not (false).
|
|
*
|
|
* @details This function removes a session from the `mysql_sessions` array, effectively
|
|
* unregistering it as a connection handler.
|
|
*
|
|
* @note This function is typically called when a session is no longer active or needs to be
|
|
* removed from the connection handler list.
|
|
*
|
|
*/
|
|
void unregister_session_connection_handler(int idx, bool _new = false);
|
|
|
|
/**
|
|
* @brief Handles a new connection accepted by a listener.
|
|
*
|
|
* @param myds A pointer to the `PgSQL_Data_Stream` object representing the new connection.
|
|
* @param n The index of the listener in the `mypolls` array.
|
|
*
|
|
* @details This function handles the acceptance of a new connection from a listener. It
|
|
* accepts the connection using `accept()`, performs some sanity checks, and then creates
|
|
* a new `PgSQL_Session` object to manage the connection. It configures the session's
|
|
* data stream, adds the connection to the `mypolls` array, and sets the connection's
|
|
* state to `CONNECTING_CLIENT`.
|
|
*
|
|
* @note This function is called within the `run()` function of the `PgSQL_Thread` class
|
|
* when a new connection is accepted by a listener. It is responsible for initializing
|
|
* the session and adding the connection to the polling loop.
|
|
*
|
|
*/
|
|
void listener_handle_new_connection(PgSQL_Data_Stream * myds, unsigned int n);
|
|
|
|
/**
|
|
* @brief Calculates and updates the memory statistics for the current thread.
|
|
*
|
|
* @details This function iterates through all sessions associated with the current
|
|
* thread and gathers memory usage information from each session. It updates
|
|
* the `status_variables` structure with the calculated memory statistics,
|
|
* including the following:
|
|
*
|
|
* - `st_var_mysql_backend_buffers_bytes`: Total bytes used for backend
|
|
* connection buffers when fast forwarding is enabled.
|
|
* - `st_var_mysql_frontend_buffers_bytes`: Total bytes used for frontend
|
|
* connection buffers (read/write buffers and other queues).
|
|
* - `st_var_mysql_session_internal_bytes`: Total bytes used for internal
|
|
* session data structures.
|
|
*
|
|
* @note This function is called by `SQL3_GlobalStatus()` when the `_memory`
|
|
* flag is set to true.
|
|
*
|
|
*/
|
|
void Get_Memory_Stats();
|
|
|
|
/**
|
|
* @brief Retrieves a local connection from the thread's cached connection pool.
|
|
*
|
|
* @param _hid The hostgroup ID to search for connections in.
|
|
* @param sess The current session requesting the connection.
|
|
* @param gtid_uuid The UUID of the GTID to consider (if applicable).
|
|
* @param gtid_trxid The transaction ID of the GTID to consider (if applicable).
|
|
* @param max_lag_ms The maximum replication lag allowed for the connection (if applicable).
|
|
*
|
|
* @return A pointer to a `PgSQL_Connection` object if a suitable connection is found,
|
|
* `NULL` otherwise.
|
|
*
|
|
* @details This function attempts to find a suitable connection in the thread's
|
|
* cached connection pool (`cached_connections`). It checks for matching hostgroup
|
|
* ID, connection options, GTID (if provided), and maximum replication lag (if
|
|
* provided). If a matching connection is found, it is removed from the cache and
|
|
* returned.
|
|
*
|
|
* @note This function is used by `PgSQL_Session::handler()` to obtain a
|
|
* connection from the local cache before resorting to the global connection pool.
|
|
*
|
|
*/
|
|
PgSQL_Connection* get_MyConn_local(unsigned int, PgSQL_Session * sess, char* gtid_uuid, uint64_t gtid_trxid, int max_lag_ms);
|
|
|
|
/**
|
|
* @brief Adds a connection to the thread's local connection cache.
|
|
*
|
|
* @param c The `PgSQL_Connection` object to add to the cache.
|
|
*
|
|
* @details This function checks the status of the connection's parent server
|
|
* (`c->parent->status`) and the connection's asynchronous state machine
|
|
* (`c->async_state_machine`). If the server is online and the connection is idle,
|
|
* the connection is added to the `cached_connections` pool. Otherwise, the
|
|
* connection is pushed to the global connection pool using
|
|
* `PgHGM->push_MyConn_to_pool()`.
|
|
*
|
|
* @note This function is used to manage the thread's local connection cache.
|
|
*
|
|
*/
|
|
void push_MyConn_local(PgSQL_Connection*);
|
|
|
|
/**
|
|
* @brief Returns all connections in the thread's local cache to the global pool.
|
|
*
|
|
* @details This function iterates through the `cached_connections` pool and
|
|
* pushes each connection to the global connection pool using
|
|
* `PgHGM->push_MyConn_to_pool_array()`. After pushing the connections, the
|
|
* local cache is cleared.
|
|
*
|
|
* @note This function is called periodically by `PgSQL_Thread::run()` to
|
|
* ensure that unused connections are returned to the global pool.
|
|
*
|
|
*/
|
|
void return_local_connections();
|
|
|
|
/**
|
|
* Pseudocode (plan)
|
|
* - For each pending connection-termination request (conn_ids):
|
|
* - If request.thread_id != sess.thread_session_id: continue.
|
|
* - If request.username is present AND session has a connected frontend user:
|
|
* - If request.username == session.frontend_user:
|
|
* - Log info, mark session as killed.
|
|
* - Erase the processed request from the queue.
|
|
* - Break (at most one matching request per session).
|
|
* - Return sess->killed (true if this function marked it or it was already marked).
|
|
*/
|
|
|
|
/**
|
|
* @brief Handle session termination requests targeting the given session.
|
|
*
|
|
* @details
|
|
* Scans the provided connection-termination queue for a request matching the
|
|
* specified session. If a matching request is found and the request carries a
|
|
* username that matches the authenticated frontend user of the session, the
|
|
* session is marked for termination (sess->killed = true)
|
|
*
|
|
* @param sess The session potentially targeted for termination.
|
|
* @return true if the session is (now) marked as killed, false otherwise.
|
|
*/
|
|
bool Scan_Sessions_to_Kill___handle_session_termination(PgSQL_Session* sess);
|
|
|
|
/**
|
|
* - Iterate over query_ids:
|
|
* - If request.thread_id != sess->thread_session_id: continue
|
|
* - Determine authorization method:
|
|
* - If request.username is null: authenticate via secret_key == sess->cancel_secret_key
|
|
* - Else: authorize via username == session frontend user
|
|
* - If authorized and session has a backend server_myds:
|
|
* - Log the request
|
|
* - Set server_myds->wait_until = curtime to wake processing loop
|
|
* - Set server_myds->kill_type = 1 to request backend cancellation
|
|
* - Mark canceled_query = true
|
|
* - Erase the processed request from query_ids
|
|
* - Break (process at most one request per call)
|
|
* - Return canceled_query
|
|
*/
|
|
|
|
/**
|
|
* @brief Handle query cancellation requests for the given session.
|
|
*
|
|
* @param sess Target session that may have a running query to cancel.
|
|
* @return true if a cancellation was scheduled for this session; false otherwise.
|
|
*/
|
|
bool Scan_Sessions_to_Kill___handle_query_cancellation(PgSQL_Session* sess);
|
|
|
|
/**
|
|
* @brief Iterates through a session array to identify and kill sessions.
|
|
*
|
|
* @param mysess A pointer to the `PtrArray` containing the sessions to scan.
|
|
*
|
|
* @details This function iterates through the specified session array and checks
|
|
* each session against the thread's kill queues (`sess_intrpt_queue.conn_ids` and
|
|
* `sess_intrpt_queue.query_ids`). If a session matches a kill request, its `killed` flag is set
|
|
* to true. The kill queues are then updated to remove the processed kill
|
|
* requests.
|
|
*
|
|
* @note This function is called by `Scan_Sessions_to_Kill_All()` to kill
|
|
* sessions based on kill requests.
|
|
*
|
|
*/
|
|
void Scan_Sessions_to_Kill(PtrArray * mysess);
|
|
|
|
/**
|
|
* @brief Scans all session arrays across all threads to identify and kill sessions.
|
|
*
|
|
* @details This function iterates through all session arrays across different threads, including main worker threads and idle threads.
|
|
* It calls `Scan_Sessions_to_Kill()` for each session array to check for kill requests.
|
|
* The kill queues (`sess_intrpt_queue.conn_ids` and `sess_intrpt_queue.query_ids`) are cleared after processing all kill requests.
|
|
*
|
|
* @note This function is called by `PgSQL_Threads_Handler::kill_connection_or_query()` to kill sessions based on kill requests.
|
|
*
|
|
*/
|
|
void Scan_Sessions_to_Kill_All();
|
|
};
|
|
|
|
|
|
typedef PgSQL_Thread* create_PgSQL_Thread_t();
|
|
typedef void destroy_PgSQL_Thread_t(PgSQL_Thread*);
|
|
|
|
class PgSQL_Listeners_Manager {
|
|
private:
|
|
PtrArray* ifaces;
|
|
public:
|
|
PgSQL_Listeners_Manager();
|
|
~PgSQL_Listeners_Manager();
|
|
int add(const char* iface, unsigned int num_threads, int** perthrsocks);
|
|
int find_idx(const char* iface);
|
|
int find_idx(const char* address, int port);
|
|
iface_info* find_iface_from_fd(int fd);
|
|
int get_fd(unsigned int idx);
|
|
void del(unsigned int idx);
|
|
};
|
|
|
|
/*struct p_th_counter {
|
|
enum metric {
|
|
queries_backends_bytes_sent = 0,
|
|
queries_backends_bytes_recv,
|
|
queries_frontends_bytes_sent,
|
|
queries_frontends_bytes_recv,
|
|
query_processor_time_nsec,
|
|
backend_query_time_nsec,
|
|
com_backend_stmt_prepare,
|
|
com_backend_stmt_execute,
|
|
com_backend_stmt_close,
|
|
com_frontend_stmt_prepare,
|
|
com_frontend_stmt_execute,
|
|
com_frontend_stmt_close,
|
|
questions,
|
|
slow_queries,
|
|
gtid_consistent_queries,
|
|
gtid_session_collected,
|
|
connpool_get_conn_latency_awareness,
|
|
connpool_get_conn_immediate,
|
|
connpool_get_conn_success,
|
|
connpool_get_conn_failure,
|
|
generated_error_packets,
|
|
max_connect_timeouts,
|
|
backend_lagging_during_query,
|
|
backend_offline_during_query,
|
|
queries_with_max_lag_ms,
|
|
queries_with_max_lag_ms__delayed,
|
|
queries_with_max_lag_ms__total_wait_time_us,
|
|
mysql_unexpected_frontend_com_quit,
|
|
hostgroup_locked_set_cmds,
|
|
hostgroup_locked_queries,
|
|
mysql_unexpected_frontend_packets,
|
|
aws_aurora_replicas_skipped_during_query,
|
|
automatic_detected_sql_injection,
|
|
mysql_whitelisted_sqli_fingerprint,
|
|
mysql_killed_backend_connections,
|
|
mysql_killed_backend_queries,
|
|
client_host_error_killed_connections,
|
|
__size
|
|
};
|
|
};
|
|
|
|
struct p_th_gauge {
|
|
enum metric {
|
|
active_transactions = 0,
|
|
client_connections_non_idle,
|
|
client_connections_hostgroup_locked,
|
|
mysql_backend_buffers_bytes,
|
|
mysql_frontend_buffers_bytes,
|
|
mysql_session_internal_bytes,
|
|
mirror_concurrency,
|
|
mirror_queue_lengths,
|
|
mysql_thread_workers,
|
|
// global_variables
|
|
mysql_wait_timeout,
|
|
mysql_max_connections,
|
|
mysql_monitor_enabled,
|
|
mysql_monitor_ping_interval,
|
|
mysql_monitor_ping_timeout,
|
|
mysql_monitor_ping_max_failures,
|
|
mysql_monitor_aws_rds_topology_discovery_interval,
|
|
mysql_monitor_read_only_interval,
|
|
mysql_monitor_read_only_timeout,
|
|
mysql_monitor_writer_is_also_reader,
|
|
mysql_monitor_replication_lag_group_by_host,
|
|
mysql_monitor_replication_lag_interval,
|
|
mysql_monitor_replication_lag_timeout,
|
|
mysql_monitor_history,
|
|
__size
|
|
};
|
|
};
|
|
|
|
struct th_metrics_map_idx {
|
|
enum index {
|
|
counters = 0,
|
|
gauges
|
|
};
|
|
};
|
|
*/
|
|
/**
|
|
* @brief Structure holding the data for a Client_Host_Cache entry.
|
|
*/
|
|
typedef struct _PgSQL_Client_Host_Cache_Entry {
|
|
/**
|
|
* @brief Last time the entry was updated.
|
|
*/
|
|
uint64_t updated_at;
|
|
/**
|
|
* @brief Error count associated with the entry.
|
|
*/
|
|
uint32_t error_count;
|
|
} PgSQL_Client_Host_Cache_Entry;
|
|
|
|
class PgSQL_Threads_Handler
|
|
{
|
|
private:
|
|
int shutdown_;
|
|
size_t stacksize;
|
|
pthread_attr_t attr;
|
|
pthread_rwlock_t rwlock;
|
|
PtrArray* bind_fds;
|
|
PgSQL_Listeners_Manager* MLM;
|
|
// VariablesPointers_int stores:
|
|
// key: variable name
|
|
// tuple:
|
|
// variable address
|
|
// min value
|
|
// max value
|
|
// special variable : if true, min and max values are ignored, and further input validation is required
|
|
std::unordered_map<std::string, std::tuple<int*, int, int, bool>> VariablesPointers_int;
|
|
// VariablesPointers_bool stores:
|
|
// key: variable name
|
|
// tuple:
|
|
// variable address
|
|
// special variable : if true, further input validation is required
|
|
std::unordered_map<std::string, std::tuple<bool*, bool>> VariablesPointers_bool;
|
|
/**
|
|
* @brief Holds the clients host cache. It keeps track of the number of
|
|
* errors associated to a specific client:
|
|
* - Key: client identifier, based on 'clientaddr'.
|
|
* - Value: Structure of type 'PgSQL_Client_Host_Cache_Entry' holding
|
|
* the last time the entry was updated and the error count associated
|
|
* with the client.
|
|
*/
|
|
std::unordered_map<std::string, PgSQL_Client_Host_Cache_Entry> client_host_cache;
|
|
/**
|
|
* @brief Holds the mutex for accessing 'client_host_cache', since every
|
|
* access can potentially perform 'read/write' operations, a regular mutex
|
|
* is enough.
|
|
*/
|
|
pthread_mutex_t mutex_client_host_cache;
|
|
|
|
public:
|
|
struct {
|
|
int authentication_method;
|
|
int monitor_history;
|
|
int monitor_connect_interval;
|
|
int monitor_connect_interval_window;
|
|
int monitor_connect_timeout;
|
|
//! Monitor ping interval. Unit: 'ms'.
|
|
int monitor_ping_interval;
|
|
int monitor_ping_interval_window;
|
|
int monitor_ping_max_failures;
|
|
//! Monitor ping timeout. Unit: 'ms'.
|
|
int monitor_ping_timeout;
|
|
//! Monitor aws rds topology discovery interval. Unit: 'one discovery check per X monitor_read_only checks'.
|
|
int monitor_aws_rds_topology_discovery_interval;
|
|
//! Monitor read only timeout. Unit: 'ms'.
|
|
int monitor_read_only_interval;
|
|
int monitor_read_only_interval_window;
|
|
//! Monitor read only timeout. Unit: 'ms'.
|
|
int monitor_read_only_timeout;
|
|
int monitor_read_only_max_timeout_count;
|
|
bool monitor_enabled;
|
|
//! ProxySQL session wait timeout. Unit: 'ms'.
|
|
bool monitor_wait_timeout;
|
|
bool monitor_writer_is_also_reader;
|
|
bool monitor_replication_lag_group_by_host;
|
|
//! How frequently a replication lag check is performed. Unit: 'ms'.
|
|
int monitor_replication_lag_interval;
|
|
//! Read only check timeout. Unit: 'ms'.
|
|
int monitor_replication_lag_timeout;
|
|
int monitor_replication_lag_count;
|
|
/* TODO: Remove
|
|
int monitor_groupreplication_healthcheck_interval;
|
|
int monitor_groupreplication_healthcheck_timeout;
|
|
int monitor_groupreplication_healthcheck_max_timeout_count;
|
|
int monitor_groupreplication_max_transactions_behind_count;
|
|
int monitor_groupreplication_max_transactions_behind_for_read_only;
|
|
int monitor_galera_healthcheck_interval;
|
|
int monitor_galera_healthcheck_timeout;
|
|
int monitor_galera_healthcheck_max_timeout_count;
|
|
int monitor_query_interval;
|
|
int monitor_query_timeout;
|
|
int monitor_slave_lag_when_null;
|
|
*/
|
|
int monitor_threads;
|
|
/* TODO: Remove
|
|
int monitor_threads_min;
|
|
int monitor_threads_max;
|
|
int monitor_threads_queue_maxsize;
|
|
*/
|
|
int monitor_local_dns_cache_ttl;
|
|
int monitor_local_dns_cache_refresh_interval;
|
|
int monitor_local_dns_resolver_queue_maxsize;
|
|
char* monitor_username;
|
|
char* monitor_password;
|
|
char* monitor_dbname;
|
|
char* monitor_replication_lag_use_percona_heartbeat;
|
|
int ping_interval_server_msec;
|
|
int ping_timeout_server;
|
|
int shun_on_failures;
|
|
int shun_recovery_time_sec;
|
|
int unshun_algorithm;
|
|
int query_retries_on_failure;
|
|
bool connection_warming;
|
|
int client_host_cache_size;
|
|
int client_host_error_counts;
|
|
int connect_retries_on_failure;
|
|
int connect_retries_delay;
|
|
int connection_delay_multiplex_ms;
|
|
int connection_max_age_ms;
|
|
int connect_timeout_client;
|
|
int connect_timeout_server;
|
|
int connect_timeout_server_max;
|
|
int free_connections_pct;
|
|
#ifdef IDLE_THREADS
|
|
int session_idle_ms;
|
|
#endif // IDLE_THREADS
|
|
bool sessions_sort;
|
|
char* default_schema;
|
|
char* interfaces;
|
|
char* keep_multiplexing_variables;
|
|
//unsigned int default_charset; // removed in 2.0.13 . Obsoleted previously using PgSQL_Variables instead
|
|
int handle_unknown_charset;
|
|
bool servers_stats;
|
|
bool commands_stats;
|
|
bool query_digests;
|
|
bool query_digests_lowercase;
|
|
bool query_digests_replace_null;
|
|
bool query_digests_no_digits;
|
|
bool query_digests_normalize_digest_text;
|
|
bool query_digests_track_hostname;
|
|
bool query_digests_keep_comment;
|
|
int query_digests_grouping_limit;
|
|
int query_digests_groups_grouping_limit;
|
|
bool parse_failure_logs_digest;
|
|
bool default_reconnect;
|
|
bool have_compress;
|
|
bool have_ssl;
|
|
bool multiplexing;
|
|
// bool stmt_multiplexing;
|
|
bool log_unhealthy_connections;
|
|
bool enforce_autocommit_on_reads;
|
|
bool autocommit_false_not_reusable;
|
|
bool autocommit_false_is_transaction;
|
|
bool verbose_query_error;
|
|
int max_allowed_packet;
|
|
bool automatic_detect_sqli;
|
|
bool firewall_whitelist_enabled;
|
|
bool use_tcp_keepalive;
|
|
int tcp_keepalive_time;
|
|
int throttle_connections_per_sec_to_hostgroup;
|
|
int max_transaction_idle_time;
|
|
int max_transaction_time;
|
|
int threshold_query_length;
|
|
int threshold_resultset_size;
|
|
int query_digests_max_digest_length;
|
|
int query_digests_max_query_length;
|
|
int query_rules_fast_routing_algorithm;
|
|
int wait_timeout;
|
|
int throttle_max_bytes_per_second_to_client;
|
|
int throttle_ratio_server_to_client;
|
|
int max_connections;
|
|
int max_stmts_per_connection;
|
|
int max_stmts_cache;
|
|
int mirror_max_concurrency;
|
|
int mirror_max_queue_length;
|
|
int default_max_latency_ms;
|
|
int default_query_delay;
|
|
int default_query_timeout;
|
|
int query_processor_iterations;
|
|
int query_processor_regex;
|
|
int set_query_lock_on_hostgroup;
|
|
int set_parser_algorithm;
|
|
int auto_increment_delay_multiplex;
|
|
int auto_increment_delay_multiplex_timeout_ms;
|
|
int long_query_time;
|
|
int hostgroup_manager_verbose;
|
|
int binlog_reader_connect_retry_msec;
|
|
char* init_connect;
|
|
char* ldap_user_variable;
|
|
char* add_ldap_user_comment;
|
|
char* default_variables[PGSQL_NAME_LAST_LOW_WM];
|
|
char* firewall_whitelist_errormsg;
|
|
#ifdef DEBUG
|
|
bool session_debug;
|
|
#endif /* DEBUG */
|
|
int poll_timeout;
|
|
int poll_timeout_on_failure;
|
|
char* eventslog_filename;
|
|
int eventslog_filesize;
|
|
int eventslog_default_log;
|
|
int eventslog_format;
|
|
char* auditlog_filename;
|
|
int auditlog_filesize;
|
|
// SSL related, proxy to server
|
|
char* ssl_p2s_ca;
|
|
char* ssl_p2s_capath;
|
|
char* ssl_p2s_cert;
|
|
char* ssl_p2s_key;
|
|
char* ssl_p2s_cipher;
|
|
char* ssl_p2s_crl;
|
|
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;
|
|
bool stats_time_query_processor;
|
|
bool query_cache_stores_empty_result;
|
|
bool kill_backend_connection_when_disconnect;
|
|
int data_packets_history_size;
|
|
char* server_version;
|
|
char* server_encoding;
|
|
/**
|
|
* The processlist variables are logically group under "pgsql-" variables
|
|
* and they are kept under PgSQL_Threads_Handler.
|
|
*
|
|
* Other than configuration load/save or sync activities, these variables
|
|
* are not utilized by PTH or PgSQL_Thread for any other purpose and hence
|
|
* they are not associated with thread-local variables.
|
|
*
|
|
* At runtime, ProxySQL_Admin keeps a copy of these variables and uses them
|
|
* when collecting stats for stats_pgsql_processlist.
|
|
*/
|
|
#ifdef IDLE_THREADS
|
|
bool session_idle_show_processlist;
|
|
#endif
|
|
int show_processlist_extended;
|
|
int processlist_max_query_length;
|
|
} variables;
|
|
struct {
|
|
unsigned int mirror_sessions_current;
|
|
int threads_initialized = 0;
|
|
/// Prometheus metrics arrays
|
|
//std::array<prometheus::Counter*, p_th_counter::__size> p_counter_array{};
|
|
//std::array<prometheus::Gauge*, p_th_gauge::__size> p_gauge_array{};
|
|
} status_variables;
|
|
|
|
std::atomic<bool> bootstrapping_listeners;
|
|
|
|
/**
|
|
* @brief Update the client host cache with the supplied 'client_sockaddr',
|
|
* and the supplied 'error' parameter specifying if there was a connection
|
|
* error or not.
|
|
*
|
|
* NOTE: This function is not safe, the supplied 'client_sockaddr' should
|
|
* have been initialized by 'accept' or 'getpeername'. NULL checks are not
|
|
* performed.
|
|
*
|
|
* @details The 'client_sockaddr' parameter is inspected, and the
|
|
* 'client_host_cache' map is only updated in case of:
|
|
* - 'address_family' is either 'AF_INET' or 'AF_INET6'.
|
|
* - The address obtained from it isn't '127.0.0.1'.
|
|
*
|
|
* In case 'client_sockaddr' matches the previous description, the update
|
|
* of the client host cache is performed in the following way:
|
|
* 1. If the cache is full, the oldest element in the cache is searched.
|
|
* In case the oldest element address doesn't match the supplied
|
|
* address, the oldest element is removed.
|
|
* 2. The cache is searched looking for the supplied address, in case of
|
|
* being found, the entry is updated, otherwise the entry is inserted in
|
|
* the cache.
|
|
*
|
|
* @param client_sockaddr A 'sockaddr' holding the required client information
|
|
* to update the 'client_host_cache_map'.
|
|
* @param error 'true' if there was an error in the connection that should be
|
|
* register, 'false' otherwise.
|
|
*/
|
|
void update_client_host_cache(struct sockaddr* client_sockaddr, bool error);
|
|
/**
|
|
* @brief Retrieves the entry of the underlying 'client_host_cache' map for
|
|
* the supplied 'client_sockaddr' in case of existing. In case it doesn't
|
|
* exist or the supplied 'client_sockaddr' doesn't met the requirements
|
|
* for being registered in the map, and zeroed 'PgSQL_Client_Host_Cache_Entry'
|
|
* is returned.
|
|
*
|
|
* NOTE: This function is not safe, the supplied 'client_sockaddr' should
|
|
* have been initialized by 'accept' or 'getpeername'. NULL checks are not
|
|
* performed.
|
|
*
|
|
* @details The 'client_sockaddr' parameter is inspected, and the
|
|
* 'client_host_cache' map is only searched in case of:
|
|
* - 'address_family' is either 'AF_INET' or 'AF_INET6'.
|
|
* - The address obtained from it isn't '127.0.0.1'.
|
|
*
|
|
* @param client_sockaddr A 'sockaddr' holding the required client information
|
|
* to update the 'client_host_cache_map'.
|
|
* @return If found, the corresponding entry for the supplied 'client_sockaddr',
|
|
* a zeroed 'PgSQL_Client_Host_Cache_Entry' otherwise.
|
|
*/
|
|
PgSQL_Client_Host_Cache_Entry find_client_host_cache(struct sockaddr* client_sockaddr);
|
|
/**
|
|
* @brief Delete all the entries in the 'client_host_cache' internal map.
|
|
*/
|
|
void flush_client_host_cache();
|
|
/**
|
|
* @brief Returns the current entries of 'client_host_cache' in a
|
|
* 'SQLite3_result'. In case the param 'reset' is specified, the structure
|
|
* is cleaned after being queried.
|
|
*
|
|
* @param reset If 'true' the entries of the internal structure
|
|
* 'client_host_cache' will be cleaned after scrapping.
|
|
*
|
|
* @return SQLite3_result holding the current entries of the
|
|
* 'client_host_cache'. In the following format:
|
|
*
|
|
* [ 'client_address', 'error_num', 'last_updated' ]
|
|
*
|
|
* Where 'last_updated' is the last updated time expressed in 'ns'.
|
|
*/
|
|
SQLite3_result* get_client_host_cache(bool reset);
|
|
/**
|
|
* @brief Callback to update the metrics.
|
|
*/
|
|
void p_update_metrics();
|
|
unsigned int num_threads;
|
|
proxysql_pgsql_thread_t* pgsql_threads;
|
|
#ifdef IDLE_THREADS
|
|
proxysql_pgsql_thread_t* pgsql_threads_idles;
|
|
#endif // IDLE_THREADS
|
|
/**
|
|
* @brief Returns the current global version number for thread variables.
|
|
*
|
|
* @return The current global version number.
|
|
*
|
|
* @details This function retrieves the current global version number for thread variables.
|
|
* This number is incremented whenever a thread variable is changed, allowing threads to
|
|
* detect changes and refresh their local variables accordingly.
|
|
*
|
|
* @note This function is used by threads to check for changes in global variables and
|
|
* to update their local copies if necessary.
|
|
*
|
|
*/
|
|
unsigned int get_global_version();
|
|
|
|
/**
|
|
* @brief Acquires a write lock on the thread variables.
|
|
*
|
|
* @details This function acquires a write lock on the thread variables using a read-write lock.
|
|
* This lock prevents other threads from modifying the variables while the lock is held.
|
|
*
|
|
* @note This function should be called before modifying any thread variables to ensure
|
|
* data consistency.
|
|
*
|
|
*/
|
|
void wrlock();
|
|
|
|
/**
|
|
* @brief Releases a write lock on the thread variables.
|
|
*
|
|
* @details This function releases the write lock on the thread variables that was previously
|
|
* acquired using `wrlock()`. After calling this function, other threads can modify the
|
|
* variables.
|
|
*
|
|
* @note This function should be called after modifying thread variables to release the
|
|
* lock and allow other threads to access the variables.
|
|
*
|
|
*/
|
|
void wrunlock();
|
|
|
|
/**
|
|
* @brief Commits changes to thread variables and increments the global version.
|
|
*
|
|
* @details This function increments the global version number for thread variables, signaling
|
|
* to other threads that changes have been made. It also updates the global variables
|
|
* handler (`GloPTH`) with the committed changes.
|
|
*
|
|
* @note This function should be called after modifying thread variables to ensure that
|
|
* other threads are notified of the changes and can update their local copies.
|
|
*
|
|
*/
|
|
void commit();
|
|
|
|
/**
|
|
* @brief Retrieves the value of a thread variable as a string.
|
|
*
|
|
* @param name The name of the variable to retrieve.
|
|
*
|
|
* @return A pointer to a string containing the value of the variable, or `NULL` if
|
|
* the variable is not found.
|
|
*
|
|
* @details This function retrieves the value of a thread variable as a string. It first
|
|
* checks for monitor-related variables, then for SSL variables, and finally for default
|
|
* variables. If the variable is found, its value is returned as a dynamically allocated
|
|
* string. Otherwise, `NULL` is returned.
|
|
*
|
|
* @note This function is used to access the values of thread variables from other parts
|
|
* of the code.
|
|
*
|
|
*/
|
|
char* get_variable(char* name);
|
|
|
|
/**
|
|
* @brief Sets the value of a thread variable.
|
|
*
|
|
* @param name The name of the variable to set.
|
|
* @param value The new value to assign to the variable.
|
|
*
|
|
* @return `true` if the variable is set successfully, `false` otherwise.
|
|
*
|
|
* @details This function sets the value of a thread variable. It first checks for monitor,
|
|
* SSL, and default variables. If the variable is found, it updates the variable's value
|
|
* with the provided string. For integer variables, it performs range validation. For
|
|
* boolean variables, it checks for valid "true" or "false" values. For some variables,
|
|
* it performs additional input validation. If the variable is not found or the provided
|
|
* value is invalid, `false` is returned.
|
|
*
|
|
* @note This function is used to modify the values of thread variables from other parts
|
|
* of the code.
|
|
*
|
|
*/
|
|
bool set_variable(char* name, const char* value);
|
|
|
|
/**
|
|
* @brief Returns a list of all available thread variables.
|
|
*
|
|
* @return A dynamically allocated array of strings containing the names of all thread
|
|
* variables, or `NULL` if there are no variables.
|
|
*
|
|
* @details This function retrieves a list of all available thread variables. It scans both
|
|
* the `pgsql_thread_variables_names` array and the `mysql_tracked_variables` array to
|
|
* include both PgSQL-specific and MySQL-related variables. The returned list is dynamically
|
|
* allocated and should be freed by the caller.
|
|
*
|
|
* @note This function is used to obtain a list of available thread variables for
|
|
* display or other purposes.
|
|
*
|
|
*/
|
|
char** get_variables_list();
|
|
|
|
/**
|
|
* @brief Checks if a thread variable exists.
|
|
*
|
|
* @param name The name of the variable to check.
|
|
*
|
|
* @return `true` if the variable exists, `false` otherwise.
|
|
*
|
|
* @details This function checks if a thread variable exists. It scans both the
|
|
* `pgsql_thread_variables_names` array and the `mysql_tracked_variables` array to
|
|
* determine if the variable is defined.
|
|
*
|
|
* @note This function is used to check for the existence of thread variables before
|
|
* attempting to access or modify them.
|
|
*
|
|
*/
|
|
bool has_variable(const char* name);
|
|
|
|
/**
|
|
* @brief Default constructor for the PgSQL_Threads_Handler class.
|
|
*
|
|
* @details This constructor initializes various members of the PgSQL_Threads_Handler object
|
|
* to their default values. It sets up mutexes, initializes variables, and creates a
|
|
* `PgSQL_Listeners_Manager` object. It also sets the `bootstrapping_listeners` flag to
|
|
* `true` to indicate that the listener bootstrapping process is ongoing.
|
|
*
|
|
* @note This constructor is called when a new PgSQL_Threads_Handler object is created.
|
|
*
|
|
*/
|
|
PgSQL_Threads_Handler();
|
|
|
|
/**
|
|
* @brief Destructor for the PgSQL_Threads_Handler class.
|
|
*
|
|
* @details This destructor cleans up the PgSQL_Threads_Handler object, releasing resources
|
|
* and freeing allocated memory. It frees dynamically allocated strings, deletes the
|
|
* `PgSQL_Listeners_Manager` object, and destroys mutexes.
|
|
*
|
|
* @note This destructor is called automatically when the PgSQL_Threads_Handler object
|
|
* goes out of scope or is explicitly deleted.
|
|
*
|
|
*/
|
|
~PgSQL_Threads_Handler();
|
|
|
|
/**
|
|
* @brief Retrieves the value of a thread variable as a string.
|
|
*
|
|
* @param name The name of the variable to retrieve.
|
|
*
|
|
* @return A pointer to a string containing the value of the variable, or `NULL` if
|
|
* the variable is not found.
|
|
*
|
|
* @details This function retrieves the value of a thread variable as a string. It checks
|
|
* if the variable exists and then returns its value as a dynamically allocated string.
|
|
* If the variable is not found, it returns `NULL`.
|
|
*
|
|
* @note This function is used internally by the `get_variable()` function to retrieve
|
|
* the value of a variable as a string.
|
|
*/
|
|
char* get_variable_string(char* name);
|
|
|
|
/**
|
|
* @brief Retrieves the value of a thread variable as an integer.
|
|
*
|
|
* @param name The name of the variable to retrieve.
|
|
*
|
|
* @return The value of the variable as an integer, or 0 if the variable is not found
|
|
* or its value is not a valid integer.
|
|
*
|
|
* @details This function retrieves the value of a thread variable as an integer. It checks
|
|
* if the variable exists and then converts its value to an integer. If the variable is
|
|
* not found or its value is not a valid integer, it returns 0.
|
|
*
|
|
* @note This function is used internally by the `get_variable()` function to retrieve
|
|
* the value of a variable as an integer.
|
|
*/
|
|
int get_variable_int(const char* name);
|
|
|
|
/**
|
|
* @brief Prints the current version of the PgSQL_Threads_Handler class.
|
|
*
|
|
* @details This function prints the current version of the PgSQL_Threads_Handler class
|
|
* to the standard error stream.
|
|
*
|
|
* @note This function is used for debugging and informational purposes.
|
|
*/
|
|
void print_version();
|
|
|
|
/**
|
|
* @brief Initializes the PgSQL_Threads_Handler object.
|
|
*
|
|
* @param num The number of threads to create.
|
|
* @param stack The stack size for each thread.
|
|
*
|
|
* @details This function initializes the PgSQL_Threads_Handler object, creating the
|
|
* specified number of threads with the given stack size. It also initializes the
|
|
* global variables handler (`GloPTH`) and sets up the thread pool.
|
|
*
|
|
* @note This function is called once during the PgSQL_Threads_Handler object's
|
|
* lifetime to prepare it for managing threads.
|
|
*/
|
|
void init(unsigned int num = 0, size_t stack = 0);
|
|
|
|
/**
|
|
* @brief Creates a new thread.
|
|
*
|
|
* @param tn The thread number.
|
|
* @param start_routine The start routine for the thread.
|
|
* @param epoll_thread A boolean flag indicating whether the thread is an epoll thread (true)
|
|
* or a worker thread (false).
|
|
*
|
|
* @return A pointer to the newly created thread object, or `NULL` if the thread creation
|
|
* failed.
|
|
*
|
|
* @details This function creates a new thread with the specified thread number, start routine,
|
|
* and thread type. It initializes the thread object, sets up the thread's variables, and
|
|
* starts the thread's execution.
|
|
*
|
|
* @note This function is used to create new threads for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
proxysql_pgsql_thread_t* create_thread(unsigned int tn, void* (*start_routine) (void*), bool);
|
|
|
|
/**
|
|
* @brief Shuts down all threads in the thread pool.
|
|
*
|
|
* @details This function shuts down all threads in the thread pool, gracefully terminating
|
|
* their execution. It sets the `shutdown` flag to `true` for each thread, allowing them
|
|
* to exit their main loop. It then waits for all threads to terminate and frees any
|
|
* associated resources.
|
|
*
|
|
* @note This function is called when the PgSQL_Threads_Handler object is being shut down
|
|
* to gracefully terminate all managed threads.
|
|
*
|
|
*/
|
|
void shutdown_threads();
|
|
|
|
/**
|
|
* @brief Adds a new listener to the thread pool, based on an interface string.
|
|
*
|
|
* @param iface The interface string in the format "address:port" or "[ipv6_address]:port".
|
|
*
|
|
* @return 0 on success, -1 on failure.
|
|
*
|
|
* @details This function adds a new listener to the thread pool based on the provided
|
|
* interface string. It delegates the actual listener creation to the `PgSQL_Listeners_Manager`
|
|
* object (`MLM`). If the listener is successfully added, it signals all threads in the pool
|
|
* to update their polling lists.
|
|
*
|
|
* @note This function is used to configure listeners for the PgSQL_Threads_Handler object.
|
|
*/
|
|
int listener_add(const char* iface);
|
|
|
|
/**
|
|
* @brief Adds a new listener to the thread pool, based on an address and port.
|
|
*
|
|
* @param address The address of the listener.
|
|
* @param port The port of the listener.
|
|
*
|
|
* @return 0 on success, -1 on failure.
|
|
*
|
|
* @details This function adds a new listener to the thread pool based on the provided
|
|
* address and port. It delegates the actual listener creation to the `PgSQL_Listeners_Manager`
|
|
* object (`MLM`). If the listener is successfully added, it signals all threads in the pool
|
|
* to update their polling lists.
|
|
*
|
|
* @note This function is used to configure listeners for the PgSQL_Threads_Handler object.
|
|
*/
|
|
int listener_add(const char* address, int port);
|
|
|
|
/**
|
|
* @brief Removes a listener from the thread pool, based on an interface string.
|
|
*
|
|
* @param iface The interface string in the format "address:port" or "[ipv6_address]:port".
|
|
*
|
|
* @return 0 on success, -1 on failure.
|
|
*
|
|
* @details This function removes a listener from the thread pool based on the provided
|
|
* interface string. It delegates the actual listener removal to the `PgSQL_Listeners_Manager`
|
|
* object (`MLM`). If the listener is successfully removed, it signals all threads in the pool
|
|
* to update their polling lists.
|
|
*
|
|
* @note This function is used to remove listeners from the PgSQL_Threads_Handler object.
|
|
*/
|
|
int listener_del(const char* iface);
|
|
|
|
/**
|
|
* @brief Removes a listener from the thread pool, based on an address and port.
|
|
*
|
|
* @param address The address of the listener to remove.
|
|
* @param port The port of the listener to remove.
|
|
*
|
|
* @return 0 on success, -1 on failure.
|
|
*
|
|
* @details This function removes a listener from the thread pool based on the provided
|
|
* address and port. It delegates the actual listener removal to the `PgSQL_Listeners_Manager`
|
|
* object (`MLM`). If the listener is successfully removed, it signals all threads in the pool
|
|
* to update their polling lists.
|
|
*
|
|
* @note This function is used to remove listeners from the PgSQL_Threads_Handler object.
|
|
*/
|
|
int listener_del(const char* address, int port);
|
|
|
|
/**
|
|
* @brief Starts all configured listeners in the thread pool.
|
|
*
|
|
* @details This function starts all listeners that have been configured for the
|
|
* PgSQL_Threads_Handler object. It parses the `interfaces` variable, which contains
|
|
* a list of interface strings, and calls `listener_add()` to add each listener
|
|
* to the pool. After all listeners have been added, it sets the `bootstrapping_listeners`
|
|
* flag to `false` to indicate that the listener bootstrapping process is complete.
|
|
*
|
|
* @note This function is called to initiate the listening process for the
|
|
* PgSQL_Threads_Handler object.
|
|
*/
|
|
void start_listeners();
|
|
|
|
/**
|
|
* @brief Stops all listeners in the thread pool.
|
|
*
|
|
* @details This function stops all listeners that have been configured for the
|
|
* PgSQL_Threads_Handler object. It parses the `interfaces` variable, which contains
|
|
* a list of interface strings, and calls `listener_del()` to remove each listener
|
|
* from the pool.
|
|
*
|
|
* @note This function is called to terminate the listening process for the
|
|
* PgSQL_Threads_Handler object.
|
|
*/
|
|
void stop_listeners();
|
|
|
|
/**
|
|
* @brief Signals all threads in the thread pool.
|
|
*
|
|
* @param _c The signal value to send to each thread.
|
|
*
|
|
* @details This function sends a signal to all threads in the thread pool. It iterates
|
|
* through the thread pool and writes the signal value to the pipe associated with each
|
|
* thread.
|
|
*
|
|
* @note This function is used to send signals to threads for various purposes, such as
|
|
* notifying them of changes in global variables, requesting a thread to perform a specific
|
|
* task, or signaling a shutdown event.
|
|
*
|
|
*/
|
|
void signal_all_threads(unsigned char _c = 0);
|
|
|
|
/**
|
|
* @brief Retrieves a process list for all threads in the thread pool.
|
|
*
|
|
* @param args Processlist configuration of PgSQL.
|
|
*
|
|
* @return A `SQLite3_result` object containing the process list, or `NULL` if an error
|
|
* occurred.
|
|
*
|
|
* @details This function retrieves a process list for all threads in the thread pool. It
|
|
* iterates through the thread pool and gathers information about each active session.
|
|
* The information is then formatted into a `SQLite3_result` object, which can be used
|
|
* by the SQLite3 engine to return the process list to the client.
|
|
*
|
|
* @note This function is used to provide a process list view for the PgSQL_Threads_Handler
|
|
* object, allowing administrators to monitor active sessions and their status.
|
|
*
|
|
*/
|
|
SQLite3_result* SQL3_Processlist(processlist_config_t args);
|
|
|
|
/**
|
|
* @brief Retrieves global status information for the thread pool.
|
|
*
|
|
* @param _memory A boolean flag indicating whether to include memory statistics in the
|
|
* global status information.
|
|
*
|
|
* @return A `SQLite3_result` object containing the global status information, or `NULL`
|
|
* if an error occurred.
|
|
*
|
|
* @details This function retrieves global status information for the thread pool, including
|
|
* metrics such as uptime, active transactions, connections, and queries. If the `_memory`
|
|
* flag is set to `true`, it also includes memory statistics for each thread.
|
|
*
|
|
* @note This function is used to provide a global status view for the PgSQL_Threads_Handler
|
|
* object, allowing administrators to monitor the overall health and performance of the
|
|
* thread pool.
|
|
*
|
|
*/
|
|
SQLite3_result* SQL3_GlobalStatus(bool _memory);
|
|
|
|
/**
|
|
* @brief Kills a session based on its thread session ID.
|
|
*
|
|
* @param _thread_session_id The thread session ID of the session to kill.
|
|
*
|
|
* @return `true` if the session is found and killed, `false` otherwise.
|
|
*
|
|
* @details This function attempts to find and kill a session based on its thread session ID.
|
|
* It iterates through all threads in the thread pool and searches for a session with the
|
|
* matching ID. If the session is found, its `killed` flag is set to `true`, indicating that
|
|
* the session should be terminated.
|
|
*
|
|
* @note This function is used to terminate a specific session by its thread session ID.
|
|
*
|
|
*/
|
|
bool kill_session(uint32_t _thread_session_id);
|
|
|
|
/**
|
|
* @brief Retrieves the total length of the mirror queue across all threads.
|
|
*
|
|
* @return The total length of the mirror queue.
|
|
*
|
|
* @details This function retrieves the total length of the mirror queue across all threads.
|
|
* It iterates through the thread pool and sums the length of the mirror queue for each
|
|
* thread.
|
|
*
|
|
* @note This function is used to monitor the size of the mirror queue, which is used
|
|
* to queue mirror sessions for processing.
|
|
*
|
|
*/
|
|
unsigned long long get_total_mirror_queue();
|
|
|
|
//unsigned long long get_status_variable(enum PgSQL_Thread_status_variable v_idx, p_th_counter::metric m_idx, unsigned long long conv = 0);
|
|
//unsigned long long get_status_variable(enum PgSQL_Thread_status_variable v_idx, p_th_gauge::metric m_idx, unsigned long long conv = 0);
|
|
|
|
/**
|
|
* @brief Retrieves the total number of active transactions across all threads.
|
|
*
|
|
* @return The total number of active transactions.
|
|
*
|
|
* @details This function retrieves the total number of active transactions across all
|
|
* threads in the thread pool. It iterates through the thread pool and sums the number
|
|
* of active transactions for each thread.
|
|
*
|
|
* @note This function is used to monitor the number of active transactions, which is
|
|
* a key performance indicator for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
unsigned int get_active_transations();
|
|
|
|
#ifdef IDLE_THREADS
|
|
/**
|
|
* @brief Retrieves the number of non-idle client connections across all threads.
|
|
*
|
|
* @return The number of non-idle client connections.
|
|
*
|
|
* @details This function retrieves the number of non-idle client connections across all
|
|
* threads in the thread pool. It iterates through the thread pool and sums the number
|
|
* of non-idle client connections for each thread.
|
|
*
|
|
* @note This function is used to monitor the number of active client connections, which
|
|
* is a key performance indicator for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
unsigned int get_non_idle_client_connections();
|
|
#endif // IDLE_THREADS
|
|
|
|
/**
|
|
* @brief Retrieves the total number of bytes used for backend connection buffers across
|
|
* all threads.
|
|
*
|
|
* @return The total number of bytes used for backend connection buffers.
|
|
*
|
|
* @details This function retrieves the total number of bytes used for backend connection
|
|
* buffers across all threads in the thread pool. It iterates through the thread pool and
|
|
* sums the number of bytes used for backend connection buffers for each thread.
|
|
*
|
|
* @note This function is used to monitor the memory usage of backend connection buffers,
|
|
* which is a key performance indicator for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
unsigned long long get_pgsql_backend_buffers_bytes();
|
|
|
|
/**
|
|
* @brief Retrieves the total number of bytes used for frontend connection buffers across
|
|
* all threads.
|
|
*
|
|
* @return The total number of bytes used for frontend connection buffers.
|
|
*
|
|
* @details This function retrieves the total number of bytes used for frontend connection
|
|
* buffers across all threads in the thread pool. It iterates through the thread pool and
|
|
* sums the number of bytes used for frontend connection buffers for each thread.
|
|
*
|
|
* @note This function is used to monitor the memory usage of frontend connection buffers,
|
|
* which is a key performance indicator for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
unsigned long long get_pgsql_frontend_buffers_bytes();
|
|
|
|
/**
|
|
* @brief Retrieves the total number of bytes used for internal session data structures
|
|
* across all threads.
|
|
*
|
|
* @return The total number of bytes used for internal session data structures.
|
|
*
|
|
* @details This function retrieves the total number of bytes used for internal session
|
|
* data structures across all threads in the thread pool. It iterates through the thread pool
|
|
* and sums the number of bytes used for internal session data structures for each thread.
|
|
*
|
|
* @note This function is used to monitor the memory usage of internal session data
|
|
* structures, which is a key performance indicator for the PgSQL_Threads_Handler object.
|
|
*
|
|
*/
|
|
unsigned long long get_pgsql_session_internal_bytes();
|
|
|
|
iface_info* MLM_find_iface_from_fd(int fd) {
|
|
return MLM->find_iface_from_fd(fd);
|
|
}
|
|
|
|
/**
|
|
* @brief Calculates and updates the memory statistics for all threads in the pool.
|
|
*
|
|
* @details This function iterates through all threads in the thread pool and calls
|
|
* the `Get_Memory_Stats()` function for each thread to calculate and update its
|
|
* memory statistics.
|
|
*
|
|
* @note This function is used to gather memory statistics for all threads in the
|
|
* pool, providing a comprehensive view of memory usage.
|
|
*
|
|
*/
|
|
void Get_Memory_Stats();
|
|
|
|
/**
|
|
* @brief Sends a kill request to all threads in the pool to either kill a connection
|
|
* or a query.
|
|
*
|
|
* @param _thread_session_id The thread session ID of the connection or query to kill.
|
|
* @param query A boolean flag indicating whether to kill a query (true) or a connection
|
|
* (false).
|
|
* @param username The username associated with the connection or query.
|
|
*
|
|
* @details This function sends a kill request to all threads in the pool to either kill
|
|
* a connection or a query. It adds the kill request to the kill queue (`sess_intrpt_queue.conn_ids` or
|
|
* `sess_intrpt_queue.query_ids`) for each thread and then signals all threads to process the kill queue.
|
|
*
|
|
* @note This function is used to terminate a specific connection or query by its thread
|
|
* session ID.
|
|
*
|
|
*/
|
|
void kill_connection_or_query(uint32_t sess_thd_id, uint32_t secret_key, const char* username, bool query);
|
|
};
|
|
|
|
|
|
#endif /* __CLASS_PGSQL_THREAD_H */
|