先用--skip-grant-tables绕过权限校验登录,再查mysql.user确认root@localhost是否存在及plugin类型,最后用alter user指定mysql_native_password插件并设密码,务必执行flush privileges。

直接进不去 MySQL?先绕过权限表登录
1045 错误不是密码输错那么简单,而是 MySQL 根本没匹配到你期望的 root@localhost 这条记录。你连都进不去,就无法查表——得先用 skip-grant-tables 启动 MySQL 绕过权限校验。
Linux/macOS:停服务后执行 sudo mysqld_safe --skip-grant-tables &;Windows:在 my.ini 的 [mysqld] 段下加一行 skip-grant-tables,再重启服务。
然后直接运行 mysql -u root(不加 -p),就能无密码进去了。注意:此时任何用户都能访问,务必操作完立刻退出并恢复配置。
查清楚 root 到底存不存在、允许从哪连
进 MySQL 后立刻执行:USE mysql; 然后 SELECT User, Host, plugin, authentication_string IS NOT NULL AS has_pw FROM user WHERE User = 'root';
- 如果返回空行:说明
root@localhost根本没建——MySQL 8.0+ 安装后默认只建root@127.0.0.1或root@%,不建localhost行 - 如果只有
localhost但你用mysql -h 127.0.0.1 -u root -p登录,会失败:因为127.0.0.1和localhost在 MySQL 里是两个不同 Host - 如果
plugin是auth_socket(Ubuntu 常见)或caching_sha2_password(MySQL 8.0+ 默认),老客户端可能静默失败,哪怕密码对
改密码前必须确认字段名和插件类型
MySQL 5.7 以前用 password 字段,8.0+ 已移除,只留 authentication_string。直接写 UPDATE user SET password = PASSWORD('xxx') 会报 ERROR 1054 (42S22): Unknown column 'password'。
正确做法分两种:
- 如果是
caching_sha2_password不兼容:执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password'; - 如果是
auth_socket(不校验密码,只认系统 UID):执行ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password'; - 无论哪种,改完都必须执行
FLUSH PRIVILEGES;
别漏掉 FLUSH PRIVILEGES;——它不是可选步骤,而是让内存权限表立即生效的关键动作。
删掉 skip-grant-tables 后仍连不上?检查连接方式是否触发了 Host 不匹配
改完密码重启服务后,用 mysql -u root -p 登录失败,但 mysql -h 127.0.0.1 -u root -p 成功,说明问题出在 socket 连接路径上:前者走 Unix socket,强制匹配 Host = 'localhost';后者走 TCP,匹配的是 'root'@'127.0.0.1' 或 'root'@'%'。
验证方法:mysql -h localhost -u root -p --protocol=tcp 能进,就证明是 socket + plugin 导致的失败。
生产环境慎用 CREATE USER 'root'@'%' IDENTIFIED BY ... ——开放通配 Host 是安全风险,优先补一条 'root'@'localhost' 记录,而不是把现有 localhost 行的 Host 改成 %。











