mysql 5.7 忘记 root 密码时,必须停服务、用 --skip-grant-tables 启动绕过权限校验,再更新 authentication_string 字段并执行 flush privileges,否则新密码不会生效。

直接说结论:MySQL 5.7 忘记 root 密码时,必须停服务、用 --skip-grant-tables 启动绕过权限校验,再更新 authentication_string 字段并执行 FLUSH PRIVILEGES,否则新密码不会生效。
为什么不能直接登录或查原始密码
MySQL 5.7 的密码不是明文存储,而是哈希后存在 mysql.user 表的 authentication_string 字段里。PASSWORD() 是单向函数,没有解密能力。所有“找回密码”的说法都不成立——连 MySQL 自己都没存原始密码。你看到的报错 Access denied for user 'root'@'localhost' (using password: YES) 只是验证失败,数据本身完好无损。
Linux/macOS 下用 --skip-grant-tables 安全重置
这是最可控的应急方式,但启动后 MySQL 完全无认证,必须严格限制访问范围:
- 先停服务:
sudo systemctl stop mysqld(CentOS/RHEL)或sudo service mysql stop(Ubuntu/Debian) - 安全模式启动:
sudo mysqld --skip-grant-tables --skip-networking &——--skip-networking很关键,防止其他机器连上来绕过认证 - 新开终端免密登录:
mysql -u root(不加-p,也不输密码) - 进库后立刻执行:
USE mysql; UPDATE user SET authentication_string = PASSWORD('MyNewPass123') WHERE user = 'root' AND host = 'localhost'; FLUSH PRIVILEGES;注意:字段名必须是authentication_string,不是password;WHERE条件必须同时匹配user = 'root'和host = 'localhost',否则可能改错账户(比如root@127.0.0.1是另一个用户) - 退出后手动杀掉跳过权限的进程:
sudo kill $(pgrep -f "mysqld.*skip-grant-tables"),然后sudo systemctl start mysqld
Windows 下必须加 --shared-memory 才能连上
Windows 不支持 Unix 域套接字,不显式启用共享内存通信,mysql -u root 会报 Can't connect to MySQL server on 'localhost':
- 查服务名:
sc queryex type= service state= all | findstr "MySQL",确认是MySQL57还是其他 - 停止服务:
net stop MySQL57 - 进 MySQL
bin目录,执行:mysqld --skip-grant-tables --shared-memory --console(别关这个窗口) - 另开管理员 CMD:
mysql -u root→USE mysql;→FLUSH PRIVILEGES;→ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass123'; - 关闭两个窗口,再用
net start MySQL57正常启动
最容易被忽略的是:改完密码后没杀掉 mysqld --skip-grant-tables 进程,或者忘了删掉 my.ini 里手动加的 skip-grant-tables = true。这两处任一残留都会导致后续登录行为异常——要么一直免密,要么死活连不上。操作完成后务必用 mysql -u root -p 和 mysql -u root -h 127.0.0.1 -p 分别试一遍,确认两种连接方式都走新密码。











