Rename stats_global to stats_proxysql_global to avoid strstr substring collision

stats_global is a substring of stats_mysql_global and stats_pgsql_global,
causing the strstr-based dispatch to match incorrectly. Exclusion guards
don't work either because a query referencing both tables would suppress
the stats_proxysql_global refresh.

Renaming to stats_proxysql_global follows the existing naming convention
(stats_mysql_global, stats_pgsql_global) and eliminates the substring
collision entirely.
copilot/add-ssl-tls-certificate-stats-table
René Cannaò 2 months ago
parent 9850d9daeb
commit efedd93c92

@ -183,7 +183,7 @@
* @details Populated at query time by stats___global(). Contains metrics such as TLS load
* status, certificate file paths, and future cross-protocol statistics.
*/
#define STATS_SQLITE_TABLE_GLOBAL "CREATE TABLE stats_global (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)"
#define STATS_SQLITE_TABLE_GLOBAL "CREATE TABLE stats_proxysql_global (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)"
#define STATS_SQLITE_TABLE_MEMORY_METRICS "CREATE TABLE stats_memory_metrics (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)"

@ -809,7 +809,7 @@ class ProxySQL_Admin {
void stats___mysql_gtid_executed();
void stats___mysql_client_host_cache(bool reset);
void stats___tls_certificates();
void stats___global();
void stats___proxysql_global();
#ifdef PROXYSQLGENAI
void stats___mcp_query_tools_counters(bool reset);

@ -894,7 +894,7 @@ bool ProxySQL_Admin::init(const bootstrap_info_t& bootstrap_info) {
insert_into_tables_defs(tables_defs_stats,"stats_mysql_client_host_cache_reset", STATS_SQLITE_TABLE_MYSQL_CLIENT_HOST_CACHE_RESET);
insert_into_tables_defs(tables_defs_stats,"stats_mysql_query_events", ADMIN_SQLITE_TABLE_STATS_MYSQL_QUERY_EVENTS);
insert_into_tables_defs(tables_defs_stats,"stats_tls_certificates", STATS_SQLITE_TABLE_TLS_CERTIFICATES);
insert_into_tables_defs(tables_defs_stats,"stats_global", STATS_SQLITE_TABLE_GLOBAL);
insert_into_tables_defs(tables_defs_stats,"stats_proxysql_global", STATS_SQLITE_TABLE_GLOBAL);
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);

@ -1263,7 +1263,7 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
bool stats_pgsql_client_host_cache = false;
bool stats_pgsql_client_host_cache_reset = false;
bool stats_tls_certificates=false;
bool stats_global=false;
bool stats_proxysql_global=false;
bool dump_global_variables=false;
bool runtime_scheduler=false;
@ -1450,8 +1450,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
{ stats_pgsql_client_host_cache_reset = true; refresh = true; }
if (strstr(query_no_space,"stats_tls_certificates"))
{ stats_tls_certificates=true; refresh=true; }
if (strstr(query_no_space,"stats_global") && !strstr(query_no_space,"stats_mysql_global") && !strstr(query_no_space,"stats_pgsql_global"))
{ stats_global=true; refresh=true; }
if (strstr(query_no_space,"stats_proxysql_global"))
{ stats_proxysql_global=true; refresh=true; }
if (strstr(query_no_space,"stats_proxysql_servers_checksums"))
{ stats_proxysql_servers_checksums = true; refresh = true; }
if (strstr(query_no_space,"stats_proxysql_servers_metrics"))
@ -1714,8 +1714,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
if (stats_tls_certificates) {
stats___tls_certificates();
}
if (stats_global) {
stats___global();
if (stats_proxysql_global) {
stats___proxysql_global();
}
#ifdef PROXYSQLGENAI
if (stats_mcp_query_tools_counters) {

@ -817,11 +817,11 @@ void ProxySQL_Admin::stats___pgsql_global() {
}
/**
* @brief Populates the `stats_global` table with ProxySQL-wide metrics
* @brief Populates the `stats_proxysql_global` table with ProxySQL-wide metrics
* that are not specific to the MySQL or PgSQL protocol.
*
* @details This function is called at query time whenever the stats_global table
* is accessed (e.g. "SELECT * FROM stats.stats_global"). It deletes all existing
* @details This function is called at query time whenever the stats_proxysql_global table
* is accessed (e.g. "SELECT * FROM stats.stats_proxysql_global"). It deletes all existing
* rows and reinserts fresh values, ensuring `TLS_Last_Load_Timestamp` and other
* time-sensitive data are always current.
*
@ -833,11 +833,11 @@ void ProxySQL_Admin::stats___pgsql_global() {
* - TLS_CA_Cert_File : Path to the CA certificate file.
* - TLS_Key_File : Path to the private key file.
*/
void ProxySQL_Admin::stats___global() {
void ProxySQL_Admin::stats___proxysql_global() {
statsdb->execute("BEGIN");
statsdb->execute("DELETE FROM stats_global");
statsdb->execute("DELETE FROM stats_proxysql_global");
const string q_row_insert { "INSERT INTO stats_global VALUES (?1, ?2)" };
const string q_row_insert { "INSERT INTO stats_proxysql_global VALUES (?1, ?2)" };
int rc = 0;
stmt_unique_ptr u_row_stmt { nullptr };
std::tie(rc, u_row_stmt) = statsdb->prepare_v2(q_row_insert.c_str());

@ -1,10 +1,10 @@
/**
* @file test_tls_stats-t.cpp
* @brief TAP test for stats_tls_certificates and stats_global TLS metrics.
* @brief TAP test for stats_tls_certificates and stats_proxysql_global TLS metrics.
*
* @details This test verifies:
* 1. stats_global table exists and is queryable from the stats schema.
* 2. stats_global contains the expected TLS tracking variables:
* 1. stats_proxysql_global table exists and is queryable from the stats schema.
* 2. stats_proxysql_global contains the expected TLS tracking variables:
* - TLS_Load_Count
* - TLS_Last_Load_Timestamp
* - TLS_Last_Load_Result
@ -22,9 +22,9 @@
* 10. days_until_expiry is a reasonable value (> -36500 and < 36500).
* 11. loaded_at is a positive Unix timestamp.
* 12. After PROXYSQL RELOAD TLS:
* - TLS_Load_Count in stats_global increments by 1.
* - TLS_Load_Count in stats_proxysql_global increments by 1.
* - stats_tls_certificates rows are still present and non-empty.
* 13. TLS_Last_Load_Timestamp in stats_global increases after PROXYSQL RELOAD TLS.
* 13. TLS_Last_Load_Timestamp in stats_proxysql_global increases after PROXYSQL RELOAD TLS.
* 14. TLS-related variables are NOT present in stats_mysql_global.
*/
@ -107,7 +107,7 @@ int main(int argc, char** argv) {
diag("TAP test for SSL/TLS Certificate Statistics Table");
diag("This test verifies that ProxySQL correctly reports TLS certificate information,");
diag("tracks TLS load operations in stats_global, and updates these stats after a reload.");
diag("tracks TLS load operations in stats_proxysql_global, and updates these stats after a reload.");
if (cl.getEnv()) {
diag("Failed to get the required environmental variables.");
@ -115,8 +115,8 @@ int main(int argc, char** argv) {
}
// Tests:
// 1-5: stats_global TLS variables present
// 6-9: stats_global TLS variable values
// 1-5: stats_proxysql_global TLS variables present
// 6-9: stats_proxysql_global TLS variable values
// 10-11: TLS_Last_Load_Result valid value
// 12-16: stats_tls_certificates structure
// 17-24: stats_tls_certificates row data for 'server' and 'ca'
@ -137,13 +137,13 @@ int main(int argc, char** argv) {
}
// -----------------------------------------------------------------------
// Part 1: stats_global - TLS tracking variables
// Part 1: stats_proxysql_global - TLS tracking variables
// -----------------------------------------------------------------------
diag("Step 1: Verifying TLS tracking variables in stats.stats_global");
diag("--- Querying stats.stats_global ---");
diag("Step 1: Verifying TLS tracking variables in stats.stats_proxysql_global");
diag("--- Querying stats.stats_proxysql_global ---");
auto global_stats = query_key_value(admin,
"SELECT Variable_Name, Variable_Value FROM stats.stats_global");
"SELECT Variable_Name, Variable_Value FROM stats.stats_proxysql_global");
const vector<string> expected_tls_vars = {
"TLS_Load_Count",
@ -156,7 +156,7 @@ int main(int argc, char** argv) {
for (const auto& var : expected_tls_vars) {
ok(global_stats.count(var) > 0,
"stats_global: Variable '%s' is present", var.c_str());
"stats_proxysql_global: Variable '%s' is present", var.c_str());
}
diag("Verifying values of TLS tracking variables...");
@ -165,33 +165,33 @@ int main(int argc, char** argv) {
if (global_stats.count("TLS_Load_Count"))
tls_load_count = std::stoi(global_stats["TLS_Load_Count"]);
ok(tls_load_count >= 1,
"stats_global: TLS_Load_Count is >= 1 (was %d)", tls_load_count);
"stats_proxysql_global: TLS_Load_Count is >= 1 (was %d)", tls_load_count);
// TLS_Last_Load_Timestamp is a positive Unix timestamp (> 0)
long long tls_ts = 0;
if (global_stats.count("TLS_Last_Load_Timestamp"))
tls_ts = std::stoll(global_stats["TLS_Last_Load_Timestamp"]);
ok(tls_ts > 0,
"stats_global: TLS_Last_Load_Timestamp is positive (was %lld)", tls_ts);
"stats_proxysql_global: TLS_Last_Load_Timestamp is positive (was %lld)", tls_ts);
// TLS_Last_Load_Result must be one of NONE, SUCCESS, FAILED
string tls_result = global_stats.count("TLS_Last_Load_Result") ?
global_stats["TLS_Last_Load_Result"] : "";
ok(tls_result == "SUCCESS" || tls_result == "NONE" || tls_result == "FAILED",
"stats_global: TLS_Last_Load_Result='%s' is valid (NONE/SUCCESS/FAILED)",
"stats_proxysql_global: TLS_Last_Load_Result='%s' is valid (NONE/SUCCESS/FAILED)",
tls_result.c_str());
// TLS_Server_Cert_File should be a non-empty path
string cert_file = global_stats.count("TLS_Server_Cert_File") ?
global_stats["TLS_Server_Cert_File"] : "";
ok(!cert_file.empty(),
"stats_global: TLS_Server_Cert_File is non-empty ('%s')", cert_file.c_str());
"stats_proxysql_global: TLS_Server_Cert_File is non-empty ('%s')", cert_file.c_str());
// TLS_CA_Cert_File should be a non-empty path
string ca_file = global_stats.count("TLS_CA_Cert_File") ?
global_stats["TLS_CA_Cert_File"] : "";
ok(!ca_file.empty(),
"stats_global: TLS_CA_Cert_File is non-empty ('%s')", ca_file.c_str());
"stats_proxysql_global: TLS_CA_Cert_File is non-empty ('%s')", ca_file.c_str());
// -----------------------------------------------------------------------
// Part 2: stats_tls_certificates - table structure and row content
@ -286,28 +286,28 @@ int main(int argc, char** argv) {
}
mysql_free_result(mysql_store_result(admin));
diag("Verifying updated stats in stats.stats_global after reload...");
diag("Verifying updated stats in stats.stats_proxysql_global after reload...");
auto global_stats_after = query_key_value(admin,
"SELECT Variable_Name, Variable_Value FROM stats.stats_global");
"SELECT Variable_Name, Variable_Value FROM stats.stats_proxysql_global");
int tls_load_count_after = 0;
if (global_stats_after.count("TLS_Load_Count"))
tls_load_count_after = std::stoi(global_stats_after["TLS_Load_Count"]);
ok(tls_load_count_after == tls_load_count + 1,
"stats_global: TLS_Load_Count incremented after RELOAD TLS (%d -> %d)",
"stats_proxysql_global: TLS_Load_Count incremented after RELOAD TLS (%d -> %d)",
tls_load_count, tls_load_count_after);
long long tls_ts_after = 0;
if (global_stats_after.count("TLS_Last_Load_Timestamp"))
tls_ts_after = std::stoll(global_stats_after["TLS_Last_Load_Timestamp"]);
ok(tls_ts_after > tls_ts,
"stats_global: TLS_Last_Load_Timestamp increased after RELOAD TLS (%lld -> %lld)",
"stats_proxysql_global: TLS_Last_Load_Timestamp increased after RELOAD TLS (%lld -> %lld)",
tls_ts, tls_ts_after);
string tls_result_after = global_stats_after.count("TLS_Last_Load_Result") ?
global_stats_after["TLS_Last_Load_Result"] : "";
ok(tls_result_after == "SUCCESS",
"stats_global: TLS_Last_Load_Result='SUCCESS' after RELOAD TLS (got '%s')",
"stats_proxysql_global: TLS_Last_Load_Result='SUCCESS' after RELOAD TLS (got '%s')",
tls_result_after.c_str());
diag("Verifying stats.stats_tls_certificates rows after reload...");

Loading…
Cancel
Save