系统mysql
数据库包括几个授权表,其中包含有关用户帐户及其拥有的权限的信息。本节介绍这些表。有关系统数据库中其他表的信息,请参阅
第 5.3 节,“mysql 系统数据库”。
此处的讨论描述了授权表的底层结构以及服务器在与客户端交互时如何使用它们的内容。但是,通常您不会直接修改授权表。当您使用帐户管理语句(例如 、 和 )来设置帐户并控制每个帐户的可用权限时,会间接CREATE
USER
发生GRANT
修改
REVOKE
。参见
第 13.7.1 节,“账户管理声明”。当您使用此类语句执行帐户操作时,服务器会代表您修改授权表。
INSERT
不鼓励使用、
UPDATE
或
等语句直接修改授权表
,DELETE
这样做的风险由您自行承担。服务器可以自由地忽略由于此类修改而变得畸形的行。
从 MySQL 5.7.18 开始,对于任何修改授权表的操作,服务器都会检查该表是否具有预期的结构,如果没有则产生错误。要将表更新为预期的结构,请执行 MySQL 升级过程。请参阅 第 2.11 节,“升级 MySQL”。
这些mysql
数据库表包含授权信息:
user
:用户帐户、全局权限和其他非权限列。db
:数据库级权限。tables_priv
:表级权限。columns_priv
: 列级权限。procs_priv
: 存储过程和函数权限。proxies_priv
: 代理用户权限。
每个授权表都包含范围列和权限列:
范围列确定表中每一行的范围;即,该行适用的上下文。例如,
user
表行的Host
值为User
并且'h1.example.net'
适用'bob'
于验证h1.example.net
指定用户名为 的客户端从主机到服务器的连接bob
。类似地,db
表行的Host
、User
和Db
列值为'h1.example.net'
,'bob'
并且'reports'
在bob
从主机连接h1.example.net
以访问reports
数据库时应用。这tables_priv
和columns_priv
表包含范围列,指示每行适用的表或表/列组合。procs_priv
范围列指示每行适用的存储例程 。特权列表示表行授予哪些特权;也就是说,它允许执行哪些操作。服务器将各种授权表中的信息组合起来,形成对用户权限的完整描述。第 6.2.6 节,“访问控制,第 2 阶段:请求验证”,描述了这方面的规则。
此外,授权表可能包含用于范围或权限评估以外目的的列。
服务器以下列方式使用授权表:
表
user
范围列确定是拒绝还是允许传入连接。对于允许的连接,表中授予的任何权限都user
表示用户的全局权限。此表中授予的任何权限适用于 服务器上的所有数据库。警告因为全局权限被认为是所有数据库的权限,所以任何全局权限都使用户能够 通过检查表
SHOW DATABASES
或通过检查INFORMATION_SCHEMA
SCHEMATA
表来查看所有数据库名称。表
db
范围列确定哪些用户可以从哪些主机访问哪些数据库。特权列确定允许的操作。在数据库级别授予的权限适用于数据库和数据库中的所有对象,例如表和存储程序。和表类似于 表
tables_priv
, 但更细粒度:它们适用于表和列级别,而不是数据库级别。在表级别授予的特权适用于表及其所有列。在列级别授予的权限仅适用于特定列。columns_priv
db
该
procs_priv
表适用于存储例程(存储过程和函数)。在例程级别授予的特权仅适用于单个过程或函数。该
proxies_priv
表指示哪些用户可以充当其他用户的代理,以及用户是否可以将PROXY
权限授予其他用户。
服务器在启动时将授权表的内容读入内存。您可以通过发出FLUSH PRIVILEGES
语句或执行mysqladmin flush-privileges或
mysqladmin reload命令告诉它重新加载表。授权表的更改生效,如
第 6.2.9 节“特权更改何时生效”中所述。
修改帐户时,最好验证您的更改是否具有预期效果。要检查给定帐户的权限,请使用该SHOW
GRANTS
语句。例如,要确定授予用户名和主机名值为bob
和
的帐户的权限pc84.example.com
,请使用以下语句:
SHOW GRANTS FOR 'bob'@'pc84.example.com';
要显示帐户的非特权属性,请使用
SHOW CREATE USER
:
SHOW CREATE USER 'bob'@'pc84.example.com';
服务器
在访问控制的第一阶段和第二阶段都使用数据库中的user
和
db
表(请参阅第 6.2 节,“访问控制和帐户管理”)。和表中的列
显示在此处。
mysql
user
db
表 6.3 user 和 db 表列
表名 | user |
db |
---|---|---|
范围列 | Host |
Host |
User |
Db |
|
User |
||
特权专栏 | 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 |
||
安全栏目 | ssl_type |
|
ssl_cipher |
||
x509_issuer |
||
x509_subject |
||
plugin |
||
authentication_string |
||
password_expired |
||
password_last_changed |
||
password_lifetime |
||
account_locked |
||
资源控制栏 | max_questions |
|
max_updates |
||
max_connections |
||
max_user_connections |
表和
user
列存储身份验证插件和凭证信息。
plugin
authentication_string
服务器使用在帐户行的列中命名的插件
plugin
来验证帐户的连接尝试。
该plugin
列必须是非空的。在启动时和运行时FLUSH
PRIVILEGES
执行时,服务器会检查
user
表行。对于任何包含空
plugin
列的行,服务器都会将警告写入此表单的错误日志:
[Warning] User entry 'user_name'@'host_name' has an empty plugin
value. The user will be ignored and no one can login with this user
anymore.
要解决此问题,请参阅第 6.4.1.3 节,“从 4.1 版之前的密码散列和 mysql_old_password 插件迁移”。
该password_expired
列允许 DBA 使帐户密码过期并要求用户重置其密码。默认password_expired
值为'N'
,但可以
'Y'
使用ALTER
USER
语句设置为。帐户密码过期后,该帐户在后续与服务器的连接中执行的所有操作都会导致错误,直到用户发出ALTER USER
建立新帐户密码的语句。
虽然可以通过将过期的密码设置为当前值来“重置”该密码,但作为一种好的策略,最好选择一个不同的密码。
password_last_changed
是一
TIMESTAMP
列,指示上次更改密码的时间。该值NULL
不仅适用于使用 MySQL 内置身份验证方法的帐户(使用
mysql_native_password
或
的身份验证插件的帐户sha256_password
)。该值适用
NULL
于其他帐户,例如使用外部身份验证系统进行身份验证的帐户。
password_last_changed
由
CREATE USER
、
ALTER USER
和
SET PASSWORD
语句以及
GRANT
创建帐户或更改帐户密码的语句更新。
password_lifetime
表示帐号密码的有效期,以天为单位。如果密码已过有效期(使用该password_last_changed
列进行评估),则当客户端使用该帐户连接时,服务器会认为密码已过期。大于零的值
N
意味着必须每天更改密码N
。值为 0 将禁用自动密码过期。如果值为NULL
(默认值),则应用全局过期策略,如
default_password_lifetime
系统变量所定义。
account_locked
指示帐户是否被锁定(请参阅第 6.2.15 节,“帐户锁定”)。
在访问控制的第二阶段,服务器执行请求验证以确保每个客户端对其发出的每个请求都有足够的权限。除了
授权表,服务器还可以查询user
涉及表的请求的表
。后面的表在表和列级别提供更精细的权限控制。它们具有下表中显示的列。
db
tables_priv
columns_priv
表 6.4 tables_priv 和 columns_priv 表列
表名 | tables_priv |
columns_priv |
---|---|---|
范围列 | Host |
Host |
Db |
Db |
|
User |
User |
|
Table_name |
Table_name |
|
Column_name |
||
特权专栏 | Table_priv |
Column_priv |
Column_priv |
||
其他专栏 | Timestamp |
Timestamp |
Grantor |
和
列分别设置为当前时间戳和
Timestamp
值,但在其他方面未使用。
Grantor
CURRENT_USER
为了验证涉及存储例程的请求,服务器可以查询procs_priv
表,该表具有下表中显示的列。
表 6.5 procs_priv 表列
表名 | procs_priv |
---|---|
范围列 | Host |
Db |
|
User |
|
Routine_name |
|
Routine_type |
|
特权专栏 | Proc_priv |
其他专栏 | Timestamp |
Grantor |
该Routine_type
列是一
ENUM
列,其值为
'FUNCTION'
或'PROCEDURE'
以指示该行引用的例程类型。此列允许为具有相同名称的函数和过程分别授予权限。
和Timestamp
列Grantor
未使用。
该proxies_priv
表记录了有关代理帐户的信息。它有这些列:
对于能够将
PROXY
权限授予其他帐户的帐户,它必须在
proxies_priv
表中
有一行With_grant
设置为 1,
Proxied_host
并且
Proxied_user
设置为指示可以授予权限的一个或多个帐户。例如,'root'@'localhost'
在安装 MySQL 时创建的帐户在
proxies_priv
表中有一行可以授予
PROXY
权限
''@''
,即所有用户和所有主机。这可以root
设置代理用户,以及将设置代理用户的权限委托给其他帐户。请参阅第 6.2.14 节,“代理用户”。
授权表中的范围列包含字符串。每个的默认值为空字符串。下表显示了每列中允许的字符数。
表 6.6 授权表范围列长度
列名 | 最大允许字符数 |
---|---|
Host ,Proxied_host |
60 |
User ,Proxied_user |
32 |
Password |
41 |
Db |
64 |
Table_name |
64 |
Column_name |
64 |
Routine_name |
64 |
Host
和Proxied_host
值在存储在授权表之前被转换为小写。
出于访问检查目的,
User
、Proxied_user
、
Password
、
authentication_string
、Db
和Table_name
值的比较区分大小写。Host
、
Proxied_host
、Column_name
和值的比较Routine_name
不区分大小写。
user
和表
在db
声明为 的单独列中列出每个权限
ENUM('N','Y') DEFAULT 'N'
。换句话说,每个权限都可以禁用或启用,默认情况下是禁用的。
、tables_priv
和
表将特权列声明为columns_priv
列
。这些列中的值可以包含表控制的权限的任意组合。仅启用列值中列出的那些权限。
procs_priv
SET
表 6.7 集合类型权限列值
表名 | 列名 | 可能的集合元素 |
---|---|---|
tables_priv |
Table_priv |
'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop',
'Grant', 'References', 'Index', 'Alter', 'Create View',
'Show view', 'Trigger' |
tables_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
columns_priv |
Column_priv |
'Select', 'Insert', 'Update', 'References' |
procs_priv |
Proc_priv |
'Execute', 'Alter Routine', 'Grant' |
只有该user
表指定了管理权限,例如RELOAD
和
SHUTDOWN
。管理操作是对服务器本身的操作,而不是特定于数据库的,因此没有理由在其他授权表中列出这些权限。因此,服务器只需查询该user
表即可确定用户是否可以执行管理操作。
该FILE
权限也仅在user
表中指定。它本身不是管理特权,但用户在服务器主机上读取或写入文件的能力与所访问的数据库无关。