From 3ab964010df9350dcb7c3b6c80e487cf5a5705a0 Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Mon, 9 Feb 2026 23:06:14 +0000 Subject: [PATCH] Add protocol labels to Query Cache metrics and enable PostgreSQL QC metrics This commit resolves the prometheus metric collision between MySQL and PostgreSQL Query Cache instances by creating separate metric maps with protocol labels and using compile-time type trait selection. Changes: - Add #include to Query_Cache.cpp - Create qc_metrics_map_mysql with { "protocol", "mysql" } labels (8 metrics) - Create qc_metrics_map_pgsql with { "protocol", "pgsql" } labels (8 metrics) - Modify Query_Cache constructor to use if constexpr with std::is_same_v to select the appropriate metrics map based on derived type - Enable GloPgQC metrics export in update_modules_metrics() This allows MySQL and PostgreSQL query cache metrics to coexist without collision, following the same pattern as Thread Handler metrics. Related: #5068, #5069 --- lib/ProxySQL_Admin.cpp | 3 - lib/Query_Cache.cpp | 133 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 121 insertions(+), 15 deletions(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index f1e6bf8e6..e521c29e6 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -2637,13 +2637,10 @@ void update_modules_metrics() { if (GloMyQC) { GloMyQC->p_update_metrics(); } -#if 0 // Turning off Prometheus metrics collection for PostgreSQL modules in ProxySQL - // Note: Query Cache metrics use shared template base class and would collide between MySQL and PostgreSQL // Update pgsql query_cache metrics if (GloPgQC) { GloPgQC->p_update_metrics(); } -#endif // Update cluster metrics if (GloProxyCluster) { GloProxyCluster->p_update_metrics(); diff --git a/lib/Query_Cache.cpp b/lib/Query_Cache.cpp index 4564fcc06..e3aa9d919 100644 --- a/lib/Query_Cache.cpp +++ b/lib/Query_Cache.cpp @@ -4,6 +4,7 @@ #include "Query_Cache.h" #include "MySQL_Query_Cache.h" #include "PgSQL_Query_Cache.h" +#include #ifdef DEBUG #define DEB "_DEBUG" @@ -315,7 +316,7 @@ using qc_counter_vector = std::vector; using qc_gauge_vector = std::vector; /** - * @brief Metrics map holding the metrics for the 'Query_Cache' module. + * @brief Metrics map holding the metrics for the MySQL Query_Cache module. * * @note Many metrics in this map, share a common "id name", because * they differ only by label, because of this, HELP is shared between @@ -323,7 +324,7 @@ using qc_gauge_vector = std::vector; * sepparated using a line separator comment. */ const std::tuple -qc_metrics_map = std::make_tuple( +qc_metrics_map_mysql = std::make_tuple( qc_counter_vector { // ==================================================================== std::make_tuple ( @@ -331,7 +332,8 @@ qc_metrics_map = std::make_tuple( "proxysql_query_cache_count_get_total", "Number of failed read requests.", metric_tags { - { "status", "err" } + { "status", "err" }, + { "protocol", "mysql" } } ), std::make_tuple ( @@ -339,7 +341,8 @@ qc_metrics_map = std::make_tuple( "proxysql_query_cache_count_get_total", "Number of successful read requests.", metric_tags { - { "status", "ok" } + { "status", "ok" }, + { "protocol", "mysql" } } ), // ==================================================================== @@ -348,7 +351,100 @@ qc_metrics_map = std::make_tuple( p_qc_counter::query_cache_count_set, "proxysql_query_cache_count_set_total", "Number of write requests.", - metric_tags {} + metric_tags { + { "protocol", "mysql" } + } + ), + + // ==================================================================== + std::make_tuple ( + p_qc_counter::query_cache_bytes_in, + "proxysql_query_cache_bytes_total", + "Number of bytes (read|written) into the Query Cache.", + metric_tags { + { "op", "written" }, + { "protocol", "mysql" } + } + ), + std::make_tuple ( + p_qc_counter::query_cache_bytes_out, + "proxysql_query_cache_bytes_total", + "Number of bytes (read|written) into the Query Cache.", + metric_tags { + { "op", "read" }, + { "protocol", "mysql" } + } + ), + // ==================================================================== + + std::make_tuple ( + p_qc_counter::query_cache_purged, + "proxysql_query_cache_purged_total", + "Number of entries purged by the Query Cache due to TTL expiration.", + metric_tags { + { "protocol", "mysql" } + } + ), + std::make_tuple ( + p_qc_counter::query_cache_entries, + "proxysql_query_cache_entries_total", + "Number of entries currently stored in the query cache.", + metric_tags { + { "protocol", "mysql" } + } + ) + }, + qc_gauge_vector { + std::make_tuple ( + p_qc_gauge::query_cache_memory_bytes, + "proxysql_query_cache_memory_bytes", + "Memory currently used by the query cache.", + metric_tags { + { "protocol", "mysql" } + } + ) + } +); + +/** + * @brief Metrics map holding the metrics for the PostgreSQL Query_Cache module. + * + * @note Many metrics in this map, share a common "id name", because + * they differ only by label, because of this, HELP is shared between + * them. For better visual identification of this groups they are + * sepparated using a line separator comment. + */ +const std::tuple +qc_metrics_map_pgsql = std::make_tuple( + qc_counter_vector { + // ==================================================================== + std::make_tuple ( + p_qc_counter::query_cache_count_get, + "proxysql_query_cache_count_get_total", + "Number of failed read requests.", + metric_tags { + { "status", "err" }, + { "protocol", "pgsql" } + } + ), + std::make_tuple ( + p_qc_counter::query_cache_count_get_ok, + "proxysql_query_cache_count_get_total", + "Number of successful read requests.", + metric_tags { + { "status", "ok" }, + { "protocol", "pgsql" } + } + ), + // ==================================================================== + + std::make_tuple ( + p_qc_counter::query_cache_count_set, + "proxysql_query_cache_count_set_total", + "Number of write requests.", + metric_tags { + { "protocol", "pgsql" } + } ), // ==================================================================== @@ -357,7 +453,8 @@ qc_metrics_map = std::make_tuple( "proxysql_query_cache_bytes_total", "Number of bytes (read|written) into the Query Cache.", metric_tags { - { "op", "written" } + { "op", "written" }, + { "protocol", "pgsql" } } ), std::make_tuple ( @@ -365,7 +462,8 @@ qc_metrics_map = std::make_tuple( "proxysql_query_cache_bytes_total", "Number of bytes (read|written) into the Query Cache.", metric_tags { - { "op", "read" } + { "op", "read" }, + { "protocol", "pgsql" } } ), // ==================================================================== @@ -374,13 +472,17 @@ qc_metrics_map = std::make_tuple( p_qc_counter::query_cache_purged, "proxysql_query_cache_purged_total", "Number of entries purged by the Query Cache due to TTL expiration.", - metric_tags {} + metric_tags { + { "protocol", "pgsql" } + } ), std::make_tuple ( p_qc_counter::query_cache_entries, "proxysql_query_cache_entries_total", "Number of entries currently stored in the query cache.", - metric_tags {} + metric_tags { + { "protocol", "pgsql" } + } ) }, qc_gauge_vector { @@ -388,7 +490,9 @@ qc_metrics_map = std::make_tuple( p_qc_gauge::query_cache_memory_bytes, "proxysql_query_cache_memory_bytes", "Memory currently used by the query cache.", - metric_tags {} + metric_tags { + { "protocol", "pgsql" } + } ) } ); @@ -435,8 +539,13 @@ Query_Cache::Query_Cache() { //max_memory_size=DEFAULT_SQC_size; // Initialize prometheus metrics - init_prometheus_counter_array(qc_metrics_map, this->metrics.p_counter_array); - init_prometheus_gauge_array(qc_metrics_map, this->metrics.p_gauge_array); + if constexpr (std::is_same_v) { + init_prometheus_counter_array(qc_metrics_map_mysql, this->metrics.p_counter_array); + init_prometheus_gauge_array(qc_metrics_map_mysql, this->metrics.p_gauge_array); + } else { + init_prometheus_counter_array(qc_metrics_map_pgsql, this->metrics.p_counter_array); + init_prometheus_gauge_array(qc_metrics_map_pgsql, this->metrics.p_gauge_array); + } }; template