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

Why didn't MySQL GRANT create associated user accounts?

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

-- 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 可能有一个名为 bob_examplecom_1 的 example.com 网站帐户。当我显示此帐户的 g运行ts 时:

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)

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

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

所以,我的问题是我想使用 pt-show-grants 创建一个 SQL 文件,其中 很多 GRANT 需要 运行宁为这个开发服务器上的新用户,但我不知道如何。我是否需要追溯创建与 GRANT 匹配的用户帐户?以后我是否应该更改某些设置 and/or 以不同方式设置帐户?

更新:我只是 运行 FLUSH PRIVILEGES 并且在 mysql.user 中没有关联帐户的所有正在工作的 GRANT 都消失了。 这是否意味着它们永远消失了,并且都需要手动重新创建?为什么会发生这样的事情?我查看了 MySQL 命令历史记录,没有看到过去会删除这些帐户的命令。该服务器的正常运行时间超过 400 天,所有站点在这段时间内都正常运行。

更新 2: 我不得不重新创建所有帐户。这次,使用 GRANT USAGE 和 g运行ting 权限确实创建了用户帐户。我的问题现在很简单了:

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

根据您对观察到的行为的描述,听起来好像使用 DELETE 语句而不是 DROP USERmysql.user table 中删除了行]声明。

通过 DML 语句(DELETEINSERTUPDATE),做立即生效。 MySQL 已经读取了那些 table,信息保存在内存中。特权检查违背了内存存储; MySQL 不检查 table 的内容。

因此可以对 mysql.user table 进行更改,但这些更改不会反映在有效权限中。

FLUSH PRIVILEGES 语句导致 MySQL 重新读取所有特权 table,并重建 "in memory" 特权信息存储。


回答您的问题...

问:大概是原来的GRANT没有创建关联的用户账号吧?

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

A: GRANT 为 "new" 用户 did 创建用户帐户,如果完成成功地。适当的行 添加到 mysql.user table,权限生效(更改也应用于 "in memory" 权限结构。

问:这是否意味着它们永远消失了,需要手动重新创建?

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

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

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

如果在table上没有执行这样的操作,那么另一种可能是MyISAM table损坏了,损坏的修复导致了行的丢失。 (MyISAM 的一个已知问题 tables;这也是我们备份数据库并测试恢复的原因之一。)


这是行为的演示...从 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的内容table和有效权限:

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 table 中删除行(使用 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 table 消失,但权限仍然有效:

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 table...

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'