必须将activate_all_roles_on_login=ON写入my.cnf持久化,否则重启失效;该变量与SET DEFAULT ROLE互斥,启用后所有已授角色自动激活,且需确保角色已显式授予用户、host精确匹配、账号状态正常。

activate_all_roles_on_login 必须写进 my.cnf 才算真正启用
只执行 SET GLOBAL activate_all_roles_on_login = ON 是无效的——该变量重启后恢复 OFF,且仅影响新连接,已有连接不会刷新。生产环境必须将配置持久化到文件,否则每次重启 MySQL 权限就“掉线”。
编辑 /etc/my.cnf 或 /usr/my.cnf,在 [mysqld] 段下添加:
activate_all_roles_on_login=ON
然后重启 MySQL 或执行 FLUSH PRIVILEGES(部分版本需重启才生效)。
验证是否成功:
SELECT @@activate_all_roles_on_login;
返回 1 才表示已启用。
SET DEFAULT ROLE 和 activate_all_roles_on_login 互斥
这两个机制不能共存:一旦 activate_all_roles_on_login=ON 生效,SET DEFAULT ROLE 就完全失效。所有已授予该用户的角色都会在登录时自动激活,不再受“默认角色列表”限制。
如果你依赖最小权限原则,比如只希望用户登录时激活 'app_reader' 而非全部角色,就必须保持 activate_all_roles_on_login=OFF(即默认值),并严格使用:
GRANT 'app_reader' TO 'user1'@'%'SET DEFAULT ROLE 'app_reader' TO 'user1'@'%'
注意 host 必须精确匹配,'user1'@'localhost' 无法继承 'app_reader'@'%' 的默认设置。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
为什么开了 activate_all_roles_on_login 还没权限?检查三个硬前提
常见现象是变量已设为 ON,但用户登录后仍报 ERROR 1142 (42000): SELECT command denied。这不是配置失败,而是以下任一条件未满足:
- 角色必须已通过
GRANT 'role_name' TO 'user'@'host'显式授予(mysql.role_edges表中要有对应记录) - 用户账号不能处于
account_locked = Y或password_expired = Y状态 - 用户登录所用的 host 必须和授角色时的 host 完全一致(
'user'@'%' ≠ 'user'@'localhost')
验证命令:
SELECT * FROM mysql.role_edges WHERE to_user = 'user1' AND to_host = 'localhost';
角色名大小写与特殊字符要小心
activate_all_roles_on_login 本身不处理大小写,但角色名是否区分大小写取决于 lower_case_table_names 系统变量。若该值为 0,则 'Admin'@'%' 和 'admin'@'%' 是两个独立角色;若为 1,则会被统一转为小写。
含连字符或点号的角色名(如 'ci-pipeline'、'dev.db')在 SET ROLE 中必须用反引号包裹:
SET ROLE `ci-pipeline`;
但 activate_all_roles_on_login 不涉及语法解析,它只控制“已授予的角色是否自动激活”,所以这类角色只要被正确授予,就能被自动激活。
实际生效的关键不在“设没设”,而在“有没有完整走完角色生命周期”:创建 → 授权给角色 → 授予角色给用户 → (可选)设默认角色或开全局激活 → 用户重连验证。漏掉中间任何一环,CURRENT_ROLE() 都会返回 NONE。










