mysql 8.0 迁移旧版 mysql.user 数据需规避字段不匹配、plugin 非空、authentication_string 替代 password 等冲突,应通过 --no-create-info 导出权限表、清洗 password 字段、统一 plugin 为 'mysql_native_password'、预设 default_authentication_plugin 并按 create user→grant 顺序导入。

不能直接导入旧版 mysqldump 导出的 mysql.user 行数据——字段不匹配、plugin 非空、authentication_string 替代 Password,硬导会报错 ERROR 1067 (42000) 或登录失败。
用 mysqldump --no-create-info 提取权限表再过滤
这是最可控的起点,避开建表语句和字段结构冲突:
mysqldump -u root -p --no-create-info --skip-extended-insert mysql user db tables_priv procs_priv columns_priv proxies_priv > grants.sql- 必须删掉所有含
INSERT INTO `mysql`.`user`的行中第 50 列左右的Password字段值(MySQL 5.7 中该列存在,8.0 已移除) - 把每行
INSERT中的plugin值统一替换为'mysql_native_password'(不是空字符串,也不是caching_sha2_password) - 检查文件里有没有
CREATE DATABASE IF NOT EXISTS `mysql`——如有,必须删掉,否则会覆盖 8.0 新初始化的系统表结构
导入前先清空目标库用户记录并设好默认插件
避免新旧用户叠加、字段冲突或认证插件不一致导致连接失败:
- 在 MySQL 8.0 启动前,配置文件(如
/etc/my.cnf)中加入:default_authentication_plugin=mysql_native_password - 启动后执行:
DELETE FROM mysql.user WHERE User NOT IN ('root', 'mysql.session', 'mysql.sys');,再FLUSH PRIVILEGES; - 别漏掉
TRUNCATE mysql.db;等权限表(或至少清空非内置用户的记录),否则GRANT可能因唯一键冲突失败 - 如果已启动且 root 连不上,加
--skip-grant-tables启动,然后执行:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpass';
用 SHOW GRANTS FOR 'u'@'h' 逐个重建更可靠
比依赖 dump 文件更语义化,也绕过所有表结构差异:
-
SELECT CONCAT("SHOW GRANTS FOR '",User,"'@'",Host,"';") FROM mysql.user WHERE User NOT IN ('root','mysql.session','mysql.sys');生成批量命令 - 对每个结果执行,保存输出到
grants_user.sql;手动将IDENTIFIED BY改成IDENTIFIED WITH mysql_native_password BY - 导入顺序必须是:先
CREATE USER(显式指定插件),再GRANT;不能靠INSERT补全用户,否则plugin会按默认值填caching_sha2_password - 若源库用了角色(
mysql.role_edges),SHOW GRANTS会输出SET DEFAULT ROLE,必须一并执行
重命名用户后权限“消失”?先查 DEFINER 和 host 匹配
这不是迁移问题,而是迁移后常见误判点:
-
RENAME USER 'old'@'host' TO 'new'@'host';确实自动迁移mysql.db、mysql.tables_priv等表中的权限记录,但不会改information_schema.ROUTINES里的DEFINER - 执行前务必查:
SELECT ROUTINE_NAME, ROUTINE_TYPE, DEFINER FROM information_schema.ROUTINES WHERE DEFINER = 'old'@'host';——若有结果,这些对象重命名后会报ERROR 1449 - 连接时 host 必须完全一致:比如原账号是
'app'@'10.20.0.%',就不能用'app'@'%'去连,MySQL 8.0 不做模糊匹配 - 验证权限是否真丢了:用
SELECT User, Host, plugin, authentication_string FROM mysql.user WHERE User = 'new';,看字段值是否合理
真正容易被忽略的是:default_authentication_plugin 必须在首次启动 8.0 时就设好;一旦用默认插件创建了用户,后续再改配置也不会影响已有记录——那些用户密码哈希值跟插件强绑定,换插件等于废密码。











