能登录的前提是至少还有一个账号保留SUPER或SYSTEM_ADMIN权限且认证方式未被破坏;否则需用--skip-grant-tables启动修复,优先执行FLUSH PRIVILEGES确认状态。

误改 mysql.user 表后还能登录吗?
能登录的前提是:至少还有一个账号保留 SUPER 或 SYSTEM_ADMIN 权限,且认证方式未被破坏(比如没把 plugin 改成 auth_socket 但没装对应插件)。如果连 root 都被设成 plugin='caching_sha2_password' 且密码字段清空,或者 host 被改成 '%' 以外又没开本地 socket 认证,就进不去了。
常见错误现象:Access denied for user 'root'@'localhost'、Client does not support authentication protocol requested by server、连接直接被拒绝无提示。
- 别急着重启 MySQL——重启会加载损坏的权限表,让问题固化
- 优先用
--skip-grant-tables启动实例(需有服务器 root 权限),跳过权限校验后直连修复 - 启动后第一件事不是改表,而是执行
FLUSH PRIVILEGES确认当前内存权限状态,避免误判
如何从备份恢复 mysql 系统库
系统库不能用 mysqldump 常规导出——默认会跳过 mysql 库,且 user 表含哈希密码字段,直接 INSERT 可能因加密方式不一致导致密码失效。
正确做法是冷备 + mysql_upgrade 衔接:
- 停库后拷贝整个
mysql/子目录(路径如/var/lib/mysql/mysql/),不是只拷user.ibd - 恢复时必须保证 MySQL 版本与备份时一致或更高;低版本备份不能直接用于高版本实例
- 替换文件后不能直接启动,要运行
mysqld --upgrade=FORCE或mysql_upgrade -u root -p重建系统视图和权限缓存
注意:mysql_upgrade 在 8.0.16+ 已弃用,改由 mysqld 启动时自动执行,但旧备份恢复仍需人工触发兼容性检查。
GRANT 语句改权限比直接 UPDATE mysql.user 安全在哪?
直接写 UPDATE mysql.user SET authentication_string=... 绕过了 MySQL 的权限校验逻辑,容易留下不一致状态:比如 max_questions 字段被设为负数、account_locked 写成字符串 'Y' 而非布尔值,MySQL 不报错但后续 FLUSH PRIVILEGES 可能失败。
GRANT 是唯一受控入口:
- 自动处理密码哈希(根据
default_authentication_plugin配置选择caching_sha2_password或mysql_native_password) - 校验 host 格式合法性(不允许
'192.168.*'这种模糊写法出现在GRANT中) - 更新
mysql.tables_priv等关联表时保持事务一致性,不会出现“用户有权限但表级权限丢失”
示例:想重置 root 密码,用 ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'newpass';,别碰 authentication_string 字段。
日常该备份哪些权限相关对象?
只备份 mysql.user 表远远不够。权限分散在多个表里,缺一不可:
-
mysql.user:全局权限 + 认证信息 -
mysql.db:数据库级权限(CREATE,DROP等) -
mysql.tables_priv和mysql.columns_priv:细粒度控制,常被忽略但线上真有用 -
mysql.procs_priv:存储过程权限,微服务架构下 DBA 可能授权给应用账号调用特定 SP
备份命令建议用:mysqldump --single-transaction --routines --triggers --no-create-info mysql user db tables_priv columns_priv procs_priv > perms_backup.sql。别加 --all-databases,它会漏掉系统库元数据。
真正难的不是备份,是验证——定期用测试实例导入并尝试用各账号连接、执行 SHOW GRANTS,确认权限映射没因版本升级偏移。











