set session报错error 1227是因为mysql 8.0+将会话级变量修改权拆分为独立权限session_variables_admin,需显式授予on .,不继承自super或all privileges,授/撤权后部分需flush privileges生效。

为什么SET SESSION报错ERROR 1227?
不是权限没刷、也不是用户密码错了,而是 MySQL 8.0+ 把会话级变量修改权拆成了独立权限:SESSION_VARIABLES_ADMIN。它和 SYSTEM_VARIABLES_ADMIN 不同,只管 SET SESSION,不管 SET GLOBAL 或 SET PERSIST。没这个权限,哪怕你是 root@localhost,执行 SET SESSION wait_timeout = 600 也会被拒。
如何授予SESSION\_VARIABLES\_ADMIN权限
必须用 GRANT 显式授权,不能靠 ALL PRIVILEGES 或 SUPER 自动继承:
-
GRANT SESSION_VARIABLES_ADMIN ON *.* TO 'dev_user'@'10.20.30.%';—— 主机部分别写%,生产环境建议限定具体网段 - 权限范围只能是
*.*,不支持库级或表级,写成ON mydb.*会直接报错ERROR 1064 (42000) - 授完权不用
FLUSH PRIVILEGES,GRANT语句本身已实时生效 - 验证是否成功:
SHOW GRANTS FOR 'dev_user'@'10.20.30.%';,输出里必须出现SESSION_VARIABLES_ADMIN
如何回收SESSION\_VARIABLES\_ADMIN权限
撤销操作必须精准,仅撤 SUPER 没用:
-
REVOKE SESSION_VARIABLES_ADMIN ON *.* FROM 'dev_user'@'10.20.30.%';—— 权限名大小写敏感,拼错就无效 - 执行后必须加
FLUSH PRIVILEGES;,否则权限变更不落地(这是唯一需要FLUSH的场景) - 撤销后,该用户仍可执行
SELECT @@session.wait_timeout,但不能再改值;SET SESSION会立刻返回ERROR 1227 - 注意:即使用户有角色(role),也不能靠角色继承此权限——它只能直接授给用户账号
容易被忽略的兼容性细节
SESSION_VARIABLES_ADMIN 在 MySQL 8.0.16+ 才完整支持,且和变量作用域强耦合:
- 它只控制“能否发起
SET SESSION请求”,不保证请求一定成功。比如SET SESSION sql_mode成功,但SET SESSION innodb_buffer_pool_size会失败——后者根本不是会话级变量 - 某些变量(如
autocommit)虽属会话级,但受全局read_only影响;权限有了,read_only=ON时照样改不了 - 应用连接池若在初始化 SQL 里硬写
SET SESSION,而连接用户没这个权限,就会在建连阶段报错,不是运行时才暴露











