A ProxySQL backend alternating between ONLINE and SHUNNED more than 3 times in 10 minutes is a distinct failure pattern from a persistent SHUNNED state. The backend MySQL is healthy when checked directly, but ProxySQL’s monitor module produces false-negative health decisions on a jittery network path or under transient backend pressure. Each oscillation kills active connections, causing ConnERR spikes, latency spikes on surviving backends, and dips in Questions as traffic is disrupted and redistributed.
The root cause is a mismatch between the monitor’s sensitivity and real-world backend responsiveness. The monitor runs periodic health checks on each backend; if consecutive checks fail, it instructs the hostgroup manager to shun the server. When the check interval is too aggressive or the failure threshold too low for the network conditions, transient latency spikes lasting milliseconds can cascade into SHUNNED transitions lasting seconds.
What this means
ProxySQL has two independent paths that can trigger SHUNNED status.
Monitor path: The monitor module runs ping and connect checks against each backend at configurable intervals. After mysql-monitor_ping_max_failures (default 3) consecutive ping failures, the monitor signals the MySQL Hostgroups Manager to shun the backend. With default mysql-monitor_ping_interval of 8000ms and mysql-monitor_ping_max_failures of 3, detection requires 3 consecutive failed checks spread across approximately 24 seconds.
Connection error path: During normal data-plane operation, if ProxySQL encounters more than mysql-shun_on_failures (default 5) connection errors to the same backend, the backend is automatically shunned for mysql-shun_recovery_time_sec (default 10 seconds). The effective shun threshold is min(mysql-shun_on_failures, mysql-connect_retries_on_failure) (default min(5, 10) = 5). Raising mysql-shun_on_failures alone has no effect once it exceeds mysql-connect_retries_on_failure.
Recovery from SHUNNED is not triggered by the monitor alone. A shunned server is brought back ONLINE only after mysql-shun_recovery_time_sec has elapsed and a connection attempt succeeds, which requires active traffic to the hostgroup. In a flapping scenario, traffic is flowing, so recovery typically happens within the recovery window. The cycle repeats when the next transient failure occurs.
flowchart TD
A["Backend ONLINE"] -->|"monitor ping fails
N times in a row"| B["Backend SHUNNED
connections killed"]
B -->|"recovery timer expires
+ traffic triggers re-check"| C["Backend re-checked"]
C -->|"ping succeeds"| A
C -->|"ping fails again"| BCommon causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Aggressive monitor intervals on jittery network | Ping log shows alternating success/failure with no clear backend error. Flap period roughly matches shun_recovery_time_sec plus check interval. | monitor.mysql_server_ping_log for alternating OK/ERR pattern |
Low shun_on_failures threshold | Backend gets SHUNNED after very few connection errors. ConnERR is low but non-zero. | Current value of mysql-shun_on_failures and mysql-connect_retries_on_failure |
| Backend temporarily unresponsive | Backend MySQL is healthy but busy. Large query, backup, or DDL blocks the health check thread. Flapping correlates with backup window or batch job. | Backend MySQL process list during flap window |
connect_retries_on_failure capping effective threshold | You raised shun_on_failures but flapping persists. Effective threshold is still the lower of the two values. | Compare both variable values in global_variables |
| Network path degradation | Flapping affects multiple backends on the same network segment. Intermittent packet loss visible in OS network stats. | mtr or traceroute between ProxySQL and backend hosts |
Quick checks
# Credentials on the command line are visible in process list and shell history.
# Use a my.cnf credentials file or MYSQL_PWD in production.
# Check current backend status and connection error counts
mysql -u admin -padmin -h 127.0.0.1 -P 6032 \
-e "SELECT hostgroup, srv_host, srv_port, status, ConnUsed, ConnFree, ConnOK, ConnERR, Latency_us FROM stats_mysql_connection_pool;"
# Check monitor ping log for alternating success/failure pattern
mysql -u admin -padmin -h 127.0.0.1 -P 6032 \
-e "SELECT * FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 50;"
# Check monitor check success/failure counters
mysql -u admin -padmin -h 127.0.0.1 -P 6032 \
-e "SELECT Variable_Name, Variable_Value FROM stats_mysql_global WHERE Variable_Name IN ('MySQL_Monitor_ping_check_OK','MySQL_Monitor_ping_check_ERR','MySQL_Monitor_connect_check_OK','MySQL_Monitor_connect_check_ERR');"
# Check current monitor and shun variable values
mysql -u admin -padmin -h 127.0.0.1 -P 6032 \
-e "SELECT variable_name, variable_value FROM global_variables WHERE variable_name IN ('mysql-monitor_ping_interval','mysql-monitor_ping_max_failures','mysql-monitor_ping_timeout','mysql-shun_on_failures','mysql-shun_recovery_time_sec','mysql-connect_retries_on_failure') ORDER BY variable_name;"
# Verify backend health directly (bypass ProxySQL)
mysql -u <backend_user> -p<backend_password> -h <backend_host> -P <backend_port> \
-e "SELECT @@hostname, @@read_only; SHOW PROCESSLIST;"
# Check network path between ProxySQL and backend (~100 seconds for 100 cycles)
mtr -n -c 100 <backend_host>
How to diagnose it
Confirm the flapping pattern. Query
stats_mysql_connection_poolevery 30-60 seconds over a 10-minute window and record status changes. More than 3 transitions between ONLINE and SHUNNED in 10 minutes confirms the pattern. A single SHUNNED event that stays is a different problem.Examine the monitor ping log. Look at
monitor.mysql_server_ping_logfor the affected backend. In a monitor-induced flapping scenario, you will see alternating rows whereping_success_time_usis non-zero (success) and zero (failure), withping_errorcontaining the error string on failure rows. The error is typically a timeout or connection reset, not an authentication or permission error.Check the monitor connect log. Query
monitor.mysql_server_connect_logfor the same period. Connect failures alongside ping failures indicate a network path problem. Ping failures alone suggest the backend is reachable but not responding to the ping query in time.Verify the backend is healthy directly. Connect to the backend MySQL bypassing ProxySQL. Run
SHOW PROCESSLISTand check for long-running queries, lock waits, or thread pool exhaustion. Check backend CPU, I/O wait, and connection count. If the backend is genuinely healthy, the problem is in the monitor’s sensitivity or the network path.Correlate with timing. Does the flapping happen at regular intervals? If the period roughly matches
shun_recovery_time_secplus the monitor check interval, it is monitor-induced. Does it happen during a specific time window such as a backup, batch job, or replication lag spike? If so, the backend is genuinely too busy to respond to health checks during that window.Check both shun-related variables. Query
mysql-shun_on_failuresandmysql-connect_retries_on_failurefromglobal_variables. Ifconnect_retries_on_failureis lower thanshun_on_failures, the effective shun threshold isconnect_retries_on_failure, notshun_on_failures. Raising onlyshun_on_failureswill not help.Check network quality. Run
mtrbetween the ProxySQL host and the backend host. Even small amounts of packet loss (0.1%) on a cloud network can cause intermittent ping timeouts at aggressive intervals. Check ProxySQL host network interface error counters withip -s linkorethtool -S.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
| Backend status transitions per 10 minutes | Direct measure of flapping | More than 3 ONLINE to SHUNNED transitions in 10 minutes |
MySQL_Monitor_ping_check_ERR rate | Monitor is failing health checks | Sustained non-zero error rate on a specific backend |
ConnERR per backend | Connection failures during data-plane operation | Spikes correlated with SHUNNED transitions |
Questions rate | Disruption to query throughput | Periodic dips matching the flap period |
Latency_us per backend | Monitor-measured ping latency | Spikes preceding SHUNNED transitions |
MySQL_Monitor_Workers | Monitor thread health | Zero sustained means monitoring is disabled or not started |
| Runtime vs disk variable values | Config layer divergence after tuning changes | RUNTIME has the fix but DISK has the old value |
Fixes
Raise monitor ping interval
Increasing mysql-monitor_ping_interval reduces how frequently the monitor probes each backend, giving transient issues more time to resolve before the next check. The default is 8000ms. On jittery cloud networks, 10000 to 15000ms is often more appropriate.
-- Connect to admin interface (port 6032) first
SET mysql-monitor_ping_interval = 12000;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
Tradeoff: Slower detection of genuinely failed backends. With mysql-monitor_ping_max_failures at 3 and interval at 12000ms, detection requires 3 failed checks spread over roughly 36 seconds instead of 24 seconds. In environments with redundant backends, this is usually an acceptable tradeoff.
Raise shun_on_failures and connect_retries_on_failure
To raise the effective shun threshold, you must raise both variables. The effective threshold is min(mysql-shun_on_failures, mysql-connect_retries_on_failure).
SET mysql-shun_on_failures = 10;
SET mysql-connect_retries_on_failure = 20;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
Tradeoff: Slower shun response means the proxy sends more queries to a genuinely failing backend before removing it. In environments with redundant backends and fast failover, this favors stability over speed of removal.
Increase shun recovery time
If the flapping is causing rapid oscillation, increasing mysql-shun_recovery_time_sec gives the backend a longer cooldown period before re-checking.
SET mysql-shun_recovery_time_sec = 30;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
Tradeoff: Longer time before a recovered backend rejoins the pool. Since recovery requires active traffic to trigger the re-check, the practical impact depends on your traffic pattern.
Address network jitter
If mtr shows packet loss or high latency variance on the path between ProxySQL and the backend:
- Check for network ACL or security group rate limiting.
- Verify MTU settings are consistent across the path.
- Consider whether the backend is in a different availability zone or region with inherently higher latency variance.
- On cloud platforms, check for noisy-neighbor effects on the network fabric.
Address backend resource pressure
If the flapping correlates with backup windows, large queries, or DDL operations:
- Schedule health-critical workloads outside backup windows.
- Check if the backend MySQL thread pool is exhausted during the flap window. The monitor’s ping query competes for a backend thread.
- Verify the backend’s
max_connectionscan accommodate both application traffic and the monitor’s probes during peak load.
Prevention
- Baseline your network. Run
mtrbetween ProxySQL and each backend during normal operation. Know your baseline packet loss and latency variance before you need to diagnose flapping. - Set monitor intervals appropriate for your network. The default 8000ms is aggressive for cross-AZ or cross-region deployments. Profile how long your backends take to respond to health checks under load.
- Track
MySQL_Monitor_ping_check_ERRrate as a leading indicator. Rising error rate precedes SHUNNED transitions. - Verify config layer consistency after changes. Confirm variables are loaded to RUNTIME and saved to DISK. A restart with stale DISK config silently reverts your tuning.
- Alert on status transitions, not individual events. Alert on more than 3 ONLINE to SHUNNED transitions per backend in 10 minutes. Individual SHUNNED events cause alert fatigue; SHUNNED is ProxySQL’s protection mechanism and is often transient and self-correcting.
- Test tuning under realistic load. Simulate backend pressure (large queries, connection spikes) before deploying to production and verify monitor thresholds behave as expected.
How Netdata helps
- Per-second backend status. Netdata collects
stats_mysql_connection_poolat high frequency, catching ONLINE to SHUNNED transitions that last only seconds. - Monitor error rate correlation. Netdata surfaces
MySQL_Monitor_ping_check_OKandMySQL_Monitor_ping_check_ERRalongside backend status, so you can see the check failures that precede each SHUNNED transition without manually correlating across tables. - ConnERR rate tracking. Per-backend ConnERR deltas show the connection error spikes that accompany shun events, distinguishing monitor-induced flapping from genuine backend failures.
- Questions rate dips. Per-second Questions collection reveals the periodic throughput dips that are the user-visible symptom of flapping.
- Latency divergence detection. Per-backend
Latency_uscollected over time shows whether one backend’s ping latency is diverging from peers before it gets shunned. - ML anomaly detection. Anomaly detection can flag the irregular pattern of monitor check failures that precede flapping, even when no static threshold has been crossed.






