MySQL 5.7+ 忘记 root 密码时,唯一可行方式是停服务后以 --skip-grant-tables --skip-networking 启动,免密登录后用 ALTER USER 修改密码并执行 FLUSH PRIVILEGES;需注意 host 匹配、认证插件兼容性及关闭跳过权限进程后再正常启动。

MySQL 5.7+ 忘记 root 密码:跳过权限验证启动
直接停掉 MySQL,用 --skip-grant-tables 启动是唯一可行的“无密码进入”方式。注意:5.7.6 及以后版本禁用 UPDATE mysql.user 方式改密码,必须进实例后用 ALTER USER;但前提是得先进去。
常见错误现象:ERROR 1045 (28000): Access denied for user 'root'@'localhost',且已确认密码确实丢失或无效。
- Linux 下先停服务:
sudo systemctl stop mysql(或mysqld,取决于发行版) - 临时跳过权限表启动:
sudo mysqld --skip-grant-tables --skip-networking &——--skip-networking很关键,防止未授权远程连接 - 此时另开终端,直接
mysql -u root即可免密登录(不加-p,也不输密码)
ALTER USER 修改 root 密码失败的三个典型原因
进了 MySQL 后执行 ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass'; 报错?不是语法问题,而是权限、认证插件或 host 匹配导致的。
- 没刷新权限缓存:
FLUSH PRIVILEGES;必须在ALTER USER后立刻执行,否则新密码不生效 - 认证插件不兼容:5.7.6+ 默认用
caching_sha2_password,旧客户端可能连不上;可显式指定插件:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpass'; - host 不匹配:检查当前登录用户是哪个:
SELECT USER(), CURRENT_USER();——CURRENT_USER()才是权限系统实际匹配的用户,常是'root'@'127.0.0.1'而非'localhost',得对应修改
重启 MySQL 前必须关闭 --skip-grant-tables 进程
很多人改完密码就直接 systemctl start mysql,结果服务起不来或报 Can't start server: Bind on TCP/IP port —— 因为之前后台运行的 mysqld --skip-grant-tables 还占着 3306 端口。
- 先查进程:
ps aux | grep mysqld,找到带--skip-grant-tables的那一行 - 杀掉它:
sudo kill $(pgrep -f "mysqld.*skip-grant-tables")(或手动kill -9 PID) - 再正常启服务:
sudo systemctl start mysql;验证:mysql -u root -p输新密码
MySQL 8.0 的额外注意点:默认密码策略与双认证
8.0 开箱即用的 validate_password 插件会拒绝太短/太简单的密码,比如 '123' 或 'password',直接报 ERROR 1819 (HY000)。
- 临时关策略(仅重置时用):
SET GLOBAL validate_password.policy = LOW; - 如果 root 用户启用了双重认证(
authentication_policy),ALTER USER语句需加REQUIRE NONE显式关闭,否则下次登录仍可能被拦截 - 8.0 中
mysql_native_password插件默认未加载,若要用,启动前需在my.cnf加default_authentication_plugin=mysql_native_password,否则新用户创建或修改时可能失败
整个过程里最容易被忽略的是 CURRENT_USER() 返回的 host 和 --skip-networking 的必要性——前者导致改了密码却登不上,后者让跳过权限启动变成安全隐患。做一遍就知道,漏一个就卡住。










