mysql 8.0+ 忘记 root 密码必须用 --skip-grant-tables(windows 需加 --shared-memory)免密启动,先清空 authentication_string 再执行 alter user 设新密码并指定插件,最后 flush privileges;直接 update 或 password() 函数已失效且不安全。

MySQL 8.0+ 忘记 root 密码后,不能用 UPDATE mysql.user 直接改字段,也不能调用已移除的 PASSWORD() 函数;必须用 ALTER USER + 免密启动组合操作,否则会报错或登录后立即断连。
MySQL 8.0+ 必须用 ALTER USER,不是 UPDATE 或 SET PASSWORD
MySQL 5.7.6 起废弃了直接写 authentication_string 字段的方式,8.0 彻底删掉 PASSWORD() 函数。执行 UPDATE mysql.user SET authentication_string=PASSWORD('xxx') 会直接报错:FUNCTION PASSWORD does not exist;即使语句“成功”,密码也不生效——因为没触发认证插件重载逻辑。
-
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';是唯一推荐方式,MySQL 自动处理哈希和插件适配 - 如果客户端不兼容(如旧版 Navicat、PHP 7.4 的 mysqli),需显式指定插件:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码'; - 必须紧跟
FLUSH PRIVILEGES;,跳过它会导致密码不生效
免密启动必须加 --skip-networking,只靠 --skip-grant-tables 很危险
只加 --skip-grant-tables 会让 MySQL 继续监听 3306 端口,任何能连上本机网络的进程(包括容器、恶意脚本)都能无密码操作数据库。
- Linux/macOS 正确启动命令:
sudo mysqld --skip-grant-tables --skip-networking & -
--skip-networking会禁用 TCP 连接,只保留本地 socket 通信,这是安全底线 - Windows 不要用服务方式加参数,应新建
reset.sql,再用mysqld --init-file=C:\reset.sql --console启动
重启前务必杀干净手动启动的 mysqld 进程
用 systemctl start mysql 失败?大概率是后台还挂着你手动启的 mysqld 实例,两个进程抢端口或数据目录,systemd 会卡在 activating 或直接报 Failed to start mysql.service。
- 查进程:
ps -ef | grep mysqld | grep -v grep - 逐个 kill:
sudo kill -9 <pid></pid>(别用killall mysqld,可能误杀其他实例) - 确认清空:
sudo lsof -i :3306应该无输出
重置完立刻验证 plugin 类型,别信“能登录就完事”
密码改了,mysql -u root -p 能登进去,不代表一切正常。很多老工具(比如 PHP 7.4 的 mysqli 扩展、旧版 Workbench)根本不支持 MySQL 8.0 默认的 caching_sha2_password 插件,表面登录成功,一执行查询就断连。
- 登录后马上执行:
SELECT user, host, plugin FROM mysql.user WHERE user='root'; - 看到
caching_sha2_password且你用的是老客户端,就得切回mysql_native_password - 切完再执行一次
FLUSH PRIVILEGES;,否则变更不会落地
最容易被忽略的是插件类型和进程残留——前者让工具看似可用实则崩在查询时,后者让服务根本启不起来。动手前先看版本、动手后立刻查 plugin、重启前必杀进程,三步缺一不可。











