Mysql的权限问题以及flush privileges

Mysql的权限问题以及flush privileges:

Mysql的权限分为以下四种:
    1.全局权限
        eg:grant all privileges on *.* to 'test'@'%' with grant option;
                revoke all privileges on *.* from 'test'@'%';
    2.db权限
        eg:grant all privileges on testdb.* to 'test'@'%' with grant option;
                revoke all privileges on testdb.* from 'test'@'%';
    3.表权限
        eg:grant all privileges on testdb.test0701 to 'test'@'%' with grant option;        
    4.列权限
        eg:grant select(id), insert(id,a) on testdb.test0702 to 'test'@'%' with grant option;

每种权限的信息都会在磁盘和内存中存储,具体的存储位置为:
    1.全局权限
        磁盘:表mysql.user
        内存:数组acl_user
    2.db权限
        磁盘:表mysql.db
        内存:数组acl_dbs
    3.表权限
        磁盘:表mysql.tables_priv
        内存:和列权限组成的hash结构column_priv_hash
    4.列权限
        磁盘:表mysql.columns_priv
        内存:和表权限组成的hash结构column_priv_hash
    
每种权限的修改策略和作用范围:
    1.全局权限
        策略:已存在的连接不生效,新建立连接立即生效
        范围:当前线程
    2.db权限
        策略:所有连接立即生效
        范围:全局
        (注:这里面有个特殊情况,如果会话在持有某个db的权限时进入了该db,那么会话在执行use xxx时拿到的权限就会保存在会话变量中,即使之后别的会话revoke了权限,也不会影响到该会话,在切换出该db之前该会话会一直持有权限)
    3.表权限
        策略:所有连接立即生效
        范围:全局
    4.列权限
        策略:所有连接立即生效
        范围:全局    

关于flush privileges操作:
        对于全局权限,flush privileges操作会清空acl_user数组,然后从mysql.user表中读取数据重新构造一个acl_user数组,也就是以数据表中数据为准,将内存数组重新加载一遍
        对于db权限、表权限和列权限,Mysql也是做了这样的处理。
    
所以说如果内存中的权限数据和磁盘表中的数据一致的话,flush privileges其实是可以不用做的

而对于正常的grant/revoke/create user等操作,内存和磁盘中的数据都是同步更新的,所以正常的grant/revoke操作后是不需要flush privileges的。

flush privileges的使用场景:
    当我们直接用DML语句修改系统权限表(mysql.user、mysql.db、mysql.tables_priv、mysql.columns_priv)时,内存中的权限数组是不会同步更新的,此时我们就需要flush privileges来更新内存权限数据了。
    eg:delete from mysql.user where user='test0701';

(内容总结自极客时间 丁奇大神的Mysql实战45讲之  42 | grant之后要跟着flush privileges吗?
专栏内容很精彩,推荐给大家哟~
传送门:https://time.geekbang.org/column/intro/139)

你可能感兴趣的:(Mysql)