尝试授予权限时,用户'root'@'localhost'被拒绝访问。如何授予权限?

190

我查看了许多类似的问题,所以我正在展示我已经检查了基础知识。当然,这并不意味着我没有漏掉什么非常明显的东西。 :-)

我的问题是:为什么在我已经输入密码并获得访问权限的情况下,我被拒绝访问具有执行我要执行操作权限的用户?(为了完整起见,我试图输入错误的密码,以确保MySQL客户端在程序启动时会拒绝我的访问。)

背景:

通过ssh登录到运行MySQL服务器的机器的shell中,我以root身份登录:

[myname@host ~]$ mysql -u root -p -hlocalhost
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 62396
Server version: 5.5.18-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

太棒了。根据类似问题的答案,我应该确保权限与授权表中的内容保持一致。

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql> 

接下来,确保我是我所认为的那个人:

mysql> SELECT user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

...并确保真的真的

mysql> SELECT current_user();
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> 

到目前为止一切都很好。现在我有什么特权?

mysql> SHOW GRANTS FOR 'root'@'localhost';
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                                                                                                                                                                                                                                                                                                                                                        |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '[OBSCURED]' WITH GRANT OPTION |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

现在这样读起来有点困难,所以让我们尝试以下方式(您还将看到存在一个非本地的“root”用户):

mysql> SELECT * FROM mysql.user WHERE User='root'\G
*************************** 1. row ***************************
                 Host: localhost
                 User: root
             Password: *[OBSCURED]
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
          Reload_priv: Y
        Shutdown_priv: Y
         Process_priv: Y
            File_priv: Y
           Grant_priv: Y
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
         Show_db_priv: Y
           Super_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
         Execute_priv: Y
      Repl_slave_priv: Y
     Repl_client_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: Y
     Create_user_priv: Y
           Event_priv: Y
         Trigger_priv: Y
             ssl_type: 
           ssl_cipher: 
          x509_issuer: 
         x509_subject: 
        max_questions: 0
          max_updates: 0
      max_connections: 0
 max_user_connections: 0
*************************** 2. row ***************************
                 Host: [HOSTNAME].com
                 User: root
             Password: *[OBSCURED]
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
          Reload_priv: Y
        Shutdown_priv: Y
         Process_priv: Y
            File_priv: Y
           Grant_priv: Y
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
         Show_db_priv: Y
           Super_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
         Execute_priv: Y
      Repl_slave_priv: Y
     Repl_client_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: Y
     Create_user_priv: Y
           Event_priv: Y
         Trigger_priv: Y
             ssl_type: 
           ssl_cipher: 
          x509_issuer: 
         x509_subject: 
        max_questions: 0
          max_updates: 0
      max_connections: 0
 max_user_connections: 0
 2 rows in set (0.00 sec)

太棒了! MySQL 认为我是 root@localhost,而且 root@localhost 拥有所有这些权限。这意味着我应该能做我想做的事情,对吧?

mysql> GRANT ALL PRIVILEGES ON *.* TO 'steves'@'[hostname].com' IDENTIFIED BY '[OBSCURED]' WITH GRANT OPTION;
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

我怎么会把这么基础的东西弄糟呢?

附注:对于任何想建议我不要使用具有所有权限的 root 用户的人,这是很好的建议,我会考虑在能够给其他用户授予权限后执行此操作。

谢谢!


2
我在远程遇到了同样的问题(并且选择* FROM mysql.user where user= 'root' and host = '%'显示与您相同的权限)。然而,在本地主机上它确实可以工作,即使mysql.user中host ='%'的行与host ='localhost'的行除了该字段外完全相同。我在Windows Server 2003上运行5.0.45。非常感谢任何答案! - Richard Fawcett
4
对于如此有组织的问题点赞! - Dewsworld
1
请确保您已以管理员身份运行cmd。 - Lijo
1
我刚刚在“-p”和密码之间加了一个空格。我知道这很傻,但可能会帮助某些人。 - Vinay W
14个回答

76

当你尝试将所有表的所有权限授予另一个用户时,可能会出现这种情况,因为mysql.users表被认为是除root以外的其他用户无法访问的限制对象。

然而,以下操作应该可以正常工作:

GRANT ALL PRIVILEGES ON `%`.* TO '[user]'@'[hostname]' IDENTIFIED BY '[password]' WITH GRANT OPTION;

注意,我们使用`%`.*而不是*.*


31
为什么 '%'.* 能够运行,但是 *.* 不能? - Pacerier
这是正确的做法。您必须以 root 身份登录到 MySQL,然后尝试授予权限。 - Nav
我遇到了错误1044,访问被拒绝 :( 请帮帮我。 - Bhaumik Thakkar
谢谢,我正在尝试使用pymysql从Python应用程序访问mysql。出现了错误,显示“主机不允许连接到此MariaDB服务器”,通过添加一个新用户解决了这个问题,该用户在这里给出,然后又出现了另一个错误,显示“用户访问被拒绝”,通过您的方法解决了这个问题。 - Balraj Singh Bains
1
如果你使用'%'.*'而不是\%`.*,它将无法工作。你**必须**使用`%`.*`。 - Rosario Russo

74
我在Windows上将MySQL 5.1升级到MySQL 5.5后也遇到了同样的问题。我已经尝试过更改、创建和重置密码,这些方法在这里这里这里这里都有提到,但完全不起作用。我仍然收到相同的错误提示:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

我可以正常连接,显示所有数据库,进行选择和插入操作,创建并添加用户,但是当涉及到GRANT时,出现了访问被拒绝的错误。

我通过在MySQL服务器bin/目录中执行以下命令修复特权,如此处所述,成功解决了这个问题。

C:\MySQL Server 5.5\bin> mysql_upgrade

然后问题就解决了。我希望这个解决方案在Linux上也能起作用,因为通常MySQL在Linux和Windows上提供相同的命令。


2
谢谢。在已通过Homebrew安装了MySQL的Mac OS中,请运行以下命令: cd /usr/local/Cellar/mysql/5.5.25a/bin && mysql_upgrade - zoras
31
如果您正在使用CentOS或通过软件包管理器安装MySQL,则可能需要运行以下命令:/usr/bin/mysql_upgrade -u root -p,输入密码,就可以轻松搞定了! - Zjoia
1
我知道这是比较老的内容,但它对我很有帮助,我想为未来的访问者添加一个评论:如果你尝试运行mysql_upgrade时遇到“ACCESS DENIED”的错误,请尝试改为像这样运行:mysql_upgrade -p。 - blizz
在Ubuntu 12.04上,完全可以解决完全相同的权限问题,只需使用“mysql_upgrade -u <user> -p<password>”选项即可。 - Kai
2
我发现的是,如果你通过 mysqldump ... --all-databases 从 MySQL <= 5.1 导出数据库,然后将其导入到 MySQL >= 5.5 中,你的用户将被替换(当然),但你的 root 将会遇到与 OP 相同的问题。而且 mysql_upgrade 不起作用 - 你必须添加 --force 标志,即 mysql_upgrade -u root -p --force。希望这能帮助到这里的某个人。 - gregoltsov
显示剩余7条评论

66

注意观察输出结果

SHOW GRANTS FOR 'root'@'localhost';

并没有说'ALL PRIVILEGES',但必须详细说明root@localhost拥有什么权限。

GRANT ALL PRIVILEGES会失败,因为用户不能授权他/她没有的权限, 而服务器似乎认为缺少了某些权限...

那么到底缺少了什么呢?

在我的系统上,我得到了这个:

mysql> select version();
+------------+
| version()  |
+------------+
| 5.5.21-log |
+------------+
1 row in set (0.00 sec)

mysql> SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION        |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM mysql.user WHERE User='root' and Host='localhost'\G
*************************** 1. row ***************************
                  Host: localhost
                  User: root
              Password: 
           Select_priv: Y
           Insert_priv: Y
           Update_priv: Y
           Delete_priv: Y
           Create_priv: Y
             Drop_priv: Y
           Reload_priv: Y
         Shutdown_priv: Y
          Process_priv: Y
             File_priv: Y
            Grant_priv: Y
       References_priv: Y
            Index_priv: Y
            Alter_priv: Y
          Show_db_priv: Y
            Super_priv: Y
 Create_tmp_table_priv: Y
      Lock_tables_priv: Y
          Execute_priv: Y
       Repl_slave_priv: Y
      Repl_client_priv: Y
      Create_view_priv: Y
        Show_view_priv: Y
   Create_routine_priv: Y
    Alter_routine_priv: Y
      Create_user_priv: Y
            Event_priv: Y
          Trigger_priv: Y
Create_tablespace_priv: Y <----------------------------- new column in 5.5
              ssl_type: 
            ssl_cipher: 
           x509_issuer: 
          x509_subject: 
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin: <------------------------------- new column in 5.5
 authentication_string: <------------------------------- new column in 5.5
1 row in set (0.00 sec)

在5.5版本中还有新的表,例如mysql.proxies_user,请确保您已经拥有它们。

当安装全新的mysql服务器实例时,安装脚本将使用正确的结构创建所有mysql.*表格。

如果从旧版本升级,请确保使用适当的升级过程(mysql_upgrade),该过程将添加缺失的表格/列。

尽管只是猜测,但似乎没有为此实例执行mysql_upgrade,导致了所见到的行为。


12
这是有用的信息,但我该如何解决问题? - augurar
2
@augurar,执行mysql_upgrade。 - Marc Alff
1
或者,检查是否有另一个拥有“ALL PRIVILEGES”的用户,并切换到该用户并更改本地主机的权限。例如,我在root@127.0.0.1上拥有所有权限,而root@localhost没有。 - Carabus Manuel
这对我有用,我必须以root用户身份运行 mysql_upgrade。请参阅相关的SO帖子 https://dev59.com/PWEh5IYBdhLWcg3wTB_2 - Jason
注意,不需要在命令行中传递根密码。只需传递“-p”,然后会提示输入密码。 - Jason
显示剩余2条评论

11

你可能已经安装了MySQL 8版本(就像我一样),但没有找到满意的答案。在版本8中,您不能再像以前那样创建用户:

GRANT ALL PRIVILEGES ON *.* TO 'steves'@'[hostname].com' IDENTIFIED BY '[OBSCURED]' WITH GRANT OPTION;

您会收到一个相当令人困惑的错误消息:ERROR 1410 (42000): You are not allowed to create a user with GRANT

在版本8中创建用户需要分两步进行:

CREATE USER 'steves'@'[hostname].com' IDENTIFIED BY '[OBSCURED]';
GRANT ALL PRIVILEGES ON *.* TO 'steves'@'[hostname].com' WITH GRANT OPTION;

当然,如果您愿意,您也可以提供一些有限的权限(而不是GRANT ALL PRIVILEGES),例如GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER


我明白了,这突出显示了语句中我的用户名称存在问题。 - beppe9000

8
当我试图安装比发行版中提供的更高版本的MySQL时,发生了这种情况。
我删除了旧版本,然后安装了新版本(rpm -e ... 然后 rpm -i MySQL-server*),但没有意识到 /var/lib/mysql 中的文件仍来自旧版本(正如Marc Alff所解释的那样 - 谢谢!)。
我本可以执行 mysql_upgrade,但由于想从头开始,我选择了:
# su - mysql
$ rm -rf /var/lib/mysql/*
$ mysql_install_db
# /etc/init.d/mysql start

然后设置根密码(/usr/bin/mysqladmin -u root password),并使用GRANT命令,一切都按预期工作了...


谢谢,这对我很有帮助。幸运的是,即使我摧毁了所有的数据库,也没有关系... - Jarrod Mosen

6
在Debian(Wheezy, 7.8)上,使用MySQL 5.5.40,我发现SELECT * FROM mysql.user WHERE User='root'\G显示Event_priv和'Trigger_priv'字段存在,但未设置为Y。

运行mysql_upgrade(带或不带--force)没有任何区别; 我需要手动进行以下操作:

update user set Event_priv = 'Y',Trigger_priv = 'Y' where user = 'root'

然后最终我可以使用:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION

...然后更精确地在单个数据库/用户帐户上使用它。


1
这个方法对我也解决了问题,但是在此之前我发现你需要执行FLUSH PRIVILEGES; 然后重新登录才能设置授权选项。 - Hendrik

6

我遇到了同样的问题,即为root授权的所有特权:

SHOW GRANTS FOR 'root'@'localhost'\G
*************************** 1. row ***************************
Grants for root@localhost: GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*[blabla]' WITH GRANT OPTION

...但仍然无法创建表格:

 create table t3(id int, txt varchar(50), primary key(id));
ERROR 1142 (42000): CREATE command denied to user 'root'@'localhost' for table 't3'

嗯,这是由一个烦人的用户错误引起的,也就是我没有选择数据库。 执行USE dbname之后,它正常工作了。


5

基本上,当您没有指定密码时,就会出现此错误,这意味着您在某个选项文件中列出了不正确的密码。

阅读此文档以了解如何分配和管理帐户密码。

还要检查文件夹/var/lib/mysql/mysql的权限是否为711。


这对我有用。看起来mysql不会为'user'@'localhost'创建权限。所以我必须创建该用户并确保它有密码。 - Jerinaw
权限设置错误了!我很惊讶。非常感谢您发布这个。 - Adam

4
我曾经遇到同样的问题,为了解决它我阅读了许多Stack Overflow帖子和Google文档。最终我在Cloud SQL FAQ中找到了答案:

Google Cloud SQL不支持SUPER权限,这意味着GRANT ALL PRIVILEGES语句将无法使用。作为替代方案,您可以使用GRANT ALL ON `%`.*


3
键入 SHOW GRANTS FOR 'root'@'localhost'; 显示了一些模糊的密码,所以我使用另一台系统上的 HeidiSQL 登录到该系统的 mysql (使用 root 作为用户名和相应的密码) 并键入
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'thepassword' WITH GRANT OPTION;

当我回到该系统并使用 mysql -uroot -pthepassword; 登录时,它起作用了。


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