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的更多相关文章

  1. 42 | grant之后要跟着flush privileges吗?

    在 MySQL 里面,grant 语句是用来给用户赋权的.不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效.我最开 ...

  2. 创建MySQL用户 赋予某指定库表的权限 flush privileges才能生效!!!!;@'localhost'授权本地,@'%'授权远程

    update ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value 建议使用GRANT语句进行授权,语句如下: gra ...

  3. MySQL flush privileges 명령어

    INSERT나 UPDATE, DELETE문을 이용해서 MySQL의 사용자를 추가,삭제하거나, 사용자 권한 등을 변경하였을 때, MySQL에 변경사항을 적용하기 위해서 사용하는 명령 ...

  4. MySQL案例02:ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES

    MySQL在授权用户时出现报错信息,具体信息如下: 一.错误信息 执行命令: GRANT SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SH ...

  5. [翻译向] 当flush privileges生效时

    #前言: 最近频繁在mysql权限控制这里栽跟斗,在翻阅了一些资料之后,简单地翻译一下官网关于flush privileges的描述,抛砖引玉.   #翻译正文: If the mysqld serv ...

  6. mysql忘记root密码拯救方法(flush privileges)

    修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p password " ...

  7. flush privileges是什么意思?

    flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里.MySQL用户数据和权限有修改后 ...

  8. mysql创建新的用户及flush privileges解析

    1.首先以root用户登录到mysql mysql -u root -p 2.接着要知道mysql的用户信息是存储在mysql.user(mysql数据库下的user数据表)下的,所以我们只需添加一个 ...

  9. flush privileges 什么意思

    mysql> update mysql.user set password=PASSWORD(‘新密码’) where User=’root’;­ mysql> flush privile ...

随机推荐

  1. input check复选框选择后修改<a>标签超链接href

    1. 给复选框添加onclick事件 获取标签id <tbody> <c:forEach var="file" items="${files}" ...

  2. LVS集群的ipvsadm命令用法

    准备一台Linux服务器,安装ipvsadm软件包,练习使用ipvsadm命令,实现如下功能: - 使用命令添加基于TCP一些的集群服务 - 在集群中添加若干台后端真实服务器 - 实现同一客户端访问, ...

  3. 注册和登录(关于Cookie)

    前记 我将描述一下登陆和注册之间发生了什么,将场景分为客户端和服务端,服务器是Node.JS,客户端是由JS写的 注册 1.注册请求 这是由客户端发送一个POST请求给服务端,其中包含了用户名和密码 ...

  4. 如何在vue中引入图片?

    当我们在Vue.js项目中引用图片时,关于图片路径有以下几种情形: 使用一. 我们在data里面定义好图片路径 imgUrl:'../assets/logo.png' 然后,在template模板里面 ...

  5. MySQL数据库1初识MySQL

    目录 Mysql 一.数据库是什么? 二.为啥使用数据库?(*****) 三.数据库的分类(*****) 1.关系型数据库 2.非关系型数据库 3.关系型与非关系型区别: 四.数据库MySQL的架构 ...

  6. sql优化-派生表与inner-join

    首先来说明一下派生表? 外部的表查询的结果集是从子查询中生成的.如下形式: select ... from (select ....) dt 如上形式中括号中的查询的结果作为外面select语句的查询 ...

  7. [洛谷P2567] SCOI2010 幸运数字

    问题描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是&quo ...

  8. linux运维、架构之路-Kubernetes集群部署TLS双向认证

    一.kubernetes的认证授权       Kubernetes集群的所有操作基本上都是通过kube-apiserver这个组件进行的,它提供HTTP RESTful形式的API供集群内外客户端调 ...

  9. scoket、TCP、UDP、WebService选型

    抱着去转型产品经理的方向去面试了一家公司,面试完很惭愧,不过见到了人事我也很意外,因为其实表现也没那么好,不过在此谈谈我的感受. 1.有3轮,前2轮都是先让我做自我介绍(我都说的很干脆,直接哪年毕业, ...

  10. 详解HASH(字符串哈希)

    HASH意为(散列),是OI的常用算法. 我们常用哈希的原因是,hash可以快速(一般来说是O(段长))的求出一个子段的hash值,然后就可以快速的判断两个串是否相同. 今天先讲string类的has ...