MySQL(管理)01 -- 用户User和权限Privileges<A.权限验证>
MySQL中的user由用户名和主机名构成,如"[email protected]",同用户名但不同主机名对MySQL来讲是不同的,也就是说"[email protected]"和"[email protected]"是不同的,尽管它们都是root用户。
1.权限验证
在MySQL服务器启动后会载入权限表到内存中,当用户要连接服务器,会读取权限表来验证和分配权限,即在内存中进行权限的读取和写入。
MySQL中的权限系统经过两步验证:
1.合法性验证:验证user是否合法,合法者允许连接服务器,否则拒绝连接。
2.权限验证和分配:对通过合法性验证的用户分配对数据库中各对象的操作权限。
1.1 权限表
MySQL中的权限表都存放在mysql数据库(schema)中。权限相关的表有user表、db表、tables_priv表、columns_priv表、procs_priv表(存储过程和函数相关的权限)。 下表来自于MySQL8 的官方文档。
表名 | user | db | tables_priv | columns_priv | procs_priv |
用户和名词 | Host | Host | Host | Host | Host |
User | Db | Db | Db | Db | |
User | User | User | User | ||
Table_name | Table_name | Routine_name | |||
Column_name | Routine_type | ||||
权限列 | Select_priv | Select_priv | Table_priv | Column_priv | Proc_priv |
Insert_priv | Insert_priv | Column_priv | |||
Update_priv | Update_priv | ||||
Delete_priv | Delete_priv | ||||
Index_priv | Index_priv | ||||
Alter_priv | Alter_priv | ||||
Create_priv | Create_priv | ||||
Drop_priv | Drop_priv | ||||
Grant_priv | Grant_priv | ||||
Create_view_priv | Create_view_priv | ||||
Show_view_priv | Show_view_priv | ||||
Create_routine_priv | Create_routine_priv | ||||
Alter_routine_priv | Alter_routine_priv | ||||
Execute_priv | Execute_priv | ||||
Trigger_priv | Trigger_priv | ||||
Event_priv | Event_priv | ||||
Create_tmp_table_priv | Create_tmp_table_priv | ||||
Lock_tables_priv | Lock_tables_priv | ||||
References_priv | References_priv | ||||
Reload_priv | |||||
Shutdown_priv | |||||
Process_priv | |||||
File_priv | |||||
Show_db_priv | |||||
Super_priv | |||||
Repl_slave_priv | |||||
Repl_client_priv | |||||
Create_user_priv | |||||
Create_tablespace_priv | |||||
Create_role_priv | |||||
Drop_role_priv | |||||
安全字段 | ssl_type | ||||
ssl_cipher | |||||
x509_issuer | |||||
x509_subject | |||||
plugin | |||||
authentication_string(这是存放用户密码) | |||||
password_expired | |||||
password_last_changed | |||||
password_lifetime | |||||
account_locked | |||||
Password_reuse_history | |||||
Password_reuse_time | |||||
Password_require_current | |||||
User_attributes | |||||
资源控制列 | max_questions | ||||
max_updates | |||||
max_connections | |||||
max_user_connections | |||||
其他字段 | Timestamp | Timestamp | Timestamp | ||
Grantor | Grantor |
注:对database和Table,MySQL设计有专门drop权限的,则需要拥有drop权限的用户才能drop删除对象。而对于routine,因为MySQL没有设计专门的drop权限,则拥有create routine权限即自动同时拥有drop routine权限。
这几个表用的最多的是user表。user表主要分为几个部分:用户列、权限列、安全列、资源控制列以及杂项列,最需要关注的是用户列和权限列。其中权限列又分为普通权限(上表中红色字体)和管理权限列,如select类的为普通权限,super权限为管理权限。且可以看到,db表中的权限全都是普通权限,user表中除了db表中具有的普通权限还有show_db_pirv和create_tablespace_priv,除此之外还有几个管理员权限。也就是说,db中没有的权限是无法授予到指定数据库的。例如不能授予super权限给test数据库。
另外,usage权限在上表中没有列出,因为该权限是所有用户都有的权限,它只用来表示能否登录数据库,它的一个特殊功能是grant仅指定该权限的时候不会影响现有权限,也就是说可以拿grant来修改密码而不影响现有权限。
需要说明的是,从user表到db表再到tables_priv表最后是columns_priv表,它们的权限是逐层细化的。user表中的普通权限是针对所有数据库的,例如在user表中的select_priv为Y,则对所有数据库都有select权限;db表是针对特定数据库中所有表的,如果只有test数据库中有select权限,那么db表中就有一条记录test数据库的select权限为Y,这样对test数据库中的所有表都有select权限,而此时user表中的select权限就为N(因为为Y的时候是所有数据库都有权限);同理tables_priv表也一样,是针对特定表中所有列的权限;columns_priv则是针对特定列的权限。
所以对于已经通过身份合法性验证的用户的权限读取和分配的机制如下:
- 1.读取uesr表,看看user表是否有对应为Y的权限列,有则分配。
- 2.读取db表,看看db表中是否有哪个数据库分配了对应的权限。
- 3.读取tables_priv表,看看哪些表中有对应的权限。
- 4.读取columns_priv表,看看对哪些具体的列有什么权限。
例如,为某一用户授予test数据库的select权限。可以看到user表中的select_priv为N,而db表中的select为Y。
-
GRANT SELECT ON test.* TO 'long'@'192.168.100.1' IDENTIFIED BY '123456';
-
SELECT host,user,select_priv FROM mysql.user;
-
SELECT * FROM mysql.db;
1.2 图解认证和权限分配的两个阶段
1.3 权限生效时机
在服务器启动时读取权限表到内存中,从此时开始权限表生效。
之后使用grant、revoke、set password 等命令也会隐含的刷新权限表到内存中。
另外,使用显式的命令flush privileges或mysqladmin flush-privileges或mysqladmin reolad也会将上述几张权限表重新刷到内存中以供后续的身份验证和权限验证、分配。
转载链接:https://blog.****.net/zyplanke/article/details/103669732