如何在MySQL中将所有权限恢复给root用户?

12

我使用--skip-grant-tables选项登录了MySQL。但是我不知道如何将所有权限还原给root用户。

我尝试过:

GRANT ALL PRIVILEGES ON * . * TO 'root'@'localhost';

MySQL 说:

# 1290 - The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

尝试:

GRANT ALL PRIVILEGES ON * . * TO 'root'@'localhost'
WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0
MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;

MySQL 说:

# 1290 - The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

1
在这个问题/答案中似乎有一个解决方案 https://dev59.com/nHI-5IYBdhLWcg3wta_w - Jeff Paquette
6个回答

23

针对 MySQL 8.0.12+
我尝试过文档(无效),还尝试了其他各种选项,但都失败了。

PASSWORD() 已弃用,SET PASSWORDALTER USER 均已禁用。

  1. 停止 MySQL 服务
  2. 以以下方式启动它:/usr/local/mysql/bin/mysqld_safe --skip-grant-tables
  3. 登录(mysql)并执行: use mysql; update user set authentication_string='' where User='root';
  4. killall mysqld
  5. 再次启动服务

现在您可以在登录时没有密码的情况下使用 set passwordalter user


2
这就是答案!为什么PASSWORD()被弃用了?太奇怪了。 - mbrinson
2
@mbrinson 我注意到的MySQL的问题非常多。 事实上,它没有得到专业的维护,是数百个丑陋的黑客组合而成。INNODB在计数方面很慢,因为mysql只使用一个线程,在处理周期时延迟很大,解决方案是什么?他们发明了一个复杂的结果缓存。 随着Mysql 8的推出,他们删除了缓存(破坏了成千上万的应用程序),并发明了多线程,但只有对没有WHERE的查询进行多线程处理,因此只适用于计数。我可以举出无数这样的例子,它由“代码黑客”维护。 - John
3
我遇到了“未选择数据库”的错误。 - Overload119
1
@Overload119:在执行 UPDATE user... 前先执行 USE mysql; - Daniel Rikowski
我收到了“列'authentication_string'不可更新”的错误信息。 - Burrito

8
如果您无法作为root访问mysql服务器,则应删除或无法恢复mysql.user表中的所有root记录,删除所有记录并添加新记录。
您应该使用mysql PASSWORD()函数对明文密码进行哈希处理。有关更多信息,请查看http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html 首先停止mysql服务器并使用--skip-grant-tables启动mysqld。
[root@mysql ~]# service mysqld stop; mysqld_safe --skip-grant-tables &

将明文密码进行哈希。

mysql> select PASSWORD('CLEARTEXT_PASSWORD');
+-------------------------------------------+
| PASSWORD('CLEARTEXT_PASSWORD')            |
+-------------------------------------------+
| *1EADAEB11872E413816FE51216C9134766DF39F9 |
+-------------------------------------------+
1 row in set (0.00 sec)

使用MySQL数据库应用更改。
mysql> use mysql;

删除所有根记录

mysql> delete from user where User='root';

添加新记录,使root用户可以从您的IP地址访问并拥有所有权限。

mysql> insert into `user` VALUES('YOUR_IP_ADDRESS','root','*1EADAEB11872E413816FE51216C9134766DF39F9','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'','');

刷新更改。

mysql> FLUSH PRIVILEGES;

退出mysql命令行。

mysql> exit;

重新启动mysqld服务。

[root@mysql ~]# /etc/init.d/mysqld restart

如果您运行这些MySQL命令/查询,您将获得对MySQL服务器的新访问权限。


如果插入操作难以匹配所需的特权列,请参见下面的答案。如果您只需要一个新的授权,例如另一个允许的主机列,请复制现有行。 - user18099
3
使用以下命令将明文密码加密:SELECT PASSWORD('CLEARTEXT_PASSWORD'); 出现1064错误,SQL语法有误,请查看与您的MySQL服务器版本相对应的手册以了解正确使用方法。 - Draif Kroneg

7

首先,停止MySQL服务器,然后使用--skip-grant-tables选项启动它。

[root@backups1 mysql5.7]# /etc/init.d/mysqld stop
[root@backups1 mysql5.7]# /usr/local/mysql/bin/mysqld_safe --skip-grant-tables --user=mysql

然后,无需密码即可连接到您的实例:
[root@backups1 mysql5.7]# mysql -u root

然后,重置root用户的密码。

mysql> flush privileges;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '';
mysql> flush privileges;

切换到MySQL的正常模式,然后无需密码连接。


如果我使用skip-grant-tables选项以root身份登录,则无法执行任何语句。错误是:“MySQL服务器正在使用--skip-grant-tables选项运行,因此无法执行此语句”。 - Vincent
1
在这种情况下,您需要运行flush privileges。 - Mansur Ul Hasan
我尝试了很多方法都没有成功,直到这个方法。我认为关键是在任何alter user命令之前运行flush privileges。您能解释一下为什么这样可以抑制错误“MySQL服务器正在使用--skip-grant-tables选项运行,因此无法执行此语句”吗? - Burrito

5
当您使用--skip-grant-tables运行mysql时,mysql不会检查任何权限。因此,基本上您可以做任何事情。
要恢复root权限,您需要在mysql数据库中运行以下查询。
select * from user where user = 'root'

只是为了检查root用户是否仍然存在 如果正常:

UPDATE user SET Grant_priv = 1, Super_priv = 1 WHERE user = 'root'

在你不使用--skip-grant-tables的情况下重新启动mysql,root用户应该能够进行一些授权操作,因此您的查询应该可以正常工作。


2
在MariaDb中,正确的语句是UPDATE user SET Grant_priv = 'Y', Super_priv = 'Y' WHERE user = 'root',因为它使用了ENUM('Y','N')。您原来的版本已经被执行,但表中的值'Y'/'N'没有更新,但这个小修改解决了问题。 - Dankó Dávid

1
如果你使用 --skip-grant-tables 的目的是插入新的授权,你可以在 mysql.user 中插入一行(请参阅其他答案)。
如果你的挑战在于给这个新授权赋予所有所需的权限(许多 Y/N 列),那么你可以复制一个现有的 root 授权,并仅调整你需要的内容。
CREATE TEMPORARY TABLE mysql.tmpUser SELECT * FROM mysql.user WHERE host="old" and user="root";
UPDATE mysql.tmpUser SET host="new" WHERE user = "root";
INSERT INTO mysql.user SELECT * FROM mysql.tmpUser;

这个解决方案非常适合像在 Vagrant 中进行的环境自动化。 - Ghazi Triki

-10
运行一个 GRANT 查询,你只需要不要使用 skip-grant-tables 运行 mysql -- 这有什么复杂的...?


6
他需要获取root权限。 - RageZ
...所以他不应该使用skip-grant-tables--他为什么要同时使用GRANT呢?虽然我承认你的方法也可以。 - Alex Martelli
3
他好像忘记了root用户的密码。 - bluszcz
这个问题似乎是关于获取特权标志的。您可以使用skip-grant登录,但无法授予权限。您可以在mysql.user中插入一行新的root授权行,但查询需要匹配许多特权列。每个特权需要一个Y/N。 - user18099

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接