diff --git a/include/ProxySQL_Admin_Tables_Definitions.h b/include/ProxySQL_Admin_Tables_Definitions.h index 691e55f70..d15cfb60a 100644 --- a/include/ProxySQL_Admin_Tables_Definitions.h +++ b/include/ProxySQL_Admin_Tables_Definitions.h @@ -288,13 +288,6 @@ #define ADMIN_SQLITE_TABLE_RUNTIME_PGSQL_HOSTGROUP_ATTRIBUTES "CREATE TABLE runtime_pgsql_hostgroup_attributes (hostgroup_id INT NOT NULL PRIMARY KEY , max_num_online_servers INT CHECK (max_num_online_servers>=0 AND max_num_online_servers <= 1000000) NOT NULL DEFAULT 1000000 , autocommit INT CHECK (autocommit IN (-1, 0, 1)) NOT NULL DEFAULT -1 , free_connections_pct INT CHECK (free_connections_pct >= 0 AND free_connections_pct <= 100) NOT NULL DEFAULT 10 , init_connect VARCHAR NOT NULL DEFAULT '' , multiplex INT CHECK (multiplex IN (0, 1)) NOT NULL DEFAULT 1 , connection_warming INT CHECK (connection_warming IN (0, 1)) NOT NULL DEFAULT 0 , throttle_connections_per_sec INT CHECK (throttle_connections_per_sec >= 1 AND throttle_connections_per_sec <= 1000000) NOT NULL DEFAULT 1000000 , ignore_session_variables VARCHAR CHECK (JSON_VALID(ignore_session_variables) OR ignore_session_variables = '') NOT NULL DEFAULT '' , hostgroup_settings VARCHAR CHECK (JSON_VALID(hostgroup_settings) OR hostgroup_settings = '') NOT NULL DEFAULT '' , servers_defaults VARCHAR CHECK (JSON_VALID(servers_defaults) OR servers_defaults = '') NOT NULL DEFAULT '' , comment VARCHAR NOT NULL DEFAULT '')" #define ADMIN_SQLITE_TABLE_RUNTIME_PGSQL_REPLICATION_HOSTGROUPS "CREATE TABLE runtime_pgsql_replication_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>=0) , check_type VARCHAR CHECK (LOWER(check_type) IN ('read_only','innodb_read_only','super_read_only','read_only|innodb_read_only','read_only&innodb_read_only')) NOT NULL DEFAULT 'read_only' , comment VARCHAR NOT NULL DEFAULT '', UNIQUE (reader_hostgroup))" -/* -#define STATS_SQLITE_TABLE_PGSQL_QUERY_RULES "CREATE TABLE stats_pgsql_query_rules (rule_id INTEGER PRIMARY KEY , hits INT NOT NULL)" -#define STATS_SQLITE_TABLE_PGSQL_COMMANDS_COUNTERS "CREATE TABLE stats_pgsql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)" -#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST "CREATE TABLE stats_pgsql_query_digest (hostgroup INT , schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, schemaname, username, client_address, digest))" -#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST_RESET "CREATE TABLE stats_pgsql_query_digest_reset (hostgroup INT , schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, schemaname, username, client_address, digest))" -*/ - #define STATS_SQLITE_TABLE_PGSQL_GLOBAL "CREATE TABLE stats_pgsql_global (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)" #define STATS_SQLITE_TABLE_PGSQL_CONNECTION_POOL "CREATE TABLE stats_pgsql_connection_pool (hostgroup INT , srv_host VARCHAR , srv_port INT , status VARCHAR , ConnUsed INT , ConnFree INT , ConnOK INT , ConnERR INT , MaxConnUsed INT , Queries INT , Bytes_data_sent INT , Bytes_data_recv INT , Latency_us INT)" #define STATS_SQLITE_TABLE_PGSQL_CONNECTION_POOL_RESET "CREATE TABLE stats_pgsql_connection_pool_reset (hostgroup INT , srv_host VARCHAR , srv_port INT , status VARCHAR , ConnUsed INT , ConnFree INT , ConnOK INT , ConnERR INT , MaxConnUsed INT , Queries INT , Bytes_data_sent INT , Bytes_data_recv INT , Latency_us INT)" @@ -305,6 +298,11 @@ #define STATS_SQLITE_TABLE_PGSQL_ERRORS_RESET "CREATE TABLE stats_pgsql_errors_reset (hostgroup INT NOT NULL , hostname VARCHAR NOT NULL , port INT NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , database VARCHAR NOT NULL , sqlstate VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , last_error VARCHAR NOT NULL DEFAULT '' , PRIMARY KEY (hostgroup, hostname, port, username, database, sqlstate) )" #define STATS_SQLITE_TABLE_PGSQL_CLIENT_HOST_CACHE "CREATE TABLE stats_pgsql_client_host_cache (client_address VARCHAR NOT NULL , error_count INT NOT NULL , last_updated BIGINT NOT NULL)" #define STATS_SQLITE_TABLE_PGSQL_CLIENT_HOST_CACHE_RESET "CREATE TABLE stats_pgsql_client_host_cache_reset (client_address VARCHAR NOT NULL , error_count INT NOT NULL , last_updated BIGINT NOT NULL)" +#define STATS_SQLITE_TABLE_PGSQL_QUERY_RULES "CREATE TABLE stats_pgsql_query_rules (rule_id INTEGER PRIMARY KEY , hits INT NOT NULL)" +#define STATS_SQLITE_TABLE_PGSQL_COMMANDS_COUNTERS "CREATE TABLE stats_pgsql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)" +#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST "CREATE TABLE stats_pgsql_query_digest (hostgroup INT , database VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, database, username, client_address, digest))" +#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST_RESET "CREATE TABLE stats_pgsql_query_digest_reset (hostgroup INT , database VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, database, username, client_address, digest))" + //#define STATS_SQLITE_TABLE_MEMORY_METRICS "CREATE TABLE stats_memory_metrics (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)" diff --git a/include/proxysql_admin.h b/include/proxysql_admin.h index e42cd406c..3b2731773 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -640,6 +640,7 @@ class ProxySQL_Admin { ); int stats___mysql_query_digests(bool reset, bool copy=false); int stats___mysql_query_digests_v2(bool reset, bool copy, bool use_resultset); + int stats___pgsql_query_digests_v2(bool reset, bool copy, bool use_resultset); //void stats___mysql_query_digests_reset(); void stats___mysql_commands_counters(); void stats___mysql_processlist(); @@ -657,6 +658,8 @@ class ProxySQL_Admin { void stats___pgsql_processlist(); void stats___pgsql_errors(bool reset); void stats___pgsql_client_host_cache(bool reset); + void stats___pgsql_query_rules(); + void stats___pgsql_commands_counters(); int stats___save_pgsql_query_digest_to_sqlite( const bool reset, const bool copy, const SQLite3_result* resultset, const umap_query_digest* digest_umap, const umap_query_digest_text* digest_text_umap diff --git a/lib/Admin_Bootstrap.cpp b/lib/Admin_Bootstrap.cpp index f5ed48433..6bd80ffe5 100644 --- a/lib/Admin_Bootstrap.cpp +++ b/lib/Admin_Bootstrap.cpp @@ -112,6 +112,7 @@ extern struct MHD_Daemon *Admin_HTTP_Server; extern ProxySQL_Statistics *GloProxyStats; +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg); extern char *ssl_key_fp; @@ -684,6 +685,10 @@ bool ProxySQL_Admin::init(const bootstrap_info_t& bootstrap_info) { insert_into_tables_defs(tables_defs_stats,"stats_pgsql_errors_reset", STATS_SQLITE_TABLE_PGSQL_ERRORS_RESET); insert_into_tables_defs(tables_defs_stats,"stats_pgsql_client_host_cache", STATS_SQLITE_TABLE_PGSQL_CLIENT_HOST_CACHE); insert_into_tables_defs(tables_defs_stats,"stats_pgsql_client_host_cache_reset", STATS_SQLITE_TABLE_PGSQL_CLIENT_HOST_CACHE_RESET); + insert_into_tables_defs(tables_defs_stats,"stats_pgsql_query_rules", STATS_SQLITE_TABLE_PGSQL_QUERY_RULES); + insert_into_tables_defs(tables_defs_stats,"stats_pgsql_commands_counters", STATS_SQLITE_TABLE_PGSQL_COMMANDS_COUNTERS); + insert_into_tables_defs(tables_defs_stats,"stats_pgsql_query_digest", STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST); + insert_into_tables_defs(tables_defs_stats,"stats_pgsql_query_digest_reset", STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST_RESET); // ProxySQL Cluster insert_into_tables_defs(tables_defs_admin,"proxysql_servers", ADMIN_SQLITE_TABLE_PROXYSQL_SERVERS); diff --git a/lib/Admin_FlushVariables.cpp b/lib/Admin_FlushVariables.cpp index e6c9f8145..445e98c1c 100644 --- a/lib/Admin_FlushVariables.cpp +++ b/lib/Admin_FlushVariables.cpp @@ -112,6 +112,7 @@ extern struct MHD_Daemon *Admin_HTTP_Server; extern ProxySQL_Statistics *GloProxyStats; +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg); extern char *ssl_key_fp; diff --git a/lib/Admin_Handler.cpp b/lib/Admin_Handler.cpp index 7d11946a0..0210d9183 100644 --- a/lib/Admin_Handler.cpp +++ b/lib/Admin_Handler.cpp @@ -112,6 +112,7 @@ extern struct MHD_Daemon *Admin_HTTP_Server; extern ProxySQL_Statistics *GloProxyStats; +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg); extern char *ssl_key_fp; @@ -1198,7 +1199,7 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query unsigned long long curtime2 = monotonic_time(); curtime1 = curtime1 / 1000; curtime2 = curtime2 / 1000; - proxy_info("Saved stats_mysql_query_digest to disk: %llums to write %u entries\n", curtime2 - curtime1, r1); + proxy_info("Saved stats_pgsql_query_digest to disk: %llums to write %u entries\n", curtime2 - curtime1, r1); SPA->send_ok_msg_to_client(sess, NULL, r1, query_no_space); return false; } @@ -2386,6 +2387,19 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) { goto __run_query; } + // if the client simply executes: + // SELECT COUNT(*) FROM runtime_pgsql_query_rules_fast_routing + // we just return the count + if (strcmp("SELECT COUNT(*) FROM runtime_pgsql_query_rules_fast_routing", query_no_space) == 0) { + int cnt = GloPgQPro->get_current_query_rules_fast_routing_count(); + l_free(query_length, query); + char buf[256]; + sprintf(buf, "SELECT %d AS 'COUNT(*)'", cnt); + query = l_strdup(buf); + query_length = strlen(query) + 1; + goto __run_query; + } + if (!strncasecmp("TRUNCATE ", query_no_space, strlen("TRUNCATE "))) { if (sess->session_type == PROXYSQL_SESSION_ADMIN) { // no stats if (strstr(query_no_space,"stats_mysql_query_digest")) { @@ -2416,13 +2430,49 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) { SPA->vacuum_stats(true); // purge the digest map, asynchronously, in single thread char *msg = NULL; - int r1 = ProxySQL_Test___PurgeDigestTable(true, false, &msg); + int r1 = ProxySQL_Test___PurgeDigestTable(true, false, &msg); SPA->send_ok_msg_to_client(sess, msg, r1, query_no_space); free(msg); run_query=false; goto __run_query; } } + + if (strstr(query_no_space, "stats_pgsql_query_digest")) { + bool truncate_digest_table = false; + static char* truncate_digest_table_queries[] = { + (char*)"TRUNCATE TABLE stats.stats_pgsql_query_digest", + (char*)"TRUNCATE TABLE stats.stats_pgsql_query_digest_reset", + (char*)"TRUNCATE TABLE stats_pgsql_query_digest", + (char*)"TRUNCATE TABLE stats_pgsql_query_digest_reset", + (char*)"TRUNCATE stats.stats_pgsql_query_digest", + (char*)"TRUNCATE stats.stats_pgsql_query_digest_reset", + (char*)"TRUNCATE stats_pgsql_query_digest", + (char*)"TRUNCATE stats_pgsql_query_digest_reset" + }; + size_t l = sizeof(truncate_digest_table_queries) / sizeof(char*); + unsigned int i; + for (i = 0; i < l; i++) { + if (truncate_digest_table == false) { + if (strcasecmp(truncate_digest_table_queries[i], query_no_space) == 0) { + truncate_digest_table = true; + } + } + } + if (truncate_digest_table == true) { + ProxySQL_Admin* SPA = (ProxySQL_Admin*)pa; + SPA->admindb->execute("DELETE FROM stats.stats_pgsql_query_digest"); + SPA->admindb->execute("DELETE FROM stats.stats_pgsql_query_digest_reset"); + SPA->vacuum_stats(true); + // purge the digest map, asynchronously, in single thread + char* msg = NULL; + int r1 = ProxySQL_Test___PurgeDigestTable(true, false, &msg); + SPA->send_ok_msg_to_client(sess, msg, r1, query_no_space); + free(msg); + run_query = false; + goto __run_query; + } + } } } #ifdef DEBUG diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 23d3091b2..b4d010d00 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -112,6 +112,7 @@ struct MHD_Daemon *Admin_HTTP_Server; extern ProxySQL_Statistics *GloProxyStats; +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg); extern char *ssl_key_fp; @@ -1147,7 +1148,9 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign bool stats_mysql_connection_pool=false; bool stats_mysql_connection_pool_reset=false; bool stats_mysql_query_digest=false; + bool stats_pgsql_query_digest = false; bool stats_mysql_query_digest_reset=false; + bool stats_pgsql_query_digest_reset = false; bool stats_mysql_errors=false; bool stats_mysql_errors_reset=false; bool stats_pgsql_errors = false; @@ -1155,7 +1158,9 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign bool stats_mysql_global=false; bool stats_memory_metrics=false; bool stats_mysql_commands_counters=false; + bool stats_pgsql_commands_counters = false; bool stats_mysql_query_rules=false; + bool stats_pgsql_query_rules = false; bool stats_mysql_users=false; bool stats_pgsql_users = false; bool stats_mysql_gtid_executed=false; @@ -1228,8 +1233,12 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign } if (strstr(query_no_space,"stats_mysql_query_digest")) { stats_mysql_query_digest=true; refresh=true; } + if (strstr(query_no_space, "stats_pgsql_query_digest")) + { stats_pgsql_query_digest = true; refresh = true; } if (strstr(query_no_space,"stats_mysql_query_digest_reset")) { stats_mysql_query_digest_reset=true; refresh=true; } + if (strstr(query_no_space, "stats_pgsql_query_digest_reset")) + { stats_pgsql_query_digest_reset = true; refresh = true; } if (stats_mysql_query_digest_reset == true && stats_mysql_query_digest == true) { int nd = 0; int ndr= 0; @@ -1251,6 +1260,27 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats_mysql_query_digest = false; } } + if (stats_pgsql_query_digest_reset == true && stats_pgsql_query_digest == true) { + int nd = 0; + int ndr = 0; + char* c = NULL; + char* _ret = NULL; + c=(char*)query_no_space; + _ret=NULL; + while ((_ret=strstr(c,"stats_pgsql_query_digest_reset"))) { + ndr++; + c = _ret+strlen("stats_pgsql_query_digest_reset"); + } + c=(char*)query_no_space; + _ret = NULL; + while ((_ret=strstr(c,"stats_pgsql_query_digest"))) { + nd++; + c = _ret+strlen("stats_pgsql_query_digest"); + } + if (nd==ndr) { + stats_pgsql_query_digest = false; + } + } if (strstr(query_no_space,"stats_mysql_errors")) { stats_mysql_errors=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_errors_reset")) @@ -1284,8 +1314,12 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign { stats_pgsql_free_connections=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_commands_counters")) { stats_mysql_commands_counters=true; refresh=true; } + if (strstr(query_no_space, "stats_pgsql_commands_counters")) + { stats_pgsql_commands_counters = true; refresh = true; } if (strstr(query_no_space,"stats_mysql_query_rules")) { stats_mysql_query_rules=true; refresh=true; } + if (strstr(query_no_space,"stats_pgsql_query_rules")) + { stats_pgsql_query_rules = true; refresh = true; } if (strstr(query_no_space,"stats_mysql_users")) { stats_mysql_users=true; refresh=true; } if (strstr(query_no_space,"stats_pgsql_users")) @@ -1441,6 +1475,13 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats___mysql_query_digests_v2(false, false, false); } } + if (stats_pgsql_query_digest_reset) { + stats___pgsql_query_digests_v2(true, stats_pgsql_query_digest, false); + } else { + if (stats_pgsql_query_digest) { + stats___pgsql_query_digests_v2(false, false, false); + } + } if (stats_mysql_errors) stats___mysql_errors(false); if (stats_mysql_errors_reset) { @@ -1476,8 +1517,12 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats___memory_metrics(); if (stats_mysql_query_rules) stats___mysql_query_rules(); + if (stats_pgsql_query_rules) + stats___pgsql_query_rules(); if (stats_mysql_commands_counters) stats___mysql_commands_counters(); + if (stats_pgsql_commands_counters) + stats___pgsql_commands_counters(); if (stats_mysql_users) stats___mysql_users(); if (stats_pgsql_users) @@ -1641,7 +1686,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats_mysql_gtid_executed || stats_mysql_free_connections || stats_pgsql_global || stats_pgsql_connection_pool || stats_pgsql_connection_pool_reset || stats_pgsql_free_connections || stats_pgsql_users || stats_pgsql_processlist || - stats_pgsql_errors || stats_pgsql_errors_reset + stats_pgsql_errors || stats_pgsql_errors_reset || stats_pgsql_query_rules || stats_pgsql_commands_counters || + stats_pgsql_query_digest || stats_pgsql_query_digest_reset ) { ret = true; } @@ -1835,6 +1881,7 @@ void ProxySQL_Admin::vacuum_stats(bool is_admin) { } const vector tablenames = { "stats_mysql_commands_counters", + "stats_pgsql_commands_counters", "stats_mysql_free_connections", "stats_pgsql_free_connections", "stats_mysql_connection_pool", @@ -1846,7 +1893,10 @@ void ProxySQL_Admin::vacuum_stats(bool is_admin) { "stats_pgsql_processlist", "stats_mysql_query_digest", "stats_mysql_query_digest_reset", + "stats_pgsql_query_digest", + "stats_pgsql_query_digest_reset", "stats_mysql_query_rules", + "stats_pgsql_query_rules", "stats_mysql_users", "stats_pgsql_users", "stats_proxysql_servers_checksums", diff --git a/lib/ProxySQL_Admin_Stats.cpp b/lib/ProxySQL_Admin_Stats.cpp index 4e9ceb330..16510160f 100644 --- a/lib/ProxySQL_Admin_Stats.cpp +++ b/lib/ProxySQL_Admin_Stats.cpp @@ -1308,6 +1308,28 @@ void ProxySQL_Admin::stats___mysql_commands_counters() { delete resultset; } +void ProxySQL_Admin::stats___pgsql_commands_counters() { + if (!GloPgQPro) return; + SQLite3_result* resultset = GloPgQPro->get_stats_commands_counters(); + if (resultset == NULL) return; + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_pgsql_commands_counters"); + char* a = (char*)"INSERT INTO stats_pgsql_commands_counters VALUES (\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\")"; + for (std::vector::iterator it = resultset->rows.begin(); it != resultset->rows.end(); ++it) { + SQLite3_row* r = *it; + int arg_len = 0; + for (int i = 0; i < 15; i++) { + arg_len += strlen(r->fields[i]); + } + char* query = (char*)malloc(strlen(a) + arg_len + 32); + sprintf(query, a, r->fields[0], r->fields[1], r->fields[2], r->fields[3], r->fields[4], r->fields[5], r->fields[6], r->fields[7], r->fields[8], r->fields[9], r->fields[10], r->fields[11], r->fields[12], r->fields[13], r->fields[14]); + statsdb->execute(query); + free(query); + } + statsdb->execute("COMMIT"); + delete resultset; +} + void ProxySQL_Admin::stats___mysql_query_rules() { if (!GloMyQPro) return; SQLite3_result * resultset=GloMyQPro->get_stats_query_rules(); @@ -1330,6 +1352,28 @@ void ProxySQL_Admin::stats___mysql_query_rules() { delete resultset; } +void ProxySQL_Admin::stats___pgsql_query_rules() { + if (!GloPgQPro) return; + SQLite3_result* resultset = GloPgQPro->get_stats_query_rules(); + if (resultset == NULL) return; + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_pgsql_query_rules"); + char* a = (char*)"INSERT INTO stats_pgsql_query_rules VALUES (\"%s\",\"%s\")"; + for (std::vector::iterator it = resultset->rows.begin(); it != resultset->rows.end(); ++it) { + SQLite3_row* r = *it; + int arg_len = 0; + for (int i = 0; i < 2; i++) { + arg_len += strlen(r->fields[i]); + } + char* query = (char*)malloc(strlen(a) + arg_len + 32); + sprintf(query, a, r->fields[0], r->fields[1]); + statsdb->execute(query); + free(query); + } + statsdb->execute("COMMIT"); + delete resultset; +} + void ProxySQL_Admin::stats___proxysql_servers_checksums() { // NOTE: This mutex unlock is required due to a race condition created when: // - One Admin session has the following callstack: @@ -1740,6 +1784,24 @@ int ProxySQL_Admin::stats___mysql_query_digests_v2(bool reset, bool copy, bool u return num_rows; } +int ProxySQL_Admin::stats___pgsql_query_digests_v2(bool reset, bool copy, bool use_resultset) { + if (!GloPgQPro) return 0; + std::pair res; + if (reset == true) { + res = GloPgQPro->get_query_digests_reset_v2(copy, use_resultset); + } else { + res = GloPgQPro->get_query_digests_v2(use_resultset); + } + + if (res.first == NULL) + return res.second; + + int num_rows = GloAdmin->stats___save_pgsql_query_digest_to_sqlite(reset, copy, res.first, NULL, NULL); + delete res.first; + + return num_rows; +} + void ProxySQL_Admin::stats___mysql_client_host_cache(bool reset) { if (!GloMyQPro) return; diff --git a/lib/ProxySQL_Admin_Tests.cpp b/lib/ProxySQL_Admin_Tests.cpp index 1f0fe752e..c7fd89831 100644 --- a/lib/ProxySQL_Admin_Tests.cpp +++ b/lib/ProxySQL_Admin_Tests.cpp @@ -55,9 +55,14 @@ bool ProxySQL_Test___Refresh_MySQL_Variables(unsigned int cnt) { return true; } +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg) { int r = 0; - r = GloMyQPro->purge_query_digests(async_purge, parallel, msg); + if constexpr (ST == SERVER_TYPE_MYSQL) { + r = GloMyQPro->purge_query_digests(async_purge, parallel, msg); + } else if constexpr (ST == SERVER_TYPE_PGSQL) { + r = GloPgQPro->purge_query_digests(async_purge, parallel, msg); + } return r; } @@ -141,3 +146,6 @@ int ProxySQL_Test___GenerateRandomQueryInDigestTable(int n) { mysql_thread___query_digests_normalize_digest_text = orig_norm; return n*1000; } + +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char** msg); +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char** msg); diff --git a/lib/ProxySQL_Admin_Tests2.cpp b/lib/ProxySQL_Admin_Tests2.cpp index 0edab1449..d14edec39 100644 --- a/lib/ProxySQL_Admin_Tests2.cpp +++ b/lib/ProxySQL_Admin_Tests2.cpp @@ -42,6 +42,7 @@ static void init_rand_del() { int ProxySQL_Test___GetDigestTable(bool reset, bool use_swap); bool ProxySQL_Test___Refresh_MySQL_Variables(unsigned int cnt); +template int ProxySQL_Test___PurgeDigestTable(bool async_purge, bool parallel, char **msg); int ProxySQL_Test___GenerateRandomQueryInDigestTable(int n); @@ -589,19 +590,19 @@ void ProxySQL_Admin::ProxySQL_Test_Handler(ProxySQL_Admin *SPA, S* sess, char *q break; case 4: // purge the digest map, synchronously, in single thread - r1 = ProxySQL_Test___PurgeDigestTable(false, false, NULL); + r1 = ProxySQL_Test___PurgeDigestTable(false, false, NULL); SPA->send_ok_msg_to_client(sess, NULL, r1, query_no_space); run_query=false; break; case 5: // purge the digest map, synchronously, in multiple threads - r1 = ProxySQL_Test___PurgeDigestTable(false, true, NULL); + r1 = ProxySQL_Test___PurgeDigestTable(false, true, NULL); SPA->send_ok_msg_to_client(sess, NULL, r1, query_no_space); run_query=false; break; case 6: // purge the digest map, asynchronously, in single thread - r1 = ProxySQL_Test___PurgeDigestTable(true, false, &msg); + r1 = ProxySQL_Test___PurgeDigestTable(true, false, &msg); SPA->send_ok_msg_to_client(sess, msg, r1, query_no_space); free(msg); run_query=false; diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index 85a421921..7c736ed2c 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -694,7 +694,11 @@ unsigned long long Query_Processor::purge_query_digests_async(char * unsigned long long curtime2=monotonic_time(); curtime1 = curtime1/1000; curtime2 = curtime2/1000; - proxy_info("TRUNCATE stats_mysql_query_digest: (not locked) %llums to remove %lu entries\n", curtime2-curtime1, map1_size); + if constexpr (std::is_same_v) { + proxy_info("TRUNCATE stats_mysql_query_digest: (not locked) %llums to remove %lu entries\n", curtime2 - curtime1, map1_size); + } else if constexpr (std::is_same_v) { + proxy_info("TRUNCATE stats_pgsql_query_digest: (not locked) %llums to remove %lu entries\n", curtime2 - curtime1, map1_size); + } } return ret; } @@ -886,7 +890,12 @@ std::pair Query_Processor::get_query_digests_ curtime2=monotonic_time(); curtime1 = curtime1/1000; curtime2 = curtime2/1000; - proxy_info("Running query on stats_mysql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2-curtime1, map_size); + + if constexpr (std::is_same_v) { + proxy_info("Running query on stats_mysql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } else if constexpr (std::is_same_v) { + proxy_info("Running query on stats_pgsql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } } // Once we finish creating the resultset or writing to SQLite, we use a @@ -1018,7 +1027,12 @@ SQLite3_result * Query_Processor::get_query_digests() { curtime2=monotonic_time(); curtime1 = curtime1/1000; curtime2 = curtime2/1000; - proxy_info("Running query on stats_mysql_query_digest: locked for %llums to retrieve %lu entries\n", curtime2-curtime1, map_size); + + if constexpr (std::is_same_v) { + proxy_info("Running query on stats_mysql_query_digest: locked for %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } else if constexpr (std::is_same_v) { + proxy_info("Running query on stats_pgsql_query_digest: locked for %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } } return result; } @@ -1133,7 +1147,13 @@ std::pair Query_Processor::get_query_digests_ curtime2=monotonic_time(); curtime1 = curtime1/1000; curtime2 = curtime2/1000; - proxy_info("Running query on stats_mysql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2-curtime1, map_size); + + if constexpr (std::is_same_v) { + proxy_info("Running query on stats_mysql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } else if constexpr (std::is_same_v) { + proxy_info("Running query on stats_pgsql_query_digest: (not locked) %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } + if (free_me) { if (defer_free) { for (int i=0; i::get_query_digests_reset() { curtime2=monotonic_time(); curtime1 = curtime1/1000; curtime2 = curtime2/1000; - proxy_info("Running query on stats_mysql_query_digest_reset: locked for %llums to retrieve %lu entries\n", curtime2-curtime1, map_size); + + if constexpr (std::is_same_v) { + proxy_info("Running query on stats_mysql_query_digest_reset: locked for %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } else if constexpr (std::is_same_v) { + proxy_info("Running query on stats_pgsql_query_digest_reset: locked for %llums to retrieve %lu entries\n", curtime2 - curtime1, map_size); + } + if (free_me) { if (defer_free) { for (int i=0; i