MySQL密码恢复,乍一看似乎非常棘手,但核心逻辑其实很简单——所有密码信息都存储在数据库mysql下的user表里。只要明确这个位置,后续操作无非是如何将正确的凭证写入该表。下面分享几种经过大量实战验证的恢复方案,从最“直接粗暴”到最“优雅稳妥”,大家可以根据自己的场景灵活选择。
方法一:直接拷贝 user 表文件(Windows→Linux)
如果你手头有一台Windows机器上的MySQL,并且拥有足够的权限,最直接的方法就是把user表的三个文件复制过来覆盖。在c:\mysql\data\mysql\(Linux下通常位于/var/lib/mysql/mysql/)下,能找到这三个关键文件:
user.frm——表结构定义user.MYD——实际数据user.MYI——索引
保险起见三个文件都复制过去,不过如果目标机器没有修改过表结构,实际上只需复制user.MYD即可。接下来执行以下操作:
# /etc/rc.d/init.d/mysql stop
# /etc/rc.d/init.d/mysql start
# mysql -u root -p XXXXXX
此时应该能用Windows下的密码登录。但别高兴太早,很可能遇到这样的错误:
mysql> use mysql;
mysql> update user set Password=PASSWORD('xxxxxx') where User='root';
ERROR 1036 (HY000): Table 'user' is read only
原因很明确——Windows下user.*文件的权限为666,复制到Linux后变成600,并且文件所有者变成了root,而不是mysql用户。解决方法就是修正所有者与权限:
# chown -R mysql:mysql user.*
# chmod 600 user.*
重启MySQL再次尝试,修改密码即可成功。最后别忘记执行以下清理命令,因为Windows默认配置可能包含匿名用户或者允许任意主机登录:
mysql> delete from user where User='';
mysql> delete from user where Host='%';
mysql> FLUSH PRIVILEGES;
到此,密码恢复完成。不过这个方法有明显的局限性——你需要有一份现成的user表文件才能操作。
方法二:使用 –skip-grant-tables 参数(最通用)
这个思路在MySQL官方中文参考手册中就有记载,也是网络上流传最广的恢复方法。核心思想是绕过权限表启动服务器,然后重置密码。
具体步骤:
- 先关闭mysqld进程(注意使用
kill -TERM,不要用-9):killall -TERM mysqld - 用
--skip-grant-tables参数启动:
Linux下:/usr/bin/safe_mysqld --skip-grant-tables
Windows下:c:\mysql\bin\mysqld --skip-grant-tables - 此时无需密码即可直接登录MySQL:
mysql -u root - 执行密码修改命令:
use mysql;update user set password=password('new_pass') where user='root';flush privileges; - 或者直接使用命令行工具:
mysqladmin -h hostname -u user password 'new password' - 重新加载权限表:
mysqladmin -h hostname flush-privileges或 SQL 命令FLUSH PRIVILEGES; - 再次杀掉mysqld,然后正常启动,用新密码登录。
这个方法不需要额外文件,任何MySQL版本都适用,强烈推荐作为首选方案。
方法三:直接编辑 user.MYD 文件(十六进制编辑)
如果你不想重启服务,又恰好拥有另一个环境下的user表文件,可以尝试直接修改Linux下的user.MYD文件。用十六进制编辑器打开,找到加密密码串的位置,替换成你已知的密文。
不过这里有一个陷阱:加密后的密码串在文件里并不是连续存储的——有些情况下最后两个字节会被切到后面别的位置。这一点我至今没完全想明白,所以操作时一定要备份原文件。另外注意,你需要事先知道新密码对应的加密串(比如从另一台机器上提取出来)。这种方法与方法一的区别在于:不需要重新设置文件所有者与权限,直接在原文件上动手即可。
以上三种方法各有利弊。场景一适合你有现成备份文件的情况;场景二最稳妥,建议优先尝试;场景三适合喜欢钻研底层数据的极客。无论选择哪种,记得操作前先停止MySQL服务,操作后务必执行FLUSH PRIVILEGES。密码安全无小事,谨慎操作总没错。
