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. svn版本服务器的搭建和简单使用

    ⼀ 服务器搭建篇 1 在”应⽤用程序”⽂文件夹下,找到”实⽤用⼯工具”,打开”终端”APP 2 运⾏行svnadmin create repository,运⾏行完毕之后,可以在当前⺫⽬目录下找 到⼀ ...

  2. Kubernetes 入门-学习-nginx安装-dashboard安装

    一.入门 1.Kubernetes中文社区---http://docs.kubernetes.org.cn/ 2.Kubernetes集群组件: - etcd 一个高可用的K/V键值对存储和服务发现系 ...

  3. mdoc.samples - 用 -mdoc 编写 BSD 手册 的 示范教程

    SYNOPSIS (总览) man mdoc.samples DESCRIPTION (描述) 这个 示范教程 用于 编写 BSD 手册页 (manual page), 它 使用了 -mdoc 宏定义 ...

  4. The Battle of Chibi(数据结构优化dp,树状数组)

    The Battle of Chibi Cao Cao made up a big army and was going to invade the whole South China. Yu Zho ...

  5. linux shell 命令笔记

    标准输入.标准输出.标准错误 File descriptors are integers associated with an opened file or data stream. File des ...

  6. Redis 启动警告解决

    Redis 启动警告解决[转] [root@centos224]# service redisd start 21985:M 24 Nov 04:07:20.376 * Increased maxim ...

  7. input输入框实现联想关键词功能

    实现原理很简单,代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  8. NOIP模拟赛(by hzwer) T2 小奇的序列

    [题目背景] 小奇总是在数学课上思考奇怪的问题. [问题描述] 给定一个长度为 n 的数列,以及 m 次询问,每次给出三个数 l,r 和 P, 询问 (a[l'] + a[l'+1] + ... + ...

  9. 【leetcode】491. Increasing Subsequences

    题目如下: 解题思路:这题把我折腾了很久,一直没找到很合适的方法,主要是因为有重复的数字导致结果会有重复.最后尝试用字典记录满足条件的序列,保证不重复,居然Accept了. 代码如下: class S ...

  10. mybatis学习$与#号取值区别

    1,多个参数传递用map或实体封装后再传给myBatis, mybatis学习$与#号取值区别 #{} 1.加了单引号,  2.#号写是可以防止sql注入,比较安全 select * from use ...