我安装了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)
据推测,原始GRANTs没有创建关联的用户帐户?另请注意,上面是一个网站的示例,其中有许多网站.我可能在这里遗漏了一些东西,但我希望在一种模式下看到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 PRIVILEGES,并且所有在mysql.user中没有关联帐户的GRANT都消失了.这是否意味着他们已经永远消失了,所有这些都需要手动重建?为什么会发生这样的事情?我查看了MySQL命令历史记录,看到过去没有删除这些帐户的命令.这台服务器上的正常运行时间超过400天,这些网站都在那个时候工作,几乎没什么问题.
更新2:我不得不重新创建所有帐户.这次,使用GRANT USAGE然后授予权限确实创建了用户帐户.我现在的问题很简单:
为什么MySQL GRANT在执行GRANT时没有创建关联的用户帐户?
解决方法:
根据您对观察到的行为的描述,听起来好像是使用DELETE语句而不是DROP USER语句从mysql.user表中删除了行.
通过DML语句(DELETE,INSERT,UPDATE)对权限表(mysql.user,mysql.db等)所做的更改不会立即生效. MySQL已经读取了这些表,并且信息保存在内存中.权限检查违反内存存储; MySQL不检查表的内容.
因此,可以对mysql.user表进行更改,而不是将这些更改反映在有效权限中.
FLUSH PRIVILEGES语句是导致MySQL重新读取所有权限表并重建权限信息的“内存”存储的原因.
回答你的问题……
问:据推测,原始GRANTs没有创建相关的用户帐户?
问:为什么MySQL GRANT在执行GRANT时没有创建关联的用户帐户?
答:“新”用户的GRANT确实创建了用户帐户(如果成功完成).适当的行已添加到mysql.user表中,并且权限生效(更改也应用于“内存中”权限结构.
问:这是否意味着他们已经永远消失了,所有人都需要手动重建?
答:是的.如果行不在mysql.user表中,则需要重新创建这些行.可以从备份中恢复mysql.user,mysql.db表中的行.
问:为什么会发生这样的事情?
答:如前所述,有人可能无意中对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'