为什么 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)
大概原来的 GRANT
s 没有创建关联的用户帐户?另请注意,以上是一个网站的示例,其中有许多 个站点。我可能在这里遗漏了一些东西,但我希望在模式中看到 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 USER
从 mysql.user
table 中删除了行]声明。
通过 DML 语句(DELETE
、INSERT
、UPDATE
),做不立即生效。 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.user
、mysql.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'
我安装了 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)
大概原来的 GRANT
s 没有创建关联的用户帐户?另请注意,以上是一个网站的示例,其中有许多 个站点。我可能在这里遗漏了一些东西,但我希望在模式中看到 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 USER
从 mysql.user
table 中删除了行]声明。
通过 DML 语句(DELETE
、INSERT
、UPDATE
),做不立即生效。 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.user
、mysql.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'