Skip to content

Commit 42bb0cf

Browse files
authored
Merge pull request #4680 from sysown/v3.0-postgres_monitor_poc
Initial POC for PostgreSQL monitoring support
2 parents 16b8396 + 1ebe70b commit 42bb0cf

15 files changed

Lines changed: 1963 additions & 179 deletions

include/PgSQL_HostGroups_Manager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ class PgSQL_HostGroups_Manager : public Base_HostGroups_Manager<PgSQL_HGC> {
585585
/**
586586
* @brief Mutex used to guard 'pgsql_servers_to_monitor' resulset.
587587
*/
588-
std::mutex pgsql_servers_to_monitor_mutex;
588+
std::mutex pgsql_servers_to_monitor_mutex {};
589589
/**
590590
* @brief Resulset containing the latest 'pgsql_servers' present in 'mydb'.
591591
* @details This resulset should be updated via 'update_table_pgsql_servers_for_monitor' each time actions

include/PgSQL_Monitor.hpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#ifndef __PGSQL_MONITOR_H
2+
#define __PGSQL_MONITOR_H
3+
4+
#include "libpq-fe.h"
5+
6+
#include "sqlite3db.h"
7+
#include "proxysql_structs.h"
8+
9+
#include <cassert>
10+
#include <mutex>
11+
#include <vector>
12+
13+
#define MONITOR_SQLITE_TABLE_PGSQL_SERVER_CONNECT_LOG "CREATE TABLE pgsql_server_connect_log (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , connect_success_time_us INT DEFAULT 0 , connect_error VARCHAR , PRIMARY KEY (hostname, port, time_start_us))"
14+
15+
#define MONITOR_SQLITE_TABLE_PGSQL_SERVER_PING_LOG "CREATE TABLE pgsql_server_ping_log ( hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , time_start_us INT NOT NULL DEFAULT 0 , ping_success_time_us INT DEFAULT 0 , ping_error VARCHAR , PRIMARY KEY (hostname, port, time_start_us))"
16+
17+
#define MONITOR_SQLITE_TABLE_PGSQL_SERVERS "CREATE TABLE pgsql_servers (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 3306 , status INT CHECK (status IN (0, 1, 2, 3, 4)) NOT NULL DEFAULT 0 , use_ssl INT CHECK (use_ssl IN(0,1)) NOT NULL DEFAULT 0 , PRIMARY KEY (hostname, port) )"
18+
19+
#define MONITOR_SQLITE_TABLE_PROXYSQL_SERVERS "CREATE TABLE proxysql_servers (hostname VARCHAR NOT NULL , port INT NOT NULL DEFAULT 6032 , weight INT CHECK (weight >= 0) NOT NULL DEFAULT 0 , comment VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostname, port) )"
20+
21+
struct PgSQL_Monitor {
22+
// @brief Flags if monitoring threads should be shutdown.
23+
bool shutdown = false;
24+
// @brief Mutex to hold to update `monitor_internal.pgsql_servers`
25+
std::mutex pgsql_srvs_mutex {};
26+
// @brief Mutex to hold to update/read `pgsql_servers` to monitor
27+
std::mutex pgsql_srvs_to_monitor_mutex {};
28+
// @brief Used to access monitor database
29+
SQLite3DB monitordb {};
30+
// @brief Used to access internal monitor database
31+
SQLite3DB monitor_internal_db {};
32+
// Internal counters for metrics
33+
///////////////////////////////////////////////////////////////////////////
34+
uint64_t connect_check_ERR { 0 };
35+
uint64_t connect_check_OK { 0 };
36+
uint64_t ping_check_ERR { 0 };
37+
uint64_t ping_check_OK { 0 };
38+
///////////////////////////////////////////////////////////////////////////
39+
40+
std::vector<table_def_t> tables_defs_monitor {
41+
{
42+
const_cast<char*>("pgsql_server_connect_log"),
43+
const_cast<char*>(MONITOR_SQLITE_TABLE_PGSQL_SERVER_CONNECT_LOG)
44+
},
45+
{
46+
const_cast<char*>("pgsql_server_ping_log"),
47+
const_cast<char*>(MONITOR_SQLITE_TABLE_PGSQL_SERVER_PING_LOG)
48+
}
49+
};
50+
51+
std::vector<table_def_t> tables_defs_monitor_internal {
52+
{
53+
const_cast<char*>("pgsql_servers"),
54+
const_cast<char*>(MONITOR_SQLITE_TABLE_PGSQL_SERVERS)
55+
}
56+
};
57+
58+
PgSQL_Monitor();
59+
};
60+
61+
struct pgsql_conn_t {
62+
PGconn* conn { nullptr };
63+
int fd { 0 };
64+
uint64_t last_used { 0 };
65+
ASYNC_ST state { ASYNC_ST::ASYNC_CONNECT_FAILED };
66+
mf_unique_ptr<char> err {};
67+
};
68+
69+
void* PgSQL_monitor_scheduler_thread();
70+
71+
#endif

include/PgSQL_Thread.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "proxysql.h"
88
#include "Base_Thread.h"
9-
#include "cpp.h"
109
#include "ProxySQL_Poll.h"
1110
#include "PgSQL_Variables.h"
1211
#ifdef IDLE_THREADS
@@ -825,6 +824,7 @@ class PgSQL_Threads_Handler
825824
//! Read only check timeout. Unit: 'ms'.
826825
int monitor_replication_lag_timeout;
827826
int monitor_replication_lag_count;
827+
/* TODO: Remove
828828
int monitor_groupreplication_healthcheck_interval;
829829
int monitor_groupreplication_healthcheck_timeout;
830830
int monitor_groupreplication_healthcheck_max_timeout_count;
@@ -836,9 +836,13 @@ class PgSQL_Threads_Handler
836836
int monitor_query_interval;
837837
int monitor_query_timeout;
838838
int monitor_slave_lag_when_null;
839+
*/
840+
int monitor_threads;
841+
/* TODO: Remove
839842
int monitor_threads_min;
840843
int monitor_threads_max;
841844
int monitor_threads_queue_maxsize;
845+
*/
842846
int monitor_local_dns_cache_ttl;
843847
int monitor_local_dns_cache_refresh_interval;
844848
int monitor_local_dns_resolver_queue_maxsize;

include/PgSQL_Variables.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#define PGSQL_VARIABLES_H
33

44
#include "proxysql.h"
5-
#include "cpp.h"
65

76
#include <cstdint>
87
#include <vector>

include/cpp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "sqlite3db.h"
1616
//#include "StatCounters.h"
1717
#include "MySQL_Monitor.hpp"
18+
#include "PgSQL_Monitor.hpp"
1819
//#include "MySQL_Protocol.h"
1920
//#include "MySQL_Authentication.hpp"
2021
//#include "MySQL_LDAP_Authentication.hpp"

include/proxysql_debug.h

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
2-
/*
3-
#ifdef DEBUG
4-
#ifndef DEBUG_EXTERN
5-
#define DEBUG_EXTERN
6-
extern debug_level *gdbg_lvl;
7-
extern int gdbg;
8-
#endif
9-
#endif
10-
*/
11-
121
#ifndef __PROXYSQL_DEBUG_H
132
#define __PROXYSQL_DEBUG_H
143

@@ -46,7 +35,6 @@ class Timer {
4635

4736
#ifdef DEBUG
4837
#define PROXY_TRACE() { proxy_debug(PROXY_DEBUG_GENERIC,10,"TRACE\n"); }
49-
//#define PROXY_TRACE2() { proxy_info("TRACE\n"); }
5038
#define PROXY_TRACE2()
5139
#else
5240
#define PROXY_TRACE()
@@ -64,7 +52,6 @@ class Timer {
6452
} \
6553
} while (0)
6654
#elif defined(__linux__)
67-
//#ifdef SYS_gettid
6855
#define proxy_debug(module, verbosity, fmt, ...) \
6956
do { if (GloVars.global.gdbg) { \
7057
proxy_debug_func(module, verbosity, syscall(SYS_gettid), __FILE__, __LINE__, __func__ , fmt, ## __VA_ARGS__); \
@@ -76,9 +63,6 @@ class Timer {
7663
#define proxy_debug(module, verbosity, fmt, ...)
7764
#endif /* DEBUG */
7865

79-
/*
80-
#ifdef DEBUG
81-
*/
8266
#define proxy_error(fmt, ...) \
8367
do { \
8468
time_t __timer; \
@@ -111,23 +95,7 @@ class Timer {
11195
strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", &__tm_info); \
11296
proxy_error_func(0, "%s %s:%d:%s(): [ERROR] " fmt, __buffer, fi, li, fu , ## __VA_ARGS__); \
11397
} while(0)
114-
/*
115-
#else
116-
#define proxy_error(fmt, ...) \
117-
do { \
118-
time_t __timer; \
119-
char __buffer[25]; \
120-
struct tm *__tm_info; \
121-
time(&__timer); \
122-
__tm_info = localtime(&__timer); \
123-
strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", __tm_info); \
124-
proxy_error_func("%s [ERROR] " fmt , __buffer , ## __VA_ARGS__); \
125-
} while(0)
126-
#endif
127-
*/
128-
/*
129-
#ifdef DEBUG
130-
*/
98+
13199
#define proxy_warning(fmt, ...) \
132100
do { \
133101
time_t __timer; \
@@ -150,20 +118,6 @@ class Timer {
150118
proxy_error_func(ecode, "%s %s:%d:%s(): [WARNING] " fmt, __buffer, __FILE__, __LINE__, __func__ , ## __VA_ARGS__); \
151119
} while(0)
152120

153-
/*
154-
#else
155-
#define proxy_warning(fmt, ...) \
156-
do { \
157-
time_t __timer; \
158-
char __buffer[25]; \
159-
struct tm *__tm_info; \
160-
time(&__timer); \
161-
__tm_info = localtime(&__timer); \
162-
strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", __tm_info); \
163-
proxy_error_func("%s [WARNING] " fmt , __buffer , ## __VA_ARGS__); \
164-
} while(0)
165-
#endif
166-
*/
167121
#ifdef DEBUG
168122
#define proxy_info(fmt, ...) \
169123
do { \
@@ -211,13 +165,26 @@ class Timer {
211165
#endif
212166

213167
#ifdef DEBUG
214-
//void *debug_logger();
215168
#endif
216169

170+
#define NULL_DB_MSG "The pointer to sqlite3 database is NULL. Cannot get error message."
171+
217172
#define ASSERT_SQLITE_OK(rc, db) \
218173
do { \
219174
if (rc!=SQLITE_OK) { \
220-
proxy_error("SQLite3 error with return code %d. Error message: %s. Shutting down.\n", rc, db?(*proxy_sqlite3_errmsg)(db->get_db()):"The pointer to sqlite3 database is null. Cannot get error message."); \
175+
proxy_error( \
176+
"SQLite3 error. Shutting down rc=%d msg='%s'\n", \
177+
rc, db ? (*proxy_sqlite3_errmsg)(db->get_db()) : NULL_DB_MSG); \
178+
assert(0); \
179+
} \
180+
} while(0)
181+
182+
#define ASSERT_SQLITE3_OK(rc, db) \
183+
do { \
184+
if (rc!=SQLITE_OK) { \
185+
proxy_error( \
186+
"SQLite3 error. Shutting down rc=%d msg='%s'\n", \
187+
rc, db ? (*proxy_sqlite3_errmsg)(db) : NULL_DB_MSG); \
221188
assert(0); \
222189
} \
223190
} while(0)
@@ -243,12 +210,12 @@ SQLite3_result* proxysql_get_message_stats(bool reset=false);
243210
*/
244211
void proxysql_init_debug_prometheus_metrics();
245212

246-
213+
class SQLite3DB;
247214
/**
248215
* @brief Set or unset if Admin has debugdb_disk fully initialized
249216
*/
250217
void proxysql_set_admin_debugdb_disk(SQLite3DB *_db);
251218

252219
void proxysql_set_admin_debug_output(unsigned int _do);
253220

254-
#endif
221+
#endif // DEBUG

include/proxysql_structs.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ enum PROXYSQL_MYSQL_ERR {
647647
ER_PROXYSQL_AWS_HEALTH_CHECK_CONN_TIMEOUT = 9017,
648648
ER_PROXYSQL_AWS_HEALTH_CHECK_TIMEOUT = 9018,
649649
ER_PROXYSQL_SRV_NULL_REPLICATION_LAG = 9019,
650+
ER_PROXYSQL_CONNECT_TIMEOUT = 9020,
650651
};
651652

652653
enum proxysql_session_type {
@@ -1079,6 +1080,21 @@ __thread char* pgsql_thread___firewall_whitelist_errormsg;
10791080
__thread bool pgsql_thread___firewall_whitelist_enabled;
10801081
__thread int pgsql_thread___query_processor_iterations;
10811082
__thread int pgsql_thread___query_processor_regex;
1083+
1084+
__thread bool pgsql_thread___monitor_enabled;
1085+
__thread int pgsql_thread___monitor_history;
1086+
__thread int pgsql_thread___monitor_connect_interval;
1087+
__thread int pgsql_thread___monitor_connect_timeout;
1088+
__thread int pgsql_thread___monitor_ping_interval;
1089+
__thread int pgsql_thread___monitor_ping_max_failures;
1090+
__thread int pgsql_thread___monitor_ping_timeout;
1091+
__thread int pgsql_thread___monitor_read_only_interval;
1092+
__thread int pgsql_thread___monitor_read_only_timeout;
1093+
__thread int pgsql_thread___monitor_read_only_max_timeout_count;
1094+
__thread int pgsql_thread___monitor_threads;
1095+
__thread char* pgsql_thread___monitor_username;
1096+
__thread char* pgsql_thread___monitor_password;
1097+
10821098
//---------------------------
10831099

10841100
__thread char *mysql_thread___default_schema;
@@ -1351,6 +1367,21 @@ extern __thread char* pgsql_thread___firewall_whitelist_errormsg;
13511367
extern __thread bool pgsql_thread___firewall_whitelist_enabled;
13521368
extern __thread int pgsql_thread___query_processor_iterations;
13531369
extern __thread int pgsql_thread___query_processor_regex;
1370+
1371+
extern __thread bool pgsql_thread___monitor_enabled;
1372+
extern __thread int pgsql_thread___monitor_history;
1373+
extern __thread int pgsql_thread___monitor_connect_interval;
1374+
extern __thread int pgsql_thread___monitor_connect_timeout;
1375+
extern __thread int pgsql_thread___monitor_ping_interval;
1376+
extern __thread int pgsql_thread___monitor_ping_max_failures;
1377+
extern __thread int pgsql_thread___monitor_ping_timeout;
1378+
extern __thread int pgsql_thread___monitor_read_only_interval;
1379+
extern __thread int pgsql_thread___monitor_read_only_timeout;
1380+
extern __thread int pgsql_thread___monitor_read_only_max_timeout_count;
1381+
extern __thread int pgsql_thread___monitor_threads;
1382+
extern __thread char* pgsql_thread___monitor_username;
1383+
extern __thread char* pgsql_thread___monitor_password;
1384+
13541385
//---------------------------
13551386

13561387
extern __thread char *mysql_thread___default_schema;

lib/Base_HostGroups_Manager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ template void Base_HostGroups_Manager<PgSQL_HGC>::wrlock();
5353
template void Base_HostGroups_Manager<PgSQL_HGC>::wrunlock();
5454

5555
template SQLite3_result * Base_HostGroups_Manager<MyHGC>::execute_query(char*, char**);
56+
template SQLite3_result * Base_HostGroups_Manager<PgSQL_HGC>::execute_query(char*, char**);
5657

5758
#if 0
5859
#define SAFE_SQLITE3_STEP(_stmt) do {\

lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ _OBJ_CXX := ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo
147147
Base_Session.oo Base_Thread.oo \
148148
proxy_protocol_info.oo \
149149
proxysql_find_charset.oo ProxySQL_Poll.oo \
150-
PgSQL_Protocol.oo PgSQL_Thread.oo PgSQL_Data_Stream.oo PgSQL_Session.oo PgSQL_Variables.oo PgSQL_HostGroups_Manager.oo PgSQL_Connection.oo PgSQL_Backend.oo PgSQL_Logger.oo PgSQL_Authentication.oo PgSQL_Error_Helper.oo
150+
PgSQL_Protocol.oo PgSQL_Thread.oo PgSQL_Data_Stream.oo PgSQL_Session.oo PgSQL_Variables.oo PgSQL_HostGroups_Manager.oo PgSQL_Connection.oo PgSQL_Backend.oo PgSQL_Logger.oo PgSQL_Authentication.oo PgSQL_Error_Helper.oo PgSQL_Monitor.oo
151151

152152
OBJ_CXX := $(patsubst %,$(ODIR)/%,$(_OBJ_CXX))
153153
HEADERS := ../include/*.h ../include/*.hpp

0 commit comments

Comments
 (0)