找回密码
 register
搜索
查看: 10|回复: 0

[每天自学] CentOS 9 下忘记 MySQL 8.0 密码的修改教程

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:523
  • 打卡月天数:12
  • 打卡总奖励:521
  • 最近打卡:2026-06-14 09:46:51
Waylee 发表于 2026-4-20 15:21 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

很多人在 CentOS 9 上忘记 MySQL 密码后,第一反应是重装或者重新初始化。这个思路风险很大,因为真正会损坏现有数据库的,通常不是“改密码”本身,而是误执行了初始化命令、误删了数据目录、或者把服务起到了错误的数据目录上。

这篇文章介绍两种做法:

  1. 推荐方案:--init-file
  2. 备用方案:--skip-grant-tables

如果你的目标是“只重置密码,不影响现有库表数据”,优先使用第一种。


一、先说结论

在 CentOS 9 上,MySQL 8.0 一般由 systemd 管理,服务名通常是 mysqld,常用命令如下:

sudo systemctl status mysqld
sudo systemctl stop mysqld
sudo systemctl start mysqld
sudo systemctl restart mysqld

忘记密码时,最重要的原则是:

  • 不要执行 mysqld --initialize
  • 不要删除 /var/lib/mysql
  • 不要改错 datadir
  • 不要直接手工改 mysql.user 表字段
  • 优先使用 ALTER USER

二、修改前先确认两件事

先确认服务是否正常,以及当前配置文件里是否定义了数据目录:

sudo systemctl status mysqld
sudo grep -R "^datadir" /etc/my.cnf /etc/my.cnf.d 2>/dev/null
which mysqld

如果你担心误操作,建议先做一份物理备份:

sudo tar -czf /root/mysql-backup-$(date +%F-%H%M%S).tar.gz /var/lib/mysql

这一步不是必须,但非常建议。


三、推荐方案:使用 --init-file 重置密码

这个方法的优点是暴露面更小,只在启动时执行一条 SQL,安全性比 --skip-grant-tables 更好。

1. 停止 MySQL 服务

sudo systemctl stop mysqld

2. 创建初始化 SQL 文件

把下面的 新密码 改成你自己的密码:

sudo tee /tmp/mysql-init <<'EOF'
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
EOF
sudo chmod 600 /tmp/mysql-init
sudo chown mysql:mysql /tmp/mysql-init

如果你不仅有 root@localhost,还有 root@127.0.0.1root@::1 或其他 Host,也可以写成多行:

sudo tee /tmp/mysql-init <<'EOF'
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '新密码';
ALTER USER 'root'@'::1' IDENTIFIED BY '新密码';
EOF
sudo chmod 600 /tmp/mysql-init
sudo chown mysql:mysql /tmp/mysql-init

3. 用初始化文件启动 MySQL

sudo mysqld --user=mysql --init-file=/tmp/mysql-init --console

说明:

  • 这里不要加 --initialize
  • 建议先前台启动,这样出错能直接看到日志
  • 如果启动成功,执行完 SQL 后保持运行是正常的

4. 新开一个终端测试登录

mysql -uroot -p

输入你刚设置的新密码。

5. 清理临时文件并恢复 systemd 管理

如果已经验证登录成功,就回到原终端结束临时实例,或者直接另开终端执行:

sudo pkill mysqld
sudo rm -f /tmp/mysql-init
sudo systemctl start mysqld

再次验证:

mysql -uroot -p

四、备用方案:使用 --skip-grant-tables 重置密码

这个方法也常见,但安全性更差。MySQL 官方文档明确说明,这种方式“less secure”。在这种模式下,权限系统暂时被绕过,本地风险更高,所以只建议在临时维护时使用。

1. 停止服务并清理残留进程

sudo systemctl stop mysqld
sudo pkill mysqld
ps -ef | grep [m]ysqld

确保没有残留 mysqld 进程。

2. 以前台方式启动免权限实例

sudo mysqld --skip-grant-tables --skip-networking --user=mysql --console

说明:

  • --skip-grant-tables 表示跳过权限校验
  • --skip-networking 可以进一步降低暴露面
  • 建议不要直接 & 放后台,否则失败了不容易发现

3. 新开一个终端连接 MySQL

mysql

如果能进入 MySQL,再执行:

FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';

注意,MySQL 8.0 下先执行 FLUSH PRIVILEGES;,再执行 ALTER USER,这是官方推荐的顺序。

如果你还有其他 root 账号,也可以逐个修改:

ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '新密码';
ALTER USER 'root'@'::1' IDENTIFIED BY '新密码';

如果不确定有哪些账号,可以先查:

SELECT user, host FROM mysql.user ORDER BY user, host;

4. 退出并恢复正常服务

exit
sudo pkill mysqld
sudo systemctl start mysqld
mysql -uroot -p

五、为什么有时执行了 --skip-grant-tables 还是报 1045?

这个情况很常见,通常不是 SQL 有问题,而是下面几种原因:

  • 新的 mysqld 实例根本没有成功启动
  • 旧的 mysqld 进程没有退出,客户端连到的还是原服务
  • socket 文件或 PID 文件冲突,导致临时实例启动失败
  • 命令放后台后报错没看到

排查方法:

ps -ef | grep [m]ysqld
sudo tail -n 100 /var/log/mysqld.log

如果是免权限实例,最稳妥的启动方式还是:

sudo mysqld --skip-grant-tables --skip-networking --user=mysql --console

这样报错会直接显示在当前终端里。


六、如何把多个 Host 的 root 账号都改成同一个密码?

先查看 root 账号有哪些 Host:

SELECT user, host FROM mysql.user WHERE user='root';

然后按实际结果逐个执行:

ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '新密码';
ALTER USER 'root'@'::1' IDENTIFIED BY '新密码';

如果只是为了本机登录,一般改这几个就够了。

不建议轻易设置:

ALTER USER 'root'@'%' IDENTIFIED BY '新密码';

因为 root@'%' 表示允许任意来源远程登录,安全风险非常高。除非你明确知道自己在做什么,否则不要开。


七、最容易踩坑的地方

  • mysqld --initialize 会初始化数据目录,不是改密码命令
  • 删除 /var/lib/mysql 会直接导致数据库丢失
  • 在 CentOS 9 上服务名通常是 mysqld,不是 mysql
  • --skip-grant-tables 模式下要先 FLUSH PRIVILEGES
  • 不要直接 UPDATE mysql.user ...,MySQL 8.0 优先使用 ALTER USER
  • 如果前台启动报错,优先看 /var/log/mysqld.log

八、建议采用哪种方案?

如果是生产环境或者你特别在意“不能破坏现有数据库”,建议:

  1. 先备份 /var/lib/mysql
  2. 优先使用 --init-file
  3. 只有在 --init-file 不方便时,才使用 --skip-grant-tables

我的建议是:
--init-file 更适合写进正式教程,--skip-grant-tables 更适合作为备用排障方案。


九、命令速查版

推荐方案:

sudo systemctl stop mysqld
sudo tee /tmp/mysql-init <<'EOF'
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
EOF
sudo chmod 600 /tmp/mysql-init
sudo chown mysql:mysql /tmp/mysql-init
sudo mysqld --user=mysql --init-file=/tmp/mysql-init --console

新开终端测试:

mysql -uroot -p

恢复:

sudo pkill mysqld
sudo rm -f /tmp/mysql-init
sudo systemctl start mysqld

备用方案:

sudo systemctl stop mysqld
sudo pkill mysqld
sudo mysqld --skip-grant-tables --skip-networking --user=mysql --console

新开终端执行:

mysql

进入后:

FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';

恢复:

sudo pkill mysqld
sudo systemctl start mysqld

参考资料

您需要登录后才可以回帖 登录 | register

本版积分规则

QQ|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-6-14 18:13 , Processed in 0.071981 second(s), 25 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表