mysql 8.0 彻底移除 grant ... identified by 语法,必须用 create user 显式指定 mysql_native_password 插件,且 alter user 改密需同时声明插件,否则默认切为 caching_sha2_password 导致客户端断连。

MySQL 8.0 执行 GRANT ... IDENTIFIED BY 直接报错
不是配置没开,也不是权限不够,是语法被彻底移除。你写的这句:GRANT SELECT ON app.* TO 'api_user'@'10.0.2.%' IDENTIFIED BY 's3cr3t!'; 在 MySQL 8.0 里会立刻触发 ERROR 1064 (42000),错误位置精准指向 IDENTIFIED BY。这不是兼容性警告,是解析器根本不认识这个语法路径。
CREATE USER 必须显式指定认证插件才能连上
即使你拆成两步写:CREATE USER 'u'@'%' IDENTIFIED BY 'pwd'; + GRANT ...,老客户端(比如 PyMySQL ERROR 1251 或 ERROR 2058。原因很简单:MySQL 8.0 默认用 caching_sha2_password 插件,而这些客户端压根不认。
正确写法必须带插件声明:CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';
-
IDENTIFIED WITH和BY是绑定的,漏掉任意一个都会报错 - 不要改全局
default_authentication_plugin,只针对具体用户设更安全 -
'u'@'%'和'u'@'localhost'是两个独立账户,本地连接走的是后者,常被忽略
ALTER USER 改密码会悄悄重置认证插件
这是最容易翻车的隐藏点:执行 ALTER USER 'u'@'%' IDENTIFIED BY 'new' 后,插件会被重置为默认的 caching_sha2_password,原来能连的用户突然断连,排查时根本想不到是这句惹的祸。
想只改密码不碰插件,必须写全:ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'new';
另外,SET PASSWORD FOR 在 8.0 已被禁用,执行即报 ERROR 1820;REVOKE 某些高权限(如 SYSTEM_USER)时,操作者自己也得有对应权限,否则报 ERROR 1227。
跨版本脚本唯一能跑通的写法
别指望用注释或条件判断绕过版本差异——MySQL 不支持 SQL 层面的 if-version。唯一可靠方案是统一用双方都认的语法:
- 开头用
CREATE USER IF NOT EXISTS 'u'@'h' IDENTIFIED WITH mysql_native_password BY 'p'; - 后面跟纯
GRANT语句,不带任何IDENTIFIED BY -
IF NOT EXISTS在 5.7 被忽略但不报错,在 8.0 生效,刚好兜底
真正麻烦的从来不是语法本身,而是插件、主机匹配、权限叠加这些细节在不同客户端和部署环节里反复咬人。











