mysql 5.7 忘记 root 密码时,必须停服务后以 --skip-grant-tables --skip-networking 启动,再更新 authentication_string 字段并执行 flush privileges,否则新密码不生效;因密码以哈希形式存于该字段,无明文可查,只能重置。

必须停服务 + 用 --skip-grant-tables 启动,再改 authentication_string 字段并执行 FLUSH PRIVILEGES,否则新密码无效。
为什么不能直接登录或查原始密码
MySQL 5.7 的 root 密码不是明文,而是哈希后存在 mysql.user 表的 authentication_string 字段里;PASSWORD() 是单向函数,没有解密能力。所有“找回密码”的说法都不成立——连 MySQL 自己都没存原始密码。
停服务后必须用 --skip-grant-tables 启动
不跳过权限表,就根本进不去数据库,一切修改都无从谈起。关键细节:
- 先停服务:
sudo systemctl stop mysqld(CentOS/RHEL)或sudo service mysql stop(Ubuntu/Debian);Windows 用net stop mysql,注意服务名(如mysql57或mysql80) - 启动命令必须带
--skip-networking:sudo mysqld --skip-grant-tables --skip-networking &,否则其他机器可能连上来绕过认证 - 该命令会后台运行,终端返回后别 Ctrl+C,也别关窗口——它就是 mysqld 进程本身
登录后只改对字段、函数和 host 才生效
新开终端执行 mysql -u root(不加 -p,也不输密码),进库后立刻执行:
- 切换数据库:
USE mysql; - 更新密码(必须用这句):
UPDATE user SET authentication_string = PASSWORD('MyNewPass123') WHERE user = 'root' AND host = 'localhost'; - 错误写法会导致静默失败或报错:
password字段在 5.7 已废弃,不能用;WHERE user = 'root'不够,必须同时限定host = 'localhost',否则可能改错账户(比如root@127.0.0.1是另一个用户) - 强制刷新内存缓存:
FLUSH PRIVILEGES;—— 这步漏掉,新密码永远不生效
改完密码后最容易被忽略的两件事
很多人改完就去试登录,发现还是免密,问题出在残留进程或配置没清理:
- 手动杀掉跳过权限的进程:
sudo kill $(pgrep -f "mysqld.*skip-grant-tables");Windows 下直接关掉运行mysqld --skip-grant-tables的命令行窗口 - 如果之前改了
/etc/my.cnf或my.ini加了skip_grant_tables=1,现在必须删掉或注释掉这一行,再systemctl restart mysqld(Linux)或net start mysql(Windows) - 验证方式:用
mysql -u root -p输入新密码登录;如果直接进了没提示输密码,说明--skip-grant-tables还在生效
整个过程的核心就三件事:停服务、绕认证、精准更新字段+刷新权限。任何一步绕开或简化,都会导致新密码不生效或留下严重安全隐患。











