在网上流传着不少关于 MySQL root 密码重置 的方法,今天我将系统梳理并汇总几种主流方案,方便大家遇到 MySQL 忘记密码 或其他密码管理问题时对照使用。
先从最简单的方案说起。
方法一:借助 phpMyAdmin 修改密码
这算是最省事的途径。直接登录 phpMyAdmin,找到 mysql 库里的 user 表,修改对应 root 用户的密码字段即可。一个小提醒:务必使用 PASSWORD() 函数加密,否则密码以明文存储,登录时系统会无法识别。
方法二:mysqladmin 命令行工具修改密码
这个其实是前面方法的一个特例——只用一条命令就能搞定:
mysqladmin -u root -p password mypasswd
执行后系统会提示输入原密码,然后 root 密码就被改为 mypasswd。将命令里的 root 换成其他用户名,即可更改相应用户的密码。
当然,局限性也很明显:如果你的 mysqladmin 无法连接 MySQL 服务器,或者你根本没有执行该命令的权限(比如权限受限),那么这条路就走不通。另外注意,mysqladmin 无法将密码直接清空,它只支持修改为非空值。
下面几种方法都需要在 MySQL 命令行提示符下操作,并且必须拥有 root 权限。
方法三:INSERT 语句增加用户
INSERT INTO mysql.user (Host,User,Password) VALUES('%','jeffrey',PASSWORD('biscuit'));
FLUSH PRIVILEGES;
严格来说这不是修改 root 密码,而是在增加一个用户。不过《MySQL 中文参考手册》里将其作为示例,我也在此列出。注意密码字段必须使用 PASSWORD() 函数,修改后还需执行 FLUSH PRIVILEGES 使权限表生效。
方法四:REPLACE 语句
思路与上面相同,只是将 INSERT 换成了 REPLACE:
REPLACE INTO mysql.user (Host,User,Password) VALUES('%','jeffrey',PASSWORD('biscuit'));
FLUSH PRIVILEGES;
效果类似,同样要求使用 PASSWORD() 和 FLUSH。
方法五:SET PASSWORD 语句
SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');
这个语法更简洁。注意仍然需要使用 PASSWORD() 函数,但好消息是不再需要执行 FLUSH PRIVILEGES,因为 SET PASSWORD 会自动触发权限刷新。
方法六:GRANT 语句
GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';
这里 PASSWORD() 函数反而用不上了,IDENTIFIED BY 后面直接跟明文密码,MySQL 内部会自动加密。同样不需要 FLUSH PRIVILEGES。
需要特别说明:MySQL 的 PASSWORD() 函数加密方式与 Unix 系统的口令加密截然不同,切勿混为一谈。
前面介绍的是常规操作。但实际工作中最常遇到的场景是——密码遗忘,该怎么办?下面就是 MySQL 忘记 root 密码的解决方案。
Linux/Unix 下的救援流程
- 如果 MySQL 正在运行,先杀掉进程:
killall -TERM mysqld - 跳过权限检查启动:
bin/safe_mysqld --skip-grant-tables & - 此时无需密码即可直接连接 MySQL:
use mysql; update user set password=password("new_pass") where user="root"; flush privileges; - 杀掉 mysqld 进程,然后以正常模式启动即可。
Windows 下的救援流程
- 以系统管理员身份登录。
- 停止 MySQL 服务。
- 打开命令提示符,进入 MySQL 安装目录的
bin目录。 - 跳过权限检查启动:
mysqld-nt --skip-grant-tables - 另外打开一个命令窗口,进入同样的目录,执行:
第二步会提示输入新密码,重复一遍。mysqladmin -u root flush-privileges password "newpassword" mysqladmin -u root -p shutdown - 停止 MySQL 服务(此时已经停掉),用正常模式重新启动。
- 用新密码连接即可。
另一种思路:直接替换 user 表文件
MySQL 的密码存储在 mysql 库的 user 表中,对应的文件有三个:user.frm(表结构)、user.MYD(数据)、user.MYI(索引)。如果你手头有另一台知道密码的 MySQL(比如 Windows 版本的),将它的 user.MYD 文件拷贝过来覆盖当前系统下的同名文件,然后重启 MySQL,就能用那个已知密码登录了。
覆盖后需要注意权限问题。在 Linux 下,文件属主可能会变成 root,需要手动改回来:
chown -R mysql:mysql /var/lib/mysql/mysql/user.*
chmod 600 /var/lib/mysql/mysql/user.*
然后重启 MySQL,再执行密码修改:
use mysql;
update user set Password=PASSWORD('xxxxxx') where User='root';
flush privileges;
额外提一句:如果 Windows 下 MySQL 是默认配置,可能还存在匿名用户和通配符主机用户,最好一并清理:
delete from user where User='';
delete from user where Host='%';
flush privileges;
终极手段:直接编辑 user.MYD 文件
这是比较硬核的方法。用十六进制编辑器(比如 UltraEdit)打开 user.MYD 文件,找到 root 用户对应的密码字段。将密码部分的 8 个字节改为特定的十六进制值——比如 56 54 91 d7 04 01 32 45 对应的明文是 123456。或者改成 00 02 02 02 02 02 02 02,这就是空密码(编辑器右边会显示成星号堆积)。改完后保存,重启 MySQL,用 root 和新密码登录即可。
这种方法的好处是不用修改文件属主和权限,但前提是你得知道明文和加密串的对应关系,或者能拿到另一个已知密码的 user.MYD 文件作为参考。
以上几套方案覆盖了从图形界面到命令行、从正常修改到暴力破解的各种场景。实际工作中遇到密码遗失,优先推荐使用 --skip-grant-tables 那条路径,通用性强,操作也最为安全。
