在我的PHP脚本中,我访问了两个数据库db1
和db2
。我的用户myuser@localhost
可以访问db1
但无法访问db2
。
从mysql.user
表中选择时,有一条记录,该用户的主机是通配符%
,没有localhost
主机。
SELECT user, host FROM mysql.user WHERE user = 'myuser';
给我:
+------------+------+
| user | host |
+------------+------+
| myuser | % |
+------------+------+
1 row in set (0.00 sec)
查看该用户的GRANTS,我发现db1
与db2
相同的权限
SHOW GRANTS FOR 'myuser'@'%';
+-----------------------------------------------------------------------------------------------------------+
| Grants for myuser@% |
+-----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'%' |
| GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'%' |
+-----------------------------------------------------------------------------------------------------------+
在我的PHP脚本中,我可以访问db1
但是我收到错误:INSERT command denied to user 'myuser'@'localhost' for table 'HISTORY'
。
它表示用户为myuser@localhost
,并且有人建议为myuser@localhost
添加权限,但为什么此用户可以访问db1
而不是db2
?
答案 0 :(得分:23)
localhost
与MySQL中的%
不匹配。它似乎应该,但事实上它不应该。您必须为user@localhost
权限和每个数据库的权限分别授予USAGE
权限。
或者您可以{em> 匹配user@127.0.0.1
%
进行连接。使用localhost的IP地址似乎应该与localhost完全相同,但事实并非如此。您需要在mysql.user
表中(以及在您的案例中的mysql.db
表中)有两行才能启用这两行。
演示localhost和127.0.0.1之间的区别:
以mysql -h localhost
身份连接使用UNIX套接字接口,并绕过TCP / IP。这可能会稍微好一点,但它会对上面描述的授权匹配产生影响。
您可以通过mysql -h 127.0.0.1
连接来强制本地TCP / IP连接。然后它将获得您对myuser@%
所做的补助。
因此,要获得套接字接口和TCP / IP接口的相同用户,密码和权限,您需要运行以下语句的所有:
GRANT USAGE ON *.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT USAGE ON *.* TO 'myuser'@'localhost' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'%'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'localhost'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'%'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'localhost'
答案 1 :(得分:6)
如果您还没有这样做,则需要运行flush privileges
以便mysql
知道有更改并为用户重新加载权限表:
FLUSH PRIVILEGES;
答案 2 :(得分:2)
这很可能与GRANTs无关。
由于MySQL中存在默认用户,因此具有不正确访问权限的一个常见原因是。特别是在''
表中User
(匿名用户)和/或Host
mysql.user
的{{1}}。由于MySQL处理authentication and proxy users的方式以及mysql.user
表条目上使用的排序规则,最终可能会使用意外用户而不是用于身份验证的用户。
使用SELECT USER();
查找身份验证期间使用的关联用户,SELECT CURRENT_USER();
查找在当前会话期间适用其权限的有效用户。
来自http://dev.mysql.com/doc/refman/5.6/en/connection-access.html
对于给定的用户名,所有人都认为这是一种常见的误解 显式命名该用户的行在服务器时首先使用 尝试找到连接的匹配项。这不是真的。 如果您能够连接到服务器,但您的权限不是 你所期望的,你可能正在被其他人认证 帐户。
类似于以下的mysql.user
表
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ... (root from any host)
| % | jeffrey | ... (jeffrey from any host)
| localhost | root | ... (root from localhost)
| localhost | | ... (any user from localhost)
+-----------+----------+-
变,
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
每当服务器将用户表读入内存时,为了处理多个匹配
当客户端尝试连接时,服务器按排序顺序查看行,并使用与客户端主机名和用户名匹配的第一行。
优先级为:值(IP地址,主机名,用户名等)> '%'
> ''
大多数情况下,应用程序服务器/客户端与数据库在同一主机上运行,导致主机名在身份验证期间被选为localhost
。
mysql -u jeffrey
使用与jeffrey@localhost
而不是''@localhost
匹配的jeffrey@%
。
执行$MYSQL_HOME/bin/mysql_secure_installation
将删除匿名用户,同时保护安装,减轻这种意外行为。
同时检查:
[1] http://bugs.mysql.com/bug.php?id=36576(最后检查评论)
[2] http://bugs.mysql.com/bug.php?id=69570
答案 3 :(得分:2)
我想我会添加一个答案。我在ubuntu上尝试这个。尝试了补助金,冲洗,没有任何工作(这是由apt-get install mysql-server之后立即执行)。只是为了笑容,我反弹了服务器,这是有效的,我的新用户现在可以登录。我做了:
sudo service mysql restart
我不知道那有什么用,但确实如此。
答案 4 :(得分:1)
您还必须授予'myuser'@'localhost'特权:
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'localhost';
GRANT ALL PRIVILEGES ON `db2_beta`.* TO 'myuser'@'localhost';
否则,在db安装期间创建的匿名用户@localhost优先于您的用户使用通配符主机名(%),如下所述:
答案 5 :(得分:0)
根据mysql手册here:
如果使用帐户管理间接修改授权表 服务器通知,如GRANT,REVOKE或SET PASSWORD等语句 这些更改并将授权表再次加载到内存中 立即
如果使用诸如的语句直接修改授权表 INSERT,UPDATE或DELETE,您的更改对权限没有影响 检查,直到您重新启动服务器或告诉它重新加载 表。如果直接更改授权表但忘记重新加载 在重新启动服务器之前,您的更改无效。这个 可能会让你想知道为什么你的改变似乎没有任何改变 差!
在大多数情况下,这似乎都是正确的。但是,在我的情况下,我正在使用Amazon Web Services(AWS)RDS mysql实例。在许多尝试授予用户权限的尝试失败后,我尝试了FLUSH PRIVILEGES
,并且数据库立即对用户可见。如果您在Amazon Web Services RDS平台上寻找解决方案时遇到此问题,您可能需要尝试一下,看看它是否有帮助。
此SO问题包含此问题的最完整解决方案,并且是大多数搜索结果中的第一个,因此我想为使用RDS的任何人添加此响应。希望它能节省RDS管理员一段时间。
答案 6 :(得分:-1)
我过去遇到过同样的问题。你试过以下这个吗?
GRANT ALL ON `db1`.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...';
GRANT ALL ON `db2`.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...';
FLUSH PRIVILEGES;