Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


8.2.15 密码管理

MySQL 支持以下密码管理功能:

  • 密码过期,要求定期更换密码。

  • 密码重用限制,不允许选择旧密码。

  • 密码验证,要求在更改密码时指定当前密码以替换。

  • 双重密码,允许客户端使用主或副密码进行连接。

  • 密码强度评估,要求使用强密码。

  • 随机密码生成,作为不需要显式管理员指定文本密码的替代方案。

  • 密码失败跟踪,允许在连续多次错误密码登录尝试后暂时锁定账户。

以下部分描述了这些功能,除了密码强度评估,它使用 validate_password 组件进行实现,并在 第 8.4.3 节“密码验证组件” 中进行描述。

Important

MySQL 使用 mysql 系统数据库中的表来实现密码管理功能。如果您从早期版本升级 MySQL,系统表可能不符合最新标准。在这种情况下,服务器在启动过程中写入类似以下信息到错误日志(具体数字可能会有所不同):

[ERROR] Column count of mysql.user is wrong. Expected
49, found 47. The table is probably corrupted
[Warning] ACL table mysql.password_history missing.
Some operations may fail.

为了解决问题,请执行 MySQL 升级程序。参见 第 3 章,升级 MySQL。直到完成此操作,密码更改是不可能的。

一些认证插件将帐户凭据存储在 MySQL 内部,使用 mysql.user 系统表:

  • caching_sha2_password

  • mysql_native_password(已弃用)

  • sha256_password(已弃用)

本节中讨论的大多数密码管理功能都适用于这些认证插件,因为大多数基于 MySQL 自身处理的内部凭据存储的密码管理能力。其他认证插件将帐户凭据存储在外部 MySQL 之外的系统上。在这种情况下,对于使用外部凭据存储的账户,必须对该系统进行外部凭据管理。

失败登录跟踪和临时账户锁定选项适用于所有账户,不仅限于使用内部凭据存储的账户,因为 MySQL 无论账户是否使用内部或外部凭据存储,都能评估任何账户的登录尝试状态。

有关单个认证插件的信息,请参见 第 8.4.1 节“认证插件”。

MySQL 允许数据库管理员手动过期帐户密码,并为自动密码过期策略建立政策。过期策略可以是全局的,单个账户也可以设置为遵循全局策略或覆盖全局策略以特定于每个账户的行为。

要手动过期一个帐户密码,请使用 ALTER USER 语句:

ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;

此操作在 mysql.user 系统表中对应的行中标记密码已过期。

根据策略自动过期的密码是基于账户最近一次密码更改的日期和时间进行评估的。mysql.user 系统表为每个账户记录了其最后一次密码更改的日期和时间,服务器在客户端连接时自动将密码视为过期,如果其年龄超过其允许的生命周期。这与不需要显式手动密码过期操作一起工作。

为了在所有服务器上自动设置密码过期政策,请使用default_password_lifetime系统变量。它的默认值为0,这意味着不启用自动密码过期。如果default_password_lifetime的值是一个正整数N,它表示允许的密码有效期,因此必须每隔N天更换密码。

示例:

  • 要设置一个全局政策,使密码有效期大约为六个月,启动服务器时,请在服务器配置文件my.cnf中添加以下行:

    [mysqld]
    default_password_lifetime=180
  • 要设置一个全局政策,使密码永不过期,请将default_password_lifetime设置为0:

    [mysqld]
    default_password_lifetime=0
  • default_password_lifetime也可以在运行时设置并持久化:

    SET PERSIST default_password_lifetime = 180;
    SET PERSIST default_password_lifetime = 0;

    SET PERSIST用于为正在运行的MySQL实例设置值。此外,它将保存该值,以便于服务器重启后继续使用;请参阅Section 15.7.6.1, “SET 语法用于变量分配”。要更改运行中的MySQL实例的值,但不让其在重启后继续使用,请使用GLOBAL关键字而不是PERSIST。

全局密码过期政策适用于所有没有被设置为覆盖它的账户。要为单个账户设置策略,请使用CREATE USER和ALTER USER语句中的PASSWORD EXPIRE选项。请参阅Section 15.7.1.3, “CREATE USER 语句”和Section 15.7.1.1, “ALTER USER 语句”。

示例账户特定的语句:

  • 每隔90天更换密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

    这条过期选项会覆盖全局策略,对所有名为该语句的账户生效。

  • 禁用密码过期:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;

    这条过期选项会覆盖全局策略,对所有名为该语句的账户生效。

  • 遵循全局过期策略对所有名为该语句的账户:

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE DEFAULT;

当客户端成功连接时,服务器将确定账户密码是否已过期:

  • 服务器检查密码是否被手动设置为过期。

  • 否则,服务器检查密码年龄是否超过了根据自动密码过期策略允许的有效期。如果是,则服务器认为密码已过期。

如果密码已过期(无论是手动还是自动),服务器将断开客户端连接或限制其操作权限(请参阅Section 8.2.16, “服务器处理过期密码”)。客户端执行受限制操作时将收到错误,直到用户为账户设置新密码为止:

mysql> SELECT 1;
ERROR 1820 (HY000): You must reset your password using ALTER USER
statement before executing this statement.

mysql> ALTER USER USER() IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

客户端重置密码后,服务器会恢复正常访问权限,并且对于该账户的所有后续连接也会恢复。管理员用户可以重置账户密码,但任何现有的受限制会话将继续受到限制。使用该账户的客户端必须断开并重新连接,以便能够成功执行语句。

Note

尽管可能通过设置为当前值来“‘reset’”一个过期密码,但作为一种好政策,应该选择不同的密码。数据库管理员可以通过建立适当的密码重用策略来强制这一点。请参阅Password Reuse Policy。

MySQL 允许对之前密码的重用进行限制。重用限制可以基于密码更改次数、时间间隔或两者都来建立。重用策略可以在全局层面上建立,并且单个账户可以被设置为遵循全局策略或覆盖全局策略并具有特定于账户的行为。

一个账户的密码历史包括它过去分配过的密码。MySQL 可以限制新密码不能来自这个历史:

  • 如果账户受到基于密码更改次数的限制,新的密码不能是指定数量最近的密码中的任何一个。例如,如果最小密码更改次数设置为3,新的密码不能是最近3个密码中的任何一个。

  • 如果账户被基于时间的限制,新密码不能来自于在指定天数内之前选择过的密码。例如,如果密码重用间隔设置为60天,那么新密码必须是在过去60天之外曾经选择过的。

Note

空密码不计入密码历史,并且可以随时被重用。

为了在服务器级别上建立密码重用策略,可以使用password_history和password_reuse_interval系统变量。

示例:

  • 要禁止重用最近6个密码或在365天内选择过的密码,可以将以下行添加到服务器配置文件my.cnf中:

    [mysqld]
    password_history=6
    password_reuse_interval=365
  • 为了在运行时设置并持久化变量,可以使用类似这样的语句:

    SET PERSIST password_history = 6;
    SET PERSIST password_reuse_interval = 365;

    SET PERSIST为运行的MySQL实例设置一个值。它还将保存这个值,以便在服务器重启后继续使用;请参阅第15.7.6.1节,“SET Syntax for Variable Assignment”。要为运行的MySQL实例更改值而不让其持久化到重启后,可以使用GLOBAL关键字而不是PERSIST。

全局密码重用策略适用于所有没有被设置为覆盖它的账户。为了在单个账户上建立策略,可以使用CREATE USER和ALTER USER语句中的PASSWORD HISTORY和PASSWORD REUSE INTERVAL选项。请参阅第15.7.1.3节,“CREATE USER Statement”和第15.7.1.1节,“ALTER USER Statement”。

示例账户特定的语句:

  • 要求在允许重用之前至少更改5次密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;
    ALTER USER 'jeffrey'@'localhost' PASSWORD HISTORY 5;

    这个历史长度选项会覆盖全局策略,对所有名为该语句的账户生效。

  • 要求在允许重用之前至少经过365天:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REUSE INTERVAL 365 DAY;

    这个时间间隔选项会覆盖全局策略,对所有名为该语句的账户生效。

  • 为了结合两种类型的重用限制,可以同时使用PASSWORD HISTORY和PASSWORD REUSE INTERVAL:

    CREATE USER 'jeffrey'@'localhost'
      PASSWORD HISTORY 5
      PASSWORD REUSE INTERVAL 365 DAY;
    ALTER USER 'jeffrey'@'localhost'
      PASSWORD HISTORY 5
      PASSWORD REUSE INTERVAL 365 DAY;

    这些选项会覆盖全局策略中的所有账户名为该语句的重用限制。

  • 遵循全局策略的重用限制:

    CREATE USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;
    ALTER USER 'jeffrey'@'localhost'
      PASSWORD HISTORY DEFAULT
      PASSWORD REUSE INTERVAL DEFAULT;

可以要求更改账户密码时验证尝试,通过指定要替换的当前密码。这使得DBA能够防止用户在没有证明他们知道当前密码的情况下更改密码。这样的更改可能发生在一个用户暂时离开终端会话而未登录的情况下,一名恶意用户使用该会话更改原始用户的MySQL密码。这样做的后果不幸的是:

  • 原始用户无法再访问MySQL,直到管理员重置账户密码。

  • 在密码被重置之前,恶意用户可以使用原用户更改后的凭据访问MySQL。

密码验证策略可以在全局层面上建立,并且单个账户可以设置为遵循全局策略或覆盖全局策略的特定行为。

对于每个账户,其mysql.user行指示是否有账户特定的设置要求在更改密码尝试时验证当前密码。该设置由CREATE USER和ALTER USER语句中的PASSWORD REQUIRE选项建立:

  • 如果账户设置为PASSWORD REQUIRE CURRENT

  • 如果账户设置为PASSWORD REQUIRE CURRENT OPTIONAL

  • 如果账户设置为PASSWORD REQUIRE CURRENT DEFAULTpassword_require_current系统变量决定了验证所需的策略:

    • 如果password_require_current启用,密码更改必须指定当前密码。

    • 如果password_require_current被禁用,密码更改可能但不必指定当前密码。

换句话说,如果帐户设置不是PASSWORD REQUIRE CURRENT DEFAULT,则帐户设置优先于由password_require_current系统变量确定的全局策略。否则,帐户将遵循password_require_current设置。

默认情况下,密码验证是可选的:password_require_current被禁用,而创建无PASSWORD REQUIRE选项的帐户默认为PASSWORD REQUIRE CURRENT DEFAULT。

以下表格显示了如何将每个帐户设置与password_require_current系统变量的值相结合,以确定帐户密码更改所需的策略。

表8.10 密码验证策略

Per-Account Setting password_require_current System Variable Password Changes Require Current Password?
PASSWORD REQUIRE CURRENT OFF 是
PASSWORD REQUIRE CURRENT ON 是
PASSWORD REQUIRE CURRENT OPTIONAL OFF 否
PASSWORD REQUIRE CURRENT OPTIONAL ON 否
PASSWORD REQUIRE CURRENT DEFAULT OFF 否
PASSWORD REQUIRE CURRENT DEFAULT ON 是

Note

有特权的用户可以更改任何帐户密码而无需指定当前密码,无论验证所需策略是什么。一个有特权的用户是指具有全局CREATE USER特权或对mysql系统数据库具有UPDATE特权的用户。

要全局设置密码验证策略,请使用password_require_current系统变量。其默认值为OFF,因此它不要求帐户密码更改指定当前密码。

示例:

  • 要全局设置一个策略,该策略要求密码更改指定当前密码,请在服务器启动时将以下行添加到my.cnf文件中:

    [mysqld]
    password_require_current=ON
  • 要在运行时设置并持久化password_require_current,请使用类似于以下的语句之一:

    SET PERSIST password_require_current = ON;
    SET PERSIST password_require_current = OFF;

    SET PERSIST将值设置为运行中的MySQL实例。它还将保存该值,以便在服务器重启后继续使用;请参阅第15.7.6.1节,“SET Syntax for Variable Assignment”。要将值设置为运行中的MySQL实例而不让其在重启后继续使用,请使用GLOBAL关键字而不是PERSIST。

全局密码验证所需策略适用于所有没有被设置为覆盖它的帐户。要为单个帐户建立策略,请使用CREATE USER和ALTER USER语句的PASSWORD REQUIRE选项。请参阅第15.7.1.3节,“CREATE USER Statement”和第15.7.1.1节,“ALTER USER Statement”。

示例帐户特定语句:

  • 要求密码更改指定当前密码:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;

    此验证选项会覆盖全局策略,对于所有名为该语句的帐户。

  • 不要求密码更改指定当前密码(当前密码可能但不必给出):

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;

    此验证选项会覆盖全局策略,对于所有名为该语句的帐户。

  • 遵循全局密码验证所需策略对所有名为该语句的帐户:

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;
    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT DEFAULT;

验证当前密码在用户使用ALTER USER或SET PASSWORD语句更改密码时会发生。这里的例子使用了ALTER USER,它比SET PASSWORD更受推荐,但这里描述的原则适用于两种语句。

在密码更改语句中,REPLACE子句指定要替换的当前密码。示例:

  • 更改当前用户的密码:

    ALTER USER USER() IDENTIFIED BY 'auth_string' REPLACE 'current_auth_string';
  • 更改一个命名用户的密码:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED BY 'auth_string'
      REPLACE 'current_auth_string';
  • 更改一个命名用户的认证插件和密码:

    ALTER USER 'jeffrey'@'localhost'
      IDENTIFIED WITH caching_sha2_password BY 'auth_string'
      REPLACE 'current_auth_string';

REPLACE子句的工作方式是:

  • REPLACE必须提供,如果账户的密码更改需要指定当前密码,以验证尝试进行更改的用户实际知道当前密码。

  • REPLACE是可选的,如果账户的密码更改可能但不一定要指定当前密码。

  • 如果提供了REPLACE,它必须指定正确的当前密码,否则会发生错误。这对于即使REPLACE是可选的也是如此。

  • REPLACE只能在更改当前用户账户密码时指定。(这意味着上面显示的例子中明确命名账户为jeffrey的语句,除非当前用户是jeffrey,否则会失败。这对于尝试对另一个用户进行更改而由具有特权的用户执行也是如此;然而,这样的用户可以在不指定REPLACE的情况下更改任何密码。

  • REPLACE不会出现在二进制日志中,以避免将明文密码写入其中。

用户账户允许有两个密码,称为主密码和次要密码。双重密码能力使得在以下场景中进行凭据更改成为可能:

  • 系统拥有大量的MySQL服务器,可能涉及到复制。

  • 多个应用程序连接到不同的MySQL服务器。

  • 必须定期对用于连接到服务器的账户或账户进行密码更改。

考虑在前述类型的场景中,当一个账户仅允许单一密码时,如何进行凭据更改。在这种情况下,必须有紧密的协作来确定何时对所有服务器和应用程序更新新密码,以及何时更新所有使用该账户的应用程序以使用新的密码。这可能涉及到在服务器或应用程序不可用的时间段内进行停机。

使用双重密码,凭据更改可以更加容易地分阶段进行,无需紧密协作,也无需停机:

  1. 对于每个受影响的账户,在服务器上建立一个新的主密码,将当前密码保留为次要密码。这使得服务器能够识别出使用主密码或次要密码连接到任何账户,同时应用程序可以继续使用相同的密码(现在是次要密码)连接到服务器。

  2. 在新密码更改已传播到所有服务器之后,修改使用受影响账户的任何应用程序,以便它们使用该账户的主密码连接。

  3. 在所有应用程序都迁移到次要密码到主密码之后,次要密码就不再需要了。等到这次更改传播到所有服务器之后,只有每个账户的主密码才能用来连接。更改现在已经完成。

MySQL 使用双重密码能力的语法保存和丢弃次要密码:

  • 在ALTER USER和SET PASSWORD语句中使用RETAIN CURRENT PASSWORD子句,保存一个账户当前密码作为其次要密码,当分配新主密码时。

  • 在ALTER USER语句中使用DISCARD OLD PASSWORD子句,丢弃账户的次要密码,只留下主密码。

假设对于前述描述的凭据更改场景,一个名为'appuser1'@'host1.example.com'的账户被应用程序用于连接到服务器,并且该账户的密码要从'password_a'更改为'password_b'。

为了执行此更改,使用ALTER USER语句如下:

  1. 在所有不是副本服务器的每台服务器上,为 'appuser1' 用户设置新的主密码 password_b,并保留当前密码作为次要密码:

    ALTER USER 'appuser1'@'host1.example.com'
      IDENTIFIED BY 'password_b'
      RETAIN CURRENT PASSWORD;
  2. 等待密码更改在系统中完全同步到所有副本服务器。

  3. 修改每个使用 'appuser1' 账户的应用程序,使其连接到服务器时使用密码 password_b 而不是 password_a。

  4. 在此点,次要密码不再需要。在所有不是副本服务器的每台服务器上,丢弃次要密码:

    ALTER USER 'appuser1'@'host1.example.com'
      DISCARD OLD PASSWORD;
  5. 等待密码丢弃更改同步到所有副本服务器后,凭据更改就完成了。

RETAIN CURRENT PASSWORD 和 DISCARD OLD PASSWORD 子句的效果如下:

修改次要密码的语句需要这些特权:

CREATE USER、ALTER USER 和 SET PASSWORD 语句都有能力为用户账户生成随机密码,作为替代于要求明确管理员指定的字面密码。每个语句的描述中都有详细说明该语句的语法。此部分描述了所有生成的随机密码共有的特性。

默认情况下,生成的随机密码长度为20个字符。这一长度由

对于每个账户,生成随机密码的语句都会将密码存储在 mysql.user 系统表中,适当地对其进行加密,以便与账户认证插件配合使用。该语句还会返回一个结果集的行,使得密码可供执行该语句的用户或应用程序访问。结果集的列名分别为 user、host、生成的密码 和 auth_factor,它们分别表示在 mysql.user 系统表中识别受影响行的用户名和主机名值,以及清文生成的密码以及该密码显示值适用的认证因素。

mysql> CREATE USER
       'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
       'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD,
       'u3'@'%.org' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+-------------+
| user | host          | generated password   | auth_factor |
+------+---------------+----------------------+-------------+
| u1   | localhost     | iOeqf>Mh9:;XD&qn(Hl} |           1 |
| u2   | %.example.com | sXTSAEvw3St-R+_-C3Vb |           1 |
| u3   | %.org         | nEVe%Ctw/U/*Md)Exc7& |           1 |
+------+---------------+----------------------+-------------+
mysql> ALTER USER
       'u1'@'localhost' IDENTIFIED BY RANDOM PASSWORD,
       'u2'@'%.example.com' IDENTIFIED BY RANDOM PASSWORD;
+------+---------------+----------------------+-------------+
| user | host          | generated password   | auth_factor |
+------+---------------+----------------------+-------------+
| u1   | localhost     | Seiei:&cw}8]@3OA64vh |           1 |
| u2   | %.example.com | j@&diTX80l8}(NiHXSae |           1 |
+------+---------------+----------------------+-------------+
mysql> SET PASSWORD FOR 'u3'@'%.org' TO RANDOM;
+------+-------+----------------------+-------------+
| user | host  | generated password   | auth_factor |
+------+-------+----------------------+-------------+
| u3   | %.org | n&cz2xF;P3!U)+]Vw52H |           1 |
+------+-------+----------------------+-------------+

CREATE USER、ALTER USER 或 SET PASSWORD 语句,如果为账户生成了随机密码,将以 CREATE USER 或 ALTER USER 语句的形式写入二进制日志,其中包含一个 IDENTIFIED WITH auth_plugin AS 'auth_string' 子句,其中 auth_plugin 是账户的认证插件,'auth_string' 是账户的加密密码值。

如果安装了 validate_password 组件,那么它实现的策略对生成的密码没有影响。(密码验证的目的是帮助人类创建更好的密码。)

失败登录跟踪和临时账户锁定

管理员可以配置用户账户,以便在连续的登录尝试失败达到一定次数后,暂时锁定账户。

“登录失败” 在这里指的是客户端未能提供正确密码而导致的连接尝试失败,不包括因未知用户或网络问题等原因导致的连接失败。对于具有双重密码(见双重密码支持)的账户,任何一个密码都算作正确的。

可配置的登录失败次数和锁定时间是通过 CREATE USER 和 ALTER USER 语句中的 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 选项来设置的。示例:

CREATE USER 'u1'@'localhost' IDENTIFIED BY 'password'
  FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 3;

ALTER USER 'u2'@'localhost'
  FAILED_LOGIN_ATTEMPTS 4 PASSWORD_LOCK_TIME UNBOUNDED;

当连续的登录尝试失败达到一定次数时,客户端会收到类似这样的错误信息:

ERROR 3957 (HY000): Access denied for user user.
Account is blocked for D day(s) (R day(s) remaining)
due to N consecutive failed logins.

使用以下选项:

  • FAILED_LOGIN_ATTEMPTS N

    这个选项指示是否跟踪那些指定了错误密码的登录尝试。数字 N 指定连续的错误密码次数达到多少次后,账户将被暂时锁定。

  • PASSWORD_LOCK_TIME {N | UNBOUNDED}

    这个选项指示在连续的登录尝试失败提供错误密码后,账户被锁定的时间长度。值可以是一个数字 N 来指定账户被锁定天数的数量,或是 UNBOUNDED 来表示当账户进入暂时锁定状态时,锁定的持续时间没有上限,直到账户被解锁。解锁条件将在后面描述。

每个选项的 N 允许值范围从0到32767。值为0则禁用该选项。

失败登录跟踪和临时账户锁定的特点如下:

  • 为了使失败登录跟踪和临时锁定对一个账户生效,其 FAILED_LOGIN_ATTEMPTS 和 PASSWORD_LOCK_TIME 选项都必须非零。

  • 对于 CREATE USER,如果未指定 FAILED_LOGIN_ATTEMPTS 或 PASSWORD_LOCK_TIME,那么隐式的默认值为0,对所有名为该语句的账户均无效。这意味着失败登录跟踪和临时锁定被禁用。

  • 对于 ALTER USER,如果未指定 FAILED_LOGIN_ATTEMPTS 或 PASSWORD_LOCK_TIME,那么该值保持不变,对所有名为该语句的账户均无效。

  • 为了实现临时账户锁定,必须连续发生密码错误。任何成功登录都将导致失败计数重置,直到达到 FAILED_LOGIN_ATTEMPTS 值之前的登录尝试。如果 FAILED_LOGIN_ATTEMPTS 为4,并且已经发生了三次连续的密码错误,那么需要再次失败一次才能开始锁定过程。但是,如果下一个登录成功,账户的失败登录计数将重置,使得四次连续的失败才会再次触发锁定。

  • 一旦临时锁定开始,使用正确密码进行登录都无法成功,直到锁定的持续时间结束或通过以下讨论中列出的账户重置方法之一解锁账户。

服务器读取授权表格时,它会为每个账户初始化状态信息,包括是否启用了失败登录跟踪、当前是否临时锁定以及如果是,则锁定的开始时间,以及在未锁定时达到临时锁定所需的失败次数。

账户的状态信息可以被重置,这意味着失败登录计数将重置,并且如果当前已临时锁定,账户将解锁。账户重置可以是全局性的或针对单个账户:

  • 所有账户的全局重置发生在以下条件下:

    • 服务器重启。

    • 执行 FLUSH PRIVILEGES。(以 --skip-grant-tables 启动服务器会使得授权表格不被读取,从而禁用失败登录跟踪。在这种情况下,执行 FLUSH PRIVILEGES 时,服务器将读取授权表格并启用失败登录跟踪,同时重置所有账户。)

  • 针对单个账户的重置发生在以下条件下:

    • 成功登录该账户。

    • 锁定持续时间结束。在这种情况下,失败登录计数将在下一次登录尝试时重置。

    • 执行针对该账户的 ALTER USER 语句,该语句设置了 FAILED_LOGIN_ATTEMPTS 或 PASSWORD_LOCK_TIME(或两者)到任何值(包括当前选项值),或者执行针对该账户的 ALTER USER ... UNLOCK 语句。

      其他针对该账户的 ALTER USER 语句不会影响其当前失败登录计数或锁定状态。

失败登录跟踪与用于验证凭据的登录账户相关联。如果在使用用户代理的情况下进行登录,跟踪将针对代理用户而不是被代理用户进行。这意味着跟踪与 USER() 指示的账户相关联,而不是 CURRENT_USER() 指示的账户。有关代理用户和被代理用户区别的信息,请参阅第 8.2.19 节,“Proxy Users”。