的mysql
系统数据库包括几个授权表,其中包含关于用户帐户及其所持有的特权的信息。本节将描述这些表。有关系统数据库中其他表的信息,请参见第5.3节“mysql系统架构”.
这里的讨论描述授权表的底层结构,以及服务器在与客户机交互时如何使用授权表的内容。但是,通常不直接修改授权表。当您使用帐户管理报表时,修改会间接发生创建用户
,格兰特
,撤销
建立帐户并控制每个帐户的权限。看到第13.7.1节“帐户管理报表”.当您使用这些语句执行帐户操作时,服务器将代表您修改授权表。
直接修改拨款表使用语句,如插入
,更新
,或删除
不鼓励,你自己承担风险。服务器可以随意忽略由于此类修改而变得畸形的行。
对于任何修改授权表的操作,服务器都会检查表是否具有预期的结构,如果没有则产生错误。要将表更新为预期的结构,请执行MySQL升级过程。看到第2.11节“升级MySQL”.
这些mysql
数据库表包含拨款信息:
用户
:用户帐户、静态全局特权和其他非特权列。global_grants
:动态全局特权。db
:数据库级权限。tables_priv
:表级权限。columns_priv
:列级特权。procs_priv
:存储过程和函数的权限。proxies_priv
:代理用户的特权。default_roles
:默认用户角色。role_edges
:角色子图的边。password_history
:密码修改历史。
有关静态和动态全局特权之间区别的信息,请参见静态与动态特权.)
在MySQL 8.0中,授权表使用InnoDB
存储引擎和事务性的。在MySQL 8.0之前,授权表使用MyISAM
存储引擎和是非事务性的。授权表存储引擎的这种更改支持对帐户管理语句的行为进行相应的更改,例如创建用户
或格兰特
.以前,指定多个用户的帐户管理语句可能对某些用户成功,而对另一些用户失败。现在,每个语句都是事务性的,对于所有指定的用户要么成功,要么回滚,如果发生任何错误也没有影响。
每个授权表包含范围列和权限列:
Scope列确定表中每一行的范围;也就是说,行应用的上下文。例如,一个
用户
表行与宿主
而且用户
的值“h1.example.net”
而且“鲍勃”
适用于对从主机到服务器的连接进行身份验证h1.example.net
指定用户名的客户端鲍勃
.同样,一个db
表行与宿主
,用户
,Db
列的值“h1.example.net”
,“鲍勃”
而且“报告”
适用于当鲍勃
从主机连接h1.example.net
访问报告
数据库。的tables_priv
而且columns_priv
表包含范围列,指示每一行应用到的表或表/列组合。的procs_priv
作用域列指示每一行应用到的存储例程。特权列表示表行授予哪些特权;也就是说,它允许执行哪些操作。服务器将各种授权表中的信息结合起来,形成对用户特权的完整描述。第6.2.7节,“访问控制,第二阶段:请求验证”,描述了这方面的规则。
此外,授权表可能包含用于范围或特权评估以外目的的列。
服务器使用授权表的方式如下:
的
用户
表范围列决定是拒绝还是允许传入的连接。中授予的任何特权用户
表指示用户的静态全局权限。该表中授予的任何特权都适用于所有服务器上的数据库。的
global_grants
表列出了当前分配给用户帐户的动态全局特权。对于每一行,作用域列确定哪个用户拥有特权列中指定的特权。的
db
表范围列确定哪些用户可以从哪些主机访问哪些数据库。特权列决定允许的操作。在数据库级别授予的特权适用于数据库和数据库中的所有对象,如表和存储的程序。的
tables_priv
而且columns_priv
表类似于db
表,但更细粒度:它们应用于表和列级别,而不是数据库级别。在表级别授予的特权适用于表及其所有列。在列级别授予的特权只应用于特定的列。的
procs_priv
表适用于存储例程(存储过程和函数)。在例程级别授予的特权只应用于单个过程或函数。的
proxies_priv
表指示哪些用户可以作为其他用户的代理,以及用户是否可以授予代理
其他用户的权限。的
default_roles
而且role_edges
表包含关于角色关系的信息。的
password_history
表保留以前选择的密码,以启用对密码重用的限制。看到第6.2.15节“密码管理”.
服务器在启动时将授权表的内容读入内存。您可以通过发出一个冲洗的特权
语句或执行mysqladmin flush-privileges或mysqladmin重载命令。对授权表的更改生效第6.2.13节,“当特权更改生效时”.
当您修改帐户时,最好验证您的更改是否达到了预期的效果。要检查给定帐户的权限,请使用秀奖助金
声明。例如,要确定授予用户名和主机名值为的帐户的特权鲍勃
而且pc84.example.com
,使用以下语句:
SHOW GRANTS FOR 'bob'@'pc84.example.com';
若要显示帐户的非特权属性,请使用显示创建用户
:
CREATE USER 'bob'@'pc84.example.com';
服务器使用用户
而且db
表mysql
数据库在访问控制的第一和第二阶段(参见第6.2节“访问控制和帐户管理”).的列用户
而且db
表格显示在这里。
表6.4 user和db表列
表名 | 用户 |
db |
---|---|---|
范围列 | 宿主 |
宿主 |
用户 |
Db |
|
用户 |
||
特权列 | Select_priv |
Select_priv |
Insert_priv |
Insert_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 |
||
插件 |
||
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 |
的用户
表格插件
而且authentication_string
列存储身份验证插件和凭据信息。
中命名的插件插件
用于验证帐户的连接尝试的帐户行的列。
的插件
列必须非空。在启动时,在运行时冲洗的特权
执行,服务器检查用户
表行。对于任何有空的行插件
列时,服务器向此表单的错误日志写入警告:
[警告]用户条目'user_name“@”host_name的插件值为空。该用户将被忽略,没有人可以再使用该用户登录。
要将插件分配给缺少插件的帐户,请使用改变用户
声明。
的password_expired
列允许dba使帐户密码过期,并要求用户重置密码。默认的password_expired
值是“N”
,但可以设置为“Y”
与改变用户
声明。帐户的密码过期后,该帐户在后续连接服务器时执行的所有操作都会导致错误,直到用户发出一个改变用户
语句以建立新的帐户密码。
虽然这是可能的”重置”如果将过期的密码设置为当前值,作为一种良好的策略,最好选择一个不同的密码。dba可以通过建立适当的密码重用策略来强制非重用。看到密码重用策略.
password_last_changed
是一个时间戳
列,指示密码最后一次更改的时间。取值为non-零
仅适用于使用MySQL内置认证插件(mysql_native_password
,sha256_password
,或caching_sha2_password
).这个值是零
对于其他帐户,例如使用外部身份验证系统验证的帐户。
password_last_changed
的更新创建用户
,改变用户
,设置密码
语句,格兰特
创建帐户或更改帐户密码的语句。
password_lifetime
帐户密码存活时间,单位为天。如果密码超过了其生命周期(使用password_last_changed
列),则当客户端使用该帐户连接时,服务器将认为密码过期。的值N
大于0意味着密码必须每次修改一次N
天。值为0禁用密码自动过期。如果值为零
方法定义的全局过期策略(默认值)default_password_lifetime
系统变量。
account_locked
指示帐户是否被锁定(请参见第6.2.19节“帐户锁定”).
Password_reuse_history
是价值的密码历史
帐户选项,或零
默认历史记录。
Password_reuse_time
是价值的密码重用间隔
帐户选项,或零
为默认的时间间隔。
Password_require_current
(在MySQL 8.0.13中添加)对应于密码需要
选项,如下表所示。
表6.5允许的Password_require_current值
Password_require_current价值 | 对应的密码要求选项 |
---|---|
“Y” |
密码需要电流 |
“N” |
密码要求当前可选 |
零 |
密码要求当前默认值 |
User_attributes
(在MySQL 8.0.14中添加的)是一个json格式的列,它存储没有存储在其他列中的帐户属性:
additional_password
:如果有辅助密码,则输入辅助密码。看到双重密码支持.限制
:限制清单(如有)。通过部分撤销操作添加限制。属性值是每个元素的数组数据库
而且限制
指示受限制数据库的名称和对其适用的限制的键(参见第6.2.12节,“使用部分撤销的特权限制”).Password_locking
:登录失败跟踪和临时帐户锁定的条件(如果有的话)登录失败跟踪和临时帐户锁定).的Password_locking
属性将根据FAILED_LOGIN_ATTEMPTS
而且PASSWORD_LOCK_TIME
选项的创建用户
而且改变用户
语句。属性值是一个哈希failed_login_attempts
而且password_lock_time_days
指示已为帐户指定的选项值的键。如果缺少一个键,它的值隐式为0。如果键值隐式或显式为0,则禁用相应的功能。这个属性是在MySQL 8.0.19中添加的。
如果没有应用属性,User_attributes
是零
.
示例:一个拥有二级密码和部分被撤销数据库权限的帐户additional_password
而且限制
列值中的属性:
mysql> SELECT User_attributes FROM mysql用户WHERE User = 'u'\G *************************** 1. row *************************** User_attributes: {"Restrictions": [{"Database": "mysql", "Privileges": ["SELECT"]}], "additional_password": "hashed_credentials"}
要确定出现了哪些属性,请使用JSON_KEYS ()
功能:
SELECT User, Host, JSON_KEYS(User_attributes) FROM mysql。用户属性不为空;
提取一个特定的属性,例如限制
这样做:
SELECT User, Host, User_attributes->>'$。“从mysql的限制。用户WHERE User_attributes->>'$.Restrictions' <> '';
在访问控制的第二阶段,服务器执行请求验证,以确保每个客户机对它发出的每个请求都有足够的特权。除了用户
而且db
授权表,服务器也可以咨询tables_priv
而且columns_priv
表,用于涉及表的请求。后一种表在表和列级别提供更精细的特权控制。它们的列如下表所示。
表6.6 tables_priv和column_priv表列
表名 | tables_priv |
columns_priv |
---|---|---|
范围列 | 宿主 |
宿主 |
Db |
Db |
|
用户 |
用户 |
|
Table_name |
Table_name |
|
Column_name |
||
特权列 | Table_priv |
Column_priv |
Column_priv |
||
其他列 | 时间戳 |
时间戳 |
委托人 |
的时间戳
而且委托人
列设置为当前时间戳和CURRENT_USER
值,但在其他方面不使用。
对于包含存储例程的请求的验证,服务器可以参考procs_priv
表,其列如下表所示。
的Routine_type
列是一个枚举
值为的列“函数”
或“过程”
指示行引用的例程的类型。此列允许为具有相同名称的函数和过程分别授予特权。
的时间戳
而且委托人
列是未使用的。
的proxies_priv
该表记录代理帐号信息。它有这些列:
帐户才能授予代理
特权到其他账户,就必须有行了proxies_priv
表With_grant
设置为1Proxied_host
而且Proxied_user
设置以指示可授予权限的帐户。例如,“根”@“localhost”
帐户在MySQL安装过程中创建的proxies_priv
表,它支持授予代理
特权的“@”
,即针对所有用户和所有主机。这使根
设置代理用户,以及将设置代理用户的权限委派给其他帐户。看到第6.2.18节“代理用户”.
的global_grants
表列出了当前分配给用户帐户的动态全局特权。表格有这些列:
用户
,宿主
:被授予权限帐户的用户名和主机名。我感到
:权限名。WITH_GRANT_OPTION
:该帐户是否可以授予其他帐户权限。
的default_roles
默认用户角色如表所示。它有这些列:
宿主
,用户
:使用默认角色的帐户或角色。DEFAULT_ROLE_HOST
,DEFAULT_ROLE_USER
:默认角色。
的role_edges
表列出角色子图的边。它有这些列:
FROM_HOST
,FROM_USER
:被授予角色的帐户。TO_HOST
,TO_USER
:授予该帐户的角色。WITH_ADMIN_OPTION
:该帐户是否可以通过使用将该角色授予其他帐户或从其他帐户撤销该角色与管理选项
.
的password_history
表包含有关密码更改的信息。它有这些列:
宿主
,用户
:修改密码的帐号。Password_timestamp
:密码修改的时间。密码
:新的密码哈希值。
的password_history
表为每个帐户积累了足够数量的非空密码,以使MySQL能够对帐户密码历史长度和重用间隔进行检查。当尝试修改密码时,会自动删除两个限制之外的条目。
空密码不计入密码历史记录,随时可以重用。
如果一个帐户被重命名,它的条目也被重命名以匹配。如果帐户被删除或其身份验证插件被更改,则其条目将被删除。
授权表中的范围列包含字符串。它们的默认值都是空字符串。下表显示了每列中允许的字符数。
表6.8授予表范围列长度
列名 | 最大允许的字符 |
---|---|
宿主 ,Proxied_host |
255 (MySQL 8.0.17之前是60) |
用户 ,Proxied_user |
32 |
Db |
64 |
Table_name |
64 |
Column_name |
64 |
Routine_name |
64 |
宿主
而且Proxied_host
值在存储到授予表之前被转换为小写。
出于访问检查的目的,比较用户
,Proxied_user
,authentication_string
,Db
,Table_name
值是区分大小写的。的比较宿主
,Proxied_host
,Column_name
,Routine_name
值不区分大小写。
的用户
而且db
表在声明为的单独列中列出每个特权枚举(' N ', ' Y ')默认“N”
.换句话说,每个特权都可以禁用或启用,默认的特权是禁用的。
的tables_priv
,columns_priv
,procs_priv
表将特权列声明为集
列。这些列中的值可以包含表所控制的特权的任何组合。只启用列值中列出的那些特权。
表6.9 Set-Type特权列值
表名 | 列名 | 可能设置元素 |
---|---|---|
tables_priv |
Table_priv |
'选择','插入','更新','删除','创建','删除','授予','引用','索引','修改','创建视图','显示视图','触发' |
tables_priv |
Column_priv |
“选择”,“插入”,“更新”,“引用” |
columns_priv |
Column_priv |
“选择”,“插入”,“更新”,“引用” |
procs_priv |
Proc_priv |
“执行”,“改变程序”,“授予” |
只有用户
而且global_grants
表指定了管理权限,例如重新加载
,关闭
,SYSTEM_VARIABLES_ADMIN
.管理操作是服务器本身上的操作,不是特定于数据库的,因此没有理由在其他授权表中列出这些权限。因此,服务器只需要查询用户
而且global_grants
表来确定用户是否可以执行管理操作。
的文件
权限也只在用户
表格这并不是一种管理特权,而是用户在服务器主机上读写文件的能力与所访问的数据库无关。
从MySQL 8.0.22开始,为了允许在MySQL授权表上并发DML和DDL操作,以前在MySQL授权表上获得行锁的读操作被执行为非锁定读。在MySQL授权表上执行的非锁定读取操作包括:
从授权表读取数据时不再获取行锁的语句,如果在使用基于语句的复制时执行,则会报告警告。
当使用- - - - - -binlog_format =混合
,从授权表读取数据的DML操作被作为行事件写入二进制日志,以确保操作对混合模式复制是安全的。
选择……为分享
从授权表读取数据的语句报告一个警告。与为分享
子句时,在授予表上不支持读锁。
从授权表读取数据并使用可序列化的
隔离级别报告警告。类时通常获取的锁可序列化的
授予表上不支持隔离级别。