如何编写好的Mysql grants脚本
我正在使用脚本来创建 Mysql 数据库和表。这些脚本包含如下所示的授予部分:
GRANT SELECT ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
REVOKE ALL PRIVILEGES ON my_database.* FROM my_user@"%";
GRANT SELECT, UPDATE ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
最初,我只使用了第三行,但遇到了以下问题:每当我从用户中删除权限 Q 并重新运行该脚本时,该用户在数据库中仍然具有该权限。所以我在授予行之前添加了撤销行。
然后我遇到了以下问题:每当我在“全新”Mysql 安装上运行脚本时,撤销都会失败,因为用户尚不存在。因此,我在撤销之前添加了“虚拟”补助金。
问题:有没有更好的方法来实现这个目标?我的“真实”脚本包含大量用户和大量数据库,并且很难阅读,因为我需要三行来表示我想要分配的每组权限。我只想用一根线。
编辑(基于答案和评论的反馈):
我正在寻找最短的方式来表达诸如
SET PRIVILEGES SELECT, UPDATE
ON my_database.*
TO my_user@"%"
IDENTIFIED BY 'my_password';
my_user 可能
- 已经存在(但可能是新的)
- 当前拥有的内容扩展我希望他拥有的
- 其他数据库的权限,这些权限必须不受影响
I'm using scripts to create Mysql databases and tables. Those scripts contain grant sections like the following:
GRANT SELECT ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
REVOKE ALL PRIVILEGES ON my_database.* FROM my_user@"%";
GRANT SELECT, UPDATE ON my_database.* TO my_user@"%" IDENTIFIED BY 'my_password';
Initially, I used only the third line, but ran into the following problem: Whenever I removed privilege Q from a user and re-ran that script, the user still had that privilege in the database. So I added the revoke line before the grant line.
Then I ran into the following problem: Whenever I ran the script on a 'fresh' Mysql installation, the revoke failed because the user was not yet existing. So I added a 'dummy' grant before the revoke.
Question: Is there any better way to accomplish this? My 'real' scripts contain lots of users and lots of databases and are hard to read, because I need three lines for each set of privileges I want to assign. I'd like to use only one line.
Edit (based on feedback from answers and comments):
I'm looking for the shortest way to say something like
SET PRIVILEGES SELECT, UPDATE
ON my_database.*
TO my_user@"%"
IDENTIFIED BY 'my_password';
where my_user might
- already exists (but could be new)
- currently have privileges extending the ones I want him to have
- have privileges on other databases, which must remain unaffected
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如有必要,您可以使用过程创建新用户并授予数据库权限。我使用了 准备好的语句 和 GRANT 语句。 MySQL 5.5中的Prepared statements支持GRANT,如果您使用的是较低版本,那么您可以将GRANT命令重写为INSERT INTO。
使用测试;
使用示例:
You can use a procedure to create new user if necessary and grant privileges to database. I used prepared statements and GRANT statements. Prepared statements in MySQL 5.5 supports GRANT, if you are using lower version, then you can rewrite GRANT command to INSERT INTO.
USE test;
Using examples:
确保用户存在而不授予任何权限:
如果您确实想一步完成授予和撤销,您可能必须直接修改内部权限存储表:
但是,这样的可移植性较差,需要更多权限,并且不必要时不要创建用户帐户,因此您最好使用三语句方法。
为了帮助解决可读性问题,您可以创建某种包含帐户和权限的 CSV,并从中生成 SQL 脚本。
To ensure that the user exists without granting any privileges:
If you really want to do the grants and revokes in one step, you may have to muck with the internal permissions storage table directly:
However, that's less portable, requires more permissions, and doesn't create the user account when necessary, so you're probably better off with the three-statement method.
To help with the readability issue, you could create some sort of CSV with accounts and permissions, generating the SQL script from that.
抱歉,答案很长,实际上是一条评论,但我不明白。你的“第三行”GRANT 命令对我来说效果很好。这是应该有效的两种情况。如果您可以发布一些重现该错误的测试命令,那就太好了。至少我可以从中学习:)
情况 #1,用户不存在:
好的,用户不存在。
好的,他有 SELECT 权限。
情况 #2,用户存在并且对
other_database
和my_database
也有权限:好的,用户不存在。
上面是测试装置,现在我们向用户授予新的
UPDATE
权限:他的权限在
other_database
上没有更改,并且他获得了新的UPDATE
对my_database
和之前的SELECT
的权限。根据评论,它应该只是
UPDATE
而没有SELECT
。不幸的是,对于当前的 MySQL 版本,仅使用一个命令无法做到这一点。
GRANT
没有REMOVE EXISTING
子句。我认为最好的解决方案是 @eswald 的
GRANT USAGE ON ...
但它仍然是 3 个命令。另一个解决方案是 a,但它需要一个 FLUSH PRIVILEGES,所以它也是 3 个命令。
解决方法可能是一个 bash 脚本,它生成问题中的三个命令:
它打印:(
我已将第一个
GRANT SELECT
更改为USAGE
。)Sorry for the long answer which actually a comment but I don't get it. Your "third line" GRANT command works well for me. Here is the two cases which should work. It would be great if you could post some test commands which reproduce the bug. At least I could learn from it :)
Case #1, the user does not exist:
OK, the user does not exist.
OK, he has the SELECT permission.
Case #2, the user exists and has right on
other_database
andmy_database
too:OK, the user does not exist.
The above is the test fixture and now we grant a new
UPDATE
permission to the user:His permission haven't changed on the
other_database
and he got the newUPDATE
permission onmy_database
and the formerSELECT
as well.Based on the comments it should be only
UPDATE
withoutSELECT
.Unfortunately with the current MySQL versions it's not possible to do that with only one command.
GRANT
does not haveREMOVE EXISTING
clause.I think the best solution is @eswald's
GRANT USAGE ON ...
but it still 3 commands. Another solution is abut it needs a
FLUSH PRIVILEGES
so it's also 3 commands.A workaround could be a bash script which generates the three commands which is is in the question:
It prints:
(I've changed the first
GRANT SELECT
toUSAGE
.)我只是想知道,你运行过
FLUSH PRIVILEGES
吗?I'm just wondering, have you run
FLUSH PRIVILEGES
?