必须跳过权限验证才能重置:先停服务,再以--skip-grant-tables启动MySQL,免密登录后根据版本用ALTER USER(8.0+)或UPDATE user(5.7)修改密码,执行FLUSH PRIVILEGES刷新权限,最后恢复正常启动。

mysql.user 表的认证流程,再手动更新密码字段。
用 --skip-grant-tables 启动 MySQL(最通用,Linux/macOS/Windows 都适用)
这是最稳妥、兼容性最强的方式,不依赖外部工具或初始化脚本,适用于所有 MySQL 5.7+ 和 MySQL 8.0+ 版本。
- 先停服务:
systemctl stop mysqld(Linux)或net stop mysql(Windows) - 临时跳过权限表启动:
mysqld --skip-grant-tables --skip-networking &(Linux/macOS);Windows 下需在命令行中执行mysqld --skip-grant-tables,该窗口会卡住,属正常现象 - 新开终端,直接登录:
mysql -u root(不加-p,也不输密码) - 进入后立刻切库:
USE mysql; - 根据版本选更新语句:
- MySQL 5.7:
UPDATE user SET authentication_string = PASSWORD('MyNewPass123') WHERE user = 'root' AND host = 'localhost'; - MySQL 8.0+:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass123';(推荐,更安全)
- MySQL 5.7:
- 强制刷新权限:
FLUSH PRIVILEGES;(这步不能省,否则新密码不生效) - 退出并关掉
--skip-grant-tables进程,再用正常方式启动服务
修改 /etc/my.cnf 或 my.ini 添加 skip_grant_tables
适合无法直接调用 mysqld 命令(如某些 Docker 环境或受限 shell),但需要重启服务,且容易漏删配置导致长期无权限校验。
- 编辑配置文件,在
[mysqld]段下添加一行:skip_grant_tables=1 - 保存后重启服务:
systemctl restart mysqld(Linux)或 Windows 服务管理器重启 - 此时可免密登录:
mysql -u root - 更新密码后,**必须删除或注释掉
skip_grant_tables=1这行**,再重启一次服务,否则任何用户都能无密码访问 - 注意:Windows 下配置文件通常是
C:\ProgramData\MySQL\MySQL Server X.X\my.ini,不是安装目录下的my.ini
MySQL 8.0+ 必须用 ALTER USER,PASSWORD() 函数已废弃
MySQL 8.0 移除了 PASSWORD() 函数,且默认认证插件改为 caching_sha2_password。直接用 UPDATE 写 authentication_string 字段容易失败或登录异常。
- 如果执行
UPDATE user SET authentication_string = PASSWORD(...)报错FUNCTION does not exist,说明你正在用 MySQL 8.0+ - 正确做法是:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass123'; - 如果提示
ERROR 1396 (HY000): Operation ALTER USER failed...,先确认用户是否存在:SELECT User, Host FROM user WHERE User = 'root'; - 若只有
'root'@'%'而没有'root'@'localhost',需改成对应 host:ALTER USER 'root'@'%' IDENTIFIED BY 'MyNewPass123'; - 改完后仍连不上?检查客户端是否支持
caching_sha2_password—— MySQL Shell 或新版 MySQL Workbench 可以,老版 Navicat 可能需要降级插件或加参数
mysqladmin 和 SET PASSWORD 在忘密时完全无效
这两个命令都要求你**已经知道当前密码**,属于“有密改密”场景,不是恢复手段。
-
mysqladmin -u root -p password 'newpass'会卡在输入旧密码环节,没密码就过不去 -
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');同样需要先成功登录,否则报Access denied - 网上有些教程把它们和恢复流程混写,容易误导——忘密时请直接跳过这两条
--skip-grant-tables 的作用边界:它只跳过权限检查,不改变数据结构;而 MySQL 8.0 的密码存储逻辑和认证流程已和 5.7 不同,硬套旧语法大概率卡在登录环节。动手前先确认版本:mysql --version 或登录后查 SELECT VERSION();。


















