MySQL里没有“用户”和“账户”的本质区别——user
就是账户,账户就是 user
,二者是同一概念在不同语境下的说法。 所谓“用户”指的就是能连上 MySQL 实例、带用户名+主机名+密码+权限的一套认证实体;所谓“账户”只是更偏运维/安全角度的叫法。真正有区分意义的是“系统用户”和“普通用户”,这是从 MySQL 8.0.16 起引入的权限层级控制机制,不是命名习惯问题,而是安全策略落地的关键。
为什么必须区分“系统用户”和“普通用户”?
这不是为了分类而分类,而是为堵住一个真实存在的提权漏洞:
在 MySQL 8.0.16 之前,只要用户有CREATE USER或
SUPER权限,就能
DROP USER 'root'@'localhost'—— 真的能删掉 root 也能执行
ALTER USER 'root'@'localhost' IDENTIFIED BY 'xxx',直接劫持最高权限账号 攻击者一旦拿下一个有
GRANT OPTION的 DBA 账号,就等于拿下了整个实例
引入
SYSTEM_USER权限后,上述操作是否生效,不再只看有没有
CREATE USER,而要看执行者自己是不是“系统用户”。它像一道闸门:没这把钥匙,连 root 的密码都改不了。
怎么判断一个账号是不是“系统用户”?
查
mysql.user表里的
System_user字段(注意大小写),或者用
SHOW GRANTS看是否含
SYSTEM_USER权限:
SELECT User, Host, System_user FROM mysql.user;
或
SHOW GRANTS FOR 'admin'@'%';
输出中若含
GRANT SYSTEM_USER ON *.* TO ...,就是系统用户。注意:
SYSTEM_USER是独立权限,不附带任何其他能力(比如不能
SELECT、不能
CREATE DATABASE),它只管“能不能动系统级账号”这一件事。
创建/修改系统用户时最容易踩的坑
CREATE USER本身不授予
SYSTEM_USER权限,必须显式
GRANT:
CREATE USER 'sysop'@'%' IDENTIFIED BY 'p@ssw0rd'; GRANT SYSTEM_USER ON *.* TO 'sysop'@'%';普通用户即使有
CREATE USER,也无法给他人授
SYSTEM_USER权限(会报错
ERROR 1045 (28000): Access denied) 用
ALTER USER ... REQUIRE ISSUER等高级认证选项修改系统用户时,执行者也必须是系统用户,否则直接拒绝 MySQL 8.0.16+ 默认 root 是系统用户,但如果你用
mysqld --initialize初始化后手动改过 root 密码,没补
GRANT SYSTEM_USER,它可能已降级为普通用户——此时你反而无法再用 root 去管理其他系统用户
真正容易被忽略的是:系统用户的“系统性”不体现在登录方式或存储位置,而完全由权限位控制;它不改变账号结构(仍是
'user'@'host'),也不影响连接行为,只在执行特定 DDL 操作时动态拦截。别被名字带偏——重点永远是权限表里那一个
Y或
N。
