Jacopo Gobbi
06/25/2026, 7:05 AMSET my_var = my_value) and the use of proxysql to front starrocks? We are seeing an issue where setting variables and calling a select hangs indefinitely, and it looks like a peculiar interaction between proxysql and multi node starrocks, doesn't happen in single nodeRocky
06/25/2026, 7:05 AMSET session variables followed by a SELECT hang indefinitely in a multi-node StarRocks setup with ProxySQL—is likely caused by ProxySQL's connection multiplexing and its interaction with StarRocks' FE session management.
1. Connection Multiplexing Mismatch
ProxySQL's "Multiplexing" feature allows multiple frontend client connections to share a smaller pool of backend connections to the StarRocks FEs.
• The Issue: When you execute a SET command, ProxySQL attempts to track the session state to "replay" it if the session is moved to a different backend FE node. In a multi-node setup, if ProxySQL routes the subsequent SELECT to a different FE or fails to reconcile the state (e.g., due to parsing errors or unsupported MySQL capability bits), the connection can hang while ProxySQL waits for a protocol response that StarRocks doesn't send in the expected format.
• Single Node vs. Multi-Node: In a single-node setup, ProxySQL typically stays on the same backend connection, masking the state synchronization issue.
2. Recommended Solutions
A. Disable Multiplexing
The most reliable fix when using session variables with ProxySQL is to disable multiplexing for those connections. You can do this globally or for specific users/queries:
• Globally: Set mysql-multiplexing=false in the ProxySQL global variables.
• Via Query Rules: Create a rule to disable multiplexing for connections that use SET or for all StarRocks traffic:
sql
INSERT INTO mysql_query_rules (rule_id, active, match_digest, multiplex) VALUES (1, 1, '.', 0);
LOAD MYSQL QUERY RULES TO RUNTIME;
B. Use SET_VAR Hints (Best Practice)
Instead of executing a separate SET statement, use StarRocks' statement-level hints. This makes the variable scoped only to that specific query, which is stateless and proxy-friendly:
sql
SELECT /*+ SET_VAR(query_timeout = 60, exec_mem_limit = 8589934592) */ * FROM my_table;
This avoids triggering ProxySQL's session-state tracking logic entirely.
C. FE Configuration
Ensure your StarRocks FEs are configured to handle disconnected proxy clients properly. In your fe.conf, check:
• `mysql_service_kill_after_disconnect = true`: This ensures that if ProxySQL drops or resets a connection, StarRocks kills the associated query immediately rather than leaving it in a "hanging" state.
D. ProxySQL Version
If you are using an older version of ProxySQL (e.g., 2.x), consider upgrading to 3.0.8 or later. These versions introduced improved MySQL session-variable tracking (mysql-session_track_variables) which is more robust, though StarRocks compatibility with this specific protocol may vary depending on the StarRocks version.
3. Summary of Causes
* Session State: StarRocks session variables are local to the FE node that received the SET command. They are not synchronized across other FEs.
* Protocol Hang: ProxySQL may hang if it enters a state where it's waiting for a "Success" or "OK" packet with session-state flags that StarRocks (which is MySQL-compatible but not a 1:1 MySQL clone) does not provide in the specific sequence ProxySQL expects during state requires.
sequence.
* Forwarding Logic: In multi-node StarRocks, some queries are internally forwarded to the Leader FE; this internal hop can sometimes clash with ProxySQL's own routing and timeout logic if multiplexing is active.
multiplexing is active
References
• administration/management/FE_configuration.md
• sql-reference/System_variable.md
• deployment/deploy_manually.mdJacopo Gobbi
06/25/2026, 7:20 AMRocky
06/25/2026, 7:21 AMTransaction not found or, in some protocol edge cases, hang as the proxy and backend fail to sync.
• ProxySQL's Logic: ProxySQL is designed to automatically disable multiplexing when it detects BEGIN, START TRANSACTION, or an active transaction flag in the MySQL protocol. However, if your application uses SET autocommit=0 to start transactions, some older versions of ProxySQL or specific configurations might not catch this state immediately, leading to a connection switch.
2. Potential Issues with Multiplexing & Transactions
* Visibility Issues: If an INSERT happens on FE-A but the COMMIT is accidentally routed to FE-B (due to a multiplexing glitch), the COMMIT will fail, and your data will never be persisted.
* Hanging on Commit/Rollback: As you've seen with session variables, if the protocol state becomes "dirty" (where the Proxy thinks the connection is multiplex-safe but the Backend is in a transaction), the handshake for the next query can hang or time out.
* Internal Forwarding Conflicts: StarRocks FEs often forward DML (Write) requests to the Leader FE. If ProxySQL is also trying to manage the connection via multiplexing, you end up with two layers of routing (Proxy -> FE -> Leader FE). This double-hop increases the chance of a timeout or a "broken pipe" if any layer decides to prune the connection.
3. Recommended Safeguards for Transactions
To avoid future issues and "mysterious" hangs during transactions:
* Explicitly Disable Multiplexing for Transactional Users:
If you have a specific service user that performs writes/transactions, disable multiplexing for that user entirely in ProxySQL:
sql
UPDATE mysql_users SET transaction_persistent=1 WHERE username='your_app_user';
LOAD MYSQL USERS TO RUNTIME;
This ensures that once a session starts, it stays pinned to the same backend FE for its duration.
* Use BEGIN ... COMMIT Blocks:
Avoid relying solely on autocommit=0. Explicit BEGIN and COMMIT statements are more reliably intercepted by ProxySQL's state machine to trigger "multiplexing disabled" mode.
* StarRocks v3.5+ SQL Transactions:
If you are using the newer SQL Transaction feature (available from v3.5.0), ensure your ProxySQL is updated to at least v2.5.5+ or v2.6.x to ensure better compatibility with modern MySQL protocol flags that StarRocks uses to signal transaction status.
* Set `mysql-connection_delay_multiplex_ms`:
In ProxySQL, you can set a small delay (e.g., SET mysql-connection_delay_multiplex_ms=100) which prevents the proxy from immediately returning a connection to the pool after a query, giving the app time to send the next statement in a sequence without a connection switching.
Summary
While ProxySQL is excellent for load balancing StarRocks SELECT traffic, multiplexing is generally dangerous for session-heavy or transactional workloads in StarRocks. Because StarRocks FEs do not share session state (like variables or open transactions), you should pin these connections to a single FE using transaction_persistent=1 or by disabling multiplexing for those specific query rules.
ReferencesRocky
06/25/2026, 7:21 AMRocky
06/25/2026, 7:25 AMtransaction_persistent=1, you lose this "fan-in" effect. If 1,000 clients connect to ProxySQL, ProxySQL must open 1,000 connections to your StarRocks FEs.
* StarRocks Limit: The default limit for StarRocks FEs is 4096 connections (qe_max_connection). If you have many application instances, you could hit this limit quickly.
2. Uneven Load Balancing
With multiplexing enabled, ProxySQL can balance every individual query across all FEs.
* The Downside: With persistent connections, ProxySQL balances the connection only at login. If one application connection becomes very "heavy" (running many complex queries) and others are idle, that specific FE node will be overworked while others sit idle. You lose the "granular" query-by-query balancing.
3. Memory and Resource Overhead
* On ProxySQL: Managing thousands of persistent backend connections requires more memory and file descriptors.
* On StarRocks: Each active connection on the FE consumes a thread and memory. Thousands of idle persistent connections can slightly degrade FE performance compared to a small, active pool.
──────────
The "Ideal" Approach: Use SET_VAR
To avoid the downsides above while fixing the hanging issue, the best path is often to keep multiplexing enabled but stop using SET statements. Instead, use StarRocks SET_VAR hints:
* Standard approach (Dangerous with Proxy):
sql
SET query_timeout = 60; -- ProxySQL might move the next query to a different node
SELECT * FROM table; -- Hangs or fails if node changed
* SET_VAR approach (Safe & Efficient):
sql
SELECT /_+ SET_VAR(query_timeout = 60) _/ * FROM table;
Why this is better:
1. Stateless: The variable is only applied to that one query.
2. Multiplex-Friendly: ProxySQL treats this as a standard, independent query and can safely route it to any FE without needing to "track" session state.
3. No Connection Bloat: You can keep your backend connection pool small (e.g., 50-100 connections) even with thousands of users.
When to use transaction_persistent=1
You should only resort to pinning connections (persistent mode) if:
1. Your application logic requires multi-statement transactions (BEGIN ... COMMIT).
2. You are using User Defined Variables (SET @my_var = 123) which cannot be passed via SET_VAR hints.
3. You cannot modify the application code to use hints.
application code to use hints.
References
• administration/management/FE_configuration.md
• sql-reference/sql-statements/data-query/SET_VAR.md
• administration/management/resource_management/Load_balance.md
_management/Load_balance)
References
• administration/management/FE_configuration.md
• deployment/environment_configurations.mdJacopo Gobbi
06/25/2026, 7:26 AMSET_VAR Hints (Best Practice)
Instead of executing a separate SET statement, use StarRocks' statement-level hints. This makes the variable scoped only to that specific query, which is stateless and proxy-friendly:
sql
SELECT /*+ SET_VAR(query_timeout = 60, exec_mem_limit = 8589934592) */ * FROM my_table;
still allow us to get the profile of the query with SELECT get_query_profile(last_query_id()) through the same connection? Assuming we are changing these variables
SET SESSION enable_profile = true;
SET SESSION big_query_profile_threshold = 0;
SET SESSION pipeline_profile_level = 1;
SET SESSION runtime_profile_report_interval = 0;
SET SESSION enable_query_cache = false;Rocky
06/25/2026, 7:27 AMSET_VAR approach allows you to set profiling variables for a single query without the "hanging" issues caused by ProxySQL multiplexing, it creates a new challenge for retrieving the profile.
1. Does SET_VAR work for profiling variables?
Yes. You can successfully include profiling variables in the hint. This will trigger the StarRocks BEs to generate a profile for that specific statement:
sql
SELECT /*+ SET_VAR(enable_profile = true, pipeline_profile_level = 1, enable_query_cache = false) */ * FROM my_table;
This avoids modifying the session state, which is what typically causes ProxySQL to hang or get "out of sync" when tracking variables.
2. Can you still retrieve the profile?
This is where the ProxySQL interaction becomes problematic. Even if the query generates a profile, the standard retrieval workflow (last_query_id() -> get_query_profile()) will likely fail if multiplexing is active:
* last_query_id() is Session-Local: ProxySQL multiplexing allows different queries from the same application client to be sent to different StarRocks sessions (and different FE nodes). If the SELECT query runs on FE-A but the SELECT last_query_id() is routed to FE-B (or even a different session on FE-A), it will return the wrong ID or NULL.
* Profile Storage is Node-Local: In multi-node StarRocks, query profiles are typically stored in the memory of the specific FE node that coordinated the query. If ProxySQL routes your get_query_profile() call to a different FE, that FE won't have the profile in its local cache, and the function will return an empty result.
* get_query_profile Requirement: The get_query_profile() function itself checks the enable_profile variable. If you use SET_VAR for the main query, the variable is only true for that query. You would need to use SET_VAR again on the retrieval call itself:
sql
-- This might still return empty if ProxySQL switched your backend connection
SELECT /_+ SET_VAR(enable_profile=true) _/ get_query_profile('your-query-id');
3. Recommended Solution for Profiling with ProxySQL
If you need to retrieve profiles while using ProxySQL, the SET_VAR hint alone is not enough because of the "state" requirement of the profile retrieval steps. Use one of these two paths:
Option A: Pin the Connection (Best for DBAs)
Create a ProxySQL rule or use a specific user that has multiplexing disabled. This ensures all three steps (SET, SELECT, get_query_profile) happen on the exact same physical session and FE:
sql
-- In ProxySQL, pin this user to avoid connection switching
UPDATE mysql_users SET transaction_persistent=1 WHERE username='dba_user';
LOAD MYSQL USERS TO RUNTIME;
Option B: Use the StarRocks Web UI
Instead of using SQL functions through the proxy, log directly into the Web UI of any FE node (http://<fe_ip>:8030).
* In a multi-node FE setup, you may need to check the "Queries" tab on each FE to find your query, as each node lists the queries it coordinated.
* This bypasses ProxySQL entirely and is the most reliable way to view profiles in a multi-node environment.
Summary of variables compatibility
Variable | SET_VAR Compatible? | Notes
enable_profile | Yes | Triggers profile generation for the specific query.
big_query_profile_threshold | Yes | Note: Value must be a string (e.g., '0s').
pipeline_profile_level | Yes | Controls the depth of the generated profile.
enable_query_cache | Yes | Disables cache for that specific execution.
Conclusion: Use SET_VAR to avoid the hang during query execution, but be aware that you will likely need to disable ProxySQL multiplexing or bypass the proxy to successfully retrieve that profile using last_query_id().
References
• sql-reference/System_variable.md