42 grant与flush privileges
42 grant与flush privileges
在mysql里, grant是给用户赋权的,一些文档中经常提到在grant执行后,马上执行一个flush privileges,才能使赋权语句生效,那么,grant之后真的需要执行flush privileges吗?如果没有执行这个flush操作,赋权语句能否生效?
(root@localhost:mysql.sock) [(none)]> create user 'ua'@'%' identified by 'pa';
Query OK, 0 rows affected (0.06 sec)
语句逻辑创建一个用户’ua’@’%’,密码pa,在mysql里,user+host才表示一个用户。
--在磁盘上,往mysql.user表中插入一行,由于没有指定权限,在这行数据上表示权限的字段都是N
--内存里,往数组acl_users里插入一个acl_user对象,对象的值为0

全局权限
全局权限,作用于整个mysql实例,信息保存在mysql.user里,赋予最高权限。
(root@localhost:mysql.sock) [(none)]> grant all privileges on *.* to 'ua'@'%' with grant option;
Query OK, 0 rows affected (0.00 sec)
这个命令的动作
--磁盘上,在mysql.user表里,把’ua’@’%’这一行对应权限的值都修改为Y
--内存里,把acl_users对应对象的值改为1
--1 grant命令对于全局权限,同时更新了磁盘和内存,命令完成后即使生效,接下来新创建的连接会使用新的权限
--2 对于一个已经存在的连接,它的全局权限不受grant的影响。
(root@localhost:mysql.sock) [(none)]> grant all privileges on db1.* to 'ua'@'%' with grant option;
Query OK, 0 rows affected (0.00 sec)
回收上面的权限
db权限
除了全局权限,mysql还支持db级的权限定义,
(root@localhost:mysql.sock) [(none)]> grant all privileges on db1.* to 'ua'@'%' with grant option;
Query OK, 0 rows affected (0.00 sec)
让用户’ua’@’%’用于db1的所有权限。基于db级的权限,保存在mysql.db表中,

--磁盘上,在mysql.db表中,对应的权限修改为Y
--内存里,增加一个对象到acl_dbs中,值为1
每次需要判断一个用户对一个数据库读写权限的时候,都要遍历一次acl_dbs数组,根据user\host\db找到匹配的对象,然后根据对象的权限位来判断。
也就是说,grant修改db权限的时候,是同时对磁盘和内存生效的。
|
SESSION A |
SESSION B |
SESSION C |
|
|
T1 |
Connect(root,root) Create database db1; Create user ‘ua’@’%’ identified by ‘pa’; Grant super on *.* to ‘ua’@’%’; Grant all privileges on db1.* to ‘ua’@’%’; |
||
|
T2 |
Connect(ua,pa) Set global sync_binlog=1; Create table db1.t(c int); |
Connect(ua,pa) Use db1; |
|
|
T3 |
Revoke super on *.* from ‘ua’@’%’; |
||
|
T4 |
Set global sync_binlog=1; Alter table db1.t engine=innodb; |
Alter table db1.t engine=innodb; |
|
|
T5 |
Revoke all privileges on db1.* from ‘ua’@’%’; |
||
|
T6 |
Set global sync_binlog=1; Alter table db1.t engine=innodb;(command denied) |
Alter table db1.t engine=innodb; |
需要说明的是,set global sync_binlog需要super权限。
可以看到,虽然用ua的super权限在t3时刻被收回,但是在t4时刻执行set global的时候,权限认证还是通过了,这是因为super是全局权限,这个权限信息再线程对象中,而revoke操作影响不了这个线程对象。
在t5时刻去掉了ua对db1的所有权限,在t6时刻执行db1库的表就会报权限不足,因为acl_dbs是一个全局数组,所有线程判断db权限都用这个数组,这样revoke操作影响了session B
如果当前会话已经处于某一个db里面,之前use这个库的时候拿到的权限会保存在会话变量中。
表权限和列权限
除了db级别的权限,mysql还执行表和列级别的权限,表权限的定义在mysql.tables_priv中,列权限定义在表mysql.columns_priv中。这两类权限,组合起来放在内存的hash结构column_priv_hash中。
create table db1.t1(id int, a int); grant all privileges on db1.t1 to 'ua'@'%' with grant option;
GRANT SELECT(id), INSERT (id,a) ON mydb.mytbl TO 'ua'@'%' with grant option;
Flush privileges命令会清空acl_users数组,然后从mysql.user表中读取数据重新加载,重新构造一个acl_users数组。对应db权限、表权限、列权限做了同样的处理。
因此正常情况下,grant命令之后,没有必要跟着执行flush privileges命令。
Flush privileges使用场景
Flush privileges语句用来重建内存数据,比如直接用dml操作系统权限表,就需要flush privileges来刷新权限。
|
SESSION A |
SESSION B |
|
|
T1 |
Connect(root,root) Create user ‘ua’@’%’ identified by ‘pa’; |
|
|
T2 |
Connect(ua,pa) Disconnect |
|
|
T3 |
Delete from mysql.user where user=’ua’ |
|
|
T4 |
Connect(ua,pa) Disconnect |
|
|
T5 |
Flush privileges |
|
|
T6 |
Connect(ua,pa)--access denied |
在T3时刻,用delete语句删除了用户ua,但是在t4时刻,ua用户仍让可以连接,原因就是这个时候内存中acl_users数组中还有这个用户,
在T5时候,经过flush刷新内存后,T6时刻在用ua来登录,就会被拒绝。
直接操作系统表是规范的操作,这个不一致状态会导致一些异常的错误。
|
Client A |
|
|
T1 |
Connect(root,root) Create user ‘ua’@’%’ identified by ‘pa’; |
|
T2 |
|
|
T3 |
delete from mysql.user where user='ua'; |
|
T4 |
grant super on *.* to 'ua'@'%' with grant option; ERROR 1133 (42000): Can't find any matching row in the user table |
|
T5 |
create user 'ua'@'%' identified by 'pa'; ERROR 1396 (HY000): Operation CREATE USER failed for 'ua'@'%' |
由于在t3时刻直接删除了数据表的记录,而内存的数据还存在,就导致了T4时刻给用于ua赋权失效,在mysql.user表中找不到这条记录,在t5时刻,重新创建这个用户,因为在内存中判断,会认为这个用户还存在。
42 grant与flush privileges的更多相关文章
- 42 | grant之后要跟着flush privileges吗?
在 MySQL 里面,grant 语句是用来给用户赋权的.不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效.我最开 ...
- 创建MySQL用户 赋予某指定库表的权限 flush privileges才能生效!!!!;@'localhost'授权本地,@'%'授权远程
update ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value 建议使用GRANT语句进行授权,语句如下: gra ...
- MySQL flush privileges 명령어
INSERT나 UPDATE, DELETE문을 이용해서 MySQL의 사용자를 추가,삭제하거나, 사용자 권한 등을 변경하였을 때, MySQL에 변경사항을 적용하기 위해서 사용하는 명령 ...
- MySQL案例02:ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
MySQL在授权用户时出现报错信息,具体信息如下: 一.错误信息 执行命令: GRANT SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SH ...
- [翻译向] 当flush privileges生效时
#前言: 最近频繁在mysql权限控制这里栽跟斗,在翻阅了一些资料之后,简单地翻译一下官网关于flush privileges的描述,抛砖引玉. #翻译正文: If the mysqld serv ...
- mysql忘记root密码拯救方法(flush privileges)
修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p password " ...
- flush privileges是什么意思?
flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里.MySQL用户数据和权限有修改后 ...
- mysql创建新的用户及flush privileges解析
1.首先以root用户登录到mysql mysql -u root -p 2.接着要知道mysql的用户信息是存储在mysql.user(mysql数据库下的user数据表)下的,所以我们只需添加一个 ...
- flush privileges 什么意思
mysql> update mysql.user set password=PASSWORD(‘新密码’) where User=’root’; mysql> flush privile ...
随机推荐
- 自己制作 Android Vector Asset 矢量图
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/c5138891/article/deta ...
- java调用webservice接口 几种方法
webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...
- python email模块
python email模块 官方文档 email模块 电子邮件包是一个用于管理电子邮件消息的库.它的特殊设计不用于向SMTP (RFC 2821).NNTP或其他服务器发送任何电子邮件消息;这些是模 ...
- 管线命令(Pipe)
管线命令接受|前面传来的stdout,管线示意图如下所示: 管线两个需要注意的地方: 1.管线仅会处理stdout,忽略对stderr的处理 2.管线必须接受前个指令的stdin才是 那么,如果我想接 ...
- 在浏览器输入URL发生了什么
在我们输入google.com之后,浏览器上很快就会呈现出谷歌的页面,本文简单介绍一下从URL的输入到浏览器页面的展示,这中间发生了些什么. URL是什么URL全名叫统一资源定位符,uniform r ...
- PAT Basic 1036 跟奥巴马一起编程 (15 分)
美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统.2014 年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个 ...
- 个人第二次作业-c++实现四则运算生成器
c++实现四则运算生成器 GIT地址 Link Git用户名 Redwarx008 学号后五位 61128 博客地址 Link 作业链接 Link 环境配置 使用VS2019社区版,一键式安装,这里不 ...
- centos 安装samba
1 安装 yum install samba samba-client samba-common -y 2 配置 vim /etc/samba/smb.conf 在最下面增加 [wolbo] path ...
- H5 图片上传
1.h5 图片异步上传 (1) 异步上传input触发onchange事件的时候,就把图片上传至服务器.后台可能会返回图片的链接等信息,前台可以把图片信息展示给用户看. (2) 另一种情况可能需要前台 ...
- webpack中require.context 用法
1.require.context(directory, useSubdirectories = false, regExp = /^\.\//) Examples: require.context( ...