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库的完整性、字符集一致性、插件兼容性这三点,漏掉任何一环都会让权限失效——而且往往表现得像“神秘丢失”,其实每一步都有迹可循。
