为什么MySQL GRANT没有创建关联的用户帐户?

时间:2015-06-11 11:14:19

标签: mysql grant percona

我安装了Percona Toolkit以使用pt-show-grants,但它没有显示所有授权。当我运行它时,我看到以下输出:

-- Grants dumped by pt-show-grants
-- Dumped from server Localhost via UNIX socket, MySQL 5.5.43-log at 2015-06-11 09:19:19
-- Grants for 'bob'@'12.34.56.78'
GRANT SUPER ON *.* TO 'bob'@'12.34.56.78' IDENTIFIED BY PASSWORD '*4F72B97CAAAAAAAAAAA9C38064C4CCB18CA0DD8';
GRANT SELECT ON `mydb`.* TO 'bob'@'12.34.56.78';
...

在这种情况下,bob只是一个用户。但是,所有网站都使用特定凭据,例如开发人员Bob可能拥有其example.com网站的帐户,名为bob_examplecom_1。当我显示此帐户的拨款时:

mysql> SHOW GRANTS FOR 'bob_examplecom_1'@'localhost';
+-------------------------------------------------------------------------------------------------------------------------+
| Grants for bob_examplecom_1@localhost                                                                                   |
+-------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bob_examplecom_1'@'localhost' IDENTIFIED BY PASSWORD '*74AE8018AAAAAAAAAAAAAAAABB87B5C83E650CB' |
| GRANT ALL PRIVILEGES ON `bob_core`.* TO 'bob_examplecom_1'@'localhost' WITH GRANT OPTION                            |
| GRANT ALL PRIVILEGES ON `bob_examplecom_main`.* TO 'bob_examplecom_1'@'localhost' WITH GRANT OPTION                      |
| GRANT ALL PRIVILEGES ON `bob_blog`.* TO 'bob_examplecom_1'@'localhost'                                    |
+-------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

但是,当我尝试找到关联用户时:

mysql> SELECT User, Host FROM mysql.user WHERE User LIKE 'bob\_%';
Empty set (0.00 sec)

大概原始的GRANT没有创建关联的用户帐户?另请注意,以上是一个网站的示例,其中有许多网站。我可能在这里遗漏了一些东西,但我希望在模式中看到NO_AUTO_CREATE_USER

mysql> SELECT @@GLOBAL.sql_mode;
+-------------------+
| @@GLOBAL.sql_mode |
+-------------------+
|                   |
+-------------------+
1 row in set (0.00 sec)

所以,我的问题是我想使用pt-show-grants来创建许多 GRANT的SQL文件,这个文件需要在此开发服务器上为新用户运行,但我无法弄清楚如何。我是否需要追溯创建与GRANT匹配的用户帐户?我将来应该以不同的方式更改某些设置和/或设置帐户吗?

更新:我刚刚运行FLUSH PRIVILEGESGRANT中没有相关帐户的所有mysql.user消失了。这是否意味着他们'很好,所有都需要手动重建?为什么会发生这样的事情?我查看了MySQL命令历史记录,看到过去没有删除这些帐户的命令。这台服务器上的正常运行时间超过400天,这些网站都在那段时间内完成了工作,几乎没什么问题。

更新2:我必须重新创建所有帐户。这次,使用GRANT USAGE然后授予权限确实创建了用户帐户。我现在的问题很简单:

为什么MySQL GRANT在执行GRANT时没有创建关联的用户帐户?

1 个答案:

答案 0 :(得分:5)

根据您对观察到的行为的描述,听起来好像是使用mysql.user语句而不是DELETE语句从DROP USER表中删除了行。

通过DML语句(mysql.usermysql.dbDELETE)对权限表(INSERTUPDATE等)所做的更改立即生效。 MySQL已经读取了这些表,并且信息保存在内存中。权限检查违反内存存储; MySQL没有检查表的内容。

因此,可以对mysql.user表进行更改,而不是将这些更改反映在有效权限中。

FLUSH PRIVILEGES语句是导致MySQL重新读取所有权限表的原因,并在内存中重建""特权信息存储。

回答你的问题......

问:据说原创GRANTs没有创建关联的用户帐户?

问:为什么MySQL GRANT在执行GRANT时没有创建关联的用户帐户?

A:"新" GRANT用户创建用户帐户(如果已成功完成)。适当的行 被添加到mysql.user表中,并且权限生效(更改也应用于"内存和#34;权限结构。

问:这是否意味着他们已经永远消失了,所有这些都需要手动重新创建?

A:是的。如果行不在mysql.user表中,则需要重新创建这些行。可以从备份中恢复mysql.usermysql.db表中的行。

问:为什么会发生这样的事情?

A:如前所述,有人可能无意中对mysql.user表运行了DELETE语句。 (它也可能是TRUNCATE,或DROP和CREATE。(从包含DROP TABLE语句的mysqldump脚本执行SQL,从旧备份重新加载表?)

如果没有在表上执行此类操作,则另一种可能性是MyISAM表损坏,并且修复损坏导致丢失行。 (MyISAM表的已知问题;以及我们备份数据库和测试恢复的原因之一。)

以下是对行为的演示......从mysql.user中删除一行并不会立即反映在有效权限中:

验证用户不存在:

mysql> SELECT USER, HOST FROM mysql.user WHERE USER LIKE 'bob' ;
Empty set (0.00 sec)
mysql> SHOW GRANTS FOR 'bob'@'192.168.11.121' ;
ERROR 1141 (42000): There is no such grant defined for user 'bob' on host '192.168.11.121'

使用GRANT语句创建用户:

mysql> GRANT SELECT ON ergo.* TO 'bob'@'192.168.11.121' IDENTIFIED BY 'mysecret';
Query OK, 0 rows affected (0.00 sec)

检查mysql.user表的内容和有效权限:

mysql> SELECT USER, HOST FROM mysql.user WHERE USER LIKE 'bob' ;
+------+----------------+
| USER | HOST           |
+------+----------------+
| bob  | 192.168.11.121 |
+------+----------------+
1 row in set (0.00 sec)

mysql> SHOW GRANTS FOR 'bob'@'192.168.11.121' ;
+-----------------------------------------------------------------------------------------------------------------+
| Grants for bob@192.168.11.121                                                                                   |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bob'@'192.168.11.121' IDENTIFIED BY PASSWORD '*440A4F469FD488A1C73204842936CC18A62A7D7F' |
| GRANT SELECT ON `ergo`.* TO 'bob'@'192.168.11.121'                                                              |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

从mysql.user表中删除行(使用DML操作而不是DROP USER语句)

mysql> DELETE FROM mysql.user WHERE USER = 'bob' AND HOST = '192.168.11.121';
Query OK, 1 row affected (0.00 sec)

行已从mysql.user表中删除,但权限仍然有效:

mysql> SELECT USER, HOST FROM mysql.user WHERE USER LIKE 'bob' ;
Empty set (0.00 sec)

mysql> SHOW GRANTS FOR 'bob'@'192.168.11.121' ;
+-----------------------------------------------------------------------------------------------------------------+
| Grants for bob@192.168.11.121                                                                                   |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bob'@'192.168.11.121' IDENTIFIED BY PASSWORD '*440A4F469FD488A1C73204842936CC18A62A7D7F' |
| GRANT SELECT ON `ergo`.* TO 'bob'@'192.168.11.121'                                                              |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

强制MySQL重建权限,从mysql.user表中读取...

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

特权不再有效:

mysql> SHOW GRANTS FOR 'bob'@'192.168.11.121' ;
ERROR 1141 (42000): There is no such grant defined for user 'bob' on host '192.168.11.121'