Fix metrics collection for wait_timeout counters

The get_status_variable() function was only scanning worker threads
but ignoring auxiliary threads (idle threads) where timeout
terminations are detected. This caused the timeout termination
counter to show incorrect/zero values.

- Added idle thread scanning to both overloaded versions of
  get_status_variable() function
- Now properly collects metrics from both worker and idle threads
- Fixes the issue where proxysql_mysql_timeout_terminated_connections_total
  showed zero despite actual timeout terminations

Resolves the metrics reading issue identified in the previous commits.
pull/4901/head
Rene Cannao 5 months ago
parent fbf5f2d762
commit 5a7b22181f

@ -90,6 +90,8 @@ enum MySQL_Thread_status_variable {
st_var_automatic_detected_sqli,
st_var_mysql_whitelisted_sqli_fingerprint,
st_var_client_host_error_killed_connections,
st_var_set_wait_timeout_commands,
st_var_timeout_terminated_connections,
MY_st_var_END
};
@ -281,6 +283,8 @@ struct p_th_counter {
hostgroup_locked_set_cmds,
hostgroup_locked_queries,
mysql_unexpected_frontend_packets,
mysql_set_wait_timeout_commands,
mysql_timeout_terminated_connections,
aws_aurora_replicas_skipped_during_query,
automatic_detected_sql_injection,
mysql_whitelisted_sqli_fingerprint,

@ -6600,6 +6600,9 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
std::string value = *values++;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Client requested SET wait_timeout = %s\n", value.c_str());
// Increment counter for SET wait_timeout commands
thread->status_variables.stvar[st_var_set_wait_timeout_commands]++;
unsigned long long client_timeout = 0;
try {
client_timeout = std::stoull(value) * 1000;

@ -165,6 +165,8 @@ mythr_st_vars_t MySQL_Thread_status_variables_counter_array[] {
{ st_var_max_connect_timeout_err, p_th_counter::max_connect_timeouts, (char *)"max_connect_timeouts" },
{ st_var_generated_pkt_err, p_th_counter::generated_error_packets, (char *)"generated_error_packets" },
{ st_var_client_host_error_killed_connections, p_th_counter::client_host_error_killed_connections, (char *)"client_host_error_killed_connections" },
{ st_var_set_wait_timeout_commands, p_th_counter::mysql_set_wait_timeout_commands, (char *)"mysql_set_wait_timeout_commands" },
{ st_var_timeout_terminated_connections, p_th_counter::mysql_timeout_terminated_connections, (char *)"mysql_timeout_terminated_connections" },
};
mythr_g_st_vars_t MySQL_Thread_status_variables_gauge_array[] {
@ -807,6 +809,18 @@ th_metrics_map = std::make_tuple(
"proxysql_client_host_error_killed_connections",
"Killed client connections because address exceeded 'client_host_error_counts'.",
metric_tags {}
),
std::make_tuple (
p_th_counter::mysql_set_wait_timeout_commands,
"proxysql_mysql_set_wait_timeout_commands_total",
"Number of SET wait_timeout commands received from clients.",
metric_tags {}
),
std::make_tuple (
p_th_counter::mysql_timeout_terminated_connections,
"proxysql_mysql_timeout_terminated_connections_total",
"Number of client connections terminated due to wait_timeout.",
metric_tags {}
)
},
th_gauge_vector {
@ -3452,6 +3466,9 @@ void MySQL_Thread::idle_thread_to_kill_idle_sessions() {
unsigned long long sess_time = curtime - mysess->idle_since;
proxy_warning("Killing client connection %s:%d because inactive for %llums\n", mysess->client_myds->addr.addr, mysess->client_myds->addr.port, sess_time/1000);
mysess->killed=true;
// Increment counter for timeout-terminated connections
mysess->thread->status_variables.stvar[st_var_timeout_terminated_connections]++;
}
if (mysess->killed==true) { // because idle or for any other reason
MySQL_Data_Stream *tmp_myds=mysess->client_myds;
@ -3873,6 +3890,9 @@ void MySQL_Thread::ProcessAllSessions_MaintenanceLoop(MySQL_Session *sess, unsig
if (sess->client_myds) {
proxy_warning("Killing client connection %s:%d because inactive for %llums\n",sess->client_myds->addr.addr,sess->client_myds->addr.port, sess_time/1000);
}
// Increment counter for timeout-terminated connections
sess->thread->status_variables.stvar[st_var_timeout_terminated_connections]++;
}
}
} else {
@ -4070,6 +4090,9 @@ void MySQL_Thread::process_all_sessions() {
sess->killed=true;
sess->to_process=1;
proxy_warning("Killing client connection %s:%d because inactive for %llums\n", sess->client_myds->addr.addr, sess->client_myds->addr.port, sess_time/1000);
// Increment counter for timeout-terminated connections
sess->thread->status_variables.stvar[st_var_timeout_terminated_connections]++;
}
}
#endif // IDLE_THREADS
@ -5371,6 +5394,16 @@ unsigned long long MySQL_Threads_Handler::get_status_variable(
q+=__sync_fetch_and_add(&thr->status_variables.stvar[v_idx],0);
}
}
#ifdef IDLE_THREADS
if (GloVars.global.idle_threads)
for (i=0;i<num_threads;i++) {
if (mysql_threads_idles) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads_idles[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.stvar[v_idx],0);
}
}
#endif // IDLE_THREADS
if (m_idx != p_th_counter::__size) {
const auto& cur_val = status_variables.p_counter_array[m_idx]->Value();
double final_val = 0;
@ -5402,6 +5435,16 @@ unsigned long long MySQL_Threads_Handler::get_status_variable(
q+=__sync_fetch_and_add(&thr->status_variables.stvar[v_idx],0);
}
}
#ifdef IDLE_THREADS
if (GloVars.global.idle_threads)
for (i=0;i<num_threads;i++) {
if (mysql_threads_idles) {
MySQL_Thread *thr=(MySQL_Thread *)mysql_threads_idles[i].worker;
if (thr)
q+=__sync_fetch_and_add(&thr->status_variables.stvar[v_idx],0);
}
}
#endif // IDLE_THREADS
if (m_idx != p_th_gauge::__size) {
double final_val = 0;

Loading…
Cancel
Save