mysql系统变量值可以更改,但部分只读变量(如secure_file_priv、datadir)必须修改配置文件并重启生效,与权限无关。

不能用 SET GLOBAL 修改的变量,基本不是权限问题,而是变量本身设计为只读。比如 secure_file_priv、innodb_buffer_pool_size、super_read_only(当 read_only 为 OFF 时)等,报错 Variable 'XXX' is a read only variable 是正常行为,跟用户有没有 SUPER 权限无关。
哪些变量必须改配置文件再重启?
MySQL 中有一类变量属于「启动参数」,仅在 mysqld 启动时读取一次,运行中不可动态修改:
-
secure_file_priv:限制LOAD DATA INFILE和SELECT ... INTO OUTFILE的路径,必须写进[mysqld]段落,重启生效 -
innodb_buffer_pool_size:InnoDB 缓冲池大小,5.7+ 支持在线调整部分场景,但初始值仍需配置文件设定;若报只读,说明当前实例不支持热调或未启用相关选项 -
datadir、socket、pid_file等基础路径类参数,全部只读 -
super_read_only依赖read_only:如果read_only=OFF,super_read_only就无法设为ON,且此时设它会直接报错「is a read only variable」
为什么 SET GLOBAL super_read_only = 0 有时失败?
这不是权限不足,而是触发了隐式依赖检查:
- 先执行
SELECT @@read_only, @@super_read_only;,确认两者是否都为1 - 如果
@@read_only = 0,则super_read_only实际处于未激活状态,此时设它会报只读错误 - 正确顺序是:
SET GLOBAL super_read_only = 0;→SET GLOBAL read_only = 0;,且两个操作都需要SUPER权限 - 注意:已存在的连接不会立即感知变更,新连接才受新值影响
检查 SUPER 权限只是排查第一步,不是万能解
即使你用 root@localhost 登录,也未必真有 SUPER 权限:
- 执行
SHOW GRANTS FOR CURRENT_USER;,确认输出里含GRANT SUPER ON *.* - 云数据库(如阿里云 RDS、腾讯云 CDB)默认禁用
SUPER,read_only和super_read_only只能通过控制台开关,SET GLOBAL必然失败 - Docker 容器中若用非标准启动方式(如
--defaults-file),可能绕过你认为生效的配置文件,导致变量实际没加载 - 权限没问题但还是报错?立刻怀疑变量类型——查官方文档确认它是 dynamic 还是 static
真正卡住人的地方,往往不是不知道要改配置,而是改了哪份配置、改在哪个段落、有没有被其他配置覆盖、重启的是不是目标实例——这些细节比权限判断更常出错。











