ERROR 1227是因为MySQL 8.0+要求显式授予SYSTEM_VARIABLES_ADMIN权限才能执行SET GLOBAL或SET PERSIST,该权限不继承自SUPER、ALL PRIVILEGES或角色,且必须精确匹配user@host并限定为ON .。

为什么SET GLOBAL报ERROR 1227?
因为MySQL 8.0+移除了SUPER权限对系统变量的隐式覆盖,SET GLOBAL和SET PERSIST必须显式拥有SYSTEM_VARIABLES_ADMIN权限——哪怕你给了ALL PRIVILEGES ON *.*或SUPER,只要没单独授这个权限,照样报错ERROR 1227 (42501)。
常见误判是以为“root账号肯定能改”,但root@localhost账户若未执行过GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'root'@'localhost',就真的不能改。
- 权限匹配严格依赖
user+host组合,'admin'@'%'≠'admin'@'10.0.2.5' -
SYSTEM_VARIABLES_ADMIN不继承自角色,也不能授给角色,只能直接授给用户 - 授完权无需
FLUSH PRIVILEGES,GRANT语句本身已实时生效
如何正确授予SYSTEM\_VARIABLES\_ADMIN权限
必须用GRANT语法,且范围只能是*.*,其他写法会直接报错:
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'admin_user'@'192.168.1.%';
注意几个硬性限制:
- 不能写成
ON mysql.*或ON app_db.*,MySQL会返回ERROR 1064 (42000) - 主机部分别偷懒用
'%',生产环境应限定网段(如'10.10.20.%')或具体IP - 不能通过
UPDATE mysql.user表手动插入权限字段——元数据不校验、权限不生效,还可能损坏权限系统 - 验证是否成功:运行
SHOW GRANTS FOR 'admin_user'@'192.168.1.%',输出里必须明确出现该权限项
撤销后SET GLOBAL还能执行?这是正常现象
撤销SYSTEM_VARIABLES_ADMIN后SET GLOBAL仍可能成功,这不是权限没撤掉,而是因为:
- 某些变量(如
sql_mode)允许会话级修改绕过全局权限检查 - 旧版遗留的
CONNECTION_ADMIN或SUPER权限仍可能覆盖部分变量控制逻辑 - 已通过
SET GLOBAL生效的值不会被自动回滚,撤销权限只阻止后续修改
真正清理历史变更,必须重启MySQL并确保配置文件中没有残留的手动设置(比如my.cnf里写的max_connections = 500),否则重启后还是那个值。
开发人员到底要不要这个权限?
不要。这不是开发权限,是DBA级运维权限。
SYSTEM_VARIABLES_ADMIN允许修改所有动态全局变量,包括read_only、innodb_buffer_pool_size、max_connections等直接影响服务稳定性的项。开发真正需要的是对象级权限(如SELECT、CREATE ROUTINE),不是实例状态控制权。
如果真要临时调试,优先走配置文件+重启流程,而不是给开发开SET GLOBAL口子——一次误操作就能让主库内存爆满或连接数打穿。


















