--skip-grant-tables必须与--skip-networking同时使用,否则mysql仍监听tcp端口导致本地socket连接失败;登录后须执行flush privileges并正确设置认证插件(如mysql_native_password)及host匹配(localhost/127.0.0.1),最后务必杀掉残留进程再正常重启服务。

--skip-grant-tables 不是临时调试手段,而是彻底关闭权限系统。只要它在运行,任何连接都拥有 SUPER 权限,删库、改密码、导出数据全都不需要验证。
为什么 --skip-grant-tables 启动后连 127.0.0.1 都不能用?
因为 --skip-grant-tables 默认仍监听 TCP 端口(3306),但若同时漏掉 --skip-networking,MySQL 就会拒绝本地 socket 连接(如 mysql -u root),只接受 TCP 连接——而你用 127.0.0.1 就走 TCP,结果发现连不上,误以为权限没生效,其实恰恰相反:它已经裸奔了。
- 必须显式加
--skip-networking,才能禁用 TCP 监听,只保留 Unix socket(mysql -u root可连,mysql -h 127.0.0.1 -u root必然失败) -
--skip-grant-tables和--skip-networking必须同时出现,缺一不可 - 启动命令必须用完整路径(如
/usr/sbin/mysqld),避免 systemd 或其他进程干扰
改完密码后还是 Access denied 怎么办?
不是密码设错了,而是权限没刷进内存,或插件不匹配。常见于 MySQL 5.7+ 和 8.0+。
- 必须执行
FLUSH PRIVILEGES;,否则磁盘修改不会加载到运行时缓存 - MySQL 5.7+ 默认用
caching_sha2_password插件,老客户端(Sequel Pro、旧版 Workbench)不支持,得切回:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; -
'root'@'localhost'和'root'@'127.0.0.1'是两个独立账号,改完前者,用-h 127.0.0.1连还是会失败;需单独补:CREATE USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY '同上密码'; GRANT ALL ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
重启服务前最常被忽略的一步
很多人改完就直接 systemctl start mysql,结果服务起不来,或者连上去还是免密——因为之前手工启动的 mysqld 进程还在后台跑着,占着端口和 socket 文件。
- 务必先杀掉:
sudo killall mysqld - 再确认:
ps aux | grep mysqld返回为空 - 最后才执行
systemctl start mysql - 如果跳过这步,systemd 启动的是新实例,而你连的其实是那个裸奔的老进程,安全加固等于白做
真正危险的不是不会用 --skip-grant-tables,而是用完没清理干净——残留进程、未刷新的权限缓存、插件不兼容、host 匹配错位,任何一个都可能让修复变成新的攻击面。











