紫影基地

 找回密码
 立即注册
查看: 217|回复: 0

[Mysql] MySQL何时执行flush privileges?

[复制链接]
阅读字号:

35

主题

39

帖子

6649

积分

论坛元老

Rank: 8Rank: 8

积分
6649
发表于 2024-6-8 10:39:34 | 显示全部楼层 |阅读模式

需求背景
我们平时在给用户授权grant语句执行后,都习惯性的执行一个命令flush privileges;,但是我发现有时候不执行这个命令,授权语句执行之后,权限验证也是OK的,但是有时候发现不执行这个flush privileges;命令,权限认证还不能通过。
那么到底什么情况下需要执行flsh privileges;?什么情况下不需要执行这个命令呢?
创建用户
当我们创建用户的时候,为了安全起见,我们会在用户名后面增加一个host的限制,标识该用户通过指定的密码,只能通过该IP地址段才可以登录MySQL。
创建用户,语句如下所示:
createuser'user1'@'172.19.%' identified by'123456';
上面的示例是创建了一个用户,名称为'user1'@'172.19.%',可以通过172.19.网段,使用123456密码来登录MySQL。
如果用户使用不在172.19.网段,通过这个密码是不能登录MySQL的。言外之意:'user1'@'ip1'和'uesr1'@'ip2'是两个不同的用户,我们不能单纯的靠用户名来确认用户,需要把IP地址也纳入进来。
上述语句执行成功后,MySQL会做两件事情:
会在mysql.user表中增加一条记录。记录内容如下所示:


在MySQL在内存中维护的一个数组变量:acl_users,在这个变量中插入了一个元素,就是我新增加的用户。但此时这个数组中记录的用户的权限也是全部为N,表示这个新增加的用户没有任何范围权限。
给用户授权
前面我们创建了用户,下面我们给这个用户授予访问权限,语句如下所示:
grantallon*.*to'user1'@'172.19.%';
上述语句执行完成后,MySQL也是做了两件事情:
更新了mysql.user表中的这个用户的权限列表,更新后的数据如下:

这个用户的权限如下,从下图中可以看出,该用户用于所有的权限,也就是我们给授予的*.*的权限。
但是除了一个项Grant_priv的值为N,表示该用户不能把自己当前所持有的权限再次赋予其他任何用户,只能自己拥*.*有这些权限。而如果在我们的授权语句后面追加上with grant option关键字之后,Grant_priv的值也会变成Y,表示这个用户可以把当前自己持有的权限,在赋予其他用户。生产环境将不建议给授权的用户增加with grant option选项。
更新了MySQL内存中数组acl_users的中值,把这个用户对应的权限都跟改为Y,表示该用户拥有了我们赋予它的权限。
验证登录
用户创建完成,权限也配置好了,现在我们还没有执行flush privileges;命令。尝试用用户user1@'172.19.%'来登录,登录的时候,要确保你的登录的时候使用的网段为172.19,验证结果如下:

我们发现我们并没有执行flush privileges;命令的前提下,直接使用这个用户登录,就可以登录成功了。
这是为什么?
因为我们在创建用户和为用户授权的时候,MySQL除了维护mysql.user表中的数据,还维护了内存中的acl_users数组。在内存中也更新了对应的用户和权限信息。所以我们可以直接使用新创建的用户名和密码来登录。
收回授权
现在我们把用户的权限给收回,收回后不执行flush privileges;命令,看下用户是否还可以登录MySQL。收回授权的语句如下:
revokeallprivilegeson*.*from'user1'@'172.19.%';
验证用户是否还可以访问所有的数据库,这里在验证的时候,需要退出原先的登录,重新建立连接才可以。因为MySQL数据库中,所有的权限的修改,都是对新连接才生效,已经存在的连接不受影响的。
我们退出上一次的登录,重新登录后的结果如下:

看到只能看到information-schema了,其他都看不到了。这是因为所有的用户,在没有任何权限的时候,默认都可以看到information_schema这个数据库。此时我们在收回用户授权后并没有执行flush privileges;命令。
删除用户
现在我们将用户删除掉,看下是否还可以登录MySQL数据库。删除用户的语句如下:
dropuser'user1'@'172.19.%';
验证是否可以登录,在验证的时候,同样我们需要先退出上一次的登录重新建立连接。验证后的结果如下

我们发现已经不能登录MySQL数据库了。此时我们在删除用户后并没有执行flush privileges;命令。
总结
通过上面的创建用户、给用户授权、收回授权、删除用户的操作,我们可以发现在不执行flush privileges;命令的时候,这些操作都是生效了。也就是说,此时我们是没有必要执行flush privileges;命令的。
那么什么情况下才需要执行flush privileges;命令呢?
当我们不是通过create user、grant、revoke、drop命令来操作用户和权限,而是通过update语句直接去修改了mysql.user表中的数据的时候,此时我们需要执行flush privileges;命令。
此时我们也应该知道flush privileges;命令的作用了,它的作用就是清空MySQL内存中acl_users数组的数据内容,重新从mysql.user表中加载用户的权限信息。
而当我们直接修改了mysql.user表中的内容的时候,MySQL内存中的acl_users数据信息是没有被更新的,所以此时我们想让我们对mysql.user表的修改直接生效,就需要手动的去更新acl_users数组的信息,而这个更新内存权限信息的操作,也就是通过flush privileges;命令来实现的。
所以,在我们日常的维护MySQL的时候,还是使用create user、grant、revoke、drop命令去维护用户相关的信息。尽量避免直接使用update命令去修改mysql.user表中的信息。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|紫影基地

GMT+8, 2025-1-12 06:50 , Processed in 0.081064 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表