MySQL 8.0 已弃用 mysqld_safe,应改用 mysqld --skip-grant-tables --skip-networking --user=mysql --datadir=/var/lib/mysql 启动,并执行 ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd';,最后修复文件权限 sudo chown -R mysql:mysql /var/lib/mysql。

mysqld_safe 在 MySQL 8.0 中很可能根本不存在
MySQL 8.0 官方已弃用mysqld_safe,多数新安装包(尤其是 Linux 发行版默认源或官方二进制包)不再附带该脚本。直接运行 mysqld_safe --skip-grant-tables 会报错:-bash: mysqld_safe: 未找到命令。这不是路径没加对,而是它真的被删了。别浪费时间找 which mysqld_safe 或改 PATH——先确认你的 MySQL 8.0 是否还保留它。
检查方法:
ls /usr/bin/mysqld_safe ls /usr/local/mysql/bin/mysqld_safe
如果都返回 “No such file”,就跳过所有依赖 mysqld_safe 的教程步骤,改用 mysqld 直接启动。
用 mysqld --skip-grant-tables 启动才真正可行
MySQL 8.0 支持mysqld 原生命令行参数跳过权限表,无需守护脚本。但必须显式指定用户、数据目录和关闭网络,否则启动失败或不生效:
- 先停服务:
sudo systemctl stop mysqld(或sudo service mysql stop,依实际服务名而定) - 确认 mysqld 进程已退出:
ps aux | grep mysqld,杀净残留(如sudo kill -9 PID) - 手动启动(关键参数不能少):
sudo mysqld --skip-grant-tables --skip-networking --user=mysql --datadir=/var/lib/mysql & -
--user=mysql必须指定,否则因权限问题无法访问数据文件 -
--datadir要和你实际的数据库路径一致(常见为/var/lib/mysql或/usr/local/mysql/data),错则报错Can't find file: './mysql/user.MYD'
登录后 ALTER USER 语句必须带 host 且用 IDENTIFIED BY
MySQL 8.0 不再支持UPDATE user SET authentication_string=PASSWORD('xxx'),也不接受无 host 的 'root'。执行错误会提示:ERROR 1064 (42000): You have an error in your SQL syntax 或 ERROR 1396 (HY000): Operation ALTER USER failed。
正确写法只有一条(注意引号、@ 符号、分号):
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_new_password';
- 必须写全
'root'@'localhost',不能省略@'localhost';若你之前用'root'@'%'登录过,也得对应修改那条记录 - 必须用
IDENTIFIED BY,不是SET PASSWORD或PASSWORD()函数 - 执行前务必先运行
FLUSH PRIVILEGES;,否则新密码不生效
重启前必须清理残留文件权限
用--skip-grant-tables 启动并修改密码后,直接 systemctl start mysqld 很可能失败,报错类似:Failed to start MySQL Server. Permission denied 或日志里出现 Can't open the mysql.plugin table。
原因:跳过权限验证时,mysqld 以 root 用户身份写入了部分临时文件(如 binlog.index、ib_buffer_pool),导致这些文件属主变成 root:root,而正常启动要求全部归 mysql:mysql。
修复命令(路径按你实际 datadir 调整):
sudo chown -R mysql:mysql /var/lib/mysql
然后再 sudo systemctl start mysqld,基本就能起来。
最易被忽略的一点:整个过程里,任何一步卡住,先看 sudo tail -n 20 /var/log/mysql/error.log(或 /var/log/mysqld.log),错误信息比终端提示更具体。别靠猜。


















