MySQL 5.7 允许 IDENTIFIED BY 明文密码或弃用的 BY PASSWORD(仅接受 SHA1 哈希),而 8.0 彻底移除 BY PASSWORD,强制明文输入并由服务端用 SHA2-256 哈希,认证插件默认改为 caching_sha2_password,需显式指定 mysql_native_password 以兼容旧客户端。

MySQL 5.7 的 IDENTIFIED BY 用法是“够用但宽松”
在 5.7 中,IDENTIFIED BY 可以直接跟明文密码(如 IDENTIFIED BY '123'),也能配合 BY PASSWORD 使用(如 IDENTIFIED BY PASSWORD '*ABC...')。但注意:BY PASSWORD 已被标记为弃用,且仅接受 MySQL 自己生成的哈希值(SHA1(SHA1(password))),不校验格式合法性——输错长度或非法字符也不会报错,只是后续登录失败。
常见错误现象:
- 用
CREATE USER 'u'@'%' IDENTIFIED BY PASSWORD 'abc'创建用户后无法登录,因为'abc'不是合法哈希值,但语句不报错 - 升级到 8.0 后,这类用户仍可登录,但无法再用
BY PASSWORD修改密码
MySQL 8.0 彻底移除了 BY PASSWORD,且强制密码强度与认证插件绑定
8.0 删除了 IDENTIFIED BY PASSWORD 语法,所有密码必须以明文形式传入 IDENTIFIED BY,由服务端自动哈希。同时默认认证插件从 mysql_native_password 变为 caching_sha2_password,这直接影响密码存储格式和客户端兼容性。
关键差异点:
-
CREATE USER 'u'@'%' IDENTIFIED BY 'pwd'在 8.0 中会使用 SHA2-256 哈希,并存入mysql.user.authentication_string字段(不再写password字段) - 如果客户端不支持
caching_sha2_password(如老版本 MySQL Connector/J 5.1、某些 PHP mysqli 扩展),连接会直接报错Authentication plugin 'caching_sha2_password' cannot be loaded - 想降级兼容,需显式指定插件:
CREATE USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'
ALTER USER 时 IDENTIFIED BY 的行为变化最易踩坑
5.7 中 ALTER USER 'u'@'%' IDENTIFIED BY 'new' 是安全的,等价于重置密码;但在 8.0 中,这条语句会**覆盖当前用户的认证插件为默认插件**(即 caching_sha2_password),即使原用户是用 mysql_native_password 创建的。
这意味着:
- 一个原本能被旧客户端连接的用户,执行一次无插件声明的
ALTER USER ... IDENTIFIED BY后就可能突然连不上 - 修复方式不是改密码,而是重置插件:
ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'new' -
SET PASSWORD FOR 'u'@'%' = 'xxx'在 8.0 中已被禁用(报错ERROR 1820 (HY000): You must reset your password using ALTER USER statement)
迁移时如何安全处理授权语句中的 IDENTIFIED BY
从 5.7 升级到 8.0 后,存量用户不会自动变更插件类型,但任何涉及 IDENTIFIED BY 的 DDL 都可能意外切换插件。实操建议:
- 升级前导出用户权限时,用
mysqldump --no-data --skip-triggers --databases mysql,检查mysql.user表中plugin和authentication_string字段,确认是否混用多种插件 - 自动化脚本中避免裸写
IDENTIFIED BY,统一显式声明插件:CREATE USER IF NOT EXISTS ... IDENTIFIED WITH mysql_native_password BY ... - 应用连接字符串中显式指定
?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false(针对 Java 客户端),否则caching_sha2_password握手可能失败
真正麻烦的不是语法报错,而是“语句执行成功,但下游连接静默中断”——这种问题往往卡在中间件或监控盲区里。


















