若super_read_only=ON且read_only=OFF,说明是MGR集群自动触发的保护性只读;两者均为ON时,需查variables_info确认变量是否动态可改,并核实SYSTEM_VARIABLES_ADMIN权限及配置文件加载情况。

查清是 super_read_only 还是变量本身只读
执行 SELECT @@global.super_read_only, @@global.read_only; —— 若前者为 ON,后者为 OFF,说明不是你手动设的只读,而是 MGR 集群自动触发的保护性只读;若两者都为 ON,再查 SELECT VARIABLE_NAME, VARIABLE_SCOPE, IS_DYNAMIC FROM performance_schema.variables_info WHERE VARIABLE_NAME = 'your_var';,确认该变量是否支持动态修改(IS_DYNAMIC = 'YES')且作用域为 GLOBAL。很多报错看似是权限问题,实际是变量在当前版本根本不可写,比如 explicit_defaults_for_timestamp 在 8.0.26+ 已变为只读。
确认 SET GLOBAL 权限是否真正生效
MySQL 8.0+ 不再靠 SUPER 控制全局变量修改,必须显式授予 SYSTEM_VARIABLES_ADMIN 权限。仅执行 REVOKE SUPER ON *.* FROM 'user'@'%'; 毫无意义,甚至可能留后门。正确做法是:
• 执行 SHOW GRANTS FOR 'user'@'%'; 确认输出中不含 SYSTEM_VARIABLES_ADMIN
• 若存在,运行 REVOKE SYSTEM_VARIABLES_ADMIN ON *.* FROM 'user'@'%';
• 最后别忘 FLUSH PRIVILEGES;,否则权限不刷新
注意:即使有权限,SET GLOBAL 对只读变量(如 version)、引擎依赖变量(如 innodb_buffer_pool_size 运行中不可调)或已由 MGR 锁定的变量(如 super_read_only)仍会失败,错误提示未必明确。
检查配置文件是否被加载、变量是否放对位置
很多“改了不生效”本质是配置没进 MySQL 的眼。先运行 mysql --help | grep "Default options" 看加载顺序,再用 ls -l /etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf 2>/dev/null 找出真实存在的那个。关键点:
• 所有服务端变量必须放在 [mysqld] 段下,写进 [client] 或裸露在文件开头会被忽略
• 变量名严格区分大小写(8.0+ 默认),max_connections 写成 MAX_CONNECTIONS 就报 Unknown system variable
• 单位必须大写:sort_buffer_size = 2M(小写 m 被当作文本)
• sql_mode 必须加单引号:sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
验证 SET PERSIST 是否真落盘且可加载
用 SET PERSIST 修改后以为万事大吉?不一定。它把值写入 mysqld-auto.cnf(路径由 SELECT @@datadir; 确认),但这个 JSON 文件一旦损坏,MySQL 启动直接失败。验证步骤:
• 查是否写入:SELECT * FROM performance_schema.persisted_variables WHERE VARIABLE_NAME = 'your_var';
• 查文件是否可写:ls -l $(mysql -Nse"SELECT @@datadir;")/mysqld-auto.cnf,确保属主和权限允许 mysqld 进程读写
• 查开关是否开启:SHOW VARIABLES LIKE 'persisted_globals_load'; 必须为 ON
• 若已损坏,不要手动编辑,用 RESET PERSIST your_var; 清除绑定,或临时加 --persisted_globals_load=OFF 启动恢复服务
MGR 自动锁死 super_read_only 和变量本身只读是两类完全不同的故障源,混在一起排查只会延长停机时间。前者看 performance_schema.replication_group_members,后者盯 variables_info 和权限表,不能跳过任一环节。










