MySQL忘记root密码–不重启mysqd就可重置root密码

在工作中经常有人问我,“忘记mysql的root密码,怎么重新设置一个root密码”。或者你是一个居心不良者,根本不知道root密码是什么,但又想以root身份访问数据库。

先提个问题:如何不重启mysqld,且没有权限修改用户账号和权限的情况下,如何重新设置root密码?不知道没关系,在此之前我也是不知道如何操作的,先看看下面的几种重置root密码的方法。

1、skip-grant-tables

我们常用的方法是使用skip-grant-tables选项,mysqld server启动之后并不使用权限系统(privilege system)。用户不需要任何账号、不受任何限制的访问数据库中所有数据。为了安全起见,通常加上skip-networking,mysqld不侦听任何TCP/IP连接请求。操作过程如下,

1)修改my.cnf配置文件,在mysqld选项中添加skip-grant-tables和skip-networking。

2)再重启mysqld server。

3)通过sql语句修改mysql.user表中存储密码。执行flush privileges,重新启用mysql权限系统。

UPDATE mysql.user SET Password=PASSWORD(‘MyNewPass')WHERE User='root';

FLUSH PRIVILEGES;

4)删除或者注释配置文件中skip-grant-tables和skip-networking的参数选项。如果使用skip-networking,则需要再次重启mysqld。因为skip-networking不是系统变量,只是mysqld的参数选项,而不能通过系统变量动态进行设置。如果没有适用skip-networking,只需要执行flush privileges就可以使权限系统重新生效。

2、–init-file

mysqld_safe可以使–init-file参数选项来执行重新设定密码的sql语句。

1)新建一个初始化文件,如/tmp/initfile,文件内容为上面修改密码的sql语句。

UPDATE mysql.user SET Password=PASSWORD('MyNewPass') WHERE User='root';

FLUSH PRIVILEGES;

2)关闭mysqld服务进程。

3)使用mysqld_safe启动mysqld;

mysqld_safe --init-file=/home/me/mysql-init &

上面的两种方法是在忘记root密码情况下重新设置密码的方法,可以发现都需要重启mysqld服务。很多人都是使用第一种进行重置root密码,但是比较推荐的做法反而是第二种,即安全有快捷简单。

3、不重启的mysqld的方法
还有人问我,我忘记了root密码,但又不能重启mysqld,如何重置root密码?
在没有看到Fernando的博客Recovering MySQL Access之前,我几乎认为没法完成这样的工作,Fernando的方法让人简直令人惊喜,让我学到了。
从上面两种方法可以看到,mysql的用户账号和密码存储在mysql.user表中。一只以来,我一直处于一个误区中,mysql数据中的表都是innodb存储引擎的,而实际上绝大多数表示是以myisam作为存储引擎。

select count(*), engine from information_schema.tables  where table_schema='mysql' group by engine;
+----------+--------+
| count(*) | engine |
+----------+--------+
|        2 | CSV    |
|       22 | MyISAM |
+----------+--------+

另一方面,mysqld可以处理kill命令发送的信号,如SIGHUP、SIGTERM。需要注意MAC OSX会忽略SIGHUP和SIGQUIT信号。

• SIGTERM causes the server to shut down.
• SIGHUP causes the server to reload the grant tables and to flush tables, logs, the thread cache, and the host cache. These actions are like various forms of the FLUSH statement. The server also writes a status report to the error log

SIGHUP信号产生的行为类似于flush命令,你可能想到了些什么,flush privileges?

基本的介绍就这么多,开始重置root密码之旅。

1、首先得有一个可以拥有修改权限的mysql数据库账号,当前的mysql实例账号(较低权限的账号,比如可以修改test数据库)或者其他相同版本实例的账号。把data/mysql目录下面的user表相关的文件复制到data/test目录下面。

cp mysql/user.* test/
chmod g+w test/user.* #或者chown mysql.mysql test/user.*

2、使用另一个较低权限的账号链接数据库,设置test数据库中的user存储的密码数据。

mysql -usylar -p
use test
update user set password=password('MyNewPass') where user=‘root';

3、把修改后的user.MYD和user.MYI复制到mysql目录下,记得备份之前的文件。

mv mysql/user.MYD mysql/user.MYD.bak
mv mysql/user.MYI mysql/user.MYI.bak
cp test/user.MY* mysql/

4、发送SIGHUP信号,重新加载权限表。

ps aux | grep mysqld
kill -SIGHUP 5830 (pid of mysqld)
做完上面的工作,就可以使用新的root密码访问mysql。

参考资料:

Recovering MySQL access

Dangers of skip-grant-tables

 How to Reset the Root Password

–skip-grant-tables

–skip-networking

–init-file

 

此条目发表在mysql分类目录,贴了, 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>