grant命令
grant语句可以在创建用户的同时授予权限,create user创建的用户是没有任何权限的
grant all privileges on *.* to ‘ua’@’%’ identified by ‘pa’;
语句里还包含了:
如果用户’ua’@’%'不存在,就创建这个用户,密码是 pa;
如果用户 ua 已经存在,就将密码修改成 pa。
grant select,update on *.* to 'testUser'@'localhost' identified by 'testpwd';创建一个新用户
select host,User,select_priv,update_priv from MySQL.user where user='testUser';
如何查看用户的权限?
SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE
ALL : 以上所有权限,一般是普通管理员拥有的
with grant option:超级管理员才具备的,给别的用户授权的功能
全局权限:
作用于整个Mysql实例,这些权限信息保存在Mysql库的user表里
语句:
grant all privileges on *.* to ‘fcy’@’%’ identified by ‘123456’ with grant option; 最高权限
这个grant语句做了两个动作:
1.磁盘上,将mysql.user表里,用户’ua’@‘%’这一行的所有表示权限的字段的值都修改为‘Y’;
2.内存里,从数组acl_users中找到这个用户对应的对象,将access值(权限位)修改为二进制的“全1”。
注:‘fcy’@’%‘和’fcy’@'127.0.0.1’不算是同一个用户
grant命令对于全局权限,同时更新了磁盘和内存。
命令完成后即时生效,接下来新创建的连接会使用新的权限。
对于一个已经存在的连接,它的全局权限不受grant命令的影响。
DB权限:
grant all privileges on db1.* to ‘ua’@’%’ identified by ‘123456’ with grant option; 拥有db1这个库的操作权限
基于库的权限记录保存在mysql.db表中,在内存层面的话保存在数据acl_dbs中。
这条grant命令做了以下两个动作:
在磁盘上,往mysql.db表中插入了一行记录,所有权限位字段设置为’Y‘;
内存里,增加一个对象到数组acl_dbs中,这个对象权限位修改为二进制的“全1”;
当每次需要判断是否有权限时,都要去遍历一次acl_dbs数组
表权限和列权限:
表权限定义存放在表mysql.tables_priv中,列权限定义存放在表mysql.columns_priv中。
这两类权限,组合起来存放在内存的hash结构column_priv_hash中。
跟db权限类似,这两个权限每次grant的时候都会修改数据表,也会同步修改内存中的hash结构,因此,对这两类权限的操作,也会马上影响到已经存在的连接。
回收权限:
revoke all privileges on . from ‘ua’@’%’;
两个动作:
磁盘上,将 mysql.user 表里,用户’ua’@’%'这一行的所有表示权限的字段的值都修改为“N”;
内存里,从数组 acl_users 中找到这个用户对应的对象,将 access 的值修改为 0。
全局权限:因为 super 是全局权限,这个权限信息在线程对象中,而 revoke 操作影响不到这个线程对象。
而如果是DB权限,那revoke是可以直接收回的
这是因为 acl_dbs 是一个全局数组,所有线程判断 db 权限都用这个数组,这样 revoke 操作马上就会影响到 session B,如果你在回收权限时有一个线程已经use了这个DB,那他接下去还是会有这个权限
关于修改权限后要不要flush privileges?
当数据表中的权限数据跟内存中的权限数据不一致的时候,flush privileges 语句可以用来重建内存数据,从而达到一致的状态。
举例不一致的场景?
直接用dml语句操作mysql.user表,去删除用户。