When you attempt to connect to a MySQL server, the server accepts or rejects the connection based on these conditions:当您尝试连接到MySQL服务器时,服务器会根据以下条件接受或拒绝连接:
Your identity and whether you can verify it by supplying the proper credentials.您的身份以及您是否可以通过提供适当的凭据进行验证。
Whether your account is locked or unlocked.您的帐户是锁定还是解锁。
The server checks credentials first, then account locking state. 服务器首先检查凭据,然后检查帐户锁定状态。A failure at either step causes the server to deny access to you completely. 任何一步的失败都会导致服务器完全拒绝您的访问。Otherwise, the server accepts the connection, and then enters Stage 2 and waits for requests.否则,服务器接受连接,然后进入阶段2并等待请求。
The server performs identity and credentials checking using columns in the 服务器使用user
table, accepting the connection only if these conditions are satisfied:user
表中的列执行身份和凭据检查,仅在满足以下条件时接受连接:
The client host name and user name match the 客户端主机名和用户名与某些Host
and User
columns in some user
table row. For the rules governing permissible Host
and User
values, see Section 6.2.4, “Specifying Account Names”.user
表行中的Host
和User
列匹配。有关管理允许的主机和用户值的规则,请参阅第6.2.4节,“指定帐户名”。
The client supplies the credentials specified in the row (for example, a password), as indicated by the 客户端提供行中指定的凭据(例如密码),如authentication_string
column. authentication_string
列所示。Credentials are interpreted using the authentication plugin named in the 凭据使用plugin
column.plugin
列中指定的身份验证插件进行解释。
The row indicates that the account is unlocked. 该行表示帐户已解锁。Locking state is recorded in the 锁定状态记录在account_locked
column, which must have a value of 'N'
. account_locked
列中,该列的值必须为'N'
。Account locking can be set or changed with the 可以使用CREATE USER
or ALTER USER
statement.CREATE USER
或ALTER USER
语句设置或更改帐户锁定。
Your identity is based on two pieces of information:您的身份基于两条信息:
Your MySQL user name.您的MySQL用户名。
The client host from which you connect.您连接的客户端主机。
If the 如果User
column value is nonblank, the user name in an incoming connection must match exactly. User
列值为非空,则传入连接中的用户名必须完全匹配。If the 如果User
value is blank, it matches any user name. User
值为空,则它与任何用户名匹配。If the 如果与传入连接匹配的user
table row that matches an incoming connection has a blank user name, the user is considered to be an anonymous user with no name, not a user with the name that the client actually specified. user
表行的用户名为空,则该用户将被视为没有名称的匿名用户,而不是具有客户端实际指定名称的用户。This means that a blank user name is used for all further access checking for the duration of the connection (that is, during Stage 2).这意味着在连接期间(即第2阶段),将使用空白用户名进行所有进一步的访问检查。
The authentication_string
column can be blank. This is not a wildcard and does not mean that any password matches. authentication_string
列可以为空。这不是通配符,并不意味着任何密码都匹配。It means that the user must connect without specifying a password. 这意味着用户必须在不指定密码的情况下连接。The authentication method implemented by the plugin that authenticates the client may or may not use the password in the 对客户端进行身份验证的插件实现的身份验证方法可能会也可能不会使用authentication_string
column. authentication_string
列中的密码。In this case, it is possible that an external password is also used to authenticate to the MySQL server.在这种情况下,也可能使用外部密码对MySQL服务器进行身份验证。
Nonblank password values stored in the 存储在authentication_string
column of the user
table are encrypted. user
表authentication_string
列中的非空密码值被加密。MySQL does not store passwords as cleartext for anyone to see. Rather, the password supplied by a user who is attempting to connect is encrypted (using the password hashing method implemented by the account authentication plugin). MySQL不会将密码存储为明文供任何人查看。相反,尝试连接的用户提供的密码是加密的(使用帐户身份验证插件实现的密码哈希方法)。The encrypted password then is used during the connection process when checking whether the password is correct. This is done without the encrypted password ever traveling over the connection. See Section 6.2.1, “Account User Names and Passwords”.然后在连接过程中检查密码是否正确时使用加密密码。这是在没有加密密码通过连接的情况下完成的。请参阅第6.2.1节,“帐户用户名和密码”。
From MySQL's point of view, the encrypted password is the real password, so you should never give anyone access to it. 从MySQL的角度来看,加密的密码是真实的密码,所以你永远不应该让任何人访问它。In particular, do not give nonadministrative users read access to tables in the 特别是,不要让非管理员用户读取mysql
system database.mysql
系统数据库中的表。
The following table shows how various combinations of 下表显示了User
and Host
values in the user
table apply to incoming connections.user
表中User
和Host
值的各种组合如何应用于传入连接。
User Value | Host Value | |
---|---|---|
'fred' | 'h1.example.net' | fred , connecting from
h1.example.net fred ,从'h1.example.net' 连接 |
'' | 'h1.example.net' | h1.example.net h1.example.net 连接的任何用户 |
'fred' | '%' | fred , connecting from any hostfred |
'' | '%' | |
'fred' | '%.example.net' | fred , connecting from any host in the
example.net domainfred ,从示例网域中的任何主机连接 |
'fred' | 'x.example.%' | fred , connecting from x.example.net , x.example.com , x.example.edu , and so on; this is probably not usefulfred ,从x.example.net 、x.example.com 、x.example.edu 等连接;这可能没什么用 |
'fred' | '198.51.100.177' | fred , connecting from the host with IP address 198.51.100.177 fred ,从IP地址为198.51.100.177 的主机连接 |
'fred' | '198.51.100.%' | fred , connecting from any host in the
198.51.100 class C subnetfred ,从198.51.100 C类子网中的任何主机连接 |
'fred' | '198.51.100.0/255.255.255.0' |
It is possible for the client host name and user name of an incoming connection to match more than one row in the 传入连接的客户端主机名和用户名可能与user
table. user
表中的多行匹配。The preceding set of examples demonstrates this: Several of the entries shown match a connection from 前面的一组示例演示了这一点:显示的几个条目与h1.example.net
by fred
.fred
的h1.example.net
连接相匹配。
When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows:当可能有多个匹配时,服务器必须确定使用其中的哪一个。它解决这个问题如下:
Whenever the server reads the 每当服务器将user
table into memory, it sorts the rows.user
表读入内存时,它都会对行进行排序。
When a client attempts to connect, the server looks through the rows in sorted order.当客户端尝试连接时,服务器会按排序顺序查看行。
The server uses the first row that matches the client host name and user name.服务器使用与客户端主机名和用户名匹配的第一行。
The server uses sorting rules that order rows with the most-specific 服务器使用排序规则,首先对具有最特定Host
values first:Host
值的行进行排序:
Literal IP addresses and host names are the most specific.字面IP地址和主机名是最具体的。
Prior to MySQL 8.0.23, the specificity of a literal IP address is not affected by whether it has a netmask, so 在MySQL 8.0.23之前,文字IP地址的特殊性不受其是否具有网络掩码的影响,因此198.51.100.13
and 198.51.100.0/255.255.255.0
are considered equally specific. As of MySQL 8.0.23, accounts with an IP address in the host part have this order of specificity:198.51.100.13
和198.51.100.0/255.255.255.0
被认为具有同等的特殊性。从MySQL 8.0.23开始,在主机部分具有IP地址的帐户具有以下特定顺序:
Accounts that have the host part given as an IP address:将主机部分指定为IP地址的帐户:
CREATE USER 'user_name
'@'127.0.0.1'; CREATE USER 'user_name
'@'198.51.100.44';
Accounts that have the host part given as an IP address using CIDR notation:使用CIDR表示法将主机部分指定为IP地址的帐户:
CREATE USER 'user_name
'@'192.0.2.21/8'; CREATE USER 'user_name
'@'198.51.100.44/16';
Accounts that have the host part given as an IP address with a subnet mask:将主机部分指定为具有子网掩码的IP地址的帐户:
CREATE USER 'user_name
'@'192.0.2.0/255.255.255.0'; CREATE USER 'user_name
'@'198.51.0.0/255.255.0.0';
The pattern 模式'%'
means “any host” and is least specific.'%'
表示“任何主机”,并且最不具体。
The empty string 空字符串''
also means “any host” but sorts after '%'
.''
也表示“任何主机”,但在'%'
之后排序。
Non-TCP (socket file, named pipe, and shared memory) connections are treated as local connections and match a host part of 非TCP(套接字文件、命名管道和共享内存)连接被视为本地连接,如果有任何此类帐户,则与localhost
if there are any such accounts, or host parts with wildcards that match localhost
otherwise (for example, local%
, l%
, %
).localhost
的主机部分匹配,否则与localhost
匹配的带有通配符的主机部分(例如,local%
、l%
、%
)。
Rows with the same 具有相同Host值的行首先按最具体的Host
value are ordered with the most-specific User
values first. User
值排序。A blank 空白User
value means “any user” and is least specific, so for rows with the same Host
value, nonanonymous users sort before anonymous users.User
值表示“任何用户”,并且最不具体,因此对于具有相同Host
值的行,非匿名用户会在匿名用户之前排序。
For rows with equally-specific 对于具有相同特定Host
and User
values, the order is nondeterministic.Host
和User
值的行,顺序是不确定的。
To see how this works, suppose that the 要了解其工作原理,假设user
table looks like this:user
表如下:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
When the server reads the table into memory, it sorts the rows using the rules just described. The result after sorting looks like this:当服务器将表读入内存时,它会使用刚才描述的规则对行进行排序。排序后的结果如下:
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
When a client attempts to connect, the server looks through the sorted rows and uses the first match found. 当客户端尝试连接时,服务器会查看排序后的行,并使用找到的第一个匹配项。For a connection from 对于localhost
by jeffrey
, two of the rows from the table match: the one with Host
and User
values of 'localhost'
and ''
, and the one with values of '%'
and 'jeffrey'
. jeffrey
从localhost
进行的连接,表中的两行匹配:一行的Host
和User
值为'localhost'
和''
,另一行的值为'%'
和'jeffrey'
。The 'localhost'
row appears first in sorted order, so that is the one the server uses.'localhost'
行按排序顺序首先出现,因此这是服务器使用的行。
Here is another example. Suppose that the 这是另一个例子。假设user
table looks like this:user
表如下:
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | h1.example.net | | ... +----------------+----------+-
The sorted table looks like this:排序后的表如下所示:
+----------------+----------+- | Host | User | ... +----------------+----------+- | h1.example.net | | ... | % | jeffrey | ... +----------------+----------+-
The first row matches a connection by any user from 第一行匹配h1.example.net
, whereas the second row matches a connection by jeffrey
from any host.h1.example.net
中任何用户的连接,而第二行匹配jeffrey
从任何主机的连接。
It is a common misconception to think that, for a given user name, all rows that explicitly name that user are used first when the server attempts to find a match for the connection. This is not true. 一种常见的误解是,对于给定的用户名,当服务器试图找到连接的匹配项时,会首先使用所有明确命名该用户的行。这不是真的。The preceding example illustrates this, where a connection from 前面的示例说明了这一点,其中jh1.example.net
by jeffrey
is first matched not by the row containing 'jeffrey'
as the User
column value, but by the row with no user name. effrey
从h1.example.net
创建的连接首先不是由包含'jeffrey'
作为User
列值的行匹配,而是由没有用户名的行匹配。As a result, 因此,即使jeffrey
is authenticated as an anonymous user, even though he specified a user name when connecting.jeffrey
在连接时指定了用户名,他也被认证为匿名用户。
If you are able to connect to the server, but your privileges are not what you expect, you probably are being authenticated as some other account. 如果您能够连接到服务器,但您的权限不是您所期望的,则您可能正在作为其他帐户进行身份验证。To find out what account the server used to authenticate you, use the 要找出服务器用于对您进行身份验证的帐户,请使用CURRENT_USER()
function. CURRENT_USER()
函数。(See Section 12.16, “Information Functions”.) (参阅第12.16节,“信息函数”。)It returns a value in 它返回一个值
format that indicates the user_name
@host_name
User
and Host
values from the matching user
table row. user_name@host_name
表示匹配user
表行中的用户和主机值的格式。Suppose that 假设jeffrey
connects and issues the following query:jeffrey
连接并发出以下查询:
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
The result shown here indicates that the matching 此处显示的结果表明,匹配的user
table row had a blank User
column value. In other words, the server is treating jeffrey
as an anonymous user.user
表行的User
列值为空。换句话说,服务器将jeffrey
视为匿名用户。
Another way to diagnose authentication problems is to print out the 诊断身份验证问题的另一种方法是打印出user
table and sort it by hand to see where the first match is being made.user
表并手动排序,以查看第一个匹配的位置。