全局变量(GLOBAL)影响所有新连接但不生效于当前会话;会话变量(session)仅作用于当前连接且优先级更高;确认作用域应使用SHOW GLOBAL/SESSION VARIABLES或@@global./@@session.前缀。

全局变量(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,避免歧义。