创建用户
create user 'ua'@'%' identified by 'pa';
这条命令做了两个动作:
1)磁盘上,往 mysql.user 表里插入一行,由于没有指定权限,所以这行数据上所有表示权限的字段的值都是 N;
2)内存里,往数组 acl_users 里插入一个 acl_user 对象,这个对象的 access 字段值为 0。
全局权限,作用于整个 MySQL 实例
给ua 赋一个最高权限的语句:
grant all privileges on *.* to 'ua'@'%' with grant option;
基于用户的权限记录保存在 mysql.user 表中,在内存里则保存在数组 acl_users中。
这个 grant 命令做了两个动作:
1)磁盘上,将 mysql.user 表里,用户’ua’@’%'这一行的所有表示权限的字段的值都修改为‘Y’;
2)内存里,从数组 acl_users 中找到这个用户对应的对象,将 access 值(权限位)修改为二进制的“全 1”。
grant 命令对于全局权限,同时更新了磁盘和内存。
1)命令完成后即时生效,接下来新创建的连接会使用新的权限。
2)对于已经存在的连接的全局权限不受 grant 命令的影响。
revoke 命令的用法与 grant 类似
db 权限
除了全局权限,MySQL 也支持库级别的权限定义。如果要让用户 ua 拥有库 db1 的所有权限:
grant all privileges on db1.* to 'ua'@'%' with grant option;
基于库的权限记录保存在 mysql.db 表中,在内存里则保存在数组 acl_dbs 中。
这条 grant 命令做了如下两个动作:
1)磁盘上,往 mysql.db 表中插入了一行记录,所有权限位字段设置为“Y”;
2)内存里,增加一个对象到数组 acl_dbs 中,这个对象的权限位为“全 1”。
grant 操作对于已经存在的连接的影响,在全局权限和基于 db 的权限效果是不同的:
1)super 是全局权限,这个权限信息在线程对象中,而 revoke 操作影响不到这个线程对象
2)acl_dbs 是一个全局数组,所有线程判断 db 权限都用这个数组,这样 revoke 操作马上就会影响
表权限和列权限
1) 表权限定义存放在表 mysql.tables_priv 中,列权限定义存放在表 mysql.columns_priv
2) 组合起来存放在内存的 hash 结构 column_priv_hash 中
跟 db 权限类似,这两个权限每次 grant 的时候都会修改数据表,也会同步修改内存中的 hash 结构。
因此对这两类权限的操作,也会马上影响到已经存在的连接。
flush privileges
flush privileges 命令会清空 acl_users 数组,然后从 mysql.user 表中读取数据重新加载,重新构造一个 acl_users 数组。正常情况下,grant 命令之后没有必要跟着执行 flush privileges 命令.
当数据表中的权限数据跟内存中的权限数据不一致的时候,flush privileges 语句可以用来重建内存数据,达到一致状态。这种不一致往往是由不规范的操作导致的,比如直接用 DML 语句操作系统权限表。




