MySQL 8.0中GRANT不能创建用户或设密码,必须先CREATE USER(指定插件)再GRANT授权,否则报ERROR 1064或1410;认证与授权强制分离,且caching_sha2_password插件易导致客户端连接失败。

GRANT 命令在 MySQL 8.0 中根本不能创建用户,这不是功能削弱,而是权限模型的强制重构:认证(你是谁)和授权(你能做什么)必须分离。
MySQL 8.0 执行 GRANT ... IDENTIFIED BY 直接报错 ERROR 1064
你写的语句类似 GRANT SELECT ON db.* TO 'u'@'%' IDENTIFIED BY 'p',MySQL 8.0 解析器会在语法层面拒绝——IDENTIFIED BY 已从 GRANT 语法规则中彻底移除。这不是执行时报错,而是压根不认这个写法。
- 报错信息通常是:
ERROR 1064 (42000): You have an error in your SQL syntax,错误位置指向IDENTIFIED关键字 - 旧脚本里用正则批量替换时,别只删
IDENTIFIED BY,必须拆成两行:CREATE USER+GRANT -
GRANT ALL PRIVILEGES ON *.* TO 'u'@'%'单独执行也会失败,提示ERROR 1410 (42000): You are not allowed to create a user with GRANT,哪怕你是 root
CREATE USER 必须显式指定 host 和认证插件
MySQL 8.0 默认用 caching_sha2_password 插件,但很多客户端(Navicat 11、老版 JDBC、PHP mysqli)不支持它,导致“SQL 成功执行,连接却卡死或报 ERROR 2058”。
- 安全且兼容的写法是:
CREATE USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'p@ss' -
'app'@'localhost'和'app'@'%'是两个完全独立的用户,权限、密码、插件互不影响 - 如果只写
CREATE USER 'app'@'%' IDENTIFIED BY 'p',MySQL 会按全局default_authentication_plugin走,默认就是caching_sha2_password - 已存在用户要换插件,用
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'p',之后建议跟一句FLUSH PRIVILEGES
ALTER USER 是改密唯一合法途径
密码修改不能再靠 GRANT,也不能 UPDATE mysql.user 或 SET PASSWORD —— 这些在 8.0 中要么语法失效,要么写入后认证必然失败。
- 改密必须走
ALTER USER 'u'@'h' IDENTIFIED BY 'new'(沿用原插件)或IDENTIFIED WITH plugin BY 'new'(换插件) - 对拥有
SYSTEM_USER权限的账户(如root)执行ALTER USER,操作者自己也得有SYSTEM_USER权限,否则报ERROR 1227 -
REVOKE某些高权权限(如SYSTEM_USER)也可能触发同样检查,不是权限没撤掉,而是你没资格撤
FLUSH PRIVILEGES 不是万能钥匙,但常被误用
CREATE USER 和 GRANT 在 8.0 大部分场景下已自动生效,FLUSH PRIVILEGES 并非必需;但它在改认证插件或直接操作系统表后是必须的。
- 建户+授权后加一句
FLUSH PRIVILEGES没坏处,属于保险操作 - 真正容易漏的是 host 匹配逻辑:
'u'@'%'允许远程连接,但本地用mysql -u u -p默认走 socket,匹配的是'u'@'localhost',不是同一个账号 - 调试连不上时,先查
SELECT User,Host,plugin FROM mysql.user WHERE User='u';,确认实际生效的是哪条记录
插件兼容性和 SYSTEM_USER 权限这两类问题,不会在 SQL 执行时暴露,而是在后续连接或操作中突然失效——它们藏在“成功”之后,而不是之前。


















