mysql 8.0 不支持 create user ... like 语法,执行即报 error 1064;正确做法是先 create user 创建新用户(显式指定认证插件),再用 show grants 获取原用户权限并替换用户名后执行 grant,若涉及角色还需查询 mysql.role_edges 并额外授权。

直接执行 CREATE USER ... LIKE 会报错 ERROR 1064
MySQL 8.0 及所有当前稳定版本(包括 8.4)**根本不支持** CREATE USER 'newuser'@'%' LIKE 'olduser'@'%' 语法。这不是配置问题或权限不足,而是该语句从未被 MySQL 实现过——它属于 MariaDB 10.2+ 的特性,常被误传进 MySQL 场景。你执行就会立刻收到:ERROR 1064 (42000): You have an error in your SQL syntax。
SHOW GRANTS 输出不能直接执行,必须清洗
SHOW GRANTS FOR 'olduser'@'localhost' 返回的文本里混着两类干扰项:一是开头的 GRANT USAGE ON *.* TO 'olduser'@'localhost'(空权限,且依赖用户已存在);二是末尾的 REQUIRE NONE 或 REQUIRE SSL 子句(新用户还没建,执行就卡在 ERROR 1133 (HY000): Can't find any matching row in the user table)。
- 先用
CREATE USER 'newuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pwd'创建空用户(注意 host 必须和源用户一致,否则权限不生效) - 过滤掉所有含
USAGE的行——它不授任何实际权限,跳过最安全 - 用
sed "s/'olduser'@'localhost'/'newuser'@'localhost'/g"替换用户名(单引号要转义) - 若原用户有
REQUIRE SSL但新环境不需要,整段REQUIRE ...子句得删掉
角色权限不会出现在 SHOW GRANTS FOR user 里
如果源用户被授予了角色(比如 app_reader),SHOW GRANTS FOR 'olduser'@'%' **完全不会显示这条授权**。角色关系存在 mysql.role_edges 表里,必须额外查:
- 运行
SELECT FROM_USER, FROM_HOST, TO_USER, TO_HOST FROM mysql.role_edges WHERE TO_USER = 'olduser' AND TO_HOST = '%' - 对每条结果,手动执行
GRANT ROLE 'from_role' TO 'newuser'@'%' - 别忘了设默认角色:
SET DEFAULT ROLE 'from_role' TO 'newuser'@'%'
导入后不执行 FLUSH PRIVILEGES,新权限大概率不生效
即使所有 GRANT 语句都成功执行,新用户仍连不上或权限异常——最常见的原因是没刷缓存。MySQL 5.7+ 多数情况会自动重载,但显式执行 FLUSH PRIVILEGES; 是唯一稳妥做法,尤其当脚本跨版本混用、或权限表曾被直连修改过时。
别用 mysql -e "GRANT ...; GRANT ...;" 连续执行多条,单条失败就中断;改用 mysql 批量导入更可靠。另外,所有涉及的数据库(如 <code>GRANT SELECT ON mydb.* TO ...)必须已在目标实例中存在,否则直接报 ERROR 1044 (42000)。











