MySQL 8.0+克隆用户必须先CREATE USER并指定认证插件与哈希值,不可直接INSERT mysql.user;权限须同步复制mysql.db、tables_priv、columns_priv、procs_priv四张表,并执行FLUSH PRIVILEGES后验证。

克隆用户必须先 CREATE USER,不能只 INSERT mysql.user
直接在 mysql.user 表里复制一行、改用户名再执行,新用户一定登录失败。因为 MySQL 8.0+ 要求账号必须用 CREATE USER 显式创建,且需指定认证插件和哈希值;仅插入行会跳过插件初始化校验,authentication_string 字段也不会被正确解析。
正确做法是:从原用户的 mysql.user 表查出 plugin 和 authentication_string,然后用 CREATE USER ... IDENTIFIED WITH plugin AS 'hash' 创建新账号。例如:
SELECT plugin, authentication_string FROM mysql.user WHERE user = 'olduser' AND host = 'localhost';
拿到结果后,在 SQL 标签页执行:
CREATE USER 'newuser'@'localhost' IDENTIFIED WITH caching_sha2_password AS '$A$...';
权限要从四张系统表分别复制,缺一不可
只复制 mysql.db 表的权限,会丢失表级、列级、存储过程和触发器权限。MySQL 的权限分散在以下四张表中,必须全部处理:
立即学习“PHP免费学习笔记(深入)”;
-
mysql.db:数据库级权限(如 SELECT、INSERT) -
mysql.tables_priv:表级权限(如 ALTER、INDEX) -
mysql.columns_priv:列级权限(如 SELECT (id)) -
mysql.procs_priv:存储过程/函数/触发器权限
每张表都要写一条 INSERT INTO ... SELECT ...,WHERE 条件严格匹配原用户的 User 和 Host。例如复制表级权限:
INSERT INTO mysql.tables_priv SELECT 'newuser', 'localhost', db, table_name, Grantor, Timestamp, Table_priv, Column_priv FROM mysql.tables_priv WHERE User = 'olduser' AND Host = 'localhost';
执行 FLUSH PRIVILEGES 后必须验证,不能跳过
所有 INSERT 完成后,必须执行 FLUSH PRIVILEGES,否则新权限不会加载进内存。接着立刻验证:
SHOW GRANTS FOR 'newuser'@'localhost';
如果返回空或报错 ERROR 1141 (42000): There is no such grant defined for user,说明前面某步漏了或 host 不一致(比如原用户是 'olduser'@'%',你写成了 'newuser'@'localhost')。常见疏漏点:
- 原用户 host 是
'%'或'192.168.1.%',新用户写成'localhost'→ 权限不生效 - 没检查
mysql.procs_priv表是否为空,误以为不用复制 - 执行顺序错乱:先
FLUSH PRIVILEGES再 INSERT 权限表 → 刷新时还没写入,权限丢失
图形界面导出“所选用户”不可信,别直接执行
phpMyAdmin 的「用户账户」页点击「导出所选用户」,生成的是对 mysql.user 表的 INSERT 语句,不是可运行的建号+赋权脚本。它会把 authentication_string 当作明文塞进 IDENTIFIED BY,在 MySQL 8.0+ 上必然报 ERROR 1827。
更严重的是,它完全不导出任何权限表内容,也不包含 GRANT 语句。如果你依赖这个功能,新用户只有账号、没有权限,等于白忙。
真正能复用的只有 SQL 标签页里手写的三步:建号 → 插四张权限表 → 刷新。复杂点在于 host 匹配和插件一致性,这两个地方一错,整个克隆就失效。



















