MySQL 8.0 废弃 GRANT ... IDENTIFIED BY 语法,须拆分为 CREATE USER + GRANT;ALTER USER 默认重置认证插件为 caching_sha2_password,需显式指定;默认启用 ONLY_FULL_GROUP_BY 和窗口函数、CTE,int(11) 等显示宽度被弃用。

GRANT 语句里带 IDENTIFIED BY 就会报错
MySQL 8.0 直接拒绝 GRANT ... IDENTIFIED BY 这种写法,而 5.7 默认允许。这不是警告,是硬性语法错误:ERROR 1064 (42000): You have an error in your SQL syntax [...] near 'IDENTIFIED BY'。
- 5.7 中
GRANT SELECT ON db.* TO 'u'@'%' IDENTIFIED BY 'p'会自动建用户并赋权 - 8.0 必须拆成两步:
CREATE USER 'u'@'%' IDENTIFIED BY 'p'→GRANT SELECT ON db.* TO 'u'@'%' - 如果脚本要兼容双版本,用
CREATE USER IF NOT EXISTS+ 独立GRANT最稳妥 - 注意:5.7 的
CREATE USER不支持 8.0 的PASSWORD EXPIRE等参数,跨版本初始化别混用
ALTER USER 修改密码时认证插件会被悄悄覆盖
在 8.0 中执行 ALTER USER 'u'@'%' IDENTIFIED BY 'new',哪怕原用户是用 mysql_native_password 创建的,这条语句也会把认证插件重置为默认的 caching_sha2_password —— 导致旧客户端突然连不上。
- 修复不是改密码,而是显式指定插件:
ALTER USER 'u'@'%' IDENTIFIED WITH mysql_native_password BY 'new' - Windows 安装器里勾选 “Use Legacy Authentication Method” 可避免这个问题
- MySQL 8.4 已彻底废弃
mysql_native_password,现在迁就旧驱动,后面升级会更被动
GROUP BY 和窗口函数不能混着写
5.7 允许 SELECT a, b FROM t GROUP BY a(b 没聚合也没在 GROUP BY 里),8.0 默认报错:Expression #2 of SELECT list is not in GROUP BY clause;同时 8.0 支持 ROW_NUMBER() OVER(...),但 5.7 根本不认识这个语法。
- 8.0 的
sql_mode默认启用ONLY_FULL_GROUP_BY,关掉它只是掩耳盗铃,应补全聚合或改用窗口函数 - 想加序号:8.0 用
ROW_NUMBER() OVER (ORDER BY x),5.7 只能靠用户变量模拟,且顺序不可靠 - CTE(
WITH t AS (...))在 5.7 是语法错误,在 8.0 才合法
建表时 int(11) 这种写法会触发弃用警告
从 MySQL 8.0.17 开始,int(11) 中的显示宽度被标记为 deprecated,执行建表语句不会失败,但会输出警告:Integer display width is deprecated and will be removed in a future release。
- 建议统一写成
int,不要带括号数字;tinyint(1)也一样,尤其别在布尔场景里依赖它 - 5.7 中
BOOL会被转成tinyint(1),8.0.4+ 对BOOL类型更严格,某些上下文可能直接报错 - 字符集相关字段更要小心:
utf8mb4_0900_ai_ci排序比utf8mb4_unicode_ci更严格,ORDER BY或唯一索引行为可能变化
实际迁移时最容易卡住的,不是功能有没有,而是那些“看起来没变、跑起来就崩”的隐性约束:认证插件切换无声无息,sql_mode 变严不报错只报错,GROUP BY 规则收紧后业务查询直接挂掉。这些点不提前扫清,dump/restore 后第一波请求就可能集体失败。


















