15.7.6.1 变量赋值的 SET 语法
SET variable = expr [, variable = expr] ...
variable: {
user_var_name
| param_name
| local_var_name
| {GLOBAL | @@GLOBAL.} system_var_name
| {PERSIST | @@PERSIST.} system_var_name
| {PERSIST_ONLY | @@PERSIST_ONLY.} system_var_name
| [SESSION | @@SESSION. | @@] system_var_name
}
SET
语法用于变量赋值,允许您将值分配给影响服务器或客户端操作的不同类型的变量:
-
自定义变量。请参阅第11.4节,“自定义变量”。
-
存储程序和函数参数,以及存储程序的局部变量。请参阅第15.6.4节,“存储程序中的变量”。
-
系统变量。请参阅第7.1.8节,“服务器系统变量”。系统变量也可以在服务器启动时设置,详见第7.1.9节,“使用系统变量”。
使用SET
语句将变量值分配的语句,不会写入二进制日志,因此在复制场景中只影响执行该语句的主机。要影响所有复制主机,请在每个主机上执行语句。
以下部分描述了SET
语法用于设置变量。它们使用=
赋值操作符,但:=
赋值操作符也允许用于该目的。
自定义变量是在会话中创建的,仅在该会话的上下文中存在;请参阅第11.4节,“自定义变量”。
自定义变量以@
的形式写入,并且可以分配表达式值如下:var_name
SET @var_name = expr;
示例:
SET @name = 43;
SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);
如示例语句所示,expr
可以从简单的文字值到复杂的值(由标量子查询返回的值)等。
性能_schemauser_variables_by_thread
表包含关于自定义变量的信息。请参阅第29.12.10节,“性能_schema自定义变量表”。
SET
适用于参数和本地变量在其定义的存储对象的上下文中。以下过程使用increment
过程参数和counter
本地变量:
CREATE PROCEDURE p(increment INT)
BEGIN
DECLARE counter INT DEFAULT 0;
WHILE counter < 10 DO
-- ... do work ...
SET counter = counter + increment;
END WHILE;
END;
MySQL 服务器维护系统变量,以配置其操作。系统变量可以具有全局值,影响服务器的整个操作,会话值,影响当前会话,或者两者都可以。许多系统变量是动态的,可以在运行时使用SET
语句来更改当前服务器实例的操作。使用SET
也可以将某些系统变量持久化到mysqld-auto.cnf
文件中,以影响后续启动的服务器操作。
如果对敏感系统变量进行了SET
语句,查询将被重写,以将值替换为“<redacted>
”,即使服务器实例中没有可用的加密存储组件。
如果您更改了会话系统变量,值将在您的会话中保持有效,直到您将变量更改为不同的值或会话结束。该更改对其他会话无效。
如果您更改了全局系统变量,值将被记住,并在新会话中初始化为该值,直到您将变量更改为不同的值或服务器退出。该更改对任何访问全局值的客户端可见。然而,该更改仅对连接后更改的会话生效,不会影响当前会话(包括在更改全局值的会话中)。
为了使全局系统变量设置永久生效,以便在服务器重启后生效,可以将其 persisted 到数据目录中的 mysqld-auto.cnf
文件中。也可以通过手动修改 my.cnf
选项文件来实现持久化配置更改,但是这更为繁琐,并且可能会在很久后才发现错误的设置。使用 SET
语句来 persist 系统变量更为方便,并且避免了由于语法错误而导致的设置,因为语法错误的设置将不会生效且不会更改服务器配置。关于 persist 系统变量和 mysqld-auto.cnf
文件的更多信息,请见 第7.1.9.3节,“Persisted System Variables”。
设置或 persist 全局系统变量值总是需要特殊权限。设置会话系统变量值通常不需要特殊权限,可以由任何用户执行,虽然有一些例外。关于系统变量权限的更多信息,请见 第7.1.9.1节,“System Variable Privileges”。
以下讨论描述了设置和 persist 系统变量的语法选项:
-
要将值分配给全局系统变量,precede 变量名称以
GLOBAL
关键字或@@GLOBAL.
限定符:SET GLOBAL max_connections = 1000; SET @@GLOBAL.max_connections = 1000;
-
要将值分配给会话系统变量,precede 变量名称以
SESSION
或LOCAL
关键字,@@SESSION.
、@@LOCAL.
或@@
限定符,或者不使用关键字或修改器:SET SESSION sql_mode = 'TRADITIONAL'; SET LOCAL sql_mode = 'TRADITIONAL'; SET @@SESSION.sql_mode = 'TRADITIONAL'; SET @@LOCAL.sql_mode = 'TRADITIONAL'; SET @@sql_mode = 'TRADITIONAL'; SET sql_mode = 'TRADITIONAL';
客户端可以更改自己的会话变量,但不能更改其他客户端的变量。
-
要 persist 全局系统变量到
mysqld-auto.cnf
选项文件中,precede 变量名称以PERSIST
关键字或@@PERSIST.
限定符:SET PERSIST max_connections = 1000; SET @@PERSIST.max_connections = 1000;
这
SET
语法使您可以在运行时实现配置更改,并且这些更改也将 persist 到服务器重启后。像SET GLOBAL
,SET PERSIST
也将设置全局变量的运行值,但还将将变量设置写入mysqld-auto.cnf
文件(如果存在变量设置,则将其替换)。 -
要 persist 全局系统变量到
mysqld-auto.cnf
文件中,而不设置全局变量的运行值,precede 变量名称以PERSIST_ONLY
关键字或@@PERSIST_ONLY.
限定符:SET PERSIST_ONLY back_log = 100; SET @@PERSIST_ONLY.back_log = 100;
像
PERSIST
一样,PERSIST_ONLY
将变量设置写入到mysqld-auto.cnf
中。然而,和PERSIST
不同的是,PERSIST_ONLY
不会修改全局变量的运行时值。这使得PERSIST_ONLY
适用于配置只在服务器启动时可设置的只读系统变量。
要将全局系统变量的值设置为编译时的 MySQL 默认值或会话系统变量的值设置为当前对应的全局值,请将变量设置为DEFAULT
。例如,以下两个语句在将会话值max_join_size
设置为当前全局值时是等效的:
SET @@SESSION.max_join_size = DEFAULT;
SET @@SESSION.max_join_size = @@GLOBAL.max_join_size;
使用SET
语句将全局系统变量设置为DEFAULT
或其字面值默认值将变量设置为其默认值,并将变量添加到mysqld-auto.cnf
中。要从文件中删除变量,请使用RESET PERSIST
。
一些系统变量不能被持久化或是持久化受限。请参见第7.1.9.4节,“非持久化和持久化受限系统变量”。
由插件实现的系统变量可以被持久化,如果插件在执行SET
语句时安装了。将持久化的插件变量的赋值将在服务器重启后生效,如果插件仍安装。如果插件不再安装,插件变量将在服务器读取mysqld-auto.cnf
文件时消失。在这种情况下,服务器将在错误日志中写入警告并继续:
currently unknown variable 'var_name'
was read from the persisted config file
显示系统变量名称和值:
-
使用
SHOW VARIABLES
语句;请参见第15.7.7.40节,“SHOW VARIABLES Statement”。 -
Performance Schema 表提供了系统变量信息。请参见第29.12.14节,“Performance Schema System Variable Tables”。
-
Performance Schema
variables_info
表包含了显示每个系统变量最近一次被设置的时间和设置该变量的用户的信息。请参见第29.12.14.2节,“Performance Schema variables_info Table”。 -
性能_schemapersisted_variables 表提供了 SQL 接口,以便在运行时使用
SELECT
语句来检查mysqld-auto.cnf
文件的内容。请参阅第29.12.14.1节,“性能_schema persisted_variables 表”。
如果在SET 语句中出现变量分配失败,整个语句将失败,并且不会更改任何变量,也不会更改 mysqld-auto.cnf
文件。
SET 在这里描述的情况下将产生错误。多数示例显示使用关键字语法(例如 GLOBAL
或 SESSION
),但原则也适用于使用相应修饰符(例如 @@GLOBAL.
或 @@SESSION.
)的语句。
-
使用SET(任何变体)来设置只读变量:
mysql> SET GLOBAL version = 'abc'; ERROR 1238 (HY000): Variable 'version' is a read only variable
-
使用
GLOBAL
、PERSIST
或PERSIST_ONLY
来设置只有会话值的变量:mysql> SET GLOBAL sql_log_bin = ON; ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION variable and can't be used with SET GLOBAL
-
使用
SESSION
来设置只有全局值的变量:mysql> SET SESSION max_connections = 1000; ERROR 1229 (HY000): Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
-
省略
GLOBAL
、PERSIST
或PERSIST_ONLY
来设置只有全局值的变量:mysql> SET max_connections = 1000; ERROR 1229 (HY000): Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
-
使用
PERSIST
或PERSIST_ONLY
来设置不能被持久化的变量:mysql> SET PERSIST port = 3307; ERROR 1238 (HY000): Variable 'port' is a read only variable mysql> SET PERSIST_ONLY port = 3307; ERROR 1238 (HY000): Variable 'port' is a non persistent read only variable
-
@@GLOBAL.
、@@PERSIST.
、@@PERSIST_ONLY.
、@@SESSION.
和@@
修饰符仅适用于系统变量。对用户定义变量、存储程序或函数参数或存储程序局部变量的尝试将产生错误。 -
不所有系统变量都可以设置为
DEFAULT
。在这种情况下,分配DEFAULT
将产生错误。 -
对用户定义变量、存储程序或函数参数或存储程序局部变量的尝试将产生错误。
一个SET 语句可以包含多个变量分配,使用逗号分隔。这个语句将分配一个用户定义变量和一个系统变量:
SET @x = 1, SESSION sql_mode = '';
如果您在单个语句中设置多个系统变量,那么语句中的最新的GLOBAL
、PERSIST
、PERSIST_ONLY
或SESSION
关键字将用于后续没有指定关键字的分配。
多个变量分配的示例:
SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;
SET @@GLOBAL.sort_buffer_size = 1000000, @@LOCAL.sort_buffer_size = 1000000;
SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;
@@GLOBAL.
、@@PERSIST.
、@@PERSIST_ONLY.
、@@SESSION.
和@@
修饰符仅适用于紧接的系统变量,而不是任何剩余的系统变量。这条语句将将sort_buffer_size
的全局值设置为50000,并将会话值设置为1000000:
SET @@GLOBAL.sort_buffer_size = 50000, sort_buffer_size = 1000000;
系统变量引用在表达式中
要在表达式中引用系统变量的值,请使用@@
-修饰符(除了@@PERSIST.
和@@PERSIST_ONLY.
,这两个在表达式中不可用)。例如,您可以在SELECT
语句中检索系统变量值:
SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode, @@sql_mode;
在表达式中引用系统变量的值为@@
(使用var_name
@@
而不是@@GLOBAL.
或@@SESSION.
),返回会话值如果存在,否则返回全局值。这与SET @@
不同,该语句总是引用会话值。var_name
= expr