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

CREATE USER ... LIKE 语法在 MySQL 8.0 中根本不存在,执行会直接报错 ERROR 1064 (42000): You have an error in your SQL syntax。这不是配置问题,也不是版本没升级到位,而是 MySQL 官方从未实现该语法——它属于 MariaDB(10.2+)的功能,常被误传进 MySQL 场景。
SHOW GRANTS + CREATE USER + GRANT 是唯一可靠路径
MySQL 8.0 的权限模型依赖认证插件、密码历史策略、角色继承等多层逻辑,无法靠“复制语句”或“dump mysql库”绕过校验。
-
SHOW GRANTS FOR 'olduser'@'%'返回的是可重放的授权语句,但需人工替换用户名 - 必须先用
CREATE USER显式创建新用户,并指定认证插件(如mysql_native_password),否则可能因默认caching_sha2_password导致旧客户端连不上 - 若原用户有角色(比如被授予
app_reader角色),仅靠SHOW GRANTS拿不到角色信息,必须额外查mysql.role_edges并执行GRANT ROLE ... TO
示例:
CREATE USER 'newuser'@'%' IDENTIFIED WITH mysql_native_password BY 'p@ssw0rd'; GRANT SELECT, INSERT ON app_db.* TO 'newuser'@'%'; GRANT app_reader TO 'newuser'@'%'; SET DEFAULT ROLE app_reader TO 'newuser'@'%';
CLONE PLUGIN 和用户权限克隆完全无关
CLONE LOCAL DATA DIRECTORY 或 CLONE INSTANCE 克隆的是整个数据目录的物理文件:ibd、redo log、undo tablespace、系统表数据……但它不会解析或重建权限逻辑。
- 即使你克隆出一个新实例,里面的
mysql.user表数据是二进制拷贝,但:- 新实例启动后会加载这些记录,但密码哈希是否能被当前认证插件识别,取决于插件兼容性
-
password_reuse_history、password_require_current等 8.0 新字段若在源实例未初始化,克隆后可能为 NULL,触发权限校验异常 - 如果源实例用了自定义角色映射或动态权限(如
APPLICATION_PASSWORD_ADMIN),克隆后不会自动生效
换句话说:CLONE 是“盘对盘复制”,不是“权限逻辑复刻”。
容易踩的坑:别碰 mysql.user 手动 INSERT 或 mysqldump
- 直接
INSERT INTO mysql.user会因字段缺失(如 8.0 新增的 5+ 个密码策略字段)报错ERROR 1136 (21S01): Column count doesn't match value count -
mysqldump mysql导出的 INSERT 语句在 8.0+ 上基本不可重放,FLUSH PRIVILEGES也无法修复字段不匹配问题 - 启用
skip-grant-tables后创建的用户,在重启服务后会彻底丢失权限,且无法通过常规方式恢复
真正安全的做法只有两条路:
- 走
SHOW GRANTS→ 替换 → 执行,适用于少量用户 - 写脚本自动提取
mysql.role_edges+mysql.default_roles+SHOW GRANTS输出,批量生成授权语句,适用于运维自动化场景
权限不是配置项,是状态机;克隆权限的本质,是复现那个状态机的构建过程。











