mariadb-set
MariaDB-specific syntax and behavior for SET — GLOBAL/SESSION/LOCAL scope rules and their session-isolation semantics, the SET STATEMENT ... FOR extension (and its fixed list of 13 variables it cannot
Files1
View on GitHubSKILL.mdclaude/dev-plugin/skills/mariadb-set/SKILL.md
GitHubSET in MariaDB
Last updated: 2026-07-20
This skill covers the delta between generic "assign a variable" SQL and MariaDB's SET — its scope keywords, the SET STATEMENT ... FOR per-query extension, and a persistence model that has no SET PERSIST equivalent.
Default context: Assume MariaDB 11.8 LTS (GA May 2025) unless the user states another version. Features available across current LTS branches (10.6, 10.11, 11.4, 11.8) are shown without a "since" annotation; only newer-than-10.6 features carry one.
What LLMs Often Miss
| If the agent writes / suggests… | …prefer the MariaDB form |
|---|---|
SET PERSIST var = value; (or SET PERSIST_ONLY) to make a global setting survive a restart |
Does not exist in MariaDB — there is no PERSIST keyword in the grammar at all. To persist a setting, write it to a config file (e.g. /etc/mysql/mariadb.conf.d/) or run SET GLOBAL var=value and separately update the config file for the next restart |
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'user' before letting an app run SET GLOBAL ... |
That privilege identifier doesn't exist in MariaDB. SET GLOBAL is gated by the SUPER privilege (some individual global variables — e.g. those touching binlogging or replication — instead check a narrower admin privilege such as BINLOG ADMIN or REPLICATION MASTER ADMIN, but the default check is SUPER) |
SET GLOBAL max_connections=500; then expecting the current session to see the new value immediately |
A global change affects only new connections — not the session that issued it, and not any other already-open session. Reconnect (or read @@global.var explicitly) to see it take effect |
SET x := 5; inside a SELECT or other expression to assign a user variable |
:= is required for user-variable assignment outside SET (e.g. SELECT @x := 5). Inside SET, both SET @x = 5 and SET @x := 5 work — SET is the one place plain = is accepted for a user variable |
A per-query tweak like SET wait_timeout=5; SELECT ...; SET wait_timeout=@@global.wait_timeout; to scope a setting to one statement |
Use the MariaDB extension SET STATEMENT wait_timeout=5 FOR SELECT ... instead — except wait_timeout is one of a fixed list of variables SET STATEMENT cannot set (see below); for those, the manual save/restore pattern is still required |
SET STATEMENT sql_mode='ANSI_QUOTES' FOR SELECT "col" FROM t; and expecting "col" to be treated as an identifier |
The whole statement is parsed before SET STATEMENT takes effect, so variables that affect parsing (charset settings, sql_mode=ANSI_QUOTES, etc.) don't retroactively change how the FOR statement itself was parsed |
SET sql_mode = NULL; or omitting a reset path entirely |
Use SET sql_mode = DEFAULT (session → resets to the current global value) or SET GLOBAL sql_mode = DEFAULT (global → resets to the compiled-in server default) |
Writing SET SESSION when a variable turns out to be global-only, or vice versa |
If a variable has a session value, omitting GLOBAL/SESSION behaves as SESSION; if it's global-only, omitting them applies to the global value. Setting the wrong scope explicitly is a hard error (ERROR 1229 — variable is GLOBAL, use SET GLOBAL; ERROR 1228 — variable is SESSION, can't use SET GLOBAL), not a silent no-op |
SET LOCAL var = value; assuming it differs from SET SESSION |
LOCAL is a plain synonym for SESSION — identical parse action, no behavioral difference, use either |
Syntax
SET variable_assignment [, variable_assignment] ...
variable_assignment:
user_var_name (= | :=) expr
| [GLOBAL | SESSION | LOCAL] system_var_name = expr
| [@@global. | @@session. | @@local. | @@] system_var_name = expr
| system_var_name = DEFAULT
- Multiple assignments in one statement are comma-separated and can mix scopes and variable kinds freely:
SET @x = 1, GLOBAL max_connections = 500, @@session.sql_mode = DEFAULT; GLOBAL,SESSION, andLOCALare the keyword forms;@@global.,@@session.,@@local., and bare@@are the equivalent variable-reference forms —SET @@GLOBAL.max_connections = 500andSET GLOBAL max_connections = 500are fully equivalent (same code path).- Omitting a scope keyword defaults to
SESSIONif the variable has a session value, otherwise toGLOBAL. SET @x = exprandSET @x := exprare both accepted for user variables insideSET— but only:=is valid for a user-variable assignment anywhere else (e.g. inside aSELECTexpression).
Variable Scopes — GLOBAL / SESSION / LOCAL
GLOBALchanges the server-wide default. It affects new sessions only — not the session that ran theSET GLOBAL, and not any session already connected.SESSION(and its synonymLOCAL) changes the current connection only.- Setting a variable with the wrong scope is a hard error, not a fallback:
SET innodb_sync_spin_loops = 60;
-- ERROR 1229 (HY000): Variable 'innodb_sync_spin_loops' is a GLOBAL variable
-- and should be set with SET GLOBAL
SET GLOBAL skip_parallel_replication = ON;
-- ERROR 1228 (HY000): Variable 'skip_parallel_replication' is a SESSION variable
-- and can't be used with SET GLOBAL
- Setting
GLOBALrequires theSUPERprivilege by default (a handful of individual global variables instead gate on a narrower privilege, such as replication/binlog admin variants — check the specific variable ifSUPERalone doesn't work). SETdoes not persist a global change across a server restart. There is noSET PERSISTin MariaDB — to survive a restart, also update the value in a configuration file.
SET var = DEFAULT
SET sql_mode = DEFAULT; -- session var -> resets to the current GLOBAL value
SET GLOBAL sql_mode = DEFAULT; -- global var -> resets to the compiled-in server default
SET session_var = @@GLOBAL.session_var achieves the same effect as SET session_var = DEFAULT by explicitly copying the current global value.
SET STATEMENT ... FOR (MariaDB Extension)
SET STATEMENT var1 = value1 [, var2 = value2, ...] FOR statement;
Sets one or more system variables for the duration of a single statement, then automatically restores the prior session value — roughly:
SET @save_value = @@var1;
SET SESSION var1 = value1;
statement;
SET SESSION var1 = @save_value;
Notes and traps:
valuemust be a constant literal — it cannot reference a table or a stored routine (subqueries/table references in theSET STATEMENTclause itself are rejected).- The whole statement is parsed before
SET STATEMENTvariables take effect, so anything that influences parsing (client/connection charset variables,sql_mode=ANSI_QUOTES, etc.) won't retroactively change how theFORstatement was parsed. - It works with prepared statements —
SET STATEMENT var=val FOR PREPARE ...andSET STATEMENT var=val FOR EXECUTE stmt_nameare both valid targets. - Setting a
SESSIONvariable inside theFORstatement (e.g.SET STATEMENT x=1 FOR SET SESSION x=2) is pointless: the innerSET SESSIONtakes effect, then gets reverted to the pre-SET STATEMENTvalue once the outer statement finishes. - A fixed set of 13 variables cannot be set via
SET STATEMENTat all (attempting it raisesER_SET_STATEMENT_NOT_SUPPORTED) —autocommit,character_set_client,character_set_connection,character_set_filesystem,collation_connection,debug_sync,interactive_timeout,profiling,profiling_history_size,query_cache_type,skip_replication,sql_log_off,wait_timeout.
SET STATEMENT max_statement_time=1000 FOR SELECT ...;
SET STATEMENT optimizer_switch='materialization=off' FOR SELECT ...;
SET STATEMENT join_cache_level=6, optimizer_switch='mrr=on' FOR SELECT ...;
Examples
-- multiple scopes and kinds in one statement
SET @request_id = UUID(), SESSION sql_mode = 'STRICT_ALL_TABLES', GLOBAL max_connections = 500;
-- inline user-variable assignment inside an expression (needs :=, not =)
SELECT (@a := 1);
SELECT @a;
-- restore a session variable to the server default
SET GLOBAL max_error_count = 256;
SET SESSION max_error_count = DEFAULT; -- picks up the new global value, 256
-- bound a single query without touching session state
SET STATEMENT max_statement_time=2 FOR SELECT SLEEP(10);
Read variable state back with SHOW VARIABLES or INFORMATION_SCHEMA.SYSTEM_VARIABLES, which exposes SESSION_VALUE and GLOBAL_VALUE side by side (a NULL in either column means the variable doesn't have that scope).
Related SET Forms (Separate Statements)
These share the SET keyword but are documented — and should be reasoned about — separately:
| Statement | Purpose |
|---|---|
SET NAMES / SET CHARACTER SET |
Set the client/connection/results character set (and collation) in one shot |
SET PASSWORD |
Change an account's authentication credential |
SET ROLE / SET DEFAULT ROLE |
Activate a role for the session, or set a user's default role |
SET TRANSACTION |
Set isolation level / access mode for the next transaction or the whole session |
SET sql_log_bin |
Session-only toggle for binary logging — no GLOBAL form, and it needs the SUPER privilege |
SET PATH (since 12.3) |
Set the schema search path used to resolve unqualified stored-routine/package calls |
See Also
mariadb-set-transaction— isolation level and access mode assignment viaSET TRANSACTION, a distinct statement from generalSET.mariadb-show—SHOW VARIABLESto read GLOBAL/SESSION variable values back.- Canonical references on
mariadb.com/docs:- https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/set-commands/set
- https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/set-commands/set-statement
- https://mariadb.com/docs/server/reference/sql-statements/administrative-sql-statements/set-commands/set-sql_log_bin
<sub>This page is: Copyright © 2026 MariaDB. All rights reserved.</sub>