mysql升级后权限“丢失”实为系统表结构变更、认证插件不兼容或字符集错位导致权限记录无法被新版本识别,如5.7升8.0后plugin默认值变为caching_sha2_password,需备份mysql库、检查并修正插件与字符集。

MySQL升级后权限真的会“丢”,但不是数据被删了
权限不会凭空消失,而是因为系统表结构变更、认证插件不兼容或字符集错位,导致原有权限记录无法被新版本正确识别。比如从 5.7 升到 8.0 后,mysql.user 表里 plugin 字段默认值从 mysql_native_password 变成 caching_sha2_password,老用户用旧驱动连不上,看起来就像“权限丢了”。
- 升级前必须备份整个
mysql系统库(不只是业务库),命令要用mysqldump --all-databases或显式加--databases mysql - 跨大版本(如 5.7 → 8.0)别跳过
mysql_upgrade(8.0+ 已自动执行,但要确认日志里没报错) - 检查
SELECT user, host, plugin FROM mysql.user;,发现插件不对就立刻改:ALTER USER 'u'@'h' IDENTIFIED WITH mysql_native_password BY 'pwd';
迁移时只导出业务库,等于把权限“剪掉”再搬家
很多人用 mysqldump --databases db1 db2 迁移,结果新实例只剩 root@localhost 能登录——因为 mysql 库根本没导出。权限信息全存在 mysql.user、mysql.db、mysql.tables_priv 这些表里,不带它,等于搬房子不带门锁钥匙。
- 导出命令必须包含系统库:
mysqldump --all-databases --single-transaction > full.sql - 导入前确认目标实例已初始化(不要用
mysql_secure_installation覆盖已有mysql库) - 导入后立即执行
FLUSH PRIVILEGES;,否则内存里的权限缓存还是空的 - 注意
host字段匹配:如果原库是'user'@'%',新库却只有'user'@'localhost',连接就会被拒
字符集和排序规则不一致,会让权限“看得见摸不着”
mysql.user 表若用 latin1 或 utf8(非 utf8mb4)建的,升级到 8.0 后可能字段值变成乱码或空字符串,SELECT host,user FROM mysql.user; 看起来有数据,实际匹配失败。
- 检查当前
mysql库字符集:SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='mysql'; - 应为
utf8mb4+utf8mb4_0900_ai_ci(8.0 默认);如果不是,需在导入前用mysqldump --default-character-set=utf8mb4重导 - 导入 SQL 后别忘了验证:
SHOW CREATE TABLE mysql.user;看字段定义是否含utf8mb4
升级后连不上?先看日志,别急着重置密码
错误日志里常有关键线索,比如 Plugin caching_sha2_password could not be loaded 或 Access denied for user ... (using password: YES),直接指向插件或权限加载失败,而不是密码错了。
- 查日志位置:
SHOW VARIABLES LIKE 'log_error';,然后tail -f /var/log/mysql/error.log - 如果确认是插件问题,优先改用户认证方式,而非降级整个 MySQL 的默认插件(会影响其他用户)
- 万不得已进安全模式修复时,
mysqld_safe --skip-grant-tables启动后,第一件事是UPDATE mysql.user SET authentication_string='', plugin='mysql_native_password' WHERE User='root';,再FLUSH PRIVILEGES;
mysql 库的完整性、字符集一致性、插件兼容性这三点,漏掉任何一环都会让权限失效——而且往往表现得像“神秘丢失”,其实每一步都有迹可循。










