From b4e1e1eea779ecd8175587637fa1352dc82af31f Mon Sep 17 00:00:00 2001 From: Rahim Kanji Date: Wed, 28 Aug 2024 13:09:40 +0500 Subject: [PATCH] Added stats_pgsql_free_connections table --- include/ProxySQL_Admin_Tables_Definitions.h | 2 +- include/proxysql_admin.h | 1 + lib/Admin_Bootstrap.cpp | 1 + lib/PgSQL_HostGroups_Manager.cpp | 68 +++++++------- lib/ProxySQL_Admin.cpp | 9 +- lib/ProxySQL_Admin_Stats.cpp | 98 +++++++++++++++++++++ 6 files changed, 139 insertions(+), 40 deletions(-) diff --git a/include/ProxySQL_Admin_Tables_Definitions.h b/include/ProxySQL_Admin_Tables_Definitions.h index afa34b627..fa5a90a6b 100644 --- a/include/ProxySQL_Admin_Tables_Definitions.h +++ b/include/ProxySQL_Admin_Tables_Definitions.h @@ -296,7 +296,6 @@ #define STATS_SQLITE_TABLE_MYSQL_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_MYSQL_PROCESSLIST "CREATE TABLE stats_pgsql_processlist (ThreadID INT NOT NULL , SessionID INTEGER PRIMARY KEY , user VARCHAR , db VARCHAR , cli_host VARCHAR , cli_port INT , hostgroup INT , l_srv_host VARCHAR , l_srv_port INT , srv_host VARCHAR , srv_port INT , command VARCHAR , time_ms INT NOT NULL , info VARCHAR , status_flags INT , extended_info VARCHAR)" -#define STATS_SQLITE_TABLE_MYSQL_FREE_CONNECTIONS "CREATE TABLE stats_pgsql_free_connections (fd INT NOT NULL , hostgroup INT NOT NULL , srv_host VARCHAR NOT NULL , srv_port INT NOT NULL , user VARCHAR NOT NULL , schema VARCHAR , init_connect VARCHAR , time_zone VARCHAR , sql_mode VARCHAR , autocommit VARCHAR , idle_ms INT , statistics VARCHAR , mysql_info VARCHAR)" #define STATS_SQLITE_TABLE_MYSQL_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))" @@ -305,6 +304,7 @@ #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)" +#define STATS_SQLITE_TABLE_PGSQL_FREE_CONNECTIONS "CREATE TABLE stats_pgsql_free_connections (fd INT NOT NULL , hostgroup INT NOT NULL , srv_host VARCHAR NOT NULL , srv_port INT NOT NULL , user VARCHAR NOT NULL , database VARCHAR , init_connect VARCHAR , time_zone VARCHAR , sql_mode VARCHAR , idle_ms INT , statistics VARCHAR , pgsql_info VARCHAR)" //#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 8cf75130e..d5cb8a01c 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -644,6 +644,7 @@ class ProxySQL_Admin { void stats___mysql_commands_counters(); void stats___mysql_processlist(); void stats___mysql_free_connections(); + void stats___pgsql_free_connections(); void stats___mysql_connection_pool(bool _reset); void stats___mysql_errors(bool reset); void stats___memory_metrics(); diff --git a/lib/Admin_Bootstrap.cpp b/lib/Admin_Bootstrap.cpp index 1ab506f46..f71cc51af 100644 --- a/lib/Admin_Bootstrap.cpp +++ b/lib/Admin_Bootstrap.cpp @@ -676,6 +676,7 @@ bool ProxySQL_Admin::init(const bootstrap_info_t& bootstrap_info) { insert_into_tables_defs(tables_defs_stats,"stats_pgsql_global", STATS_SQLITE_TABLE_PGSQL_GLOBAL); insert_into_tables_defs(tables_defs_stats,"stats_pgsql_connection_pool", STATS_SQLITE_TABLE_PGSQL_CONNECTION_POOL); insert_into_tables_defs(tables_defs_stats,"stats_pgsql_connection_pool_reset", STATS_SQLITE_TABLE_PGSQL_CONNECTION_POOL_RESET); + insert_into_tables_defs(tables_defs_stats,"stats_pgsql_free_connections", STATS_SQLITE_TABLE_PGSQL_FREE_CONNECTIONS); // ProxySQL Cluster insert_into_tables_defs(tables_defs_admin,"proxysql_servers", ADMIN_SQLITE_TABLE_PROXYSQL_SERVERS); diff --git a/lib/PgSQL_HostGroups_Manager.cpp b/lib/PgSQL_HostGroups_Manager.cpp index fc0923354..ecb940282 100644 --- a/lib/PgSQL_HostGroups_Manager.cpp +++ b/lib/PgSQL_HostGroups_Manager.cpp @@ -2882,7 +2882,7 @@ SQLite3_result* PgSQL_HostGroups_Manager::get_current_pgsql_table(const string& SQLite3_result * PgSQL_HostGroups_Manager::SQL3_Free_Connections() { - const int colnum=13; + const int colnum=12; proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping Free Connections in Pool\n"); SQLite3_result *result=new SQLite3_result(colnum); result->add_column_definition(SQLITE_TEXT,"fd"); @@ -2894,7 +2894,7 @@ SQLite3_result * PgSQL_HostGroups_Manager::SQL3_Free_Connections() { result->add_column_definition(SQLITE_TEXT,"init_connect"); result->add_column_definition(SQLITE_TEXT,"time_zone"); result->add_column_definition(SQLITE_TEXT,"sql_mode"); - result->add_column_definition(SQLITE_TEXT,"autocommit"); + //result->add_column_definition(SQLITE_TEXT,"autocommit"); result->add_column_definition(SQLITE_TEXT,"idle_ms"); result->add_column_definition(SQLITE_TEXT,"statistics"); result->add_column_definition(SQLITE_TEXT,"pgsql_info"); @@ -2933,17 +2933,17 @@ SQLite3_result * PgSQL_HostGroups_Manager::SQL3_Free_Connections() { pta[6] = strdup(conn->options.init_connect); } pta[7] = NULL; - if (conn->variables[SQL_TIME_ZONE].value) { + /*if (conn->variables[SQL_TIME_ZONE].value) { pta[7] = strdup(conn->variables[SQL_TIME_ZONE].value); - } + }*/ pta[8] = NULL; - if (conn->variables[SQL_SQL_MODE].value) { + /*if (conn->variables[SQL_SQL_MODE].value) { pta[8] = strdup(conn->variables[SQL_SQL_MODE].value); - } - sprintf(buf,"%d", conn->options.autocommit); - pta[9]=strdup(buf); + }*/ + //sprintf(buf,"%d", conn->options.autocommit); + //pta[9]=strdup(buf); sprintf(buf,"%llu", (curtime-conn->last_time_used)/1000); - pta[10]=strdup(buf); + pta[9]=strdup(buf); { json j; char buff[32]; @@ -2956,40 +2956,32 @@ SQLite3_result * PgSQL_HostGroups_Manager::SQL3_Free_Connections() { j["pgconnpoll_get"] = conn->statuses.pgconnpoll_get; j["pgconnpoll_put"] = conn->statuses.pgconnpoll_put; j["questions"] = conn->statuses.questions; - string s = j.dump(); - pta[11] = strdup(s.c_str()); + const string s = j.dump(); + pta[10] = strdup(s.c_str()); } { - MYSQL *_my = conn->pgsql; json j; char buff[32]; - sprintf(buff,"%p",_my); + sprintf(buff, "%p", conn->get_pg_connection()); j["address"] = buff; - j["host"] = _my->host; - j["host_info"] = _my->host_info; - j["port"] = _my->port; - j["server_version"] = _my->server_version; - j["user"] = _my->user; - j["unix_socket"] = (_my->unix_socket ? _my->unix_socket : ""); - j["db"] = (_my->db ? _my->db : ""); - j["affected_rows"] = _my->affected_rows; - j["insert_id"] = _my->insert_id; - j["thread_id"] = _my->thread_id; - j["server_status"] = _my->server_status; - j["charset"] = _my->charset->nr; - j["charset_name"] = _my->charset->csname; - - j["options"]["charset_name"] = ( _my->options.charset_name ? _my->options.charset_name : "" ); - j["options"]["use_ssl"] = _my->options.use_ssl; - j["client_flag"]["client_found_rows"] = (_my->client_flag & CLIENT_FOUND_ROWS ? 1 : 0); - j["client_flag"]["client_multi_statements"] = (_my->client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); - j["client_flag"]["client_multi_results"] = (_my->client_flag & CLIENT_MULTI_RESULTS ? 1 : 0); - j["net"]["last_errno"] = _my->net.last_errno; - j["net"]["fd"] = _my->net.fd; - j["net"]["max_packet_size"] = _my->net.max_packet_size; - j["net"]["sqlstate"] = _my->net.sqlstate; - string s = j.dump(); - pta[12] = strdup(s.c_str()); + j["host"] = conn->get_pg_host(); + j["host_addr"] = conn->get_pg_hostaddr(); + j["port"] = conn->get_pg_port(); + j["user"] = conn->get_pg_user(); + j["db"] = conn->get_pg_dbname(); + j["backend_pid"] = conn->get_pg_backend_pid(); + j["using_ssl"] = conn->get_pg_ssl_in_use() ? "YES" : "NO"; + j["error_msg"] = conn->get_pg_error_message(); + j["options"] = conn->get_pg_options(); + j["fd"] = conn->get_pg_socket_fd(); + j["protocol_version"] = conn->get_pg_protocol_version(); + j["server_version"] = conn->get_pg_server_version_str(buff, sizeof(buff)); + j["transaction_status"] = conn->get_pg_transaction_status_str(); + j["connection_status"] = conn->get_pg_connection_status_str(); + j["client_encoding"] = conn->get_pg_client_encoding(); + j["is_nonblocking"] = conn->get_pg_is_nonblocking() ? "YES" : "NO"; + const string s = j.dump(); + pta[11] = strdup(s.c_str()); } result->add_row(pta); for (k=0; k tablenames = { "stats_mysql_commands_counters", "stats_mysql_free_connections", + "stats_pgsql_free_connections", "stats_mysql_connection_pool", "stats_mysql_connection_pool_reset", "stats_pgsql_connection_pool", diff --git a/lib/ProxySQL_Admin_Stats.cpp b/lib/ProxySQL_Admin_Stats.cpp index 487981fbc..9b74877cc 100644 --- a/lib/ProxySQL_Admin_Stats.cpp +++ b/lib/ProxySQL_Admin_Stats.cpp @@ -1200,6 +1200,104 @@ void ProxySQL_Admin::stats___mysql_free_connections() { delete resultset; } +void ProxySQL_Admin::stats___pgsql_free_connections() { + int rc; + if (!PgHGM) return; + SQLite3_result* resultset = PgHGM->SQL3_Free_Connections(); + if (resultset == NULL) return; + + sqlite3_stmt* statement1 = NULL; + sqlite3_stmt* statement32 = NULL; + //sqlite3 *mydb3=statsdb->get_db(); + char* query1 = NULL; + char* query32 = NULL; + std::string query32s = ""; + + query1 = (char*)"INSERT INTO stats_pgsql_free_connections VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)"; + query32s = "INSERT INTO stats_pgsql_free_connections VALUES " + generate_multi_rows_query(32, 12); + query32 = (char*)query32s.c_str(); + + //rc=(*proxy_sqlite3_prepare_v2)(mydb3, query1, -1, &statement1, 0); + rc = statsdb->prepare_v2(query1, &statement1); + ASSERT_SQLITE_OK(rc, statsdb); + //rc=(*proxy_sqlite3_prepare_v2)(mydb3, query32, -1, &statement32, 0); + rc = statsdb->prepare_v2(query32, &statement32); + ASSERT_SQLITE_OK(rc, statsdb); + + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_pgsql_free_connections"); + + int row_idx = 0; + int max_bulk_row_idx = resultset->rows_count / 32; + max_bulk_row_idx = max_bulk_row_idx * 32; + for (std::vector::iterator it = resultset->rows.begin(); it != resultset->rows.end(); ++it) { + SQLite3_row* r1 = *it; + int idx = row_idx % 32; + if (row_idx < max_bulk_row_idx) { // bulk + rc = (*proxy_sqlite3_bind_int64)(statement32, (idx * 12) + 1, atoll(r1->fields[0])); ASSERT_SQLITE_OK(rc, statsdb); // FD + rc = (*proxy_sqlite3_bind_int64)(statement32, (idx * 12) + 2, atoll(r1->fields[1])); ASSERT_SQLITE_OK(rc, statsdb); // hostgroup + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 3, r1->fields[2], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // srv_host + if (r1->fields[3]) { + rc = (*proxy_sqlite3_bind_int64)(statement32, (idx * 12) + 4, atoll(r1->fields[3])); ASSERT_SQLITE_OK(rc, statsdb); // srv_port + } + else { + rc = (*proxy_sqlite3_bind_null)(statement32, (idx * 12) + 4); ASSERT_SQLITE_OK(rc, statsdb); + } + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 5, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // user + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 6, r1->fields[5], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // database + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 7, r1->fields[6], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // init_connect + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 8, r1->fields[7], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // time_zone + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 9, r1->fields[8], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // sql_mode + if (r1->fields[9]) { + rc = (*proxy_sqlite3_bind_int64)(statement32, (idx * 12) + 10, atoll(r1->fields[9])); ASSERT_SQLITE_OK(rc, statsdb); // idle_ms + } + else { + rc = (*proxy_sqlite3_bind_null)(statement32, (idx * 12) + 10); ASSERT_SQLITE_OK(rc, statsdb); + } + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 11, r1->fields[10], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // statistics + rc = (*proxy_sqlite3_bind_text)(statement32, (idx * 12) + 12, r1->fields[11], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // pgsql_info + if (idx == 31) { + SAFE_SQLITE3_STEP2(statement32); + rc = (*proxy_sqlite3_clear_bindings)(statement32); ASSERT_SQLITE_OK(rc, statsdb); + rc = (*proxy_sqlite3_reset)(statement32); ASSERT_SQLITE_OK(rc, statsdb); + } + } + else { // single row + rc = (*proxy_sqlite3_bind_int64)(statement1, 1, atoll(r1->fields[0])); ASSERT_SQLITE_OK(rc, statsdb); // FD + rc = (*proxy_sqlite3_bind_int64)(statement1, 2, atoll(r1->fields[1])); ASSERT_SQLITE_OK(rc, statsdb); // hostgroup + rc = (*proxy_sqlite3_bind_text)(statement1, 3, r1->fields[2], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // srv_host + if (r1->fields[3]) { + rc = (*proxy_sqlite3_bind_int64)(statement1, 4, atoll(r1->fields[3])); ASSERT_SQLITE_OK(rc, statsdb); // srv_port + } + else { + rc = (*proxy_sqlite3_bind_null)(statement1, 4); ASSERT_SQLITE_OK(rc, statsdb); + } + rc = (*proxy_sqlite3_bind_text)(statement1, 5, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // user + rc = (*proxy_sqlite3_bind_text)(statement1, 6, r1->fields[5], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // database + rc = (*proxy_sqlite3_bind_text)(statement1, 7, r1->fields[6], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // init_connect + rc = (*proxy_sqlite3_bind_text)(statement1, 8, r1->fields[7], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // time_zone + rc = (*proxy_sqlite3_bind_text)(statement1, 9, r1->fields[8], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // sql_mode + if (r1->fields[9]) { + rc = (*proxy_sqlite3_bind_int64)(statement1, 10, atoll(r1->fields[9])); ASSERT_SQLITE_OK(rc, statsdb); // idle_ms + } + else { + rc = (*proxy_sqlite3_bind_null)(statement1, 10); ASSERT_SQLITE_OK(rc, statsdb); + } + rc = (*proxy_sqlite3_bind_text)(statement1, 11, r1->fields[10], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // statistics + rc = (*proxy_sqlite3_bind_text)(statement1, 12, r1->fields[11], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); // pgsql_info + SAFE_SQLITE3_STEP2(statement1); + rc = (*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, statsdb); + rc = (*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, statsdb); + } + row_idx++; + } + statsdb->execute("COMMIT"); + (*proxy_sqlite3_finalize)(statement1); + (*proxy_sqlite3_finalize)(statement32); + delete resultset; +} + + void ProxySQL_Admin::stats___mysql_commands_counters() { if (!GloQPro) return; SQLite3_result * resultset=GloQPro->get_stats_commands_counters();