MySQL8-中文参考-六十五-

58 阅读1小时+

MySQL8 中文参考(六十五)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/rename-user.html

15.7.1.7 RENAME USER 语句

RENAME USER *old_user* TO *new_user*
    [, *old_user* TO *new_user*] ...

RENAME USER 语句重命名现有的 MySQL 帐户。对于不存在的旧帐户或已存在的新帐户,将出现错误。

要使用RENAME USER,您必须具有全局CREATE USER特权,或者对mysql系统模式具有UPDATE特权。当启用read_only系统变量时,RENAME USER 还需要CONNECTION_ADMIN特权(或已弃用的SUPER特权)。

截至 MySQL 8.0.22 版,如果要重命名的任何帐户被命名为任何存储对象的DEFINER属性,则RENAME USER 将失败并显示错误。(也就是说,如果重命名帐户会导致存储对象变成孤立状态,则该语句将失败。)要执行操作,您必须具有SET_USER_ID特权;在这种情况下,该语句将成功并显示警告,而不是失败并显示错误。有关更多信息,包括如何识别哪些对象将给定帐户命名为DEFINER属性,请参见孤立存储对象。

每个帐户名使用第 8.2.4 节,“指定帐户名”中描述的格式。例如:

RENAME USER 'jeffrey'@'localhost' TO 'jeff'@'127.0.0.1';

账户名的主机名部分,如果省略,默认为'%'

RENAME USER 导致旧用户持有的特权变为新用户持有的特权。然而,RENAME USER 不会自动删除或使旧用户创建的数据库或其中的对象失效。这包括DEFINER属性命名旧用户的存储过程或视图。如果在定义者安全上下文中执行这些对象,访问这些对象可能会产生错误。(有关安全上下文的信息,请参见第 27.6 节,“存储对象访问控制”。)

特权更改将按照第 8.2.13 节,“特权更改生效时间”中指示的方式生效。

原文:dev.mysql.com/doc/refman/8.0/en/revoke.html

15.7.1.8 REVOKE Statement

REVOKE [IF EXISTS]
    *priv_type* [(*column_list*)]
      [, *priv_type* [(*column_list*)]] ...
    ON [*object_type*] *priv_level*
    FROM *user_or_role* [, *user_or_role*] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] ALL [PRIVILEGES], GRANT OPTION
    FROM *user_or_role* [, *user_or_role*] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] PROXY ON *user_or_role*
    FROM *user_or_role* [, *user_or_role*] ...
    [IGNORE UNKNOWN USER]

REVOKE [IF EXISTS] *role* [, *role* ] ...
    FROM *user_or_role* [, *user_or_role* ] ...
    [IGNORE UNKNOWN USER]

*user_or_role*: {
    *user* (see Section 8.2.4, “Specifying Account Names”)
  | *role* (see Section 8.2.5, “Specifying Role Names”
}

REVOKE语句使系统管理员能够撤销用户帐户和角色的权限和角色。

有关权限存在的级别、允许的*priv_typepriv_levelobject_type*值,以及指定用户和密码的语法的详细信息,请参见第 15.7.1.6 节,“GRANT Statement”。

有关角色的信息,请参见第 8.2.10 节,“使用角色”。

当启用read_only系统变量时,REVOKE需要CONNECTION_ADMIN或权限(或已弃用的SUPER权限),以及以下讨论中描述的任何其他所需权限。

从 MySQL 8.0.30 开始,所有REVOKE显示的形式都支持IF EXISTS选项以及IGNORE UNKNOWN USER选项。如果没有这两个修改,REVOKE对所有命名用户和角色都成功,或者如果发生任何错误则回滚并且没有效果;如果对所有命名用户和角色都成功,则该语句仅写入二进制日志。IF EXISTSIGNORE UNKNOWN USER 的确切效果将在本节后面讨论。

每个帐户名称使用第 8.2.4 节,“指定帐户名称”中描述的格式。每个角色名称使用第 8.2.5 节,“指定角色名称”中描述的格式。例如:

REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';
REVOKE 'role1', 'role2' FROM 'user1'@'localhost', 'user2'@'localhost';
REVOKE SELECT ON world.* FROM 'role3';

帐户或角色名称的主机名部分,如果省略,默认为'%'

要使用第一个REVOKE语法,您必须具有GRANT OPTION权限,并且必须具有您要撤销的权限。

要撤销所有权限,请使用第二种语法,该语法会为指定的用户或角色删除所有全局、数据库、表、列和例程权限。

REVOKE ALL PRIVILEGES, GRANT OPTION
  FROM *user_or_role* [, *user_or_role*] ...

REVOKE ALL PRIVILEGES, GRANT OPTION 不会撤销任何角色。

要使用此REVOKE语法,您必须具有全局CREATE USER权限,或者对mysql系统模式具有UPDATE权限。

后跟一个或多个角���名称的REVOKE关键字的语法需要一个FROM子句,指示要从中撤销角色的一个或多个用户或角色。

IF EXISTSIGNORE UNKNOWN USER 选项(MySQL 8.0.30 及更高版本)具有以下列出的效果:

  • IF EXISTS 意味着,如果目标用户或角色存在,但由于任何原因未分配给目标,找不到这样的权限或角色,则会引发警告,而不是错误;如果语句中命名的权限或角色未分配给目标,语句没有(其他)效果。否则,REVOKE 正常执行;如果用户不存在,则语句会引发错误。

    示例:给定数据库 test 中的表 t1,我们执行以下语句,并显示结果。

    mysql> CREATE USER jerry@localhost;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost;
    ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host
    'localhost' on table 't1' 
    mysql> REVOKE IF EXISTS SELECT ON test.t1 FROM jerry@localhost;
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1\. row ***************************
      Level: Warning
       Code: 1147
    Message: There is no such grant defined for user 'jerry' on host 'localhost' on
    table 't1' 1 row in set (0.00 sec)
    

    如果 REVOKE 语句包括 IF EXISTS,即使命名的权限或角色不存在,或者语句尝试在错误的级别分配它,也会将错误降级为警告。

  • 如果 REVOKE 语句包括 IGNORE UNKNOWN USER,则对于语句中命名但未找到的任何目标用户或角色,语句会引发警告;如果语句中没有存在的目标,REVOKE 成功但没有实际效果。否则,语句会像往常一样执行,并且尝试撤销由于任何原因未分配给目标的权限会引发错误,如预期的那样。

    示例(继续上一个示例):

    mysql> DROP USER IF EXISTS jerry@localhost;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost;
    ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host
    'localhost' on table 't1' 
    mysql> REVOKE SELECT ON test.t1 FROM jerry@localhost IGNORE UNKNOWN USER;
    Query OK, 0 rows affected, 1 warning (0.01 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1\. row ***************************
      Level: Warning
       Code: 3162
    Message: Authorization ID jerry does not exist. 1 row in set (0.00 sec)
    
  • IF EXISTSIGNORE UNKNOWN USER 的组合意味着 REVOKE 永远不会因为未知的目标用户或角色或未分配或不可用的权限而引发错误,在这种情况下,整个语句成功;只要可能,现有目标用户或角色将被移除角色或权限,并且任何无法撤销的撤销将引发警告并执行为 NOOP

    示例(继续上一项中的示例):

    # No such user, no such role
    mysql> DROP ROLE IF EXISTS Bogus;
    Query OK, 0 rows affected, 1 warning (0.02 sec)
    
    mysql> SHOW WARNINGS;
    +-------+------+----------------------------------------------+
    | Level | Code | Message                                      |
    +-------+------+----------------------------------------------+
    | Note  | 3162 | Authorization ID 'Bogus'@'%' does not exist. |
    +-------+------+----------------------------------------------+
    1 row in set (0.00 sec)
    
    # This statement attempts to revoke a nonexistent role from a nonexistent user
    mysql> REVOKE Bogus ON test FROM jerry@localhost;
    ERROR 3619 (HY000): Illegal privilege level specified for test
    
    # The same, with IF EXISTS
    mysql> REVOKE IF EXISTS Bogus ON test FROM jerry@localhost;
    ERROR 1147 (42000): There is no such grant defined for user 'jerry' on host
    'localhost' on table 'test' 
    
    # The same, with IGNORE UNKNOWN USER
    mysql> REVOKE Bogus ON test FROM jerry@localhost IGNORE UNKNOWN USER;
    ERROR 3619 (HY000): Illegal privilege level specified for test
    
    # The same, with both options
    mysql> REVOKE IF EXISTS Bogus ON test FROM jerry@localhost IGNORE UNKNOWN USER;
    Query OK, 0 rows affected, 2 warnings (0.01 sec)
    
    mysql> SHOW WARNINGS;
    +---------+------+--------------------------------------------+
    | Level   | Code | Message                                    |
    +---------+------+--------------------------------------------+
    | Warning | 3619 | Illegal privilege level specified for test |
    | Warning | 3162 | Authorization ID jerry does not exist.     |
    +---------+------+--------------------------------------------+
    2 rows in set (0.00 sec)
    

mandatory_roles 系统变量值中命名的角色无法被撤销。当在尝试移除强制权限的语句中同时使用 IF EXISTSIGNORE UNKNOWN USER 时,通常由于尝试这样做而引发的错误会降级为警告;语句成功执行,但不会进行任何更改。

撤销的角色立即影响被撤销的任何用户账户,因此在账户的任何当前会话中,其权限将在执行下一条语句时进行调整。

撤销角色会撤销角色本身,而不是它代表的权限。假设一个账户被授予一个包含给定权限的角色,并且还明确授予该权限或包含该权限的另一个角色。在这种情况下,如果撤销第一个角色,则账户仍然拥有该权限。例如,如果一个账户被授予两个都包含 SELECT 的角色,那么在撤销任一角色后,该账户仍然可以进行选择。

REVOKE ALL ON *.*(在全局级别)撤销所有授予的静态全局权限和所有授予的动态权限。

服务器不知道的已授予但未知的已撤销权限会带有警告被撤销。这种情况可能发生在动态权限上。例如,动态权限可以在安装注册它的组件时授予,但如果随后卸载该组件,则权限变为未注册,尽管拥有该权限的账户仍然拥有它,并且可以从他们那里撤销。

REVOKE会移除权限,但不会从mysql.user系统表中删除行。要完全删除用户账户,请使用DROP USER。参见 Section 15.7.1.5, “DROP USER Statement”。

如果授权表中包含包含大小写混合的数据库或表名的权限行,并且lower_case_table_names系统变量设置为非零值,则无法使用REVOKE来撤销这些权限。在这种情况下,必须直接操作授权表。(GRANT在设置lower_case_table_names时不会创建这样的行,但在设置变量之前可能已创建这样的行。只能在初始化服务器时配置lower_case_table_names设置。)

当成功从mysql程序执行时,REVOKE会回应Query OK, 0 rows affected。要确定操作后剩余的权限,使用SHOW GRANTS。参见 Section 15.7.7.21, “SHOW GRANTS Statement”。

原文:dev.mysql.com/doc/refman/8.0/en/set-default-role.html

15.7.1.9 SET DEFAULT ROLE Statement

SET DEFAULT ROLE
    {NONE | ALL | *role* [, *role* ] ...}
    TO *user* [, *user* ] ...

对于紧跟在TO关键字后面的每个*user*,此语句定义了用户连接到服务器并进行身份验证时或用户在会话期间执���SET ROLE DEFAULT语句时激活的角色。

SET DEFAULT ROLEALTER USER ... DEFAULT ROLE的替代语法(参见第 15.7.1.1 节,“ALTER USER Statement”)。然而,ALTER USER只能为单个用户设置默认角色,而SET DEFAULT ROLE可以为多个用户设置默认角色。另一方面,您可以为ALTER USER语句指定CURRENT_USER作为用户名,而对于SET DEFAULT ROLE则不行。

SET DEFAULT ROLE需要以下权限:

  • 为另一个用户设置默认角色需要全局CREATE USER权限,或者对mysql.default_roles系统表的UPDATE权限。

  • 为自己设置默认角色不需要特殊权限,只要你想要作为默认角色的角色已经被授予。

每个角色名称使用第 8.2.5 节,“指定角色名称”中描述的格式。例如:

SET DEFAULT ROLE 'admin', 'developer' TO 'joe'@'10.0.0.1';

如果省略角色名称的主机名部分,则默认为'%'

DEFAULT ROLE关键字后面的子句允许这些值:

  • NONE: 将默认设置为NONE(无角色)。

  • ALL: 将默认设置为授予给账户的所有角色。

  • *role* [, *role* ] ...: 将默认设置为指定的角色,这些角色必须在执行SET DEFAULT ROLE时存在并被授予给账户。

注意

SET DEFAULT ROLESET ROLE DEFAULT是不同的语句:

  • SET DEFAULT ROLE定义了在账户会话中默认激活哪些账户角色。

  • SET ROLE DEFAULT将当前会话中的活动角色设置为当前账户的默认角色。

有关角色使用示例,请参见第 8.2.10 节,“使用角色”。

原文:dev.mysql.com/doc/refman/8.0/en/set-password.html

15.7.1.10 SET PASSWORD语句

SET PASSWORD [FOR *user*] *auth_option*
    [REPLACE '*current_auth_string*']
    [RETAIN CURRENT PASSWORD]

*auth_option*: {
    = '*auth_string*'
  | TO RANDOM
}

SET PASSWORD语句为 MySQL 用户帐户分配密码。密码可以在语句中明确指定,也可以由 MySQL 随机生成。该语句还可以包括一个密码验证条款,该条款指定要替换的帐户当前密码,以及一个管理帐户是否具有次要密码的条款。'*auth_string*''*current_auth_string*'分别表示明文(未加密)密码。

注意

与使用SET PASSWORD分配密码不同,ALTER USER是首选语句,用于帐户更改,包括分配密码。例如:

ALTER USER *user* IDENTIFIED BY '*auth_string*';

注意

仅适用于使用将凭据存储在 MySQL 内部的身份验证插件的帐户的随机密码生成、密码验证和次要密码的条款。对于使用针对 MySQL 外部凭据系统执行身份验证的插件的帐户,密码管理也必须在该系统外部处理。有关内部凭据存储的更多信息,请参见第 8.2.15 节,“密码管理”。

REPLACE '*current_auth_string*'条款执行密码验证,并自 MySQL 8.0.13 起可用。如果给出:

  • REPLACE指定要替换的帐户当前密码,作为明文(未加密)字符串。

  • 如果需要更改帐户密码,则必须提供该条款,以指定当前密码,以验证试图进行更改的用户实际知道当前密码。

  • 如果需要更改帐户密码,但不需要指定当前密码,则该条款是可选的。

  • 如果给出该条款但与当前密码不匹配,则该语句将失败,即使该条款是可选的。

  • 只有在更改当前用户的帐户密码时才可以指定REPLACE

有关通过指定当前密码进行密码验证的更多信息,请参见第 8.2.15 节,“密码管理”。

RETAIN CURRENT PASSWORD条款实现双密码功能,并自 MySQL 8.0.14 起可用。如果给出:

  • RETAIN CURRENT PASSWORD 保留账户当前密码作为其次要密码,替换任何现有的次要密码。新密码成为主密码,但客户端可以使用该账户使用主密码或次要密码连接到服务器。 (例外情况:如果SET PASSWORD语句指定的新密码为空,则次要密码也变为空,即使给出了 RETAIN CURRENT PASSWORD。)

  • 如果为一个主密码为空的账户指定 RETAIN CURRENT PASSWORD,该语句将失败。

  • 如果一个账户有一个次要密码,并且您更改其主密码而不指定 RETAIN CURRENT PASSWORD,则次要密码保持不变。

有关双重密码使用的更多信息,请参阅第 8.2.15 节,“密码管理”。

SET PASSWORD 允许使用���些 auth_option 语法:

  • = '*auth_string*'

    为账户分配指定的明文密码。

  • TO RANDOM

    为账户分配由 MySQL 随机生成的密码。该语句还会在结果集中返回明文密码,以便用户或执行该语句的应用程序使用。

    有关结果集和随机生成密码的特性的详细信息,请参阅随机密码生成。

    随机密码生成功能自 MySQL 8.0.18 版本开始提供。

重要提示

在某些情况下,SET PASSWORD 可能会记录在服务器日志中或客户端的历史文件中,例如 ~/.mysql_history,这意味着明文密码可能被任何具有读取权限的人读取。有关在服务器日志中发生这种情况的条件以及如何控制它的信息,请参阅第 8.1.2.3 节,“密码和日志记录”。有关客户端日志记录的类似信息,请参阅第 6.5.1.3 节,“mysql 客户端日志记录”。

SET PASSWORD 可以使用或不使用显式命名用户账户的 FOR 子句:

  • 使用 FOR *user* 子句,该语句为指定的账户设置密码,该账户必须存在:

    SET PASSWORD FOR 'jeffrey'@'localhost' = '*auth_string*';
    
  • 没有 FOR *user* 子句,该语句为当前用户设置密码:

    SET PASSWORD = '*auth_string*';
    

    任何使用非匿名账户连接到服务器的客户端都可以更改该账户的密码(特别是可以更改自己的密码)。要查看服务器对您进行身份验证的账户,请调用CURRENT_USER()函数:

    SELECT CURRENT_USER();
    

如果给出了FOR *user*子句,则账户名使用第 8.2.4 节“指定账户名”中描述的格式。 例如:

SET PASSWORD FOR 'bob'@'%.example.org' = '*auth_string*';

如果省略了账户名的主机名部分,则默认为'%'

SET PASSWORD将字符串解释为明文字符串,将其传递给与账户关联的认证插件,并将插件返回的结果存储在mysql.user系统表中的账户行中。(插件有机会将值哈希为其期望的加密格式。插件可以按照指定的值使用该值,这种情况下不会发生哈希。)

为具名账户(使用FOR子句)设置密码需要对mysql系统模式具有UPDATE权限。 为自己设置密码(对于没有FOR子句的非匿名账户)不需要特殊权限。

修改次要密码的语句需要以下权限:

  • 需要APPLICATION_PASSWORD_ADMIN权限才能使用RETAIN CURRENT PASSWORD子句来对自己的账户执行SET PASSWORD语句。 大多数用户只需要一个密码,因此需要该权限来操作自己的次要密码。

  • 如果要允许一个账户操作所有账户的次要密码,则应授予CREATE USER权限,而不是APPLICATION_PASSWORD_ADMIN

当启用read_only系统变量时,SET PASSWORD需要CONNECTION_ADMIN权限(或已弃用的SUPER权限),以及任何其他所需权限。

有关设置密码和认证插件的更多信息,请参见第 8.2.14 节“分配账户密码”和第 8.2.17 节“可插拔认证”。

原文:dev.mysql.com/doc/refman/8.0/en/set-role.html

15.7.1.11 设置角色语句

SET ROLE {
    DEFAULT
  | NONE
  | ALL
  | ALL EXCEPT *role* [, *role* ] ...
  | *role* [, *role* ] ...
}

SET ROLE通过指定哪些授予的角色是活动的,修改当前用户在当前会话中的有效特权。授予的角色包括明确授予用户的角色和在mandatory_roles系统变量值中命名的角色。

示例:

SET ROLE DEFAULT;
SET ROLE 'role1', 'role2';
SET ROLE ALL;
SET ROLE ALL EXCEPT 'role1', 'role2';

每个角色名称使用第 8.2.5 节,“指定角色名称”中描述的格式。如果省略角色名称的主机名部分,则默认为'%'

用户直接授予的特权(而不是通过角色)不受活动角色的更改影响。

该语句允许这些角色说明符:

  • DEFAULT: 激活账户的默认角色。默认角色是使用SET DEFAULT ROLE指定的角色。

    当用户连接到服务器并成功验证时,服务器确定要激活的默认角色。如果启用了activate_all_roles_on_login系统变量,则服务器激活所有授予的角色。否则,服务器隐式执行SET ROLE DEFAULT。服务器仅激活可以激活的默认角色。服务器会将警告写入其错误日志,对于无法激活的默认角色,但客户端不会收到警告。

    如果用户在会话期间执行SET ROLE DEFAULT,则如果任何默认角色无法激活(例如,如果不存在或未授予给用户),则会发生错误。在这种情况下,当前活动角色不会更改。

  • NONE: 将活动角色设置为NONE(无活动角色)。

  • ALL: 激活授予账户的所有角色。

  • ALL EXCEPT *role* [, *role* ] ...: 激活授予账户的所有角色,除了指定的角色。指定的角色不需要存在或被授予给账户。

  • *role* [, *role* ] ...: 激活命名的角色,这些角色必须授予给账户。

注意

SET DEFAULT ROLESET ROLE DEFAULT是不同的语句:

  • SET DEFAULT ROLE定义了默认情况下在账户会话中激活的账户角色。

  • SET ROLE DEFAULT将当前会话中的活动角色设置为当前账户的默认角色。

有关角色使用示例,请参见第 8.2.10 节,“使用角色”。

15.7.2 资源组管理语句

原文:dev.mysql.com/doc/refman/8.0/en/resource-group-statements.html

15.7.2.1 ALTER RESOURCE GROUP 语句

15.7.2.2 CREATE RESOURCE GROUP 语句

15.7.2.3 DROP RESOURCE GROUP 语句

15.7.2.4 SET RESOURCE GROUP 语句

MySQL 支持资源组的创建和管理,并允许将在服务器内运行的线程分配到特定的组,以便线程根据组可用的资源执行。本节描述了用于资源组管理的 SQL 语句。有关资源组功能的一般讨论,请参见第 7.1.16 节,“资源组”。

原文:dev.mysql.com/doc/refman/8.0/en/alter-resource-group.html

15.7.2.1 ALTER RESOURCE GROUP Statement

ALTER RESOURCE GROUP *group_name*
    [VCPU [=] *vcpu_spec* [, *vcpu_spec*] ...]
    [THREAD_PRIORITY [=] *N*]
    [ENABLE|DISABLE [FORCE]]

*vcpu_spec*: {*N* | *M* - *N*}

ALTER RESOURCE GROUP 用于资源组管理(参见 Section 7.1.16, “Resource Groups”)。此语句更改现有资源组的可修改属性。它需要RESOURCE_GROUP_ADMIN 权限。

group_name 标识要更改的资源组。如果该组不存在,则会出现错误。

可以使用ALTER RESOURCE GROUP修改 CPU 亲和性、优先级以及组是否启用的属性。这些属性的指定方式与CREATE RESOURCE GROUP中描述的方式相同(参见 Section 15.7.2.2, “CREATE RESOURCE GROUP Statement”)。只有指定的属性会被更改,未指定的属性保留其当前值。

FORCE 修饰符与 DISABLE 一起使用。如果资源组有任何线程分配给它,则确定语句的行为:

  • 如果未给出 FORCE,则组中的现有线程将继续运行直到终止,但新线程不能分配给该组。

  • 如果给出 FORCE,则组中的现有线程将移动到各自的默认组(系统线程到 SYS_default,用户线程到 USR_default)。

名称和类型属性在组创建时设置,之后不能使用ALTER RESOURCE GROUP进行修改。

示例:

  • 更改组 CPU 亲和性:

    ALTER RESOURCE GROUP rg1 VCPU = 0-63;
    
  • 更改组线程优先级:

    ALTER RESOURCE GROUP rg2 THREAD_PRIORITY = 5;
    
  • 禁用一个组,将任何分配给它的线程移动到默认组:

    ALTER RESOURCE GROUP rg3 DISABLE FORCE;
    

资源组管理是在发生的服务器上本地的。ALTER RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。

原文:dev.mysql.com/doc/refman/8.0/en/create-resource-group.html

15.7.2.2 创建资源组语句

CREATE RESOURCE GROUP *group_name*
    TYPE = {SYSTEM|USER}
    [VCPU [=] *vcpu_spec* [, *vcpu_spec*] ...]
    [THREAD_PRIORITY [=] *N*]
    [ENABLE|DISABLE]

*vcpu_spec*: {*N* | *M* - *N*}

CREATE RESOURCE GROUP 用于资源组管理(参见 Section 7.1.16, “Resource Groups”)。此语句创建一个新的资源组并分配其初始属性值。它需要 RESOURCE_GROUP_ADMIN 权限。

group_name 标识要创建的资源组。如果该组已经存在,则会出现错误。

TYPE 属性是必需的。对于系统资源组应为 SYSTEM,对于用户资源组应为 USER。组类型会影响允许的 THREAD_PRIORITY 值,如后面所述。

VCPU 属性表示 CPU 亲和性;也就是说,组可以使用的虚拟 CPU 集合:

  • 如果没有给定 VCPU,资源组没有 CPU 亲和性,可以使用所有可用的 CPU。

  • 如果给定了 VCPU,则属性值是逗号分隔的 CPU 数字或范围的列表:

    • 每个数字必须是从 0 到 CPU 数量 - 1 的范围内的整数。例如,在具有 64 个 CPU 的系统上,数字的范围可以从 0 到 63。

    • 范围以 MN 的形式给出,其中 M 小于或等于 N,并且两个数字都在 CPU 范围内。

    • 如果 CPU 数字是超出允许范围的整数或不是整数,则会出现错误。

示例 VCPU 指定器(这些都是等效的):

VCPU = 0,1,2,3,9,10
VCPU = 0-3,9-10
VCPU = 9,10,0-3
VCPU = 0,10,1,9,3,2

THREAD_PRIORITY 属性表示分配给组的线程的优先级:

  • 如果没有给定 THREAD_PRIORITY,默认优先级为 0。

  • 如果给定了 THREAD_PRIORITY,则属性值必须在 -20(最高优先级)到 19(最低优先级)的范围内。系统资源组的优先级必须在 -20 到 0 的范围内。用户资源组的优先级必须在 0 到 19 的范围内。使用不同的范围为系统和用户组确保用户线程永远不会比系统线程具有更高的优先级。

ENABLEDISABLE 指定资源组最初是启用还是禁用。如果没有指定任何一个,那么该组默认是启用的。禁用的组不能分配线程。

示例:

  • 创建一个启用的用户组,具有单个 CPU 和最低优先级:

    CREATE RESOURCE GROUP rg1
      TYPE = USER
      VCPU = 0
      THREAD_PRIORITY = 19;
    
  • 创建一个禁用的系统组,没有 CPU 亲和性(可以使用所有 CPU)和最高优先级:

    CREATE RESOURCE GROUP rg2
      TYPE = SYSTEM
      THREAD_PRIORITY = -20
      DISABLE;
    

资源组管理是在发生的服务器上本地的。CREATE RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。

原文:dev.mysql.com/doc/refman/8.0/en/drop-resource-group.html

15.7.2.3 删除资源组语句

DROP RESOURCE GROUP *group_name* [FORCE]

DROP RESOURCE GROUP 用于资源组管理(参见第 7.1.16 节,“资源组”)。此语句删除一个资源组。它需要RESOURCE_GROUP_ADMIN 权限。

group_name 标识要删除的资源组。如果该组不存在,则会出现错误。

FORCE 修饰符确定资源组有任何线程分配时语句的行为:

  • 如果未给出 FORCE 并且任何线程被分配到该组,则会出现错误。

  • 如果给出 FORCE,则组中的现有线程将移动到各自的默认组(系统线程到 SYS_default,用户线程到 USR_default)。

示例:

  • 删除一个组,如果该组包含任何线程则失败:

    DROP RESOURCE GROUP rg1;
    
  • 删除一个组并将现有线程移动到默认组:

    DROP RESOURCE GROUP rg2 FORCE;
    

资源组管理是发生在其上的服务器本地的。DROP RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。

原文:dev.mysql.com/doc/refman/8.0/en/set-resource-group.html

15.7.2.4 SET RESOURCE GROUP Statement

SET RESOURCE GROUP *group_name*
    [FOR *thread_id* [, *thread_id*] ...]

SET RESOURCE GROUP 用于资源组管理(参见 第 7.1.16 节,“资源组”)。此语句将线程分配给资源组。它需要 RESOURCE_GROUP_ADMINRESOURCE_GROUP_USER 权限。

group_name 标识要分配的资源组。任何 thread_id 值表示要分配给该组的线程。线程 ID 可以从性能模式 threads 表中确定。如果资源组或任何命名线程 ID 不存在,则会出现错误。

没有 FOR 子句时,该语句将当前会话的当前线程分配给资源组。

使用命名线程 ID 的 FOR 子句时,该语句将这些线程分配给资源组。

尝试将系统线程分配给用户资源组或用户线程分配给系统资源组时,会发出警告。

示例:

  • 将当前会话线程分配给一个组:

    SET RESOURCE GROUP rg1;
    
  • 将命名线程分配给一个组:

    SET RESOURCE GROUP rg2 FOR 14, 78, 4;
    

资源组管理是局限于发生在其上的服务器的。SET RESOURCE GROUP 语句不会写入二进制日志,也不会被复制。

一个替代 SET RESOURCE GROUP 的方法是 RESOURCE_GROUP 优化器提示,它将单个语句分配给资源组。参见 第 10.9.3 节,“优化器提示”。

15.7.3 表维护语句

原文:dev.mysql.com/doc/refman/8.0/en/table-maintenance-statements.html

15.7.3.1 分析表语句

15.7.3.2 检查表语句

15.7.3.3 校验表语句

15.7.3.4 优化表语句

15.7.3.5 修复表语句

原文:dev.mysql.com/doc/refman/8.0/en/analyze-table.html

15.7.3.1 ANALYZE TABLE Statement

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE *tbl_name* [, *tbl_name*] ...

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE *tbl_name*
    UPDATE HISTOGRAM ON *col_name* [, *col_name*] ...
        [WITH *N* BUCKETS]

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] 
    TABLE *tbl_name*
    UPDATE HISTOGRAM ON *col_name* [USING DATA '*json_data*']

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE *tbl_name*
    DROP HISTOGRAM ON *col_name* [, *col_name*] ...

ANALYZE TABLE生成表统计信息:

  • ANALYZE TABLE 在没有HISTOGRAM子句的情况下执行键分布分析,并为指定的表或表存储分布。对于MyISAM表,进行键分布分析的ANALYZE TABLE等同于使用myisamchk --analyze

  • 带有UPDATE HISTOGRAM子句的ANALYZE TABLE为指定表列生成直方图统计信息,并将其存储在数据字典中。此语法仅允许一个表名。MySQL 8.0.31 及更高版本还支持将单个列的直方图设置为用户定义的 JSON 值。

  • 带有DROP HISTOGRAM子句的ANALYZE TABLE从数据字典中删除指定表列的直方图统计信息。此语法仅允许一个表名。

此语句需要表的SELECTINSERT权限。

ANALYZE TABLE适用于InnoDBNDBMyISAM表。它不适用于视图。

如果启用了innodb_read_only系统变量,则ANALYZE TABLE可能会失败,因为它无法更新使用InnoDB的数据字典中的统计表,用于更新键分布的ANALYZE TABLE操作,即使操作更新表本身(例如,如果是MyISAM表),也可能会发生失败。要获取更新后的分布统计信息,请设置information_schema_stats_expiry=0

支持对分区表进行ANALYZE TABLE操作,您可以使用ALTER TABLE ... ANALYZE PARTITION来分析一个或多个分区;有关更多信息,请参见第 15.1.9 节,“ALTER TABLE Statement”和第 26.3.4 节,“Partitions 的维护”。

在分析过程中,对于InnoDBMyISAM,表将被读锁定。

默认情况下,服务器将ANALYZE TABLE语句写入二进制日志,以便它们复制到副本。要禁止记录日志,请指定可选的NO_WRITE_TO_BINLOG关键字或其别名LOCAL

以前,ANALYZE TABLE需要一个刷新锁。这意味着,当调用ANALYZE TABLE时,如果仍有长时间运行的语句或事务在使用表,则任何后续语句和事务都必须等待这些操作完成,然后才能释放刷新锁。在 MySQL 8.0.24(及更高版本)中解决了这个问题,ANALYZE TABLE不再导致后续操作等待。

  • ANALYZE TABLE 输出

  • 键分布分析

  • 直方图统计分析

  • 其他考虑

ANALYZE TABLE 输出

ANALYZE TABLE 返回一个包含以下表中所示列的结果集。

Table表名
Opanalyzehistogram
Msg_typestatus, error, info, note, 或 warning
Msg_text一个信息性消息
键分布分析

ANALYZE TABLE没有HISTOGRAM子句时执行键分布分析并存储表或表的分布。任何现有的直方图统计数据保持不变。

如果表自上次键分布分析以来未发生更改,则不会再次分析该表。

MySQL 使用存储的键分布来决定除常数外其他内容的连接应该以什么顺序连接表。此外,在决定查询中特定表使用哪些索引时,可以使用键分布。

要检查存储的键分布基数,使用SHOW INDEX语句或INFORMATION_SCHEMA STATISTICS表。参见第 15.7.7.22 节,“SHOW INDEX Statement”和第 28.3.34 节,“The INFORMATION_SCHEMA STATISTICS Table”。

对于InnoDB表,ANALYZE TABLE通过在每个索引树上执行随机潜水并相应地更新索引基数估计来确定索引基数。由于这些只是估计值,多次运行ANALYZE TABLE可能会产生不同的数字。这使得ANALYZE TABLEInnoDB表上运行速度快,但不是 100%准确,因为它没有考虑所有行。

通过启用innodb_stats_persistent,可以使ANALYZE TABLE收集的统计信息更加精确和稳定,如第 17.8.10.1 节,“配置持久性优化器统计参数”中所解释的那样。在启用innodb_stats_persistent时,重要的是在索引列数据发生重大更改后运行ANALYZE TABLE,因为统计信息不会定期重新计算(例如在服务器重新启动后)。

如果启用了innodb_stats_persistent,可以通过修改innodb_stats_persistent_sample_pages系统变量来更改随机潜水次数。如果禁用了innodb_stats_persistent,则改为修改innodb_stats_transient_sample_pages

有关InnoDB中键分布分析的更多信息,请参见第 17.8.10.1 节,“配置持久性优化器统计参数”和第 17.8.10.3 节,“估算 InnoDB 表的 ANALYZE TABLE 复杂度”。

MySQL 在连接优化中使用索引基数估计。如果连接没有以正确的方式优化,请尝试运行ANALYZE TABLE。在极少数情况下,ANALYZE TABLE无法为您的特定表生成足够好的值,您可以在查询中使用FORCE INDEX强制使用特定索引,或者设置max_seeks_for_key系统变量以确保 MySQL 优先选择索引查找而不是表扫描。参见第 B.3.5 节,“与优化器相关的问题”。

直方图统计分析

带有HISTOGRAM子句的ANALYZE TABLE启用了对表列值的直方图统计管理。有关直方图统计信息,请参见第 10.9.6 节,“优化器统计信息”。

可用的直方图操作如下:

  • 带有UPDATE HISTOGRAM子句的ANALYZE TABLE为命名表列生成直方图统计信息,并将其存储在数据字典中。此语法仅允许一个表名。

    可选的WITH *N* BUCKETS子句指定直方图的桶数。*N*的值必须是 1 到 1024 之间的整数。如果省略此子句,则桶数为 100。

  • 带有DROP HISTOGRAM子句的ANALYZE TABLE从数据字典中删除了命名表列的直方图统计信息。此语法仅允许一个表名。

存储的直方图管理语句仅影响指定的列。考虑以下语句:

ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c2, c3 WITH 10 BUCKETS;
ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c3 WITH 10 BUCKETS;
ANALYZE TABLE t DROP HISTOGRAM ON c2;

第一条语句更新了c1c2c3列的直方图,替换了这些列的任何现有直方图。第二条语句更新了c1c3列的直方图,而c2列的直方图保持不变。第三条语句移除了c2列的直方图,而c1c3列的直方图保持不变。

在对用户数据进行抽样以构建直方图时,并非所有值都会被读取;这可能导致遗漏一些被认为重要的值。在这种情况下,修改直方图或根据自己的标准明确设置自己的直方图可能是有用的,例如完整数据集。MySQL 8.0.31 添加了对ANALYZE TABLE *tbl_name* UPDATE HISTOGRAM ON *col_name* USING DATA '*json_data*'的支持,用于使用与显示信息模式COLUMN_STATISTICS表中HISTOGRAM列值相同的 JSON 格式提供的数据更新直方图表的列。在使用 JSON 数据更新直方图时,只能修改一个列。

我们可以通过首先在表t的列c1上生成直方图来说明USING DATA的用法,就像这样:

mysql> ANALYZE TABLE t UPDATE HISTOGRAM ON c1;
+--------+-----------+----------+-----------------------------------------------+
| Table  | Op        | Msg_type | Msg_text                                      |
+--------+-----------+----------+-----------------------------------------------+
| mydb.t | histogram | status   | Histogram statistics created for column 'c1'. |
+--------+-----------+----------+-----------------------------------------------+

我们可以在COLUMN_STATISTICS表中看到生成的直方图:

mysql> TABLE information_schema.column_statistics\G
*************************** 1\. row ***************************
SCHEMA_NAME: mydb
 TABLE_NAME: t
COLUMN_NAME: c1
  HISTOGRAM: {"buckets": [[206, 0.0625], [456, 0.125], [608, 0.1875]],
"data-type": "int", "null-values": 0.0, "collation-id": 8, "last-updated":
"2022-10-11 16:13:14.563319", "sampling-rate": 1.0, "histogram-type":
"singleton", "number-of-buckets-specified": 100}

现在我们删除了直方图,当我们检查COLUMN_STATISTICS时,它现在是空的:

mysql> ANALYZE TABLE t DROP HISTOGRAM ON c1;
+--------+-----------+----------+-----------------------------------------------+
| Table  | Op        | Msg_type | Msg_text                                      |
+--------+-----------+----------+-----------------------------------------------+
| mydb.t | histogram | status   | Histogram statistics removed for column 'c1'. |
+--------+-----------+----------+-----------------------------------------------+

mysql> TABLE information_schema.column_statistics\G
Empty set (0.00 sec)

我们可以通过将先前从COLUMN_STATISTICS表的HISTOGRAM列中获取的 JSON 表示插入来恢复已删除的直方图,当我们再次查询该表时,我们可以看到直方图已恢复到先前的状态:

mysql> ANALYZE TABLE t UPDATE HISTOGRAM ON c1 
 ->     USING DATA '{"buckets": [[206, 0.0625], [456, 0.125], [608, 0.1875]],
    ->               "data-type": "int", "null-values": 0.0, "collation-id":
    ->               8, "last-updated": "2022-10-11 16:13:14.563319",
    ->               "sampling-rate": 1.0, "histogram-type": "singleton",
    ->               "number-of-buckets-specified": 100}';   
+--------+-----------+----------+-----------------------------------------------+
| Table  | Op        | Msg_type | Msg_text                                      |
+--------+-----------+----------+-----------------------------------------------+
| mydb.t | histogram | status   | Histogram statistics created for column 'c1'. |
+--------+-----------+----------+-----------------------------------------------+

mysql> TABLE information_schema.column_statistics\G
*************************** 1\. row ***************************
SCHEMA_NAME: mydb
 TABLE_NAME: t
COLUMN_NAME: c1
  HISTOGRAM: {"buckets": [[206, 0.0625], [456, 0.125], [608, 0.1875]],
"data-type": "int", "null-values": 0.0, "collation-id": 8, "last-updated":
"2022-10-11 16:13:14.563319", "sampling-rate": 1.0, "histogram-type":
"singleton", "number-of-buckets-specified": 100}

不支持为加密表(以避免在统计数据中暴露数据)或TEMPORARY表生成直方图。

直方图生成适用于除几何类型(空间数据)和JSON之外的所有数据类型的列。

可以为存储和虚拟生成列生成直方图。

无法为由单列唯一索引覆盖的列生成直方图。

直方图管理语句尝试尽可能执行请求的操作,并对其余部分报告诊断消息。例如,如果UPDATE HISTOGRAM语句命名了多个列,但其中一些列不存在或具有不受支持的数据类型,则会为其他列生成直方图,并为无效列生成消息。

直方图受以下 DDL 语句影响:

  • DROP TABLE会移除已删除表中的列的直方图。

  • DROP DATABASE会移除已删除数据库中任何表的直方图,因为该语句会删除数据库中的所有表。

  • RENAME TABLE不会移除直方图。相反,它会将重命名后的表的直方图重命名为与新表名相关联。

  • ALTER TABLE语句删除或修改列时会删除该列的直方图。

  • ALTER TABLE ... CONVERT TO CHARACTER SET会移除字符列的直方图,因为它们受字符集更改的影响。非字符列的直方图不受影响。

histogram_generation_max_mem_size系统变量控制用于直方图生成的最大内存量。全局和会话值可以在运行时设置。

更改全局histogram_generation_max_mem_size值需要具有足够权限设置全局系统变量的权限。更改会话histogram_generation_max_mem_size值需要具有足够权限设置受限会话系统变量的权限。参见 Section 7.1.9.1, “System Variable Privileges”。

如果用于直方图生成的估计数据量超过由histogram_generation_max_mem_size定义的限制,MySQL 会对数据进行抽样而不是全部读入内存。抽样均匀分布在整个表上。MySQL 使用SYSTEM抽样,这是一种基于页面级别的抽样方法。

可以查询信息模式COLUMN_STATISTICS表中HISTOGRAM列中的sampling-rate值,以确定用于创建直方图的数据分数。sampling-rate是一个介于 0.0 和 1.0 之间的数字。值为 1 表示所有数据都被读取(没有抽样)。

以下示例演示了抽样。为了确保数据量超过histogram_generation_max_mem_size限制,以便进行示例,先将限制设置为较低值(2000000 字节),然后为employees表的birth_date列生成直方图统计信息。

mysql> SET histogram_generation_max_mem_size = 2000000;

mysql> USE employees;

mysql> ANALYZE TABLE employees UPDATE HISTOGRAM ON birth_date WITH 16 BUCKETS\G
*************************** 1\. row ***************************
   Table: employees.employees
      Op: histogram
Msg_type: status
Msg_text: Histogram statistics created for column 'birth_date'. 
mysql> SELECT HISTOGRAM->>'$."sampling-rate"'
       FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
       WHERE TABLE_NAME = "employees"
       AND COLUMN_NAME = "birth_date";
+---------------------------------+
| HISTOGRAM->>'$."sampling-rate"' |
+---------------------------------+
| 0.0491431208869665              |
+---------------------------------+

sampling-rate值为 0.0491431208869665 表示大约有 4.9%的birth_date列数据被读入内存以生成直方图统计信息。

截至 MySQL 8.0.19,InnoDB存储引擎为存储在InnoDB表中的数据提供了自己的抽样实现。当存储引擎不提供自己的抽样实现时,MySQL 使用的默认抽样实现需要进行全表扫描,对于大表来说代价高昂。InnoDB抽样实现通过避免全表扫描来提高抽样性能。

sampled_pages_readsampled_pages_skipped``INNODB_METRICS计数器可用于监视InnoDB数据页的采样。(有关一般INNODB_METRICS计数器使用信息,请参见 Section 28.4.21, “The INFORMATION_SCHEMA INNODB_METRICS Table”。)

以下示例演示了采样计数器的使用,需要在生成直方图统计信息之前启用计数器。

mysql> SET GLOBAL innodb_monitor_enable = 'sampled%';

mysql> USE employees;

mysql> ANALYZE TABLE employees UPDATE HISTOGRAM ON birth_date WITH 16 BUCKETS\G
*************************** 1\. row ***************************
   Table: employees.employees
      Op: histogram
Msg_type: status
Msg_text: Histogram statistics created for column 'birth_date'. 
mysql> USE INFORMATION_SCHEMA;

mysql> SELECT NAME, COUNT FROM INNODB_METRICS WHERE NAME LIKE 'sampled%'\G
*************************** 1\. row ***************************
 NAME: sampled_pages_read
COUNT: 43
*************************** 2\. row ***************************
 NAME: sampled_pages_skipped
COUNT: 843

这个公式基于采样计数器数据近似采样率:

sampling rate = sampled_page_read/(sampled_pages_read + sampled_pages_skipped)

基于采样计数器数据的采样率大致等同于信息模式COLUMN_STATISTICS表中HISTOGRAM列中的sampling-rate值。

有关生成直方图时执行的内存分配的信息,请监视性能模式memory/sql/histograms工具。参见 Section 29.12.20.10, “Memory Summary Tables”。

其他考虑因素

ANALYZE TABLE从信息模式INNODB_TABLESTATS表中清除表统计信息,并将STATS_INITIALIZED列设置为Uninitialized。统计信息在下次访问表时再次收集。

原文:dev.mysql.com/doc/refman/8.0/en/check-table.html

15.7.3.2 CHECK TABLE Statement

CHECK TABLE *tbl_name* [, *tbl_name*] ... [*option*] ...

*option*: {
    FOR UPGRADE
  | QUICK
  | FAST
  | MEDIUM
  | EXTENDED
  | CHANGED
}

CHECK TABLE 检查一个或多个表中的错误。CHECK TABLE 也可以检查视图是否存在问题,例如在视图定义中引用的表已不存在。

要检查一个表,您必须���其具有某些权限。

CHECK TABLE 适用于 InnoDB, MyISAM, ARCHIVE, 和 CSV 表。

在对 InnoDB 表运行 CHECK TABLE 之前,请参阅 InnoDB 表的 CHECK TABLE 使用注意事项。

CHECK TABLE 支持分区表,并且您可以使用 ALTER TABLE ... CHECK PARTITION 来检查一个或多个分区;有关更多信息,请参阅 第 15.1.9 节,“ALTER TABLE 语句” 和 第 26.3.4 节,“分区的维护”。

CHECK TABLE 忽略未建立索引的虚拟生成列。

  • 检查表输出

  • 检查版本兼容性

  • 检查数据一致性

  • InnoDB 表的 CHECK TABLE 使用注意事项

  • MyISAM 表的 CHECK TABLE 使用注意事项

检查表输出

CHECK TABLE 返回一个结果集,其中包含以下表中显示的列。

Table表名
Op始终为 check
Msg_typestatus, error, info, note, 或 warning
Msg_text一个信息性消息

该语句可能为每个检查的表产生许多行信息。最后一行的 Msg_type 值为 statusMsg_text 通常应为 OKTable is already up to date 表示表的存储引擎指示无需检查表。

检查版本兼容性

FOR UPGRADE选项检查指定表是否与当前版本的 MySQL 兼容。使用FOR UPGRADE,服务器会检查每个表,以确定自创建表以来是否有任何数据类型或索引的不兼容更改。如果没有,则检查成功。否则,如果存在可能的不兼容性,服务器会对表进行全面检查(可能需要一些时间)。

不兼容性可能是因为数据类型的存储格式已更改或其排序顺序已更改。我们的目标是避免这些更改,但偶尔它们是必要的,以纠正比发布之间的不兼容性更糟糕的问题。

FOR UPGRADE会发现这些不兼容性:

  • InnoDBMyISAM表中,TEXT列的末尾空格索引顺序在 MySQL 4.1 和 5.0 之间发生了变化。

  • DECIMAL数据类型的存储方法在 MySQL 5.0.3 和 5.0.5 之间发生了变化。

  • 有时会对字符集或校对规则进行更改,需要重建表索引。有关此类更改的详细信息,请参见第 3.5 节,“MySQL 8.0 中的更改”。有关重建表的信息,请参见第 3.14 节,“重建或修复表或索引”。

  • MySQL 8.0 不支持旧版本 MySQL 中允许的 2 位数YEAR(2)数据类型。对于包含YEAR(2)列的表,CHECK TABLE建议使用REPAIR TABLE,将 2 位数YEAR(2)列转换为 4 位数YEAR列。

  • 触发器创建时间保持不变。

  • 如果表中包含旧的时间列(不支持分数秒精度的TIMEDATETIMETIMESTAMP列)且avoid_temporal_upgrade系统变量已禁用,则会报告需要重建表。这有助于 MySQL 升级过程检测和升级包含旧时间列的表。如果启用了avoid_temporal_upgradeFOR UPGRADE会忽略表中存在的旧时间列;因此,升级过程不会对其进行升级。

    要检查包含这种时间列并需要重建的表格,请在执行CHECK TABLE ... FOR UPGRADE之前禁用avoid_temporal_upgrade

  • 对于使用非本机分区的表格会发出警告,因为 MySQL 8.0 中移除了非本机分区。请参阅第二十六章,分区

检查数据一致性

下表显示了可以提供的其他检查选项。这些选项将传递给存储引擎,存储引擎可能会使用或忽略它们。

类型意义
QUICK不扫描行以检查不正确的链接。适用于InnoDBMyISAM表格和视图。
FAST仅检查未正确关闭的表格。对InnoDB无效;仅适用于MyISAM表格和视图。
CHANGED仅检查自上次检查以来已更改或未正确关闭的表格。对InnoDB无效;仅适用于MyISAM表格和视图。
MEDIUM扫描行以验证已删除链接是否有效。这还为行计算一个键校验和,并将其与键的计算校验和进行验证。对InnoDB无效;仅适用于MyISAM表格和视图。
EXTENDED对每一行的所有键进行完整的键查找。这确保表格是 100%一致的,但需要很长时间。对InnoDB无效;仅适用于MyISAM表格和视图。

您可以组合检查选项,如下例所示,对表格进行快速检查以确定是否已正确关闭:

CHECK TABLE test_table FAST QUICK;

注意

如果CHECK TABLE在标记为“损坏”或“未正确关闭”的表格中未发现问题,CHECK TABLE可能会移除标记。

如果表格损坏,问题很可能在索引中而不是数据部分。所有前面的检查类型都会彻底检查索引,因此应该能找到大多数错误。

要检查一个您认为没问题的表格,请不使用检查选项或使用QUICK选项。当您匆忙时可以使用后者,并且可以承担QUICK在数据文件中找不到错误的极小风险。(在大多数情况下,在正常使用情况下,MySQL 应该能找到数据文件中的任何错误。如果发生这种情况,表格将被标记为“损坏”,直到修复为止。)

FASTCHANGED主要用于从脚本(例如从cron中执行)定期检查表格。在大多数情况下,FAST优于CHANGED。(唯一不优选的情况是当您怀疑在MyISAM代码中发现了错误时。)

仅在运行正常检查但 MySQL 尝试更新行或按键查找行时仍然从表中获得错误时才使用EXTENDED。如果正常检查成功,这是非常不可能的。

使用CHECK TABLE ... EXTENDED可能会影响查询优化器生成的执行计划。

CHECK TABLE报告的一些问题无法自动纠正:

  • 找到行,其中自增列的值为 0

    这意味着表中有一行,其中AUTO_INCREMENT索引列包含值 0。(可以通过使用UPDATE语句显式将列设置为 0 来创建AUTO_INCREMENT列为 0 的行。)

    这本身不是错误,但如果您决定转储表并恢复它,或对表进行ALTER TABLE操作可能会引起麻烦。在这种情况下,AUTO_INCREMENT列根据AUTO_INCREMENT列的规则更改值,可能会导致诸如重复键错误之类的问题。

    要消除警告,请执行UPDATE语句将列设置为非 0 值。

InnoDB 表的CHECK TABLE使用注意事项

以下注意事项适用于InnoDB表:

  • 如果CHECK TABLE遇到损坏的页,服务器会退出以防止错误传播(Bug #10132)。如果损坏发生在辅助索引中但表数据可读,运行CHECK TABLE仍可能导致服务器退出。

  • 如果CHECK TABLE在聚簇索引中遇到损坏的DB_TRX_IDDB_ROLL_PTR字段,CHECK TABLE可能会导致InnoDB访问无效的撤消日志记录,导致与 MVCC 相关的服务器退出。

  • 如果CHECK TABLEInnoDB表或索引中遇到错误,它会报告错误,并通常标记索引,有时标记表为损坏,阻止进一步使用索引或表。此类错误包括辅助索引中不正确的条目数或不正确的链接。

  • 如果CHECK TABLE在辅助索引中发现不正确的条目数,它会报告错误,但不会导致服务器退出或阻止访问文件。

  • CHECK TABLE 调查索引页结构,然后调查每个键入。它不验证指向聚簇记录的键指针,也不遵循 BLOB 指针的路径。

  • InnoDB 表存储在自己的 .ibd 文件 中时,.ibd 文件的前 3 个 页 包含头部信息而不是表或索引数据。CHECK TABLE 语句不会检测仅影响头部数据的不一致性。要验证整个 InnoDB .ibd 文件的内容,使用 innochecksum 命令。

  • 在大型 InnoDB 表上运行 CHECK TABLE 时,其他线程可能在 CHECK TABLE 执行期间被阻塞。为避免超时,信号量等待阈值(600 秒)在 CHECK TABLE 操作期间延长 2 小时(7200 秒)。如果 InnoDB 检测到 240 秒或更长时间的信号量等待,它开始将 InnoDB 监视器输出打印到错误日志中。如果锁请求超出信号量等待阈值,InnoDB 将中止该进程。为完全避免信号量等待超时的可能性,运行 CHECK TABLE QUICK 而不是 CHECK TABLE

  • InnoDB SPATIAL 索引的 CHECK TABLE 功能包括 R 树有效性检查和确保 R 树行数与聚簇索引匹配的检查。

  • CHECK TABLE 支持虚拟生成列上的辅助索引,这些索引由 InnoDB 支持。

  • 截至 MySQL 8.0.14,InnoDB 支持并行聚簇索引读取,可以提高 CHECK TABLE 的性能。InnoDBCHECK TABLE 操作期间两次读取聚簇索引。第二次读取可以并行执行。innodb_parallel_read_threads 会话变量必须设置为大于 1 的值,才能进行并行聚簇索引读取。默认值为 4。用于执行并行聚簇索引读取的实际线程数由 innodb_parallel_read_threads 设置或要扫描的索引子树数量决定,以较小者为准。

MyISAM 表的 CHECK TABLE 用法注意事项

以下注意事项适用于MyISAM表:

  • CHECK TABLE更新MyISAM表的关键统计信息。

  • 如果CHECK TABLE输出不返回OKTable is already up to date,通常应该对表进行修复。请参阅第 9.6 节,“MyISAM 表维护和崩溃恢复”。

  • 如果未指定CHECK TABLE选项QUICKMEDIUMEXTENDED,动态格式MyISAM表的默认检查类型为MEDIUM。这与在表上运行**myisamchk --medium-check *tbl_name***的结果相同。对于静态格式MyISAM表,默认的检查类型也是MEDIUM,除非指定了CHANGEDFAST。在这种情况下,默认值为QUICK。对于CHANGEDFAST,行扫描被跳过,因为行很少损坏。

原文:dev.mysql.com/doc/refman/8.0/en/checksum-table.html

15.7.3.3 CHECKSUM TABLE 语句

CHECKSUM TABLE *tbl_name* [, *tbl_name*] ... [QUICK | EXTENDED]

CHECKSUM TABLE报告表内容的校验值。您可以使用此语句在备份、回滚或其他旨在将数据恢复到已知状态的操作之前后验证内容是否相同。

这个语句需要表的SELECT权限。

这个语句不支持对视图的操作。如果你对视图运行CHECKSUM TABLEChecksum值始终为NULL,并返回一个警告。

对于不存在的表,CHECKSUM TABLE返回NULL并生成一个警告。

在校验操作期间,对于InnoDBMyISAM,表会被读锁定。

性能考虑

默认情况下,整个表会逐行读取并计算校验值。对于大表,这可能需要很长时间,因此您只会偶尔执行此操作。这种逐行计算是使用EXTENDED子句、InnoDB和除了MyISAM之外的所有其他存储引擎,以及未使用CHECKSUM=1子句创建的MyISAM表所得到的。

对于使用CHECKSUM=1子句创建的MyISAM表,CHECKSUM TABLECHECKSUM TABLE ... QUICK返回可以非常快速返回的“实时”表校验值。如果表不符合所有这些条件,QUICK方法返回NULLQUICK方法不支持InnoDB表。有关CHECKSUM子句的语法,请参见第 15.1.20 节,“CREATE TABLE Statement”。

校验值取决于表行格式。如果行格式发生变化,校验值也会发生变化。例如,MySQL 5.6 之前的 MySQL 5.6.5 对于诸如TIMEDATETIMETIMESTAMP等时间类型的存储格式发生了变化,因此如果将一个 5.5 表升级到 MySQL 5.6,校验值可能会发生变化。

重要提示

如果两个表的校验值不同,那么这两个表在某种程度上肯定是不同的。然而,由于CHECKSUM TABLE使用的哈希函数不能保证无碰撞,所以两个不完全相同的表可能产生相同的校验值的几率很小。

原文:dev.mysql.com/doc/refman/8.0/en/optimize-table.html

15.7.3.4 OPTIMIZE TABLE 语句

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE *tbl_name* [, *tbl_name*] ...

OPTIMIZE TABLE重新组织表数据和相关索引数据的物理存储,以减少存储空间并在访问表时提高 I/O 效率。对每个表所做的确切更改取决于该表使用的存储引擎。

在这些情况下使用OPTIMIZE TABLE,取决于表的类型:

  • 在对启用了innodb_file_per_table选项创建了自己的.ibd 文件的InnoDB表上进行大量插入、更新或删除操作之后。表和索引将重新组织,并且磁盘空间可以被回收供操作系统使用。

  • 在对InnoDB表中的FULLTEXT索引的列进行大量插入、更新或删除操作之后。首先设置配置选项innodb_optimize_fulltext_only=1。为了保持索引维护时间在合理范围内,设置innodb_ft_num_word_optimize选项以指定要更新搜索索引中的单词数量,并运行一系列OPTIMIZE TABLE语句,直到搜索索引完全更新。

  • 在删除MyISAMARCHIVE表的大部分内容,或对具有可变长度行的MyISAMARCHIVE表进行许多更改(具有VARCHARVARBINARYBLOBTEXT列的表)。已删除的行将保留在链表中,并且后续的INSERT操作将重用旧的行位置。您可以使用OPTIMIZE TABLE来回收未使用的空间并对数据文件进行碎片整理。在对表进行大量更改后,此语句有时也可以显著改善使用该表的语句的性能。

此语句需要表的SELECTINSERT权限。

OPTIMIZE TABLE适用于InnoDBMyISAMARCHIVE表。OPTIMIZE TABLE也支持内存中动态列的NDB表。它不适用于内存表的固定宽度列,也不适用于磁盘数据表。可以使用--ndb-optimization-delay来调整 NDB Cluster 表上OPTIMIZE的性能,该选项控制OPTIMIZE TABLE处理批处理行之间等待的时间长度。有关更多信息,请参见第 25.2.7.11 节,“NDB Cluster 8.0 中解决的以前的 NDB Cluster 问题”。

对于 NDB Cluster 表,OPTIMIZE TABLE可以被(例如)终止执行OPTIMIZE操作的 SQL 线程所中断。

默认情况下,OPTIMIZE TABLE不适用于使用任何其他存储引擎创建的表,并返回指示此不支持的结果。您可以通过使用--skip-new选项启动mysqld来使OPTIMIZE TABLE适用于其他存储引擎。在这种情况下,OPTIMIZE TABLE只是映射到ALTER TABLE

此语句不适用于视图。

OPTIMIZE TABLE支持分区表。有关在分区表和表分区中使用此语句的信息,请参见第 26.3.4 节,“分区的维护”。

默认情况下,服务器会将OPTIMIZE TABLE语句写入二进制日志,以便在副本中复制。要禁止记录日志,请指定可选的NO_WRITE_TO_BINLOG关键字或其别名LOCAL

  • OPTIMIZE TABLE 输出

  • InnoDB 详细信息

  • MyISAM 详细信息

  • 其他考虑因素

OPTIMIZE TABLE 输出

OPTIMIZE TABLE 返回一个结果集,其中包含下表所示的列。

Table表名
Op始终为 optimize
Msg_typestatus, error, info, note, 或 warning
Msg_text一个信息性消息

OPTIMIZE TABLE 表捕获并抛出在从旧文件复制表统计信息到新创建的文件时发生的任何错误。例如,如果.MYD.MYI文件的所有者用户 ID 与 mysqld 进程的用户 ID 不同,OPTIMIZE TABLE 会生成“无法更改文件所有权”错误,除非 mysqld 是由 root 用户启动的。

InnoDB 详情

对于 InnoDB 表,OPTIMIZE TABLE 被映射为 ALTER TABLE ... FORCE,该操作重建表以更新索引统计信息并释放聚簇索引中未使用的空间。当你在 InnoDB 表上运行 OPTIMIZE TABLE 时,输出中会显示这一点:

mysql> OPTIMIZE TABLE foo;
+----------+----------+----------+-------------------------------------------------------------------+
| Table    | Op       | Msg_type | Msg_text                                                          |
+----------+----------+----------+-------------------------------------------------------------------+
| test.foo | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.foo | optimize | status   | OK                                                                |
+----------+----------+----------+-------------------------------------------------------------------+

OPTIMIZE TABLE 使用在线 DDL 来对常规和分区的 InnoDB 表进行重建,从而减少并发 DML 操作的停机时间。由 OPTIMIZE TABLE 触发的表重建是就地完成的。在操作的准备阶段和提交阶段仅短暂地获取独占表锁。在准备阶段,元数据被更新并创建一个中间表。在提交阶段,表元数据更改被提交。

在以下条件下,OPTIMIZE TABLE 使用表复制方法重建表:

  • 当启用 old_alter_table 系统变量时。

  • 当服务器使用 --skip-new 选项启动时。

使用在线 DDL 的 OPTIMIZE TABLE 不支持包含 FULLTEXT 索引的 InnoDB 表。而是使用表复制方法。

InnoDB 使用页面分配方法存储数据,并且不像传统存储引擎(如MyISAM)那样受到碎片化的影响。在考虑是否运行优化时,请考虑服务器预计要处理的事务工作负载:

  • 一定程度的碎片化是可以预期的。InnoDB只将页面填充到 93%的容量,以便为更新留出空间,而无需分割页面。

  • 删除操作可能会留下间隙,导致页面填充不足,这可能值得优化表格。

  • 对行的更新通常会在同一页面内重写数据,取决于数据类型和行格式,在有足够空间的情况下。请参阅 Section 17.9.1.5, “How Compression Works for InnoDB Tables” 和 Section 17.10, “InnoDB Row Formats”。

  • 高并发工作负载可能会随着时间的推移在索引中留下间隙,因为InnoDB通过其 MVCC 机制保留了相同数据的多个版本。请参阅 Section 17.3, “InnoDB Multi-Versioning”。

MyISAM 详细信息

对于MyISAM表,OPTIMIZE TABLE 的工作方式如下:

  1. 如果表中有已删除或已分割的行,请修复表格。

  2. 如果索引页面未排序,请对其进行排序。

  3. 如果表格的统计数据不是最新的(且无法通过对索引进行排序来修复),请更新它们。

其他考虑事项

OPTIMIZE TABLE 用于在线执行常规和分区的InnoDB表。否则,在运行OPTIMIZE TABLE 时,MySQL 会锁定表格。

OPTIMIZE TABLE 不会对 R-tree 索引进行排序,例如POINT列上的空间索引。(Bug #23578)

原文:dev.mysql.com/doc/refman/8.0/en/repair-table.html

15.7.3.5 修复表语句

REPAIR [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE *tbl_name* [, *tbl_name*] ...
    [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLE 修复可能损坏的表,仅适用于某些存储引擎。

此语句需要表的SELECTINSERT权限。

虽然通常情况下您不应该经常运行REPAIR TABLE,但如果发生灾难,这个语句很可能从MyISAM表中恢复所有数据。如果您的表经常损坏,请尝试找出原因,以消除使用REPAIR TABLE的必要性。参见第 B.3.3.3 节,“如果 MySQL 经常崩溃怎么办”,以及第 18.2.4 节,“MyISAM 表问题”。

REPAIR TABLE 检查表以查看是否需要升级。如果需要,它执行升级,遵循与CHECK TABLE ... FOR UPGRADE相同的规则。有关更多信息,请参见第 15.7.3.2 节,���检查表语句”。

重要提示

  • 在执行表修复操作之前备份表;在某些情况下,该操作可能导致数据丢失。可能的原因包括但不限于文件系统错误。请参见第九章,“备份和恢复”。

  • 如果服务器在REPAIR TABLE操作期间退出,在重新启动后,立即执行另一个REPAIR TABLE语句对该表进行修复是至关重要的,然后再对其执行其他操作。在最坏的情况下,您可能会得到一个没有关于数据文件信息的新干净索引文件,然后您执行的下一个操作可能会覆盖数据文件。这是一个不太可能但可能发生的情况,强调了首先进行备份的价值。

  • 如果源上的表损坏并且您在其上运行REPAIR TABLE,则对原始表的任何更改不会传播到副本。

  • 修复表存储引擎和分区支持

  • 修复表选项

  • 修复表输出

  • 表修复注意事项

修复表存储引擎和分区支持

REPAIR TABLE适用于MyISAMARCHIVECSV表。对于MyISAM表,默认情况下具有与**myisamchk --recover *tbl_name***相同的效果。此语句不适用于视图。

REPAIR TABLE支持分区表。但是,在分区表上不能使用USE_FRM选项。

您可以使用ALTER TABLE ... REPAIR PARTITION来修复一个或多个分区;有关更多信息,请参见第 15.1.9 节,“ALTER TABLE 语句”和第 26.3.4 节,“分区维护”。

修复表选项
  • NO_WRITE_TO_BINLOGLOCAL

    默认情况下,服务器将REPAIR TABLE语句写入二进制日志,以便它们复制到副本。要禁止记录日志,请指定可选的NO_WRITE_TO_BINLOG关键字或其别名LOCAL

  • QUICK

    如果使用QUICK选项,REPAIR TABLE尝试仅修复索引文件,而不是数据文件。这种类型的修复类似于myisamchk --recover --quick所做的操作。

  • EXTENDED

    如果使用EXTENDED选项,MySQL 会逐行创建索引行,而不是一次性创建一个索引并进行排序。这种类型的修复类似于myisamchk --safe-recover所做的操作。

  • USE_FRM

    如果.MYI索引文件丢失或其头部损坏,可以使用USE_FRM选项。此选项告诉 MySQL 不要信任.MYI文件头中的信息,并使用数据字典中的信息重新创建它。这种修复无法使用myisamchk进行。

    注意

    仅在无法使用常规REPAIR模式时才使用USE_FRM选项。告诉服务器忽略.MYI文件会使存储在.MYI中的重要表元数据对修复过程不可用,这可能会产生有害后果:

    • 当前的AUTO_INCREMENT值丢失了。

    • 表中已删除记录的链接丢失了,这意味着删除记录后的空闲空间仍然未被占用。

    • .MYI 头部指示表是否被压缩。如果服务器忽略这些信息,它就无法知道表是否被压缩,修复可能会导致表内容的更改或丢失。这意味着不应该在压缩表上使用 USE_FRM。无论如何,这是不必要的:压缩表是只读的,因此它们不应该变得损坏。

    如果您对由当前运行的 MySQL 服务器的不同版本创建的表使用 USE_FRMREPAIR TABLE 不会尝试修复表。在这种情况下,REPAIR TABLE 返回的结果集包含一个 Msg_type 值为 errorMsg_text 值为 Failed repairing incompatible .FRM file 的行。

    如果使用 USE_FRMREPAIR TABLE 不会检查表以查看是否需要升级。

修复表输出

REPAIR TABLE 返回一个包含以下表中列的结果集。

Table表名
Op始终为 repair
Msg_typestatuserrorinfonotewarning
Msg_text一个信息性消息

REPAIR TABLE 语句可能为每个修复的表产生许多行信息。最后一行的 Msg_type 值为 statusMsg_test 通常应为 OK。对于 MyISAM 表,如果没有得到 OK,应尝试使用 myisamchk --safe-recover 进行修复。(REPAIR TABLE 没有实现所有 myisamchk 的选项。使用 myisamchk --safe-recover,您还可以使用 --max-record-lengthREPAIR TABLE 不支持的选项。)

REPAIR TABLE 表捕获并抛出在从旧损坏文件复制表统计信息到新创建文件时发生的任何错误。例如,如果 .MYD.MYI 文件的所有者的用户 ID 与 mysqld 进程的用户 ID 不同,REPAIR TABLE 会生成一个“无法更改文件所有权”的错误,除非 mysqld 是由 root 用户启动的。

表修复考虑事项

修复表 会升级表格,如果它包含旧的时间列,格式为 5.6.4 之前的格式(TIMEDATETIMETIMESTAMP 列,不支持分数秒精度),并且 avoid_temporal_upgrade 系统变量被禁用。如果 avoid_temporal_upgrade 被启用,修复表 会忽略表中存在的旧时间列,并且不会升级它们。

要升级包含这些时间列的表格,请在执行 修复表 前禁用 avoid_temporal_upgrade

通过设置特定的系统变量,您可以提高 修复表 的性能。请参阅 第 10.6.3 节,“优化修复表语句”。

15.7.4 组件、插件和可加载函数语句

原文:dev.mysql.com/doc/refman/8.0/en/component-statements.html

15.7.4.1 创建可加载函数的 CREATE FUNCTION 语句

15.7.4.2 卸载可加载函数的 DROP FUNCTION 语句

15.7.4.3 安装组件语句

15.7.4.4 安装插件语句

15.7.4.5 卸载组件语句

15.7.4.6 卸载插件语句

原文:dev.mysql.com/doc/refman/8.0/en/create-function-loadable.html

15.7.4.1 可加载函数的 CREATE FUNCTION 语句

CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] *function_name*
    RETURNS {STRING|INTEGER|REAL|DECIMAL}
    SONAME *shared_library_name*

这个语句加载了名为*function_name*的可加载函数。(CREATE FUNCTION也用于创建存储函数;请参阅 Section 15.1.17, “CREATE PROCEDURE and CREATE FUNCTION Statements”.)

可加载函数是通过新函数扩展 MySQL 的一种方式,其工作方式类似于本机(内置)MySQL 函数,如ABS()CONCAT()。请参阅添加可加载函数。

*function_name*是应在 SQL 语句中使用的名称来调用函数。RETURNS子句指示函数返回值的类型。DECIMALRETURNS后的合法值,但当前DECIMAL函数返回字符串值,应该像STRING函数一样编写。

IF NOT EXISTS可以防止出现错误,如果已经存在具有相同名称的可加载函数。它会防止出现错误,如果已经存在具有相同名称的内置函数。IF NOT EXISTS支持从 MySQL 8.0.29 开始的CREATE FUNCTION语句。另请参阅函数名称解析。

如果指定了AGGREGATE关键字,则表示该函数是一个聚合(组)函数。聚合函数的工作方式与本机 MySQL 聚合函数(如SUM()COUNT())完全相同。

*shared_library_name*是包含实现函数代码的共享库文件的基本名称。该文件必须位于插件目录中。此目录由plugin_dir系统变量的值给出。有关更多信息,请参阅 Section 7.7.1, “Installing and Uninstalling Loadable Functions”.

CREATE FUNCTION需要对mysql系统模式具有INSERT权限,因为它向mysql.func系统表添加一行以注册函数。

CREATE FUNCTION还将函数添加到提供有关已安装可加载函数的运行时信息的性能模式user_defined_functions表中。请参阅 Section 29.12.21.10, “The user_defined_functions Table”。

注意

mysql.func系统表类似,性能模式user_defined_functions表列出使用CREATE FUNCTION安装的可加载函数。与mysql.func表不同,user_defined_functions表还列出服务器组件或插件自动安装的可加载函数。这种差异使得user_defined_functionsmysql.func更适合检查已安装的可加载函数。

在正常启动序列期间,服务器加载在mysql.func表中注册的函数。如果使用--skip-grant-tables选项启动服务器,则表中注册的函数不会加载且不可用。

注意

要升级与可加载函数关联的共享库,请发出DROP FUNCTION语句,升级共享库,然后发出CREATE FUNCTION语句。如果您先升级共享库,然后使用DROP FUNCTION,服务器可能会意外关闭。

原文:dev.mysql.com/doc/refman/8.0/en/drop-function-loadable.html

15.7.4.2 DROP FUNCTION Statement for Loadable Functions

DROP FUNCTION [IF EXISTS] *function_name*

此语句删除名为 function_name 的可加载函数。(DROP FUNCTION 也用于删除存储函数;请参阅 Section 15.1.29, “DROP PROCEDURE and DROP FUNCTION Statements”.)

DROP FUNCTIONCREATE FUNCTION 的补充。它需要 mysql 系统模式的 DELETE 权限,因为它会从注册函数的 mysql.func 系统表中删除行。

DROP FUNCTION 还会从性能模式 user_defined_functions 表中删除提供有关已安装可加载函数的运行时信息的函数。请参阅 Section 29.12.21.10, “The user_defined_functions Table”.

在正常启动序列期间,服务器会加载在 mysql.func 表中注册的函数。因为 DROP FUNCTION 删除了被删除函数的 mysql.func 行,所以服务器在后续重新启动时不会加载该函数。

DROP FUNCTION 不能用于删除由组件或插件自动安装而不是使用 CREATE FUNCTION 安装的可加载函数。这样的函数在卸载安装它的组件或插件时也会自动删除。

注意

要升级与可加载函数关联的共享库,请发出 DROP FUNCTION 语句,升级共享库,然后发出 CREATE FUNCTION 语句。如果先升级共享库,然后使用 DROP FUNCTION,服务器可能会意外关闭。

原文:dev.mysql.com/doc/refman/8.0/en/install-component.html

15.7.4.3 INSTALL COMPONENT 语句

INSTALL COMPONENT *component_name*  [, *component_name* ...
     [SET *variable* = *expr* [, *variable* = *expr*] ...] 

  *variable*: {
    {GLOBAL | @@GLOBAL.} [*component_prefix*.]*system_var_name*
  | {PERSIST | @@PERSIST.} [*component_prefix*.]*system_var_name*
}

此语句安装一个或多个组件,这些组件立即生效。组件提供服务器和其他组件可用的服务;请参阅第 7.5 节,“MySQL 组件”。INSTALL COMPONENT需要对mysql.component系统表具有INSERT权限,因为它向该表添加一行以注册组件。

示例:

INSTALL COMPONENT 'file://component1', 'file://component2';

组件使用以file://开头的 URN 命名,指示实现组件的库文件的基本名称,位于由plugin_dir系统变量命名的目录中。组件名称不包括任何平台相关的文件名后缀,如.so.dll。(这些命名细节可能会发生变化,因为组件名称的解释本身是由一个服务执行的,并且组件基础设施使得可以用替代实现替换默认服务实现。)

INSTALL COMPONENT(从 8.0.33 版本开始)允许在安装一个或多个组件时设置组件系统变量的值。SET子句使您能够在需要时精确指定变量值,而不会受到其他形式赋值的不便或限制。具体来说,您还可以使用以下替代方法设置组件变量:

  • 在服务器启动时使用命令行选项或选项文件,但这样做需要重新启动服务器。在安装组件之前,这些值不会生效。您可以在命令行上为组件指定一个无效的变量名而不会触发错误。

  • 在服务器运行时通过SET语句动态设置,这使您可以修改服务器的操作而无需停止和重新启动。不允许设置只读变量。

可选的SET子句仅将一个值或多个值应用于INSTALL COMPONENT语句中指定的组件,而不是应用于该组件的所有后续安装。SET GLOBAL|PERSIST适用于所有类型的变量,包括只读变量,而无需重新启动服务器。使用INSTALL COMPONENT设置的组件系统变量优先于来自命令行或选项文件的任何冲突值。

示例:

INSTALL COMPONENT 'file://component1', 'file://component2' 
    SET GLOBAL component1.var1 = 12 + 3, PERSIST component2.var2 = 'strings';

省略PERSISTGLOBAL等同于指定GLOBAL

SET 中为任何变量指定 PERSIST 会在 INSTALL COMPONENT 加载组件后立即执行 SET PERSIST_ONLY,但在更新 mysql.component 表之前。如果 SET PERSIST_ONLY 失败,则服务器会卸载所有先前加载的新组件,而不会将任何内容持久化到 mysql.component

SET 子句仅接受正在安装的组件的有效变量名称,并对所有无效名称发出错误消息。子查询、存储函数和聚合函数不允许作为值表达式的一部分。如果安装单个组件,则不需要使用组件名称作为变量名称的前缀。

注意

使用 SET 子句指定变量值与命令行类似——在变量注册时立即可用——但 SET 子句在处理布尔变量的 无效数值 时有明显差异。例如,如果将布尔变量设置为 11(component1.boolvar = 11),您会看到以下行为:

  • SET 子句返回 true

  • 命令行返回 false(11 既不是 ON 也不是 1)

如果发生任何错误,语句将失败且不会产生任何效果。例如,如果组件名称错误,命名组件不存在或已安装,或组件初始化失败,则会发生这种情况。

加载服务处理组件加载,包括将已安装的组件添加到作为注册表的 mysql.component 系统表。对于后续的服务器重启,mysql.component 中列出的任何组件都将在启动序列期间由加载服务加载。即使服务器使用 --skip-grant-tables 选项启动也会发生这种情况。

如果一个组件依赖于注册表中不存在的服务,并且您尝试安装该组件而没有安装提供所依赖服务的组件或组件,则会发生错误:

ERROR 3527 (HY000): Cannot satisfy dependency for service 'component_a'
required by component 'component_b'.

要避免此问题,要么在同一语句中安装所有组件,要么在安装任何依赖的组件之后安装依赖组件。

注意

对于密钥环组件,请勿使用 INSTALL COMPONENT。而是使用清单文件配置密钥环组件加载。参见 Section 8.4.4.2, “Keyring Component Installation”。

原文:dev.mysql.com/doc/refman/8.0/en/install-plugin.html

15.7.4.4 安装插件语句

INSTALL PLUGIN *plugin_name* SONAME '*shared_library_name*'

此语句安装服务器插件。它需要对mysql.plugin系统表的INSERT权限,因为它向该表添加一行以注册插件。

plugin_name 是插件的名称,定义在库文件中包含的插件描述符结构中(参见插件数据结构)。插件名称不区分大小写。为了最大兼容性,插件名称应该限制为 ASCII 字母、数字和下划线,因为它们在 C 源文件、shell 命令行、M4 和 Bourne shell 脚本以及 SQL 环境中使用。

shared_library_name 是包含插件代码的共享库的名称。该名称包括文件名扩展名(例如,libmyplugin.solibmyplugin.dll,或 libmyplugin.dylib)。

共享库必须位于插件目录中(由plugin_dir系统变量命名的目录)。库必须位于插件目录本身,而不是子目录中。默认情况下,plugin_dir是由pkglibdir配置变量命名的目录下的plugin目录,但可以通过在服务器启动时设置plugin_dir的值来更改。例如,在my.cnf文件中设置其值:

[mysqld]
plugin_dir=*/path/to/plugin/directory*

如果plugin_dir的值是相对路径名,则被视为相对于 MySQL 基本目录(basedir系统变量的值)。

INSTALL PLUGIN 加载并初始化插件代码,使插件可供使用。插件通过执行其初始化函数进行初始化,该函数处理插件在可以使用之前必须执行的任何设置。当服务器关闭时,它会执行每个已加载插件的去初始化函数,以便插件有机会执行任何最终清理。

INSTALL PLUGIN还通过向mysql.plugin系统表添加指示插件名称和库文件名的行来注册插件。在正常启动序列期间,服务器加载和初始化在mysql.plugin中注册的插件。这意味着插件仅通过INSTALL PLUGIN安装一次,而不是每次服务器启动时都安装。如果使用--skip-grant-tables选项启动服务器,则在mysql.plugin表中注册的插件不会被加载,也无法使用。

插件库可以包含多个插件。为了安装每个插件,使用单独的INSTALL PLUGIN语句。每个语句命名不同的插件,但它们都指定相同的库名称。

INSTALL PLUGIN会导致服务器在启动时读取选项(my.cnf)文件,使得插件可以从这些文件中获取任何相关选项。甚至可以在加载插件之前将插件选项添加到选项文件中(如果使用loose前缀)。也可以卸载插件,编辑my.cnf,然后再次安装插件。通过这种方式重新启动插件,使其能够在无需重新启动服务器的情况下使用新的选项值。

对于控制单个插件在服务器启动时加载的选项,请参阅第 7.6.1 节,“安装和卸载插件”。如果需要在给定--skip-grant-tables选项(告诉服务器不要读取系统表)的情况下为单个服务器启动加载插件,请使用--plugin-load选项。请参阅第 7.1.7 节,“服务器命令选项”。

要移除插件,请使用UNINSTALL PLUGIN语句。

有关插件加载的其他信息,请参阅第 7.6.1 节,“安装和卸载插件”。

要查看已安装的插件,请使用SHOW PLUGINS语句或查询INFORMATION_SCHEMAPLUGINS表。

如果重新编译插件库并需要重新安装它,可以使用以下任一方法:

  • 使用UNINSTALL PLUGIN命令卸载库中的所有插件,将新的插件库文件安装到插件目录中,然后使用INSTALL PLUGIN命令安装库中的所有插件。这个过程的优点是可以在不停止服务器的情况下使用。然而,如果插件库包含许多插件,您必须发出许多INSTALL PLUGINUNINSTALL PLUGIN命令。

  • 停止服务器,将新的插件库文件安装到插件目录中,然后重新启动服务器。

原文:dev.mysql.com/doc/refman/8.0/en/uninstall-component.html

15.7.4.5 UNINSTALL COMPONENT Statement

UNINSTALL COMPONENT *component_name* [, *component_name* ] ...

此语句停用并卸载一个或多个组件。组件提供服务器和其他组件可用的服务;请参阅 Section 7.5, “MySQL Components”。UNINSTALL COMPONENTINSTALL COMPONENT的补充。它需要对mysql.component系统表具有DELETE权限,因为它会从注册组件的表中删除行。UNINSTALL COMPONENT不会撤消已持久化的变量,包括使用INSTALL COMPONENT ... SET PERSIST持久化的变量。

示例:

UNINSTALL COMPONENT 'file://component1', 'file://component2';

有关组件命名的信息,请参阅 Section 15.7.4.3, “INSTALL COMPONENT Statement”。

如果发生任何错误,该语句将失败且不起作用。例如,如果组件名称错误,未安装命名组件或无法卸载因为其他已安装的组件依赖于它。

一个加载程序服务处理组件卸载,包括从作为注册表的mysql.component系统表中删除已卸载的组件。因此,在后续服务器重新启动的启动序列中不会加载已卸载的组件。

注意

此语句对于使用清单文件加载的密钥环组件没有效果,并且无法卸载。请参阅 Section 8.4.4.2, “Keyring Component Installation”。

原文:dev.mysql.com/doc/refman/8.0/en/uninstall-plugin.html

15.7.4.6 UNINSTALL PLUGIN Statement

UNINSTALL PLUGIN *plugin_name*

此语句移除已安装的服务器插件。UNINSTALL PLUGININSTALL PLUGIN的补充。它需要对mysql.plugin系统表的DELETE权限,因为它会从该表中删除注册插件的行。

*plugin_name*必须是mysql.plugin表中列出的某个插件的名称。服务器执行插件的去初始化函数,并从mysql.plugin系统表中删除插件的行,以便后续服务器重新启动时不加载和初始化插件。UNINSTALL PLUGIN不会删除插件的共享库文件。

如果使用插件的任何表是打开状态,则无法卸载插件。

插件的移除对关联表的使用有影响。例如,如果一个全文解析器插件与表上的FULLTEXT索引相关联,卸载插件会使表无法使用。任何尝试访问该表的操作都会导致错误。甚至无法打开表,因此无法删除使用该插件的索引。这意味着慎重卸载插件,除非你不在乎表的内容。如果你打算卸载插件而不打算以后重新安装它,并且你关心表的内容,你应该使用mysqldump导出表,并从导出的CREATE TABLE语句中删除WITH PARSER子句,以便以后重新加载表。如果你不在乎表,即使表上关联的插件丢失,也可以使用DROP TABLE

有关插件加载的更多信息,请参见 Section 7.6.1, “Installing and Uninstalling Plugins”。

15.7.5 CLONE 语句

原文:dev.mysql.com/doc/refman/8.0/en/clone.html

CLONE *clone_action*

*clone_action*: {
    LOCAL DATA DIRECTORY [=] '*clone_dir*';
  | INSTANCE FROM '*user*'@'*host*':*port*
    IDENTIFIED BY '*password*'
    [DATA DIRECTORY [=] '*clone_dir*']
    [REQUIRE [NO] SSL]
}

CLONE 语句用于在本地或从远程 MySQL 服务器实例克隆数据。要使用CLONE 语法,必须安装克隆插件。请参见 Section 7.6.7, “克隆插件”。

CLONE LOCAL DATA DIRECTORY 语法从本地 MySQL 数据目录克隆数据到 MySQL 服务器实例运行的同一服务器或节点上的目录。'clone_dir' 目录是数据克隆到的本地目录的完整路径。需要绝对路径。指定的目录不能存在,但指定的路径必须是现有路径。MySQL 服务器需要必要的写入权限以创建指定目录。有关更多信息,请参见 Section 7.6.7.2, “本地克隆数据”。

CLONE INSTANCE 语法从远程 MySQL 服务器实例(捐赠方)克隆数据并将其传输到启动克隆操作的 MySQL 实例(接收方)。

  • *user* 是在捐赠 MySQL 服务器实例上的克隆用户。

  • *host* 是捐赠 MySQL 服务器实例的hostname地址。不支持 Internet Protocol version 6 (IPv6) 地址格式。可以使用 IPv6 地址的别名。IPv4 地址可以直接使用。

  • *port* 是捐赠 MySQL 服务器实例的port号。 (不支持由mysqlx_port指定的 X 协议端口。也不支持通过 MySQL Router 连接到捐赠 MySQL 服务器实例。)

  • IDENTIFIED BY '*password*' 指定捐赠 MySQL 服务器实例上克隆用户的密码。

  • DATA DIRECTORY [=] '*clone_dir*' 是一个可选子句,用于指定在接收方用于克隆数据的目录。如果您不想删除接收方数据目录中的现有数据,请使用此选项。需要绝对路径,并且目录不能存在。MySQL 服务器必须具有必要的写入权限以创建目录。

    当不使用可选的 DATA DIRECTORY [=] '*clone_dir*' 子句时,克隆操作会删除接收方数据目录中的现有数据,用克隆数据替换它,并在之后自动重新启动服务器。

  • [REQUIRE [NO] SSL]明确指定在通过网络传输克隆数据时是否使用加密连接。如果无法满足明确规定,将返回错误。如果未指定 SSL 子句,克隆尝试默认建立加密连接,如果安全连接尝试失败,则回退到不安全连接。无论是否指定此子句,克隆加密数据时都需要安全连接。有关更多信息,请参见为克隆配置加密连接。

关于从远程 MySQL 服务器实例克隆数据的更多信息,请参见 Section 7.6.7.3, “Cloning Remote Data”。

15.7.6 设置语句

原文:dev.mysql.com/doc/refman/8.0/en/set-statement.html

15.7.6.1 变量赋值的 SET 语法

15.7.6.2 设置 CHARACTER SET 语句

15.7.6.3 设置 NAMES 语句

SET 语句有几种形式。那些与特定服务器功能不相关的形式的描述出现在本节的子部分中:

  • SET *var_name* = *value* 允许您为影响服务器或客户端操作的变量分配值。参见 第 15.7.6.1 节,“变量赋值的 SET 语法”。

  • SET CHARACTER SETSET NAMES 为与服务器当前连接相关的字符集和校对变量分配值。参见 第 15.7.6.2 节,“设置字符集语句”,以及 第 15.7.6.3 节,“设置 NAMES 语句”。

其他形式的描述出现在其他地方,与帮助实现它们的其他语句分组在一起:

  • SET DEFAULT ROLESET ROLE 设置用户账户的默认角色和当前角色。参见 第 15.7.1.9 节,“设置默认角色语句”,以及 第 15.7.1.11 节,“设置角色语句”。

  • SET PASSWORD 用于分配账户密码。参见 第 15.7.1.10 节,“设置密码语句”。

  • SET RESOURCE GROUP 为线程分配资源组。参见 第 15.7.2.4 节,“设置资源组语句”。

  • SET TRANSACTION ISOLATION LEVEL 用于设置事务处理的隔离级别。参见 第 15.3.7 节,“设置事务语句”。

原文:dev.mysql.com/doc/refman/8.0/en/set-variable.html

15.7.6.1 SET 变量赋值语法

SET *variable* = *expr* [, *variable* = *expr*] ...

*variable*: {
    *user_var_name*
  | *param_name*
  | *local_var_name*
  | {GLOBAL | @@GLOBAL.} *system_var_name*
  | {PERSIST | @@PERSIST.} *system_var_name*
  | {PERSIST_ONLY | @@PERSIST_ONLY.} *system_var_name*
  | [SESSION | @@SESSION. | @@] *system_var_name*
}

SET语法用于分配值给不同类型的变量,影响服务器或客户端的操作:

  • 用户定义的变量。参见第 11.4 节,“用户定义的变量”。

  • 存储过程和函数参数,以及存储程序局部变量。参见第 15.6.4 节,“存储程序中的变量”。

  • 系统变量。参见第 7.1.8 节,“服务器系统变量”。系统变量也可以在服务器启动时设置,如第 7.1.9 节,“使用系统变量”所述。

一个SET语句分配变量值不会写入二进制日志,因此在复制场景中仅影响执行该语句的主机。要影响所有复制主机,请在每个主机上执行该语句。

以下各节描述了用于设置变量的SET语法。它们使用=赋值运算符,但:=赋值运算符也可用于此目的。

  • 用户定义的变量赋值

  • 参数和局部变量赋值

  • 系统变量赋值

  • SET 错误处理

  • 多变量赋值

  • 表达式中的系统变量引用

用户定义的变量赋值

用户定义的变量在会话内部局部创建,仅在该会话的上下文中存在;参见第 11.4 节,“用户定义的变量”。

用户定义的变量写作@*var_name*,并按以下方式分配表达式值:

SET @*var_name* = *expr*;

示例:

SET @name = 43;
SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);

正如这些语句所示,*expr*可以从简单(字面值)到更复杂(标量子查询返回的值)。

Performance Schema user_variables_by_thread 表包含有关用户定义变量的信息。请参阅 Section 29.12.10, “Performance Schema User-Defined Variable Tables”。

参数和局部变量赋值

SET 适用于存储对象内部定义的参数和局部变量。以下过程使用了increment过程参数和counter局部变量:

CREATE PROCEDURE p(increment INT)
BEGIN
  DECLARE counter INT DEFAULT 0;
  WHILE counter < 10 DO
    -- ... do work ...
    SET counter = counter + increment;
  END WHILE;
END;
系统变量赋值

MySQL 服务器维护配置其操作的系统变量。系统变量可以具有影响整个服务器操作的全局值,影响当前会话的会话值,或两者都有。许多系统变量是动态的,可以使用SET语句在运行时更改,以影响当前服务器实例的操作。SET还可以用于将某些系统变量持久化到数据目录中的mysqld-auto.cnf文件中,以影响后续启动的服务器操作。

如果对敏感系统变量发出SET语句,则在将其记录到一般日志和审计日志之前,查询将被重写以用“<redacted>”替换值。即使在服务器实例上没有通过密钥环组件进行安全存储,这也会发生。

如果更改会话系统变量,则该值在您的会话中保持有效,直到您将变量更改为不同的值或会话结束。更改对其他会话没有影响。

如果更改全局系统变量,则该值将被记住,并用于初始化新会话的会话值,直到您将变量更改为不同的值或服务器退出。更改对访问全局值的任何客户端都是可见的。但是,更改仅影响在更改后连接的客户端的相应会话值。全局变量更改不会影响任何当前客户端会话的会话值(甚至不会影响进行全局值更改的会话)。

要使全局系统变量设置永久生效,以便在服务器重新启动时应用,您可以将其持久化到数据目录中的mysqld-auto.cnf文件中。也可以通过手动修改my.cnf选项文件来进行持久化配置更改,但这样做更加繁琐,手动输入设置中的错误可能要等到很久之后才能发现。持久化系统变量的SET语句更加方便,避免了设置语法错误的可能性,因为具有语法错误的设置不会成功,也不会更改服务器配置。有关持久化系统变量和mysqld-auto.cnf文件的更多信息,请参见第 7.1.9.3 节,“持久化系统变量”。

注意

设置或持久化全局系统变量值始终需要特殊权限。通常设置会话系统变量值不需要特殊权限,任何用户都可以执行,尽管也有例外情况。有关更多信息,请参见第 7.1.9.1 节,“系统变量权限”。

以下讨论描述了设置和持久化系统变量的语法选项:

  • 要为全局系统变量分配一个值,请在变量名称之前加上GLOBAL关键字或@@GLOBAL.修饰符:

    SET GLOBAL max_connections = 1000;
    SET @@GLOBAL.max_connections = 1000;
    
  • 要为会话系统变量分配一个值,请在变量名称之前加上SESSIONLOCAL关键字,或者使用@@SESSION.@@LOCAL.@@修饰符,或者根本不使用关键字或修饰符:

    SET SESSION sql_mode = 'TRADITIONAL';
    SET LOCAL sql_mode = 'TRADITIONAL';
    SET @@SESSION.sql_mode = 'TRADITIONAL';
    SET @@LOCAL.sql_mode = 'TRADITIONAL';
    SET @@sql_mode = 'TRADITIONAL';
    SET sql_mode = 'TRADITIONAL';
    

    客户端可以更改自己的会话变量,但不能更改任何其他客户端的变量。

  • 要将全局系统变量持久化到数据目录中的mysqld-auto.cnf选项文件中,请在变量名称之前加上PERSIST关键字或@@PERSIST.修饰符:

    SET PERSIST max_connections = 1000;
    SET @@PERSIST.max_connections = 1000;
    

    SET语法允许您在运行时进行配置更改,这些更改也会在服务器重新启动时保留。与SET GLOBAL类似,SET PERSIST设置全局变量的运行时值,并将变量设置写入mysqld-auto.cnf文件(如果存在任何现有变量设置,则会替换)。

  • 要将全局系统变量持久化到mysqld-auto.cnf文件中,而不设置全局变量的运行时值,请在变量名称之前加上PERSIST_ONLY关键字或@@PERSIST_ONLY.修饰符:

    SET PERSIST_ONLY back_log = 100;
    SET @@PERSIST_ONLY.back_log = 100;
    

    PERSIST类似,PERSIST_ONLY将变量设置写入mysqld-auto.cnf。但是,与PERSIST不同,PERSIST_ONLY不会修改全局变量的运行时值。这使得PERSIST_ONLY适用于配置只能在服务器启动时设置的只读系统变量。

要将全局系统变量值设置为编译时 MySQL 默认值或会话系统变量设置为当前对应的全局值,将变量设置为值 DEFAULT。例如,以下两个语句在将 max_join_size 的会话值设置为当前全局值时是相同的:

SET @@SESSION.max_join_size = DEFAULT;
SET @@SESSION.max_join_size = @@GLOBAL.max_join_size;

使用 SET 来将全局系统变量持久化为 DEFAULT 值或其字面默认值,会将变量赋予其默认值并在 mysqld-auto.cnf 中添加变量的设置。要从文件中移除变量,使用 RESET PERSIST

一些系统变量无法持久化或者受到持久化限制。参见第 7.1.9.4 节,“不可持久化和受限制持久化的系统变量”。

如果插件在执行 SET 语句时已安装,则插件实现的系统变量可以持久化。如果插件仍然安装,则持久化插件变量的赋值会在后续服务器重启时生效。如果插件不再安装,则当服务器读取 mysqld-auto.cnf 文件时,插件变量将不再存在。在这种情况下,服务器会向错误日志写入警告并继续:

currently unknown variable '*var_name*'
was read from the persisted config file

要显示系统变量名称和值:

  • 使用 SHOW VARIABLES 语句;参见第 15.7.7.41 节,“SHOW VARIABLES 语句”。

  • 几个 Performance Schema 表提供系统变量信息。参见第 29.12.14 节,“Performance Schema System Variable Tables”。

  • Performance Schema variables_info 表包含了显示每个系统变量最近由哪个用户何时设置的信息。参见第 29.12.14.2 节,“Performance Schema variables_info Table”。

  • Performance Schema persisted_variables 表提供了一个 SQL 接口来访问 mysqld-auto.cnf 文件,使得可以在运行时使用 SELECT 语句检查其内容。参见第 29.12.14.1 节,“Performance Schema persisted_variables Table”。

设置错误处理

如果SET语句中的任何变量赋值失败,则整个语句失败,变量不会更改,mysqld-auto.cnf文件也不会更改。

SET在这里描述的情况下会产生错误。大多数示例显示使用关键字语法的SET语句(例如,GLOBALSESSION),但这些原则也适用于使用相应修饰符的语句(例如,@@GLOBAL.@@SESSION.)。

  • 使用SET(任何变体)设置只读变量:

    mysql> SET GLOBAL version = 'abc';
    ERROR 1238 (HY000): Variable 'version' is a read only variable
    
  • 使用GLOBALPERSISTPERSIST_ONLY设置仅具有会话值的变量:

    mysql> SET GLOBAL sql_log_bin = ON;
    ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION
    variable and can't be used with SET GLOBAL
    
  • 使用SESSION设置仅具有全局值的变量:

    mysql> SET SESSION max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
    
  • 省略GLOBALPERSISTPERSIST_ONLY以设置仅具有全局值的变量:

    mysql> SET max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
    
  • 使用PERSISTPERSIST_ONLY设置无法持久化的变量:

    mysql> SET PERSIST port = 3307;
    ERROR 1238 (HY000): Variable 'port' is a read only variable
    mysql> SET PERSIST_ONLY port = 3307;
    ERROR 1238 (HY000): Variable 'port' is a non persistent read only variable
    
  • @@GLOBAL.@@PERSIST.@@PERSIST_ONLY.@@SESSION.@@修饰符仅适用于系统变量。尝试将它们应用于用户定义的变量、存储过程或函数参数或存储程序本地变量会导致错误。

  • 并非所有系统变量都可以设置为DEFAULT。在这种情况下,分配DEFAULT会导致错误。

  • 尝试将DEFAULT分配给用户定义的变量、存储过程或函数参数或存储程序本地变量会导致错误。

多变量赋值

一个SET语句可以包含多个变量赋值,用逗号分隔。此语句将值分配给用户定义的变量和系统变量:

SET @x = 1, SESSION sql_mode = '';

如果在单个语句中设置多个系统变量,则该语句中最近的GLOBALPERSISTPERSIST_ONLYSESSION关键字用于后续未指定关键字的赋值。

多变量赋值的示例:

SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;
SET @@GLOBAL.sort_buffer_size = 1000000, @@LOCAL.sort_buffer_size = 1000000;
SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;

@@GLOBAL.@@PERSIST.@@PERSIST_ONLY.@@SESSION.@@修饰符仅适用于紧接着的系统变量,而不适用于任何剩余的系统变量。此语句将sort_buffer_size全局值设置为 50000,会话值设置为 1000000:

SET @@GLOBAL.sort_buffer_size = 50000, sort_buffer_size = 1000000;
表达式中的系统变量引用

要在表达式中引用系统变量的值,请使用@@修饰符之一(除了在表达式中不允许使用@@PERSIST.@@PERSIST_ONLY.)。例如,您可以在SELECT语句中像这样检索系统变量的值:

SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode, @@sql_mode;

注意

在表达式中引用系统变量作为@@*var_name*(使用@@而不是@@GLOBAL.@@SESSION.)如果存在会返回会话值,否则返回全局值。这与SET @@*var_name* = *expr*不同,后者始终引用会话值。

原文:dev.mysql.com/doc/refman/8.0/en/set-character-set.html

15.7.6.2 SET CHARACTER SET Statement

SET {CHARACTER SET | CHARSET}
    {'*charset_name*' | DEFAULT}

此语句将服务器和当前客户端之间发送的所有字符串与给定映射进行映射。SET CHARACTER SET设置三个会话系统变量:character_set_clientcharacter_set_results设置为给定的字符集,character_set_connection设置为character_set_database的值。请参阅第 12.4 节,“连接字符集和校对”。

*charset_name*可以带引号或不带引号。

默认字符集映射可以通过使用值DEFAULT来恢复。默认值取决于服务器配置。

一些字符集不能作为客户端字符集使用。尝试与SET CHARACTER SET一起使用会产生错误。请参阅不允许的客户端字符集。

原文:dev.mysql.com/doc/refman/8.0/en/set-names.html

15.7.6.3 SET NAMES 语句

SET NAMES {'*charset_name*'
    [COLLATE '*collation_name*'] | DEFAULT}

这个语句将三个会话系统变量character_set_clientcharacter_set_connection,和character_set_results设置为给定的字符集。将character_set_connection设置为charset_name也会将collation_connection设置为charset_name的默认排序规则。参见第 12.4 节,“连接字符集和排序规则”。

可选的COLLATE子句可用于显式指定排序规则。如果提供,排序规则必须是*charset_name*允许的排序规则之一。

*charset_namecollation_name*可以带引号或不带引号。

默认映射可以通过使用DEFAULT值来恢复。默认值取决于服务器配置。

一些字符集不能用作客户端字符集。尝试与SET NAMES一起使用它们会产生错误。参见不允许的客户端字符集。

15.7.7 显示语句

原文:dev.mysql.com/doc/refman/8.0/en/show.html

15.7.7.1 显示二进制日志语句

15.7.7.2 显示二进制日志事件语句

15.7.7.3 显示字符集语句

15.7.7.4 显示排序规则语句

15.7.7.5 显示列语句

15.7.7.6 显示创建数据库语句

15.7.7.7 显示创建事件语句

15.7.7.8 显示创建函数语句

15.7.7.9 显示创建存储过程语句

15.7.7.10 显示创建表语句

15.7.7.11 显示创建触发器语句

15.7.7.12 显示创建用户语句

15.7.7.13 显示创建视图语句

15.7.7.14 显示数据库语句

15.7.7.15 显示引擎语句

15.7.7.16 显示引擎语句

15.7.7.17 显示错误语句

15.7.7.18 显示事件语句

15.7.7.19 显示函数代码语句

15.7.7.20 显示函数状态语句

15.7.7.21 显示授权语句

15.7.7.22 显示索引语句

15.7.7.23 显示主状态语句

15.7.7.24 显示打开表语句

15.7.7.25 显示插件语句

15.7.7.26 显示权限语句

15.7.7.27 显示存储过程代码语句

15.7.7.28 显示存储过程状态语句

15.7.7.29 显示进程列表语句

15.7.7.30 显示概要语句

15.7.7.31 显示概要语句

15.7.7.32 显示中继日志事件语句

15.7.7.33 显示副本语句

15.7.7.34 显示从属主机 | 显示副本语句

15.7.7.35 显示副本状态语句

15.7.7.36 显示从属 | 副本状态语句

15.7.7.37 显示状态语句

[15.7.7.38 显示表状态语句] (show-table-status.html)

15.7.7.39 显示表语句

15.7.7.40 显示触发器语句

15.7.7.41 显示变量��句

15.7.7.42 显示警告语句

显示有许多形式,提供关于数据库、表、列或服务器状态信息的信息。本节描述了以下内容:

SHOW {BINARY | MASTER} LOGS
SHOW BINLOG EVENTS [IN '*log_name*'] [FROM *pos*] [LIMIT [*offset*,] *row_count*]
SHOW {CHARACTER SET | CHARSET} [*like_or_where*]
SHOW COLLATION [*like_or_where*]
SHOW [FULL] COLUMNS FROM *tbl_name* [FROM *db_name*] [*like_or_where*]
SHOW CREATE DATABASE *db_name*
SHOW CREATE EVENT *event_name*
SHOW CREATE FUNCTION *func_name*
SHOW CREATE PROCEDURE *proc_name*
SHOW CREATE TABLE *tbl_name*
SHOW CREATE TRIGGER *trigger_name*
SHOW CREATE VIEW *view_name*
SHOW DATABASES [*like_or_where*]
SHOW ENGINE *engine_name* {STATUS | MUTEX}
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [*offset*,] *row_count*]
SHOW EVENTS
SHOW FUNCTION CODE *func_name*
SHOW FUNCTION STATUS [*like_or_where*]
SHOW GRANTS FOR *user*
SHOW INDEX FROM *tbl_name* [FROM *db_name*]
SHOW MASTER STATUS
SHOW OPEN TABLES [FROM *db_name*] [*like_or_where*]
SHOW PLUGINS
SHOW PROCEDURE CODE *proc_name*
SHOW PROCEDURE STATUS [*like_or_where*]
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW PROFILE [*types*] [FOR QUERY *n*] [OFFSET *n*] [LIMIT *n*]
SHOW PROFILES
SHOW RELAYLOG EVENTS [IN '*log_name*'] [FROM *pos*] [LIMIT [*offset*,] *row_count*]
SHOW {REPLICAS | SLAVE HOSTS}
SHOW {REPLICA | SLAVE} STATUS [FOR CHANNEL *channel*]
SHOW [GLOBAL | SESSION] STATUS [*like_or_where*]
SHOW TABLE STATUS [FROM *db_name*] [*like_or_where*]
SHOW [FULL] TABLES [FROM *db_name*] [*like_or_where*]
SHOW TRIGGERS [FROM *db_name*] [*like_or_where*]
SHOW [GLOBAL | SESSION] VARIABLES [*like_or_where*]
SHOW WARNINGS [LIMIT [*offset*,] *row_count*]

*like_or_where*: {
    LIKE '*pattern*'
  | WHERE *expr*
}

如果给定的 SHOW 语句的语法包括一个 LIKE '*pattern*' 部分,'*pattern*' 是一个字符串,可以包含 SQL 中的 %_ 通配符。该模式对于将语句输出限制为匹配值非常有用。

几个 SHOW 语句还接受一个 WHERE 子句,以提供更灵活的指定要显示哪些行的方式。请参阅 第 28.8 节,“SHOW Statements 的扩展”。

SHOW 语句的结果中,用户名称和主机名使用反引号(`)引用。

许多 MySQL API(如 PHP)使您可以将从 SHOW 语句返回的结果视为从 SELECT 返回的结果集一样处理;请参阅 第三十一章,Connectors and APIs,或者查看您的 API 文档以获取更多信息。此外,您可以在 SQL 中使用来自 INFORMATION_SCHEMA 数据库表查询的结果,而这是您无法轻松使用 SHOW 语句的结果所能做到的。请参阅 第二十八章,INFORMATION_SCHEMA Tables