全局变量(GLOBAL)影响所有新连接,但不自动生效于当前会话
MySQL 的
GLOBAL变量控制服务器级行为,比如
max_connections、
sort_buffer_size。修改它只会影响后续建立的连接,当前已存在的会话(包括你正在用的客户端)不会自动继承新值。 设置方式必须显式加
GLOBAL:
SET GLOBAL sort_buffer_size = 2097152;仅对 SUPER 权限用户可用;普通用户即使有
SESSION权限也无法改
GLOBAL部分变量是只读的(如
version),尝试设会报错:
ERROR 1238 (HY000): Variable 'version' is a read only variable重启 MySQL 后,未写入配置文件的
GLOBAL修改会丢失
会话变量(SESSION)只作用于当前连接,优先级高于全局变量
每个客户端连接启动时,会从当前
GLOBAL值拷贝一份作为自己的
SESSION初始值。之后对该变量的
SESSION级修改,只影响当前连接,不影响别人,也不影响新连接。 可省略
SESSION关键字(默认就是会话级):
SET sort_buffer_size = 4194304;等价于
SET SESSION sort_buffer_size = 4194304;普通用户只要权限允许(比如有
SELECT就能调
sql_mode这类会话变量),就能改自己的
SESSION变量 注意:有些变量不能在会话级修改(如
innodb_log_file_size),会直接报错
ERROR 1238
如何确认某个变量到底是全局还是会话级生效
最可靠的方式是查
information_schema或用
SHOW VARIABLES带作用域限定: 查全局值:
SHOW GLOBAL VARIABLES LIKE 'autocommit';查当前会话值:
SHOW SESSION VARIABLES LIKE 'autocommit';对比两者差异,能立刻看出是否已被当前会话覆盖:
SELECT @@global.autocommit, @@session.autocommit;注意
@@var_name默认取
SESSION值;要明确取全局必须写
@@global.var_name
常见踩坑:SET 不加作用域关键字时的行为模糊
执行
SET sort_buffer_size = 1024*1024看似简单,但它的实际作用域取决于变量是否支持会话级修改: 如果该变量允许
SESSION级设置(如
sort_buffer_size),则等价于
SET SESSION如果该变量**只支持**
GLOBAL(如
max_connections),则这条语句会报错:
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation更隐蔽的是某些变量既支持 GLOBAL 也支持 SESSION,但你没权限改 GLOBAL —— 此时语句静默变成 SESSION 级,容易误以为改了全局
所以,除非你明确知道变量类型和权限,否则建议始终显式写出
GLOBAL或
SESSION,避免歧义。
