结论是“无法跳过权限表”主因是mysqld未真正以--skip-grant-tables启动或连错实例;需通过ps aux确认参数、手动启动、FLUSH PRIVILEGES、匹配host与认证插件并彻底重启服务。

直接说结论:所谓“无法跳过权限表”,99% 是因为 mysqld 进程没真正用 --skip-grant-tables 启动,或者启动后你连的是另一个还在正常运行的实例。这不是 MySQL 拒绝你,是操作没对上路。
确认 mysqld 是否真在 skip-grant-tables 模式下运行
很多人改了 /etc/my.cnf 就以为万事大吉,但 systemctl restart mysqld 并不一定加载你刚加的 skip-grant-tables ——尤其当配置文件里有多个 [mysqld] 段、或被 /etc/my.cnf.d/ 下其他文件覆盖时。
- 先查当前运行的
mysqld进程实际用了哪些参数:ps aux | grep mysqld,重点看输出里有没有--skip-grant-tables - 如果没有,说明配置没生效。Linux 下更可靠的做法是手动启动:
sudo systemctl stop mysqld && sudo mysqld --skip-grant-tables --user=mysql --console(加--console能实时看到日志,避免后台启动后无声无息) - Windows 上不要依赖服务名,直接用管理员命令行跑:
mysqld --console --skip-grant-tables --shared-memory,且别关这个窗口 - macOS 如果用 Homebrew 安装,
brew services stop mysql后再手动启动,否则 brew 会自动拉起原服务
连上了却报 Access denied 或 Command denied
这通常不是密码问题,而是权限上下文错乱。跳过权限表后,MySQL 允许你登录,但很多语句仍受限——比如 ALTER USER 在 8.0+ 中要求你先 FLUSH PRIVILEGES 才能生效,而有些版本甚至禁止在 skip 模式下直接执行 ALTER USER。
- 登录后第一件事不是改密码,而是强制刷新权限:
FLUSH PRIVILEGES;(必须分号结尾) - 然后切库:
USE mysql; - 再查当前 root 用户记录:
SELECT user, host, authentication_string FROM user WHERE user = 'root';,确认你要改的是哪一行(localhost?127.0.0.1?还是%?) - MySQL 8.0+ 必须用:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_new_pass';;5.7 可用:UPDATE user SET authentication_string = PASSWORD('your_new_pass') WHERE user = 'root' AND host = 'localhost'; - 改完再执行一次
FLUSH PRIVILEGES;,否则新密码不落地
改完密码仍无法用新密码登录
最常被忽略的两个点:host 不匹配 + 认证插件不兼容。
- 检查你登录时用的 host:
mysql -u root -p默认走localhost(socket),但mysql -h 127.0.0.1 -u root -p走 TCP,对应的是root@127.0.0.1,这是两个独立账户。改密码时必须和登录方式一致 - MySQL 8.0 默认用
caching_sha2_password插件,老客户端(如某些旧版 Navicat、PHP 7.4 以下)不支持。临时解决:改插件为mysql_native_password:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_pass'; - 改完立刻退出,关掉所有
--skip-grant-tables启动的进程,再用systemctl start mysqld(或对应平台的正常启动方式)重启——残留的 skip 模式进程会一直让你免密,掩盖真实问题
真正的难点从来不在命令怎么写,而在于你连的到底是哪个 mysqld、它读的是哪份配置、你操作的 user 行是否对应你试图连接的 host、以及客户端能不能消化那个认证插件。每一步都得验证,不能靠“应该可以”。


















