MySQL8 中文参考(二十)

2024-06-25 14:21:50 浏览数 (2)

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

7.1.17 服务器端帮助支持

原文:dev.mysql.com/doc/refman/8.0/en/server-side-help-support.html

MySQL 服务器支持一个HELP语句,该语句从 MySQL 参考手册中返回信息(参见 Section 15.8.3, “HELP Statement”)。这些信息存储在mysql模式的几个表中(参见 Section 7.3, “The mysql System Schema”)。HELP语句的正确操作要求这些帮助表被初始化。

对于在 Unix 上使用二进制或源发行版进行 MySQL 的新安装,帮助表内容初始化发生在初始化数据目录时(参见 Section 2.9.1, “Initializing the Data Directory”)。对于 Linux 上的 RPM 发行版或 Windows 上的二进制发行版,内容初始化作为 MySQL 安装过程的一部分发生。

对于使用二进制发行版进行 MySQL 升级,截至 MySQL 8.0.16,帮助表内容会被服务器自动升级。在 MySQL 8.0.16 之前,内容不会自动升级,但你可以手动升级。在shareshare/mysql目录中找到fill_help_tables.sql文件。进入该目录并使用mysql客户端处理文件,如下所示:

代码语言:javascript复制
mysql -u root -p mysql < fill_help_tables.sql

此处显示的命令假定你使用具有修改mysql模式中表权限的帐户(如root)连接到服务器。根据需要调整连接参数。

在 MySQL 8.0.16 之前,如果你正在使用 Git 和 MySQL 开发源码树,源码树只包含一个“存根”版本的fill_help_tables.sql。要获取非存根版本,请使用源或二进制发行版中的一个。

注意

每个 MySQL 系列都有自己系列特定的参考手册,因此帮助表内容也是系列特定的。这对于复制有影响,因为帮助表内容应该与 MySQL 系列匹配。如果你将 MySQL 8.0 帮助内容加载到 MySQL 8.0 复制服务器中,将这些内容复制到来自不同 MySQL 系列且不适用于该内容的副本服务器是没有意义的。因此,当你在复制场景中升级单个服务器时,应该根据前面给出的说明升级每个服务器的帮助表。(只有低于 8.0.16 版本的复制服务器才需要手动升级帮助内容。如前述说明所述,从 MySQL 8.0.16 开始,内容升级会自动发生。)

7.1.18 服务器跟踪客户端会话状态

译文:dev.mysql.com/doc/refman/8.0/en/session-state-tracking.html

MySQL 服务器实现了几个会话状态跟踪器。客户端可以启用这些跟踪器以接收有关其会话状态更改的通知。

  • 会话状态跟踪器的用途
  • 可用的会话状态跟踪器
  • C API 会话状态跟踪器支持
  • 测试套件会话状态跟踪支持
会话状态跟踪器的用途

会话状态跟踪器有以下用途:

  • 为了促进会话迁移。
  • 为了促进事务切换。

跟踪机制提供了一个方法,使得 MySQL 连接器和客户端应用程序能够确定是否有任何会话上下文可用,以允许会话从一个服务器迁移到另一个服务器。(在负载平衡环境中更改会话时,需要检测是否有会话状态需要考虑,以便在决定是否可以进行切换时考虑。)

跟踪机制允许应用程序知道何时可以将事务从一个会话移动到另一个会话。事务状态跟踪使这成为可能,对于可能希望将事务从繁忙服务器移动到负载较轻的服务器的应用程序很有用。例如,管理客户端连接池的负载平衡连接器可以在池中的可用会话之间移动事务。

然而,会话切换不能在任意时间进行。如果一个会话正在进行读取或写入的事务,切换到另一个会话意味着在原始会话上进行事务回滚。只有在事务尚未在其中执行任何读取或写入时才能进行会话切换。

何时可以合理地切换事务的示例:

  • 立即在START TRANSACTION之后
  • COMMIT AND CHAIN之后

除了了解事务状态外,了解事务特性也很有用,以便在将事务移动到不同会话时使用相同的特性。以下特性对此很重要:

代码语言:javascript复制
READ ONLY
READ WRITE
ISOLATION LEVEL
WITH CONSISTENT SNAPSHOT
可用的会话状态跟踪器

为了支持会话跟踪活动,可用于这些类型的客户端会话状态信息的通知:

  • 客户端会话状态的这些属性的更改:
    • 默认模式(数据库)。
    • 系统变量的会话特定值。
    • 用户定义变量。
    • 临时表。
    • 预处理语句。

    session_track_state_change 系统变量控制此跟踪。

  • 默认模式名称更改。session_track_schema 系统变量控制此跟踪。
  • 系统变量的会话值更改。session_track_system_variables 系统变量控制此跟踪。需要 SENSITIVE_VARIABLES_OBSERVER 权限来跟踪对敏感系统变量值的更改。
  • 可用的 GTID。session_track_gtids 系统变量控制此跟踪。
  • 有关事务状态和特性的信息。session_track_transaction_info 系统变量控制此跟踪。

有关与跟踪相关的系统变量的描述,请参阅 第 7.1.8 节,“服务器系统变量”。这些系统变量允许控制哪些更改通知发生,但不提供访问通知信息的方法。通知发生在 MySQL 客户端/服务器协议中,该协议在 OK 数据包中包含跟踪信息,以便检测会话状态更改。

C API 会话状态跟踪支持

为了使客户端应用程序能够从服务器返回的 OK 数据包中提取状态更改信息,MySQL C API 提供了一对函数:

  • mysql_session_track_get_first() 获取从服务器接收的状态更改信息的第一部分。请参阅 mysql_session_track_get_first()。
  • mysql_session_track_get_next() 从服务器接收的任何剩余状态更改信息。在成功调用 mysql_session_track_get_first() 后,只要它返回成功,就重复调用此函数。请参阅 mysql_session_track_get_next()。
测试套件会话状态跟踪支持

mysqltest 程序具有 disable_session_track_infoenable_session_track_info 命令,用于控制会话跟踪通知的发生。您可以使用这些命令从命令行查看 SQL 语句产生的通知。假设一个文件 testscript 包含以下 mysqltest 脚本:

代码语言:javascript复制
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (i INT, f FLOAT);
--enable_session_track_info
SET @@SESSION.session_track_schema=ON;
SET @@SESSION.session_track_system_variables='*';
SET @@SESSION.session_track_state_change=ON;
USE information_schema;
SET NAMES 'utf8mb4';
SET @@SESSION.session_track_transaction_info='CHARACTERISTICS';
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION READ WRITE;
START TRANSACTION;
SELECT 1;
INSERT INTO test.t1 () VALUES();
INSERT INTO test.t1 () VALUES(1, RAND());
COMMIT;

运行以下脚本以查看已启用跟踪器提供的信息。有关mysqltest为各种跟踪器显示的Tracker:信息的描述,请参阅 mysql_session_track_get_first()。

代码语言:javascript复制
$> mysqltest < testscript
DROP TABLE IF EXISTS test.t1;
CREATE TABLE test.t1 (i INT, f FLOAT);
SET @@SESSION.session_track_schema=ON;
SET @@SESSION.session_track_system_variables='*';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_system_variables
-- *

SET @@SESSION.session_track_state_change=ON;
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_state_change
-- ON

USE information_schema;
-- Tracker : SESSION_TRACK_SCHEMA
-- information_schema

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

SET NAMES 'utf8mb4';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- character_set_client
-- utf8mb4
-- character_set_connection
-- utf8mb4
-- character_set_results
-- utf8mb4

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

SET @@SESSION.session_track_transaction_info='CHARACTERISTICS';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- session_track_transaction_info
-- CHARACTERISTICS

-- Tracker : SESSION_TRACK_STATE_CHANGE
-- 1

-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
--

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- ________

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET TRANSACTION READ WRITE;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION READ WRITE;

START TRANSACTION;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
-- SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION READ WRITE;

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T_______

SELECT 1;
1
1
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T_____S_

INSERT INTO test.t1 () VALUES();
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T___W_S_

INSERT INTO test.t1 () VALUES(1, RAND());
-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- T___WsS_

COMMIT;
-- Tracker : SESSION_TRACK_TRANSACTION_CHARACTERISTICS
--

-- Tracker : SESSION_TRACK_TRANSACTION_STATE
-- ________

ok

START TRANSACTION语句之前,执行两个SET TRANSACTION语句,设置下一个事务的隔离级别和访问模式特性。SESSION_TRACK_TRANSACTION_CHARACTERISTICS值指示已设置的下一个事务值。

在结束事务的COMMIT语句之后,SESSION_TRACK_TRANSACTION_CHARACTERISTICS值报告为空。这表明在事务开始之前设置的下一个事务特性已被重置,并且会应用会话默认值。要跟踪这些会话默认值的更改,请跟踪transaction_isolationtransaction_read_only系统变量的会话值。

要查看有关 GTID 的信息,请使用session_track_gtids系统变量启用SESSION_TRACK_GTIDS跟踪器。

7.1.19 服务器关闭过程

原文:dev.mysql.com/doc/refman/8.0/en/server-shutdown.html

服务器关闭过程如下进行:

关闭过程被启动。

这可以通过多种方式来启动。例如,具有SHUTDOWN权限的用户可以执行mysqladmin shutdown命令。mysqladmin可以在 MySQL 支持的任何平台上使用。还有其他特定于操作系统的关闭启动方法:Unix 上的服务器在接收到SIGTERM信号时关闭。在 Windows 上作为服务运行的服务器在服务管理器告知时关闭。

如果需要,服务器会创建一个关闭线程。

根据关闭是如何启动的,服务器可能会创建一个线程来处理关闭过程。如果关闭是由客户端请求的,将创建一个关闭线程。如果关闭是由接收到SIGTERM信号导致的,信号线程可能会自行处理关闭,或者可能会创建一个单独的线程来处理。如果服务器尝试创建关闭线程但无法(例如,内存耗尽),它会发出出现在错误日志中的诊断消息:

代码语言:javascript复制
Error: Can't create thread to kill server

服务器停止接受新连接。

为了在关闭过程中防止启动新活动,服务器通过关闭通常用于接受连接的网络接口的处理程序来停止接受新的客户端连接:TCP/IP 端口,Unix 套接字文件,Windows 命名管道以及 Windows 上的共享内存。

服务器终止当前活动。

对于与客户端连接相关的每个线程,服务器会断开与客户端的连接并将线程标记为已终止。线程在注意到自己被标记后会终止。空闲连接的线程会迅速终止。当前正在处理语句的线程会定期检查其状态并需要更长时间才能终止。有关线程终止的更多信息,请参见 Section 15.7.8.4, “KILL Statement”,特别是关于在MyISAM表上执行被终止的REPAIR TABLEOPTIMIZE TABLE操作的说明。

对于具有未完成事务的线程,事务将被回滚。如果一个线程正在更新一个非事务表,例如多行UPDATEINSERT操作可能会导致表部分更新,因为操作可能在完成之前终止。

如果服务器是一个复制源服务器,它会像对待其他客户端线程一样对待与当前连接的复制品相关的线程。也就是说,每个线程都被标记为已杀死,并在下次检查其状态时退出。

如果服务器是一个复制服务器,在标记客户端线程为已杀死之前,它会停止复制 I/O 和 SQL 线程(如果它们是活动的)。SQL 线程被允许完成当前的语句(以避免引起复制问题),然后停止。如果此时 SQL 线程正在事务中,服务器会等到当前的复制事件组(如果有的话)执行完毕,或者直到用户发出KILL QUERYKILL CONNECTION语句。另请参阅第 15.4.2.9 节,“STOP SLAVE Statement”。由于非事务性语句无法回滚,为了保证崩溃安全的复制,只能使用事务性表。

注意

为了保证复制品的崩溃安全性,必须使用--relay-log-recovery参数运行复制品。

另请参阅第 19.2.4 节,“中继日志和复制元数据存储库”。

服务器关闭或关闭存储引擎。

在此阶段,服务器刷新表缓存并关闭所有打开的表。

每个存储引擎执行其管理的表所需的任何操作。InnoDB将其缓冲池刷新到磁盘(除非innodb_fast_shutdown为 2),将当前 LSN 写入表空间,并终止其自己的内部线程。MyISAM刷新任何待处理的表的索引写入。

服务器退出。

为了向管理进程提供信息,服务器返回以下列表中描述的退出代码之一。括号中的短语指示 systemd 对代码的响应动作,对于使用 systemd 管理服务器的平台。

  • 0 = 成功的终止(未重启)
  • 1 = 不成功的终止(未重启)
  • 2 = 不成功的终止(已重启)

7.2 MySQL 数据目录

原文:dev.mysql.com/doc/refman/8.0/en/data-directory.html

MySQL 服务器管理的信息存储在一个称为数据目录的目录下。以下列表简要描述了通常在数据目录中找到的项目,并提供了额外信息的交叉引用:

  • 数据目录子目录。数据目录的每个子目录都是一个数据库目录,对应于服务器管理的数据库。所有 MySQL 安装都有一些标准数据库:
    • mysql 目录对应于 mysql 系统模式,其中包含 MySQL 服务器运行所需的信息。该数据库包含数据字典表和系统表。参见 第 7.3 节,“mysql 系统模式”。
    • performance_schema 目录对应于性能模式,提供用于在运行时检查服务器内部执行的信息。参见 第二十九章,“MySQL 性能模式”。
    • sys 目录对应于 sys 模式,提供了一组对象,以帮助更轻松地解释性能模式信息。参见 第三十章,“MySQL sys 模式”。
    • ndbinfo 目录对应于存储特定于 NDB Cluster 的信息的 ndbinfo 数据库(仅适用于构建时包含 NDB Cluster 的安装)。参见 第 25.6.16 节,“ndbinfo: NDB Cluster 信息数据库”。

    其他子目录对应于用户或应用程序创建的数据库。 注意 INFORMATION_SCHEMA 是一个标准数据库,但其实现不使用相应的数据库目录。

  • 服务器写入的日志文件。参见 第 7.4 节,“MySQL 服务器日志”。
  • InnoDB 表空间和日志文件。参见 第十七章,“InnoDB 存储引擎”。
  • 默认/自动生成的 SSL 和 RSA 证书和密钥文件。参见 第 8.3.3 节,“创建 SSL 和 RSA 证书和密钥”。
  • 服务器进程 ID 文件(服务器运行时)。
  • 存储持久化全局系统变量设置的 mysqld-auto.cnf 文件。参见 第 15.7.6.1 节,“变量赋值的 SET 语法”。

先前列表中的某些项目可以通过重新配置服务器来重新定位。此外,--datadir 选项允许更改数据目录本身的位置。对于给定的 MySQL 安装,请检查服务器配置以确定是否已移动项目。

7.3 mysql 系统模式

原文:dev.mysql.com/doc/refman/8.0/en/system-schema.html

mysql模式是系统模式。它包含存储 MySQL 服务器运行所需信息的表。一个广泛的分类是,mysql模式包含存储数据库对象元数据的数据字典表,以及用于其他操作目的的系统表。以下讨论将系统表集进一步细分为更小的类别。

  • 数据字典表
  • 授权系统表
  • 对象信息系统表
  • 日志系统表
  • 服务器端帮助系统表
  • 时区系统表
  • 复制系统表
  • 优化器系统表
  • 杂项系统表

本节的其余部分列举了每个类别中的表,附带了额外信息的交叉引用。数据字典表和系统表使用InnoDB存储引擎,除非另有说明。

mysql系统表和数据字典表存储在 MySQL 数据目录中名为mysql.ibd的单个InnoDB表空间文件中。以前,这些表是在mysql数据库目录中的单独表空间文件中创建的。

可以为mysql系统模式表空间启用数据静态加密。有关更多信息,请参见第 17.13 节,“InnoDB 数据静态加密”。

数据字典表

这些表包括数据字典,其中包含有关数据库对象的元数据。有关更多信息,请参见第十六章,MySQL 数据字典

重要

数据字典是 MySQL 8.0 中的新功能。启用数据字典的服务器与之前的 MySQL 版本相比存在一些一般操作上的差异。有关详细信息,请参阅第 16.7 节,“数据字典使用差异”。此外,从 MySQL 5.7 升级到 MySQL 8.0,升级过程与之前的 MySQL 版本有所不同,并且需要您通过检查特定先决条件来验证安装的升级准备情况。有关更多信息,请参阅第三章,“升级 MySQL”,特别是第 3.6 节,“准备安装以进行升级”。

  • catalogs: 目录信息。
  • character_sets: 可用字符集的信息。
  • check_constraints: 在表上定义的CHECK约束的信息。请参阅第 15.1.20.6 节,“CHECK 约束”。
  • collations: 每个字符集的排序规则信息。
  • column_statistics: 列值的直方图统计信息。请参阅第 10.9.6 节,“优化器统计信息”。
  • column_type_elements: 列使用的类型信息。
  • columns: 表中列的信息。
  • dd_properties: 用于标识数据字典属性的表,例如其版本。服务器使用此信息来确定数据字典是否必须升级到更新版本。
  • events: 事件调度器事件的信息。请参阅第 27.4 节,“使用事件调度器”。如果服务器使用--skip-grant-tables选项启动,则事件调度器将被禁用,并且在表中注册的事件不会运行。请参阅第 27.4.2 节,“事件调度器配置”。
  • foreign_keys, foreign_key_column_usage: 外键信息。
  • index_column_usage: 索引使用的列的信息。
  • index_partitions: 索引使用的分区信息。
  • index_stats: 用于存储执行ANALYZE TABLE时生成的动态索引统计信息。
  • indexes: 表索引的信息。
  • innodb_ddl_log: 存储崩溃安全的 DDL 操作的 DDL 日志。
  • parameter_type_elements: 存储过程和函数参数以及存储函数返回值的信息。
  • parameters: 存储过程和函数的信息。请参阅第 27.2 节,“使用存储过程”。
  • resource_groups: 资源组的信息。请参阅第 7.1.16 节,“资源组”。
  • routines: 关于存储过程和函数的信息。参见 Section 27.2, “Using Stored Routines”。
  • schemata: 关于模式的信息。在 MySQL 中,模式是数据库,因此该表提供有关数据库的信息。
  • st_spatial_reference_systems: 空间数据可用的空间参考系统信息。
  • table_partition_values: 关于表分区使用的数值信息。
  • table_partitions: 表使用的分区信息。
  • table_stats: 当执行ANALYZE TABLE时生成的动态表统计信息。
  • tables: 数据库中表的信息。
  • tablespace_files: 表空间使用的文件信息。
  • tablespaces: 活动表空间的信息。
  • triggers: 触发器的信息。
  • view_routine_usage: 视图和使用它们的存储函数之间的依赖关系信息。
  • view_table_usage: 用于跟踪视图和其基础表之间的依赖关系。

数据字典表是不可见的。它们不能通过SELECT读取,不会出现在SHOW TABLES的输出中,不会在INFORMATION_SCHEMA.TABLES表中列出等等。然而,在大多数情况下,可以查询相应的INFORMATION_SCHEMA表。从概念上讲,INFORMATION_SCHEMA提供了 MySQL 公开数据字典元数据的视图。例如,您不能直接从mysql.schemata表中选择:

代码语言:javascript复制
mysql> SELECT * FROM mysql.schemata;
ERROR 3554 (HY000): Access to data dictionary table 'mysql.schemata' is rejected.

相反,从相应的INFORMATION_SCHEMA表中选择该信息:

代码语言:javascript复制
mysql> SELECT * FROM INFORMATION_SCHEMA.SCHEMATAG
*************************** 1. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: mysql
DEFAULT_CHARACTER_SET_NAME: utf8mb4
    DEFAULT_COLLATION_NAME: utf8mb4_0900_ai_ci
                  SQL_PATH: NULL
        DEFAULT_ENCRYPTION: NO
*************************** 2. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: information_schema
DEFAULT_CHARACTER_SET_NAME: utf8mb3
    DEFAULT_COLLATION_NAME: utf8mb3_general_ci
                  SQL_PATH: NULL
        DEFAULT_ENCRYPTION: NO
*************************** 3. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: performance_schema
DEFAULT_CHARACTER_SET_NAME: utf8mb4
    DEFAULT_COLLATION_NAME: utf8mb4_0900_ai_ci
                  SQL_PATH: NULL
        DEFAULT_ENCRYPTION: NO
...

没有与mysql.indexes完全对应的信息模式表,但INFORMATION_SCHEMA.STATISTICS包含了大部分相同的信息。

到目前为止,还没有与mysql.foreign_keysmysql.foreign_key_column_usage完全对应的INFORMATION_SCHEMA表。获取外键信息的标准 SQL 方法是使用INFORMATION_SCHEMAREFERENTIAL_CONSTRAINTSKEY_COLUMN_USAGE表;这些表现在作为foreign_keysforeign_key_column_usage和其他数据字典表的视图实现。

MySQL 8.0 之前的一些系统表已被数据字典表取代,不再存在于mysql系统模式中:

  • events数据字典表取代了 MySQL 8.0 之前的event表。
  • parametersroutines数据字典表共同取代了 MySQL 8.0 之前的proc表。
授权系统表

这些系统表包含有关用户帐户和其持有的权限的授权信息。有关这些表的结构、内容和目的的其他信息,请参见第 8.2.3 节,“授权表”。

从 MySQL 8.0 开始,授权表是InnoDB(事务性)表。以前,这些是MyISAM(非事务性)表。授权表存储引擎的更改伴随着 MySQL 8.0 中帐户管理语句行为的变化,例如CREATE USERGRANT。以前,命名多个用户的帐户管理语句可能对某些用户成功,对其他用户失败。这些语句现在是事务性的,如果发生任何错误,则对所有命名用户成功或回滚并且不产生任何效果。

注意

如果 MySQL 从旧版本升级,但授权表未从MyISAM升级到InnoDB,服务器会将其视为只读,并且帐户管理语句会产生错误。有关升级说明,请参见第三章,升级 MySQL

  • user: 用户账户、全局权限和其他非权限列。
  • global_grants: 将动态全局权限分配给用户;请参见静态权限与动态权限。
  • db: 数据库级别的权限。
  • tables_priv: 表级别的权限。
  • columns_priv: 列级别的权限。
  • procs_priv: 存储过程和函数权限。
  • proxies_priv: 代理用户权限。
  • default_roles: 此表列出了用户连接和认证后要激活的默认角色,或执行SET ROLE DEFAULT
  • role_edges: 此表列出了角色子图的边缘。 给定的user表行可能指向用户帐户或角色。服务器可以通过查询role_edges表来区分行是表示用户帐户、角色还是两者之间的关系的信息。
  • password_history: 关于密码更改的信息。
对象信息系统表

这些系统表包含有关组件、可加载函数和服务器端插件的信息:

  • component: 使用INSTALL COMPONENT安装的服务器组件的注册表。在此表中列出的任何组件都将由加载程序在服务器启动序列期间安装。请参见第 7.5.1 节,“安装和卸载组件”。
  • func: 通过CREATE FUNCTION安装的可加载函数的注册表。在正常启动序列期间,服务器会加载在此表中注册的函数。如果服务器使用--skip-grant-tables选项启动,则表中注册的函数不会被加载,也无法使用。参见 Section 7.7.1, “Installing and Uninstalling Loadable Functions”。 注意 类似于mysql.func系统表,性能模式user_defined_functions表列出使用CREATE FUNCTION安装的可加载函数。与mysql.func表不同,user_defined_functions表还列出了由服务器组件或插件自动安装的函数。这种差异使得user_defined_functionsmysql.func更适合用于检查已安装的函数。参见 Section 29.12.21.10, “The user_defined_functions Table”。
  • plugin: 通过INSTALL PLUGIN安装的服务器端插件的注册表。在正常启动序列期间,服务器会加载在此表中注册的插件。如果服务器使用--skip-grant-tables选项启动,则表中注册的插件不会被加载,也无法使用。参见 Section 7.6.1, “Installing and Uninstalling Plugins”。
日志系统表

服务器使用这些系统表进行日志记录:

  • general_log: 一般查询日志表。
  • slow_log: 慢查询日志表。

日志表使用CSV存储引擎。

更多信息,请参见 Section 7.4, “MySQL Server Logs”。

服务器端帮助系统表

这些系统表包含服务器端帮助信息:

  • help_category: 关于帮助类别的信息。
  • help_keyword: 与帮助主题相关联的关键词。
  • help_relation: 帮助关键词和主题之间的映射。
  • help_topic: 帮助主题内容。

更多信息,请参见 Section 7.1.17, “Server-Side Help Support”。

时区系统表

这些系统表包含时区信息:

  • time_zone: 时区 ID 以及它们是否使用闰秒。
  • time_zone_leap_second: 当闰秒发生时。
  • time_zone_name: 时区 ID 和名称之间的映射。
  • time_zone_transition, time_zone_transition_type: 时区描述。

更多信息,请参阅第 7.1.15 节,“MySQL 服务器时区支持”。

复制系统表

服务器使用这些系统表来支持复制:

  • gtid_executed: 用于存储 GTID 值的表。请参阅 mysql.gtid_executed 表。
  • ndb_binlog_index: NDB 集群复制的二进制日志信息。只有在服务器构建时使用NDBCLUSTER支持时才会创建此表。请参阅第 25.7.4 节,“NDB 集群复制模式和表”。
  • slave_master_info, slave_relay_log_info, slave_worker_info: 用于在副本服务器上存储复制信息。请参阅第 19.2.4 节,“中继日志和复制元数据存储库”。

所有列出的表格都使用InnoDB存储引擎。

优化器系统表

这些系统表供优化器使用:

  • innodb_index_stats, innodb_table_stats: 用于InnoDB持久性优化器统计信息。请参阅第 17.8.10.1 节,“配置持久性优化器统计参数”。
  • server_cost, engine_cost: 优化器成本模型使用包含有关查询执行过程中发生的操作的成本估算信息的表格。server_cost包含一般服务器操作的优化器成本估算。engine_cost包含特定存储引擎的操作的估算。请参阅第 10.9.5 节,“优化器成本模型”。
其他系统表

其他系统表不适用于前述类别:

  • audit_log_filter, audit_log_user: 如果安装了 MySQL 企业审计,这些表提供审计日志过滤器定义和用户帐户的持久性存储。请参阅审计日志表。
  • firewall_group_allowlist, firewall_groups, firewall_memebership, firewall_users, firewall_whitelist: 如果安装了 MySQL 企业防火墙,这些表提供防火墙使用的信息的持久性存储。请参阅第 8.4.7 节,“MySQL 企业防火墙”。
  • servers: 用于FEDERATED存储引擎。参见 Section 18.8.2.2, “使用 CREATE SERVER 创建 FEDERATED 表”。
  • innodb_dynamic_metadata: 由InnoDB存储引擎使用,用于存储快速变化的表元数据,如自增计数器值和索引树损坏标志。取代了存放在InnoDB系统表空间中的数据字典缓冲表。

7.4 MySQL 服务器日志

原文:dev.mysql.com/doc/refman/8.0/en/server-logs.html

7.4.1 选择通用查询日志和慢查询日志输出目的地

7.4.2 错误日志

7.4.3 通用查询日志

7.4.4 二进制日志

7.4.5 慢查询日志

7.4.6 服务器日志维护

MySQL 服务器有几个日志可以帮助您查找正在发生的活动。

日志类型

写入日志的信息

错误日志

启动、运行或停止时遇到的问题mysqld

通用查询日志

来自客户端的已建立的客户端连接和语句

二进制日志

更改数据的语句(也用于复制)

中继日志

来自复制源服务器的数据更改

慢查询日志

执行时间超过long_query_time秒的查询

DDL 日志(元数据日志)

由 DDL 语句执行的元数据操作

默认情况下,除了 Windows 上的错误日志之外,没有启用任何日志。(DDL 日志在需要时始终创建,并且没有用户可配置的选项;请参阅 DDL 日志。)以下特定于日志的部分提供有关启用日志记录的服务器选项的信息。

默认情况下,服务器在数据目录中为所有启用的日志编写文件。您可以通过刷新日志来强制服务器关闭并重新打开日志文件(或在某些情况下切换到新的日志文件)。当您发出FLUSH LOGS语句时,日志刷新会发生;使用flush-logsrefresh参数执行mysqladmin;或使用--flush-logs--master-data选项执行mysqldump。请参阅 Section 15.7.8.3, “FLUSH Statement”,Section 6.5.2, “mysqladmin — A MySQL Server Administration Program”和 Section 6.5.4, “mysqldump — A Database Backup Program”。此外,当二进制日志的大小达到max_binlog_size系统变量的值时,二进制日志会被刷新。

您可以在运行时控制一般查询和慢查询日志。您可以启用或禁用日志记录,或更改日志文件名。您可以告诉服务器将一般查询和慢查询条目写入日志表、日志文件或两者。有关详细信息,请参阅第 7.4.1 节,“选择一般查询日志和慢查询日志输出目的地”,第 7.4.3 节,“一般查询日志”和第 7.4.5 节,“慢查询日志”。

中继日志仅在副本上使用,用于保存来自复制源服务器的数据更改,这些更改也必须在副本上进行。有关中继日志内容和配置的讨论,请参阅第 19.2.4.1 节,“中继日志”。

有关日志维护操作(如旧日志文件的过期)的信息,请参阅第 7.4.6 节,“服务器日志维护”。

关于保护日志安全的信息,请参阅第 8.1.2.3 节,“密码和日志记录”。

7.4.1 选择一般查询日志和慢查询日志输出目的地

原文:dev.mysql.com/doc/refman/8.0/en/log-destinations.html

MySQL 服务器可以灵活控制写入一般查询日志和慢查询日志的输出目的地,如果这些日志已启用。日志条目的可能目的地是日志文件或mysql系统数据库中的general_logslow_log表。可以选择文件输出、表输出或两者。

  • 服务器启动时的日志控制
  • 运行时的日志控制
  • 日志表的优势和特点
服务器启动时的日志控制

log_output系统变量指定日志输出的目的地。设置此变量本身不会启用日志;它们必须单独启用。

  • 如果在启动时未指定log_output,则默认的日志记录目的地是FILE
  • 如果在启动时指定了log_output,其值是从TABLE(记录到表)、FILE(记录到文件)或NONE(不记录到表或文件)中选择的一个或多个逗号分隔的单词列表。如果存在NONE,则优先于任何其他指定项。

general_log系统变量控制所选日志目的地的一般查询日志的记录。如果在服务器启动时指定,general_log接受一个可选参数 1 或 0 来启用或禁用日志。要为文件记录指定除默认文件名以外的文件名,请设置general_log_file变量。类似地,slow_query_log变量控制所选目的地的慢查询日志的记录,并设置slow_query_log_file指定文件记录的文件名。如果启用了任一日志,则服务器会打开相应的日志文件并将启动消息写入其中。但是,除非选择了FILE日志目的地,否则不会进一步记录查询到文件中。

示例:

  • 要将一般查询日志条目写入日志表和日志文件,请使用--log_output=TABLE,FILE选择两个日志目的地,并使用--general_log启用一般查询日志。
  • 仅将一般和慢查询日志条目写入日志表,使用--log_output=TABLE选择表格作为日志目的地,并使用--general_log--slow_query_log启用两个日志。
  • 仅将慢查询日志条目写入日志文件,使用--log_output=FILE选择文件作为日志目的地,并使用--slow_query_log启用慢查询日志。在这种情况下,因为默认的日志目的地是FILE,您可以省略log_output设置。
运行时日志控制

与日志表和文件相关的系统变量使得可以在运行时控制日志记录:

  • log_output变量指示当前的日志输出目的地。可以在运行时修改以更改目的地。
  • general_logslow_query_log变量指示一般查询日志和慢查询日志是否已启用(ON)或已禁用(OFF)。您可以在运行时设置这些变量以控制日志是否已启用。
  • general_log_fileslow_query_log_file变量指示一般查询日志和慢查询日志文件的名称。您可以在服务器启动时或在运行时设置这些变量以更改日志文件的名称。
  • 要为当前会话禁用或启用一般查询日志记录,请将会话sql_log_off变量设置为ONOFF。(假设一般查询日志本身已启用。)
日志表的优点和特点

使用表格进行日志输出具有以下优点:

日志条目具有标准格式。要显示日志表的当前结构,请使用以下语句:

代码语言:javascript复制
SHOW CREATE TABLE mysql.general_log;
SHOW CREATE TABLE mysql.slow_log;

日志内容可通过 SQL 语句访问。这使得可以使用仅选择满足特定条件的日志条目的查询。例如,要选择与特定客户关联的日志内容(这对于识别来自该客户的问题查询很有用),使用日志表比使用日志文件更容易。

日志可通过任何能连接到服务器并发出查询的客户端远程访问(如果客户端具有适当的日志表权限)。无需登录到服务器主机并直接访问文件系统。

日志表实现具有以下特点:

一般来说,日志表的主要目的是为用户提供一个接口来观察服务器的运行时执行情况,而不是干预其运行时执行。

CREATE TABLEALTER TABLEDROP TABLE 是对日志表的有效操作。对于ALTER TABLEDROP TABLE,日志表不能在使用中,必须被禁用,如后面所述。

默认情况下,日志表使用将数据以逗号分隔值格式写入的CSV存储引擎。对于可以访问包含日志表数据的.CSV文件的用户,这些文件易于导入到其他程序中,如可以处理 CSV 输入的电子表格程序。

可以修改日志表以使用MyISAM存储引擎。不能使用ALTER TABLE来修改正在使用的日志表。必须先禁用日志。日志表只能使用CSVMyISAM引擎,其他引擎不合法。

日志表和“打开文件过多”错误。 如果将TABLE作为日志目的地,并且日志表使用CSV存储引擎,您可能会发现在运行时反复禁用和启用常规查询日志或慢查询日志会导致.CSV文件的打开文件描述符数量增加,可能导致“打开文件过多”错误。为解决此问题,执行FLUSH TABLES或确保open_files_limit的值大于table_open_cache_instances的值。

要禁用日志记录以便修改(或删除)日志表,可以使用以下策略。示例使用常规查询日志;慢查询日志的过程类似,但使用slow_log表和slow_query_log系统变量。

代码语言:javascript复制
SET @old_log_state = @@GLOBAL.general_log;
SET GLOBAL general_log = 'OFF';
ALTER TABLE mysql.general_log ENGINE = MyISAM;
SET GLOBAL general_log = @old_log_state;

TRUNCATE TABLE 是对日志表的有效操作。可用于清除日志条目。

RENAME TABLE 是对日志表的有效操作。可以使用以下策略来原子地重命名日志表(例如执行日志轮换):

代码语言:javascript复制
USE mysql;
DROP TABLE IF EXISTS general_log2;
CREATE TABLE general_log2 LIKE general_log;
RENAME TABLE general_log TO general_log_backup, general_log2 TO general_log;

CHECK TABLE 是对日志表的有效操作。

LOCK TABLES 不能用于日志表。

INSERTDELETEUPDATE不能用于日志表。这些操作仅在服务器内部允许。

FLUSH TABLES WITH READ LOCKread_only系统变量的状态对日志表没有影响。服务器始终可以写入日志表。

写入日志表的条目不会写入二进制日志,因此不会被复制到副本。

要刷新日志表或日志文件,请分别使用FLUSH TABLESFLUSH LOGS

不允许对日志表进行分区。

mysqldump转储包括重新创建这些表的语句,以便在重新加载转储文件后它们不会丢失。日志表内容不会被转储。

7.4.2 错误日志

原文:dev.mysql.com/doc/refman/8.0/en/error-log.html

7.4.2.1 错误日志配置

7.4.2.2 默认错误日志目标配置

7.4.2.3 错误事件字段

7.4.2.4 错误日志过滤类型

7.4.2.5 基于优先级的错误日志过滤 (log_filter_internal)

7.4.2.6 基于规则的错误日志过滤 (log_filter_dragnet)

7.4.2.7 以 JSON 格式记录错误日志

7.4.2.8 记录错误日志到系统日志

7.4.2.9 错误日志输出格式

7.4.2.10 错误日志文件刷新和重命名

本节讨论如何配置 MySQL 服务器以将诊断消息记录到错误日志中。有关选择错误消息字符集和语言的信息,请参见 Section 12.6, “Error Message Character Set”,以及 Section 12.12, “Setting the Error Message Language”。

错误日志包含mysqld启动和关闭时间的记录。它还包含在服务器启动和关闭期间以及服务器运行时发生的错误、警告和注释的诊断消息。例如,如果mysqld注意到需要自动检查或修复表,它会向错误日志写入一条消息。

根据错误日志配置,错误消息也可能填充到性能模式error_log表中,以提供对日志的 SQL 接口,并使其内容可以被查询。参见 Section 29.12.21.2, “The error_log Table”。

在某些操作系统上,如果mysqld异常退出,错误日志中会包含堆栈跟踪。该跟踪可用于确定mysqld退出的位置。参见 Section 7.9, “Debugging MySQL”。

如果用于启动mysqldmysqld_safe可能会向错误日志写入消息。例如,当mysqld_safe注意到异常的mysqld退出时,它会重新启动mysqld并向错误日志写入mysqld restarted消息。

以下部分讨论配置错误日志的方面。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-configuration.html

7.4.2.1 错误日志配置

在 MySQL 8.0 中,错误日志记录使用了在第 7.5 节,“MySQL 组件”中描述的 MySQL 组件架构。错误日志子系统由执行日志事件过滤和写入的组件以及配置哪些组件加载和启用以实现所需日志记录结果的系统变量组成。

本节讨论了如何加载和启用错误日志记录的组件。有关特定于日志过滤器的说明,请参阅第 7.4.2.4 节,“错误日志过滤类型”。有关特定于 JSON 和系统日志接收器的说明,请参阅第 7.4.2.7 节,“以 JSON 格式记录错误日志”和第 7.4.2.8 节,“将错误日志记录到系统日志”。有关所有可用日志组件的更多详细信息,请参阅第 7.5.3 节,“错误日志组件”。

基于组件的错误日志记录提供了以下功能:

  • 可由过滤组件过滤的日志事件,以影响可用于写入的信息。
  • 由接收器(写入器)组件输出的日志事件。可以启用多个接收器组件,将错误日志输出写入多个目的地。
  • 实现默认错误日志格式的内置过滤器和接收器组件。
  • 一个可加载的接收器,可启用以 JSON 格式记录日志。
  • 一个可加载的接收器,可启用将日志记录到系统日志中。
  • 控制加载和启用哪些日志组件以及每个组件如何运行的系统变量。

错误日志配置在本节中描述如下主题:

  • 默认错误日志配置
  • 错误日志配置方法
  • 隐式错误日志配置
  • 显式错误日志配置
  • 更改错误日志配置方法
  • 故障排除配置问题
  • 配置多个日志接收器
  • 日志汇流性能模式支持
默认错误日志配置

log_error_services系统变量控制要加载的可加载日志组件(从 MySQL 8.0.30 开始)以及要为错误日志记录启用的日志组件。默认情况下,log_error_services具有以下值:

代码语言:javascript复制
mysql> SELECT @@GLOBAL.log_error_services;
 ---------------------------------------- 
| @@GLOBAL.log_error_services            |
 ---------------------------------------- 
| log_filter_internal; log_sink_internal |
 ---------------------------------------- 

该值表示日志事件首先通过log_filter_internal过滤组件,然后通过log_sink_internal汇流组件,这两个都是内置组件。过滤器修改后续命名的组件看到的日志事件。汇流是日志事件的目的地。通常,汇流将日志事件处理为具有特定格式的日志消息,并将这些消息写入其关联的输出,例如文件或系统日志。

log_filter_internallog_sink_internal的组合实现了默认的错误日志过滤和输出行为。这些组件的操作受其他服务器选项和系统变量的影响:

  • 输出目的地由--log-error选项确定(在 Windows 上,还有--pid-file--console)。这些选项确定是否将错误消息写入控制台或文件,如果写入文件,则确定错误日志文件名。参见 Section 7.4.2.2, “Default Error Log Destination Configuration”。
  • log_error_verbositylog_error_suppression_list系统变量影响log_filter_internal允许或抑制哪些类型的日志事件。参见 Section 7.4.2.5, “Priority-Based Error Log Filtering (log_filter_internal)”")。

在配置log_error_services时,请注意以下特性:

日志组件列表可以用分号或(从 MySQL 8.0.12 开始)逗号分隔,可选地跟随空格。给定设置不能同时使用分号和逗号分隔符。组件顺序很重要,因为服务器按照列出的顺序执行组件。

log_error_services值中的最终组件不能是过滤器。这是一个错误,因为它对事件的任何更改都不会对输出产生影响:

代码语言:javascript复制
mysql> SET GLOBAL log_error_services = 'log_filter_internal';
ERROR 1231 (42000): Variable 'log_error_services' can't be set to the value
of 'log_filter_internal'

要纠正问题,请在值的末尾包含一个 sink:

代码语言:javascript复制
mysql> SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal';

log_error_services 中命名的组件顺序很重要,特别是与过滤器和接收器的相对顺序有关。考虑这个 log_error_services 值:

代码语言:javascript复制
log_filter_internal; log_sink_1; log_sink_2

在这种情况下,日志事件经过内置过滤器,然后传递到第一个接收器,再传递到第二个接收器。两个接收器都会接收到经过过滤的日志事件。

将其与此 log_error_services 值进行比较:

代码语言:javascript复制
log_sink_1; log_filter_internal; log_sink_2

在这种情况下,日志事件经过第一个接收器,然后经过内置过滤器,再传递到第二个接收器。第一个接收器接收未经过滤的事件。第二个接收器接收经过过滤的事件。如果您希望一个日志包含所有日志事件的消息,另一个日志仅包含部分日志事件的消息,您可以以这种方式配置错误日志记录。

错误日志配置方法

错误日志配置涉及根据需要加载和启用错误日志组件,并执行特定于组件的配置。

有两种错误日志配置方法,隐式显式。建议选择一种配置方法并专门使用。同时使用两种方法可能会导致启动时出现警告。有关更多信息,请参阅 故障排除配置问题。

  • 隐式错误日志配置(MySQL 8.0.30 中引入) 此配置方法加载并启用由 log_error_services 变量定义的日志组件。在启动时,尚未加载的可加载组件会在InnoDB存储引擎完全可用之前隐式加载。此配置方法具有以下优点:
    • 日志组件在启动序列的早期加载,早于InnoDB存储引擎,使得记录的信息更早可用。
    • 它避免了在启动过程中发生故障时丢失缓冲的日志信息。
    • 使用 INSTALL COMPONENT 安装错误日志组件并不是必需的,简化了错误日志配置。

    要使用这种方法,请参阅 隐式错误日志配置。

  • 显式错误日志配置 注意 此配置方法支持向后兼容。推荐使用 MySQL 8.0.30 中引入的隐式配置方法。 这种配置方法需要使用INSTALL COMPONENT加载错误日志组件,然后配置log_error_services以启用日志组件。INSTALL COMPONENT将组件添加到mysql.component表(一个InnoDB表),启动时要加载的组件从该表中读取,该表只有在InnoDB初始化后才能访问。 在InnoDB存储引擎初始化期间,启动序列期间缓冲记录的信息,这有时会因为InnoDB启动序列期间发生的恢复和数据字典升级等操作而延长。 要使用此方法,请参阅显式错误日志配置。
隐式错误日志配置

本过程描述了如何使用log_error_services隐式加载和启用错误日志组件。有关错误日志配置方法的讨论,请参见错误日志配置方法。

隐式加载和启用错误日志组件:

log_error_services值中列出错误日志组件。

要在服务器启动时加载和启用错误日志组件,请在选项文件中设置log_error_services。以下示例配置了使用 JSON 日志接收器(log_sink_json)以及内置日志过滤器和接收器(log_filter_internallog_sink_internal)。

代码语言:javascript复制
[mysqld]
log_error_services='log_filter_internal; log_sink_internal; log_sink_json'

注意

要使用 JSON 日志接收器(log_sink_syseventlog)而不是默认接收器(log_sink_internal),您应该将log_sink_internal替换为log_sink_json

要立即加载和启用组件并用于后续重新启动,请使用SET PERSIST设置log_error_services

代码语言:javascript复制
SET PERSIST log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';

如果错误日志组件公开任何必须设置的系统变量以使组件初始化成功,请为这些变量分配适当的值。您可以在选项文件中设置这些变量,也可以使用SET PERSIST

重要

在实现隐式配置时,首先设置log_error_services以加载组件并公开其系统变量,然后设置组件系统变量。无论是在命令行、选项文件还是使用SET PERSIST进行变量赋值,都需要按照此配置顺序进行。

要禁用日志组件,请从log_error_services值中移除它。同时移除您定义的任何相关组件变量设置。

注意

使用log_error_services隐式加载日志组件不会影响mysql.component表。它不会将组件添加到mysql.component表中,也不会从mysql.component表中删除以前使用INSTALL COMPONENT安装的组件。

明确的错误日志配置

本过程描述了如何通过使用INSTALL COMPONENT加载组件,然后通过log_error_services启用错误日志组件。有关错误日志配置方法的讨论,请参见错误日志配置方法。

明确加载和启用错误日志组件:

使用INSTALL COMPONENT加载组件(除非它是内置的或已加载)。例如,要加载 JSON 日志接收器,请执行以下语句:

代码语言:javascript复制
INSTALL COMPONENT 'file://component_log_sink_json';

使用INSTALL COMPONENT加载组件会将其注册到mysql.component系统表中,以便服务器在InnoDB初始化后自动加载它以供后续启动使用。

使用INSTALL COMPONENT加载日志组件时使用的 URN 是组件名称前缀为file://component_。例如,对于log_sink_json组件,相应的 URN 是file://component_log_sink_json。有关错误日志组件 URN,请参见 Section 7.5.3, “Error Log Components”。

如果错误日志组件公开了必须设置的系统变量以确保组件初始化成功,为这些变量分配适当的值。您可以在选项文件中设置这些变量,也可以使用SET PERSIST

通过在log_error_services值中列出组件来启用该组件。

重要

从 MySQL 8.0.30 开始,当使用INSTALL COMPONENT显式加载日志组件时,请勿在选项文件中持久化或设置log_error_services,该选项文件在启动时隐式加载日志组件。而是使用SET GLOBAL语句在运行时启用日志组件。

以下示例配置了使用 JSON 日志接收器(log_sink_json)以及内置日志过滤器和接收器(log_filter_internallog_sink_internal)。

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';

注意

要使用 JSON 日志接收器(log_sink_syseventlog)而不是默认接收器(log_sink_internal),您应该将log_sink_internal替换为log_sink_json

要禁用日志组件,请从log_error_services值中删除它。然后,如果组件是可加载的,并且您还想卸载它,请使用UNINSTALL COMPONENT。还要删除您定义的任何相关组件变量设置。

尝试使用UNINSTALL COMPONENT卸载仍在log_error_services值中命名的可加载组件会产生错误。

更改错误日志配置方法

如果您之前使用INSTALL COMPONENT显式加载了错误日志组件,并且希望切换到隐式配置,如隐式错误日志配置中所述,建议执行以下步骤:

log_error_services设置回默认配置。

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal,log_sink_internal';

使用UNINSTALL COMPONENT卸载您之前安装的任何可加载日志组件。例如,如果之前安装了 JSON 日志接收器,请按照以下方式��载它:

代码语言:javascript复制
UNINSTALL COMPONENT 'file://component_log_sink_json';

删除已卸载组件的任何组件变量设置。例如,如果在选项文件中设置了组件变量,请从选项文件中删除这些设置。如果使用SET PERSIST设置了组件变量,请使用RESET PERSIST来清除这些设置。

按照隐式错误日志配置中的步骤重新实施您的配置。

如果需要从隐式配置恢复到显式配置,请执行以下步骤:

log_error_services设置回其默认配置以卸载隐式加载的日志组件。

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal,log_sink_internal';

删除与已卸载组件相关的任何组件变量设置。例如,如果在选项文件中设置了组件变量,请从选项文件中删除这些设置。如果使用SET PERSIST设置了组件变量,请使用RESET PERSIST清除这些设置。

重新启动服务器以卸载隐式加载的日志组件。

按照显式错误日志配置中的步骤重新实施您的配置。

故障排除配置问题

从 MySQL 8.0.30 开始,在启动时加载在log_error_services值中列出的日志组件会在 MySQL 服务器启动序列的早期隐式加载。如果以前使用INSTALL COMPONENT加载了日志组件,则服务器会在启动序列的后期尝试重新加载该组件,从而产生以下警告:

代码语言:javascript复制
Cannot load component from specified URN: 'file://component_*component_name*'

您可以在错误日志中检查此警告,或通过以下查询查询性能模式error_log表来查询此警告:

代码语言:javascript复制
SELECT error_code, data
  FROM performance_schema.error_log
 WHERE data LIKE "%'file://component_%"
   AND error_code="MY-013129" AND data LIKE "%MY-003529%";

要避免此警告,请按照更改错误日志配置方法中的说明调整您的错误日志配置。应使用隐式或显式错误日志配置,但不要同时使用两者。

当尝试显式加载在启动时隐式加载的组件时会出现类似错误。例如,如果log_error_services列出了 JSON 日志接收器组件,则该组件会在启动时隐式加载。尝试稍后显式加载相同组件会返回此错误:

代码语言:javascript复制
mysql> INSTALL COMPONENT 'file://component_log_sink_json';
ERROR 3529 (HY000): Cannot load component from specified URN: 'file://component_log_sink_json'.
配置多个日志接收器

可以配置多个日志接收器,从而可以将输出发送到多个目的地。要在默认接收器之外启用 JSON 日志接收器(而不是替代),请将log_error_services值设置如下:

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal; log_sink_json';

要恢复仅使用默认接收器并卸载系统日志接收器,请执行以下语句:

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal;
UNINSTALL COMPONENT 'file://component_log_sink_json';
日志接收器性能模式支持

如果启用了记录组件包含支持性能模式的接收器,那么写入错误日志的事件也会写入性能模式的error_log表中。这样可以使用 SQL 查询来检查错误日志内容。目前,传统格式的log_sink_internal和 JSON 格式的log_sink_json接收器支持此功能。请参阅 Section 29.12.21.2, “错误日志表”。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration.html

7.4.2.2 默认错误日志目的地配置

本节描述了哪些服务器选项配置了默认错误日志目的地,可以是控制台或命名文件。它还指出了哪些日志接收组件将其自身的输出目的地基于默认目的地。

在本讨论中,“控制台”指的是stderr,标准错误输出。这是您的终端或控制台窗口,除非标准错误输出已重定向到其他目的地。

服务器对于确定默认错误日志目的地的选项在 Windows 和 Unix 系统上有些不同。请确保使用适合您平台的信息配置目的地。服务器解释默认错误日志目的地选项后,它将设置log_error系统变量以指示默认目的地,这会影响几个日志接收组件写入错误消息的位置。以下各节将讨论这些主题。

  • Windows 上的默认错误日志目的地
  • Unix 和类 Unix 系统上的默认错误日志目的地
  • 默认错误日志目的地如何影响日志接收组件
Windows 上的默认错误日志目的地

在 Windows 上,mysqld使用--log-error--pid-file--console选项来确定默认错误日志目的地是控制台还是文件,以及如果是文件,则文件名:

  • 如果提供了--console,默认目的地是控制台。(--console优先于--log-error如果两者都提供,则关于--log-error的以下项目不适用。)
  • 如果未提供--log-error,或者提供了但没有指定文件名,则默认目的地是数据目录中名为*host_name*.err的文件,除非指定了--pid-file选项。在这种情况下,文件名是 PID 文件基本名称,带有.err后缀在数据目录中。
  • 如果给定--log-error来命名一个文件,那么默认的目的地就是该文件(如果名称没有后缀,则添加.err后缀)。文件位置位于数据目录下,除非给定绝对路径名以指定不同位置。

如果默认的错误日志目的地是控制台,服务器会将log_error系统变量设置为stderr。否则,默认目的地是一个文件,服务器会将log_error设置为文件名。

Unix 和类 Unix 系统上的默认错误日志目的地

在 Unix 和类 Unix 系统上,mysqld使用--log-error选项来确定默认的错误日志目的地是控制台还是文件,以及文件名:

  • 如果没有给定--log-error,默认的目的地是控制台。
  • 如果给定--log-error而没有命名文件,那么默认的目的地是数据目录中名为*host_name*.err的文件。
  • 如果给定--log-error来命名一个文件,那么默认的目的地就是该文件(如果名称没有后缀,则添加.err后缀)。文件位置位于数据目录下,除非给定绝对路径名以指定不同位置。
  • 如果在[mysqld][server][mysqld_safe]部分的选项文件中给定--log-error,在使用mysqld_safe启动服务器的系统上,mysqld_safe会找到并使用该选项,并将其传递给mysqld

注意

对于 Yum 或 APT 软件包安装来说,通常会在服务器配置文件中使用类似log-error=/var/log/mysqld.log的选项来配置错误日志文件位置在/var/log下。从选项中移除路径名会导致在数据目录中使用*host_name*.err文件。

如果默认的错误日志目的地是控制台,服务器会将log_error系统变量设置为stderr。否则,默认目的地是一个文件,服务器会将log_error设置为文件名。

默认错误日志目的地如何影响日志输出

在服务器解释错误日志目的地配置选项后,它将log_error系统变量设置为指示默认错误日志目的地。日志输出端组件可以基于log_error值确定自己的输出目的地,或者独立于log_error确定它们的目的地。

如果log_errorstderr,默认错误日志目的地为控制台,基于默认目的地的日志输出端也会写入控制台:

  • log_sink_internal, log_sink_json, log_sink_test: 这些输出端写入控制台。即使对于可以多次启用的输出端(例如log_sink_json),所有实例也会写入控制台。
  • log_sink_syseventlog: 此输出端写入系统日志,不受log_error值的影响。

如果log_error不是stderr,默认错误日志目的地是一个文件,并且log_error指示文件名。基于默认目的地的日志输出端会根据该文件名确定输出文件命名。 (一个输出端可能会使用完全相同的名称,或者可能会使用某种变体。)假设log_error值为*file_name*。那么日志输出端使用以下方式的名称:

  • log_sink_internal, log_sink_test: 这些输出端写入*file_name*。
  • log_sink_json: 连续的此输出端实例命名为log_error_services值写入名为*file_name*加上编号为.*NN*.json后缀的文件:*file_name*.00.json*file_name*.01.json等等。
  • log_sink_syseventlog: 此输出端写入系统日志,不受log_error值的影响。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-event-fields.html

7.4.2.3 错误事件字段

用于错误日志的错误事件包含一组字段,每个字段由键/值对组成。事件字段可以分类为核心、可选或用户定义:

  • 核心字段会自动设置为错误事件。但是,在事件处理过程中,不能保证事件���存在核心字段,因为核心字段,像任何类型的字段一样,可能会被日志过滤器取消设置。如果发生这种情况,则在该过滤器内部和在过滤器之后执行的组件(如日志接收器)中无法找到该字段。
  • 通常情况下,可选字段通常不存在,但对于某些事件类型可能存在。当存在时,可选字段根据需要和可用性提供额外的事件信息。
  • 用户定义字段是任何名称尚未定义为核心或可选字段的字段。用户定义字段在由日志过滤器创建之前不存在。

如前述描述所示,任何给定字段在事件处理过程中可能不存在,这可能是因为它一开始就不存在,或者被过滤器丢弃。对于日志接收器,字段缺失的影响是特定于接收器的。例如,接收器可能从日志消息中省略该字段,指示该字段丢失,或者替换为默认值。如果有疑问,请进行测试:使用一个取消设置该字段的过滤器,然后检查日志接收器对其的处理方式。

以下部分描述了核心和可选错误事件字段。对于单独的日志过滤器组件,可能会有关于这些字段的其他特定于过滤器的考虑,或者过滤器可能添加此处未列出的用户定义字段。有关详细信息,请参阅特定过滤器的文档。

  • 核心错误事件字段
  • 可选错误事件字段
核心错误事件字段

这些错误事件字段是核心字段:

  • time 事件时间戳,精确到微秒。
  • msg 事件消息字符串。
  • prio 事件优先级,用于指示系统、错误、警告或注意/信息事件。此字段对应于syslog中的严重性。以下表显示可能的优先级级别。 事件类型数字优先级系统事件0错误事件1警告事件2注意/信息事件3prio值是数字。与此相关,错误事件还可以包括一个可选的label字段,表示优先级为字符串。例如,具有prio值为 2 的事件可能具有label值为’警告’。 根据优先级,过滤器组件可以包含或删除错误事件,但系统事件是强制性的,不能被删除。 一般来说,消息优先级的确定如下: 这种情况或事件是否可操作?
    • 是:情况或事件是否可忽略?
      • 是:优先级是警告。
      • 不:优先级是错误。
    • 不:情况或事件是否强制性?
      • 是:优先级是系统。
      • 不:优先级是注释/信息。
  • err_code 事件错误代码,作为数字(例如,1022)。
  • err_symbol 作为字符串的事件错误符号(例如,'ER_DUP_KEY')。
  • SQL_state 作为字符串的事件 SQLSTATE 值(例如,'23000')。
  • subsystem 事件发生的子系统。可能的值为InnoDBInnoDB存储引擎)、Repl(复制子系统)、Server(其他)。
可选的错误事件字段

可选的错误事件字段属于以下类别:

  • 关于错误的其他信息,例如操作系统发出的错误或错误标签:
    • OS_errno 操作系统错误编号。
    • OS_errmsg 操作系统错误消息。
    • labelprio值对应的标签,作为字符串。
  • 事件发生的客户端的标识:
    • user 客户端用户。
    • host 客户端主机。
    • threadmysqld中负责生成错误事件的线程的 ID。此 ID 指示服务器的哪个部分生成了事件,并与一般查询日志和慢查询日志消息一致,这些消息包括连接线程 ID。
    • query_id 查询 ID。
  • 调试信息:
    • source_file 事件发生的源文件,不包含任何前导路径。
    • source_line 事件发生的源文件中的行号。
    • function 事件发生的函数。
    • component 事件发生的组件或插件。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-filtering.html

7.4.2.4 错误日志过滤类型

错误日志配置通常包括一个日志过滤组件和一个或多个日志接收组件。对于错误日志过滤,MySQL 提供了多种组件选择:

  • log_filter_internal:该过滤组件基于日志事件优先级和错误代码提供错误日志过滤,结合log_error_verbositylog_error_suppression_list系统变量。log_filter_internal是内置的,默认启用。参见 Section 7.4.2.5, “基于优先级的错误日志过滤(log_filter_internal)”。
  • log_filter_dragnet:该过滤组件基于用户提供的规则,结合dragnet.log_error_filter_rules系统变量,提供错误日志过滤。参见 Section 7.4.2.6, “基于规则的错误日志过滤(log_filter_dragnet)”。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-priority-based-filtering.html

7.4.2.5 基于优先级的错误日志过滤(log_filter_internal)

log_filter_internal日志过滤组件实现了一种基于错误事件优先级和错误代码的简单形式的日志过滤。要影响log_filter_internal如何允许或抑制写入错误日志的错误、警告和信息事件,请设置log_error_verbositylog_error_suppression_list系统变量。

log_filter_internal是内置的并默认启用。如果禁用此过滤器,log_error_verbositylog_error_suppression_list将不起作用,因此必须在需要时使用另一个过滤器服务执行过滤(例如,在使用log_filter_dragnet时使用单独的过滤规则)。有关过滤器配置的信息,请参见第 7.4.2.1 节“错误日志配置”。

  • 详细程度过滤
  • 抑制列表过滤
  • 详细程度和抑制列表交互
详细程度过滤

事件意图记录到错误日志的优先级为ERRORWARNINGINFORMATIONlog_error_verbosity系统变量控制基于哪些优先级允许写入日志的消息的详细程度,如下表所示。

log_error_verbosity 值

允许的消息优先级

1

ERROR

2

ERROR、WARNING

3

ERROR、WARNING、INFORMATION

如果log_error_verbosity为 2 或更高,则服务器会记录关于对基于语句的日志记录不安全的语句的消息。如果值为 3,则服务器会记录有关新连接尝试的中止连接和访问被拒绝的错误。请参见第 B.3.2.9 节“通信错误和中止连接”。

如果使用复制,建议将log_error_verbosity值设置为 2 或更高,以获取有关正在发生的情况的更多信息,例如有关网络故障和重新连接的消息。

如果在副本上log_error_verbosity为 2 或更高,则副本会将消息打印到错误日志中,以提供有关其状态的信息,例如二进制日志和中继日志的坐标,它开始工作的位置,当它切换到另一个中继日志时,重新连接后等等。

存在一个SYSTEM的消息优先级,不受冗长过滤的影响。关于非错误情况的系统消息会被打印到错误日志中,无论log_error_verbosity的值是多少。这些消息包括启动和关闭消息,以及一些重要的设置更改。

在 MySQL 错误日志中,系统消息标记为“System”。其他日志接收器可能会或可能不会遵循相同的约定,在生成的日志中,系统消息可能被分配给信息优先级级别使用的标签,例如“Note”或“Information”。如果基于消息标签应用任何额外的过滤或重定向以进行日志记录,系统消息不会覆盖您的过滤器,而是以与其他消息相同的方式处理。

抑制列表过滤

log_error_suppression_list系统变量适用于写入错误日志的事件,并指定在出现WARNINGINFORMATION优先级时要抑制哪些事件。例如,如果某种类型的警告被认为是错误日志中频繁发生但不感兴趣的“噪音”,则可以将其抑制。log_error_suppression_list不会抑制具有ERRORSYSTEM优先级的消息。

log_error_suppression_list的值可以是空字符串以表示无抑制,或者是一个或多个逗号分隔值的列表,指示要抑制的错误代码。错误代码可以用符号形式或数字形式指定。可以使用或不使用MY-前缀指定数字代码。数字部分的前导零不重要。允许的代码格式示例:

代码语言:javascript复制
ER_SERVER_SHUTDOWN_COMPLETE
MY-000031
000031
MY-31
31

为了可读性和可移植性,符号值比数字值更可取。

尽管要抑制的代码可以用符号形式或数字形式表示,但每个代码的数字值必须在允许的范围内:

  • 1 至 999:服务器和客户端使用的全局错误代码。
  • 10000 及以上:服务器错误代码,意在写入错误日志(不发送给客户端)。

此外,指定的每个错误代码必须实际被 MySQL 使用。尝试指定不在允许范围内或在允许范围内但未被 MySQL 使用的代码会产生错误,并且log_error_suppression_list的值保持不变。

有关错误代码范围、每个范围内定义的错误符号和数字的信息,请参见第 B.1 节,“错误消息来源和元素”,以及 MySQL 8.0 错误消息参考。

服务器可以为给定错误代码生成具有不同优先级的消息,因此与log_error_suppression_list中列出的错误代码相关联的消息的抑制取决于其优先级。假设变量的值为'ER_PARSER_TRACE,MY-010001,10002'。那么log_error_suppression_list对这些代码的消息产生以下影响:

  • 生成具有WARNINGINFORMATION优先级的消息会被抑制。
  • 生成具有ERRORSYSTEM优先级的消息不会被抑制。
详细度和抑制列表的交互

log_error_verbosity的效果与log_error_suppression_list的效果相结合。考虑使用以下设置启动的服务器:

代码语言:javascript复制
[mysqld]
log_error_verbosity=2 # error and warning messages only
log_error_suppression_list='ER_PARSER_TRACE,MY-010001,10002'

在这种情况下,log_error_verbosity允许具有ERRORWARNING优先级的消息,并丢弃具有INFORMATION优先级的消息。在未被丢弃的消息中,log_error_suppression_list会丢弃具有WARNING优先级和任何命名错误代码的消息。

注意

示例中显示的log_error_verbosity值为 2,这也是其默认值,因此该变量对INFORMATION消息的影响默认情况下如上所述,无需显式设置。如果要使log_error_suppression_list影响具有INFORMATION优先级的消息,必须将log_error_verbosity设置为 3。

考虑使用以下设置启动的服务器:

代码语言:javascript复制
[mysqld]
log_error_verbosity=1 # error messages only

在这种情况下,log_error_verbosity 允许具有ERROR优先级的消息,并丢弃具有WARNINGINFORMATION优先级的消息。设置log_error_suppression_list 不起作用,因为它可能抑制的所有错误代码已经由log_error_verbosity 设置丢弃了。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-rule-based-filtering.html

7.4.2.6 基于规则的错误日志过滤(log_filter_dragnet)

log_filter_dragnet日志过滤组件基于用户定义的规则进行日志过滤。

要启用log_filter_dragnet过滤器,首先加载过滤器组件,然后修改log_error_services的值。以下示例启用了与内置日志接收器结合使用的log_filter_dragnet

代码语言:javascript复制
INSTALL COMPONENT 'file://component_log_filter_dragnet';
SET GLOBAL log_error_services = 'log_filter_dragnet; log_sink_internal';

要设置log_error_services在服务器启动时生效,请使用第 7.4.2.1 节“错误日志配置”中的说明。这些说明也适用于其他错误日志系统变量。

启用log_filter_dragnet后,通过设置dragnet.log_error_filter_rules系统变量来定义其过滤规则。规则集由零个或多个规则组成,其中���个规则都是以句号(.)字符结尾的IF语句。如果变量值为空(零个规则),则不会进行过滤。

示例 1:此规则集丢弃信息事件,并对其他事件删除source_line字段:

代码语言:javascript复制
SET GLOBAL dragnet.log_error_filter_rules =
  'IF prio>=INFORMATION THEN drop. IF EXISTS source_line THEN unset source_line.';

其效果类似于使用log_error_verbosity=2设置的log_sink_internal过滤器执行的过滤。

为了可读性,您可能会发现将规则列在单独的行上更可取。例如:

代码语言:javascript复制
SET GLOBAL dragnet.log_error_filter_rules = '
  IF prio>=INFORMATION THEN drop.
  IF EXISTS source_line THEN unset source_line.
';

示例 2:此规则将信息事件限制为每 60 秒不超过一个:

代码语言:javascript复制
SET GLOBAL dragnet.log_error_filter_rules =
  'IF prio>=INFORMATION THEN throttle 1/60.';

一旦您按照您的意愿设置了过滤配置,请考虑使用SET PERSIST而不是SET GLOBAL来分配dragnet.log_error_filter_rules,以使设置在服务器重新启动时持久化。或者,将设置添加到服务器选项文件中。

当使用log_filter_dragnet时,log_error_suppression_list会被忽略。

要停止使用过滤语言,首先从错误日志组件集中删除它。通常这意味着使用不同的过滤组件而不是没有过滤组件。例如:

代码语言:javascript复制
SET GLOBAL log_error_services = 'log_filter_internal; log_sink_internal';

再次考虑使用SET PERSIST而不是SET GLOBAL来使设置在服务器重新启动时持久化。

然后卸载过滤器log_filter_dragnet组件:

代码语言:javascript复制
UNINSTALL COMPONENT 'file://component_log_filter_dragnet';

以下部分更详细地描述了log_filter_dragnet操作的各个方面:

  • log_filter_dragnet 规则语言的语法
  • log_filter_dragnet 规则的操作
  • log_filter_dragnet 规则中的字段引用
log_filter_dragnet 规则语言的语法

以下语法定义了log_filter_dragnet过滤规则的语言。每个规则都是以句号(.)字符结尾的IF语句。该语言不区分大小写。

代码语言:javascript复制
*rule*:
    IF *condition* THEN *action*
    [ELSEIF *condition* THEN *action*] ...
    [ELSE *action*]
    .

*condition*: {
    *field* *comparator* *value*
  | [NOT] EXISTS *field*
  | *condition* {AND | OR}  *condition*
}

*action*: {
    drop
  | throttle {*count* | *count* / *window_size*}
  | set *field* [:= | =] *value*
  | unset [*field*]
}

*field*: {
    *core_field*
  | *optional_field*
  | *user_defined_field*
}

*core_field*: {
    time
  | msg
  | prio
  | err_code
  | err_symbol
  | SQL_state
  | subsystem
}

*optional_field*: {
    OS_errno
  | OS_errmsg
  | label
  | user
  | host
  | thread
  | query_id
  | source_file
  | source_line
  | function
  | component
}

*user_defined_field*:
    *sequence of characters in [a-zA-Z0-9_] class*

*comparator*: {== | != | <> | >= | => | <= | =< | < | >}

*value*: {
    *string_literal*
  | *integer_literal*
  | *float_literal*
  | *error_symbol*
  | *priority*
}

*count*: *integer_literal*
*window_size*: *integer_literal*

*string_literal*:
    *sequence of characters quoted as '...' or "..."*

*integer_literal*:
    *sequence of characters in [0-9] class*

*float_literal*:
    *integer_literal*[.*integer_literal*]

*error_symbol*:
    *valid MySQL error symbol such as ER_ACCESS_DENIED_ERROR or ER_STARTUP*

*priority*: {
    ERROR
  | WARNING
  | INFORMATION
}

简单条件将字段与值进行比较或测试字段是否存在。要构建更复杂的条件,请使用ANDOR运算符。这两个运算符具有相同的优先级,并且从左到右进行评估。

要在字符串中转义字符,请在其前面加上反斜杠()。反斜杠用于包含反斜杠本身或字符串引号字符,对于其他字符是可选的。

为方便起见,log_filter_dragnet支持对某些字段进行比较的符号名称。为了可读性和可移植性,符号值比数值值更可取(适用的情况下)。

事件优先级值 1、2 和 3 可以指定为ERRORWARNINGINFORMATION。优先级符号仅在与prio字段进行比较时才被识别。这些比较是等效的:

代码语言:javascript复制
IF prio == INFORMATION THEN ...
IF prio == 3 THEN ...

错误代码可以以数字形式或相应的错误符号指定。例如,ER_STARTUP是错误1408的符号名称,因此这些比较是等效的:

代码语言:javascript复制
IF err_code == ER_STARTUP THEN ...
IF err_code == 1408 THEN ...

仅在与err_code字段和用户定义字段进行比较时才识别错误符号。

要找到与给定错误代码号对应的错误符号,请使用以下方法之一:

  • 在服务器错误消息参考中查看服务器错误列表。
  • 使用perror命令。给定一个错误号参数,perror会显示有关错误的信息,包括其符号。

假设一个带有错误号的规则集如下所示:

代码语言:javascript复制
IF err_code == 10927 OR err_code == 10914 THEN drop.
IF err_code == 1131 THEN drop.

使用perror,确定错误符号:

代码语言:javascript复制
$> perror 10927 10914 1131
MySQL error code MY-010927 (ER_ACCESS_DENIED_FOR_USER_ACCOUNT_LOCKED):
Access denied for user '%-.48s'@'%-.64s'. Account is locked.
MySQL error code MY-010914 (ER_ABORTING_USER_CONNECTION):
Aborted connection %u to db: '%-.192s' user: '%-.48s' host:
'%-.64s' (%-.64s).
MySQL error code MY-001131 (ER_PASSWORD_ANONYMOUS_USER):
You are using MySQL as an anonymous user and anonymous users
are not allowed to change passwords

通过用数字替换错误符号,规则集变为:

代码语言:javascript复制
IF err_code == ER_ACCESS_DENIED_FOR_USER_ACCOUNT_LOCKED
  OR err_code == ER_ABORTING_USER_CONNECTION THEN drop.
IF err_code == ER_PASSWORD_ANONYMOUS_USER THEN drop.

符号名称可以作为带引号的字符串指定,用于与字符串字段进行比较,但在这种情况下,名称是没有特殊含义的字符串,log_filter_dragnet不会将其解析为相应的数值。此外,拼写错误可能不会被检测到,而在尝试使用服务器不认识的未引用符号时,SET会立即出现错误。

log_filter_dragnet 规则的操作

log_filter_dragnet 在过滤规则中支持以下操作:

drop: 丢弃当前日志事件(不记录)。

throttle: 应用速率限制以减少匹配特定条件的事件的日志冗余。参数表示速率,形式为*countcount/window_sizecount值表示每个时间窗口允许记录的事件发生次数。window_size*值是以秒为单位的时间窗口;如果省略,则默认窗口为 60 秒。这两个值必须是整数文字。

此规则将插件关闭消息限制为每 60 秒 5 次:

代码语言:javascript复制
IF err_code == ER_PLUGIN_SHUTTING_DOWN_PLUGIN THEN throttle 5.

此规则将错误和警告限制为每小时 1000 次,信息消息限制为每小时 100 次:

代码语言:javascript复制
IF prio <= INFORMATION THEN throttle 1000/3600 ELSE throttle 100/3600.

set: 为字段赋值(如果字段不存在,则创建)。在后续规则中,对字段名称的EXISTS测试为真,并且新值可以通过比较条件进行测试。

unset: 丢弃一个字段。在后续规则中,对字段名称的EXISTS测试为假,并且对字段与任何值的比较为假。

在条件引用确切一个字段名称的特殊情况下,unset后面的字段名称是可选的,unset会丢弃命名字段。以下规则是等效的:

代码语言:javascript复制
IF myfield == 2 THEN unset myfield.
IF myfield == 2 THEN unset.
log_filter_dragnet 规则中的字段引用

log_filter_dragnet 规则支持在错误事件中引用核心、可选和用户定义的字段。

  • 核心字段引用
  • 可选字段引用
  • 用户定义字段引用
核心字段引用

log_filter_dragnet 规则语言语法中列出了过滤规则识别的核心字段。有关这些字段的一般描述,请参见 7.4.2.3 节“错误事件字段”,假定您已经熟悉。以下备注仅提供与log_filter_dragnet规则中核心字段引用相关的特定信息。

prio

事件优先级,用于指示错误、警告或注释/信息事件。在比较中,每个优先级可以指定为符号优先级名称或整数文字。优先级符号仅在与prio字段的比较中被识别。以下比较是等效的:

代码语言:javascript复制
IF prio == INFORMATION THEN ...
IF prio == 3 THEN ...

以下表格显示了允许的优先级级别。

事件类型

优先级符号

数字优先级

错误事件

ERROR

1

警告事件

WARNING

2

注意/信息事件

信息

3

还有一个消息优先级为 SYSTEM,但系统消息无法被过滤,并且始终写入错误日志。

优先级值遵循更高优先级具有较低值,反之亦然的原则。优先级值从最严重事件(错误)开始为 1,并随着优先级降低的事件而增加。例如,要丢弃优先级低于警告的事件,请测试高于 WARNING 的优先级值:

代码语言:javascript复制
IF prio > WARNING THEN drop.

以下示例显示了实现与每个 log_error_verbosity 值类似效果的 log_filter_dragnet 规则:

仅错误(log_error_verbosity=1):

代码语言:javascript复制
IF prio > ERROR THEN drop.

错误和警告(log_error_verbosity=2):

代码语言:javascript复制
IF prio > WARNING THEN drop.

错误、警告和注释(log_error_verbosity=3):

代码语言:javascript复制
IF prio > INFORMATION THEN drop.

实际上,这个规则可以被省略,因为没有比 INFORMATION 更大的 prio 值,因此实际上它什么也不丢弃。

err_code

数字事件错误代码。在比较中,要测试的值可以指定为符号错误名称或整数文字。错误符号仅在与 err_code 字段和用户定义字段的比较中被识别。这些比较是等效的:

代码语言:javascript复制
IF err_code == ER_ACCESS_DENIED_ERROR THEN ...
IF err_code == 1045 THEN ...

err_symbol

事件错误符号,作为字符串(例如,'ER_DUP_KEY')。 err_symbol 值更适用于识别日志输出中的特定行,而不适用于用于过滤规则比较,因为 log_filter_dragnet 不会将指定为字符串的比较值解析为等效的数值错误代码。(为了发生这种情况,必须使用未引用的符号指定错误。)

可选字段引用

log_filter_dragnet 语法在 Grammar for log_filter_dragnet Rule Language 中命名了过滤规则识别的可选字段。有关这些字段的一般描述,请参见 Section 7.4.2.3, “Error Event Fields”,假定您已熟悉。以下备注仅提供与 log_filter_dragnet 规则中使用的可选字段引用相关的特定信息。

标签

prio 值对应的标签,作为字符串。过滤规则可以更改支持自定义标签的日志接收器的标签。 label 值更适用于识别日志输出中的特定行,而不适用于用于过滤规则比较,因为 log_filter_dragnet 不会将指定为字符串的比较值解析为等效的数值优先级。

source_file

事件发生的源文件,不包含任何前导路径。例如,要测试 sql/gis/distance.cc 文件,写比较如下:

代码语言:javascript复制
IF source_file == "distance.cc" THEN ...
用户定义字段引用

log_filter_dragnet过滤规则中,任何未被识别为核心或可选字段名称的字段名称都被视为用户定义字段。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-json.html

7.4.2.7 JSON 格式错误日志

本节描述了如何使用内置过滤器log_filter_internal和 JSON sinklog_sink_json立即生效并在后续服务器启动时生效。有关配置错误日志的一般信息,请参阅 Section 7.4.2.1, “错误日志配置”。

要启用 JSON sink,请首先加载 sink 组件,然后修改log_error_services的值:

代码语言:javascript复制
INSTALL COMPONENT 'file://component_log_sink_json';
SET PERSIST log_error_services = 'log_filter_internal; log_sink_json';

要在服务器启动时设置log_error_services生效,请使用 Section 7.4.2.1, “错误日志配置”中的说明。这些说明也适用于其他错误日志系统变量。

log_error_services的值中可以多次命名log_sink_json。例如,要使用一个实例写入未经过滤的事件,使用另一个实例写入经过滤的事件,可以设置log_error_services如下:

代码语言:javascript复制
SET PERSIST log_error_services = 'log_sink_json; log_filter_internal; log_sink_json';

JSON sink 根据默认错误日志目的地确定其输出目的地,该目的地由log_error系统变量给出。如果log_error命名一个文件,则 JSON sink 基于该文件名进行输出文件命名,加上一个编号为.*NN*.json的后缀,其中*NN从 00 开始。例如,如果log_errorfile_name*,则在log_error_services的值中连续的log_sink_json实例将写入*file_name*.00.json*file_name*.01.json等。

如果log_errorstderr,则 JSON sink 写入控制台。如果在log_error_services的值中多次命名log_sink_json,它们都将写入控制台,这可能没有用处。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-syslog.html

7.4.2.8 将错误日志记录到系统日志

可以让mysqld将错误日志写入系统日志(Windows 上的事件日志,Unix 和类 Unix 系统上的syslog)。

本节描述如何使用内置过滤器log_filter_internal和系统日志接收器log_sink_syseventlog配置错误日志记录,以立即生效并在后续服务器启动时生效。有关配置错误日志的一般信息,请参阅 Section 7.4.2.1, “错误日志配置”。

要启用系统日志接收器,首先加载接收器组件,然后修改log_error_services的值:

代码语言:javascript复制
INSTALL COMPONENT 'file://component_log_sink_syseventlog';
SET PERSIST log_error_services = 'log_filter_internal; log_sink_syseventlog';

要在服务器启动时设置log_error_services生效,请使用 Section 7.4.2.1, “错误日志配置”中的说明。这些说明也适用于其他错误日志系统变量。

注意

对于 MySQL 8.0 配置,您必须显式启用将错误日志记录到系统日志。这与 MySQL 5.7 及更早版本不同,在 Windows 上默认启用将错误日志记录到系统日志,并且在所有平台上不需要加载组件。

将错误日志记录到系统日志可能需要额外的系统配置。请查阅您平台的系统日志文档。

在 Windows 上,写入应用程序日志中的事件日志错误消息具有以下特征:

  • 标记为ErrorWarningNote的条目会被写入事件日志,但不包括来自各个存储引擎的信息声明。
  • 事件日志条目的来源是MySQL(或MySQL-*tag*,如果syseventlog.tag定义为*tag*)。

在 Unix 和类 Unix 系统上,记录到系统日志使用syslog。以下系统变量会影响syslog消息:

  • syseventlog.facilitysyslog消息的默认设施是daemon。设置此变量以指定不同的设施。
  • syseventlog.include_pid:是否在每行syslog输出中包含服务器进程 ID。
  • syseventlog.tag:此变量定义要添加到syslog消息中服务器标识符(mysqld)的标记。如果定义了标记,则标记将以前导连字符附加到标识符后面。

注意

在 MySQL 8.0.13 之前,请使用log_syslog_facilitylog_syslog_include_pidlog_syslog_tag系统变量,而不是syseventlog.*xxx*变量。

MySQL 使用自定义标签“系统”来表示关于非错误情况的重要系统消息,例如启动、关闭和一些重要设置更改。在不支持自定义标签的日志中,包括 Windows 上的事件日志和 Unix 及类 Unix 系统上的syslog,系统消息被分配给信息优先级级别使用的标签。然而,即使 MySQL log_error_verbosity 设置通常排除信息级别的消息,这些消息也会被打印到日志中。

当日志接收器必须以“信息”标签而不是“系统”标签回退时,并且日志事件在 MySQL 服务器外进一步处理(例如,通过syslog配置进行过滤或转发),这些事件可能默认由次要应用程序处理为“信息”优先级而不是“系统”优先级。

原文:dev.mysql.com/doc/refman/8.0/en/error-log-format.html

7.4.2.9 错误日志输出格式

每个错误日志输出组件都有其用于将消息写入目的地的特征输出格式,但其他因素可能影响消息的内容:

  • 日志输出可用的信息。如果在执行输出组件之前执行了日志过滤组件以删除日志事件字段,则该字段不可用于写入。有关日志过滤的信息,请参阅第 7.4.2.4 节,“错误日志过滤类型”。
  • 与日志输出组件相关的信息。并非每个输出组件都会写入错误事件中可用的所有字段。
  • 系统变量可能会影响日志输出。请参阅影响错误日志格式的系统变量。

有关错误事件中字段的名称和描述,请参阅第 7.4.2.3 节,“错误事件字段”。对于所有日志输出,包含在错误日志消息中的线程 ID 是负责编写消息的mysqld内的线程 ID。此 ID 指示服务器的哪个部分生成了消息,并与一般查询日志和慢查询日志消息一致,这些消息包括连接线程 ID。

  • log_sink_internal 输出格式
  • log_sink_json 输出格式
  • log_sink_syseventlog 输出格式
  • 早期启动日志输出格式
  • 影响错误日志格式的系统变量
log_sink_internal 输出格式

内部日志输出产生传统错误日志输出。例如:

代码语言:javascript复制
2020-08-06T14:25:02.835618Z 0 [Note] [MY-012487] [InnoDB] DDL log recovery : begin
2020-08-06T14:25:02.936146Z 0 [Warning] [MY-010068] [Server] CA certificate /var/mysql/sslinfo/cacert.pem is self signed.
2020-08-06T14:25:02.963127Z 0 [Note] [MY-010253] [Server] IPv6 is available.
2020-08-06T14:25:03.109022Z 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5

传统格式消息具有以下字段:

代码语言:javascript复制
time thread [label] [err_code] [subsystem] msg

[] 方括号字符是消息格式中的文字字符。它们不表示字段是可选的。

label 值对应于 prio 错误事件优先级字段的字符串形式。

[err_code][subsystem] 字段在 MySQL 8.0 中添加。这些字段在旧服务器生成的日志中缺失。日志解析器可以将这些字段视为仅在包含它们的新服务器生成的日志中存在的消息文本的一部分。解析器必须将 [err_code] 指示器中的 err_code 部分视为字符串值,而不是数字,因为像 MY-012487MY-010051 这样的值包含非数字字符。

log_sink_json 输出格式

JSON 格式的日志接收器生成包含键值对的 JSON 对象作为消息。例如:

代码语言:javascript复制
{
  "prio": 3,
  "err_code": 10051,
  "source_line": 561,
  "source_file": "event_scheduler.cc",
  "function": "run",
  "msg": "Event Scheduler: scheduler thread started with id 5",
  "time": "2020-08-06T14:25:03.109022Z",
  "ts": 1596724012005,
  "thread": 5,
  "err_symbol": "ER_SCHEDULER_STARTED",
  "SQL_state": "HY000",
  "subsystem": "Server",
  "buffered": 1596723903109022,
  "label": "Note"
}

显示的消息已经重新格式化以提高可读性。写入错误日志的事件每行显示一条消息。

ts(时间戳)键在 MySQL 8.0.20 中添加,是 JSON 格式日志接收器特有的。其值是一个整数,表示自纪元('1970-01-01 00:00:00' UTC)以来的毫秒数。

tsbuffered 值是 Unix 时间戳值,可以使用 FROM_UNIXTIME() 和适当的除数进行转换:

代码语言:javascript复制
mysql> SET time_zone = ' 00:00';
mysql> SELECT FROM_UNIXTIME(1596724012005/1000.0);
 ------------------------------------- 
| FROM_UNIXTIME(1596724012005/1000.0) |
 ------------------------------------- 
| 2020-08-06 14:26:52.0050            |
 ------------------------------------- 
mysql> SELECT FROM_UNIXTIME(1596723903109022/1000000.0);
 ------------------------------------------- 
| FROM_UNIXTIME(1596723903109022/1000000.0) |
 ------------------------------------------- 
| 2020-08-06 14:25:03.1090                  |
 ------------------------------------------- 
log_sink_syseventlog 输出格式

系统日志接收器生成符合本地平台使用的系统日志格式的输出。

早期启动日志输出格式

服务器在启动选项被处理之前生成一些错误日志消息,因此在了解错误日志设置(如log_error_verbositylog_timestamps系统变量值)以及要使用的日志组件之前。服务器处理在启动过程中生成的错误日志消息如下:

  • 在 MySQL 8.0.14 之前,服务器生成具有默认时间戳、格式和详细级别的消息,并对其进行缓冲。在处理启动选项并了解错误日志配置之后,服务器会刷新缓冲的消息。由于这些早期消息使用默认日志配置,它们可能与启动选项指定的内容不同。此外,早期消息不会刷新到除默认接收器之外的日志接收器。例如,记录到 JSON 接收器不包括这些早期消息,因为它们不是 JSON 格式。
  • 从 MySQL 8.0.14 开始,服务器缓冲日志事件而不是格式化的日志消息。这使得在了解设置之后可以对这些事件进行追溯应用配置设置,结果是刷新的消息使用配置的设置,而不是默认设置。此外,消息会刷新到所有配置的接收器,而不仅仅是默认接收器。 如果在日志配置未知之前发生致命错误并且服务器必须退出,则服务器使用日志默认值格式化缓冲消息,以免丢失。如果没有发生致命错误,但启动在处理启动选项之前过于缓慢,则服务器会定期使用日志默认值格式化和刷新缓冲消息,以免显得无响应。尽管这种行为类似于 8.0.14 之前的行为,即使用默认值,但在异常情况发生时不丢失消息更为可取。
影响错误日志格式的系统变量

log_timestamps系统变量控制写入错误日志(以及一般查询日志和慢查询日志文件)中时间戳的时区。服务器在错误事件到达任何日志接收端之前应用log_timestamps,因此它影响所有接收端的错误消息输出。

允许的log_timestamps值为UTC(默认)和SYSTEM(本地系统时区)。时间戳使用 ISO 8601 / RFC 3339 格式写入:*YYYY-MM-DD*T*hh:mm:ss.uuuuuu* 加上一个尾部值Z表示 Zulu 时间(UTC)或±hh:mm(一个指示本地系统时区相对于 UTC 的调整偏移)。例如:

代码语言:javascript复制
2020-08-07T15:02:00.832521Z            (UTC)
2020-08-07T10:02:00.832521-05:00       (SYSTEM)

原文:dev.mysql.com/doc/refman/8.0/en/error-log-rotation.html

7.4.2.10 错误日志文件清空和重命名

如果使用FLUSH ERROR LOGSFLUSH LOGS语句,或者使用mysqladmin flush-logs命令来清空错误日志,服务器将关闭并重新打开正在写入的任何错误日志文件。在清空之前,请手动重命名错误日志文件。清空日志后,将使用原始文件名打开一个新文件。例如,假设日志文件名为*host_name*.err,请使用以下命令重命名文件并创建一个新文件:

代码语言:javascript复制
mv *host_name*.err *host_name*.err-old
mysqladmin flush-logs error
mv *host_name*.err-old *backup-directory*

在 Windows 上,请使用rename而不是mv

如果服务器无法写入错误日志文件的位置,则清空日志操作将无法创建新的日志文件。例如,在 Linux 上,服务器可能会将错误日志写入/var/log/mysqld.log文件,其中/var/log目录由root所有且不可写入mysqld。有关处理此情况的信息,请参见第 7.4.6 节“服务器日志维护”。

如果服务器没有写入命名的错误日志文件,则在清空错误日志时不会发生错误日志文件重命名。

7.4.3 通用查询日志

译文:dev.mysql.com/doc/refman/8.0/en/query-log.html

通用查询日志是mysqld正在执行的一般记录。当客户端连接或断开连接时,服务器会将信息写入此日志,并记录从客户端接收的每个 SQL 语句。当您怀疑客户端中存在错误并想确切知道客户端发送给mysqld的内容时,通用查询日志可能非常有用。

每当客户端连接时显示的每一行还包括using *connection_type*,表示建立连接所使用的协议。*connection_type*可以是TCP/IP(未使用 SSL 建立的 TCP/IP 连接)、SSL/TLS(使用 SSL 建立的 TCP/IP 连接)、Socket(Unix 套接字文件连接)、Named Pipe(Windows 命名管道连接)或Shared Memory(Windows 共享内存连接)。

mysqld按照接收到的顺序将语句写入查询日志,这可能与执行顺序不同。这种记录顺序与二进制日志的记录顺序相反,二进制日志中的语句是在执行后但在释放任何锁之前写入的。此外,查询日志可能包含仅选择数据的语句,而这些语句永远不会写入二进制日志。

在复制源服务器上使用基于语句的二进制日志记录时,其副本接收的语句将写入每个副本的查询日志。如果客户端使用mysqlbinlog实用程序读取事件并将其传递给服务器,则语句将写入源的查询日志。

然而,当使用基于行的二进制日志记录时,更新以行更改的形式发送,而不是 SQL 语句,因此当binlog_format设置为ROW时,这些语句永远不会写入查询日志。当此变量设置为MIXED时,根据使用的语句,给定的更新也可能不会写入查询日志。有关更多信息,请参见 Section 19.2.1.1, “基于语句和基于行的复制的优缺点”。

默认情况下,通用查询日志被禁用。要明确指定初始通用查询日志状态,请使用--general_log[={0|1}]。没有参数或参数为 1 时,--general_log启用日志。参数为 0 时,此选项禁用日志。要指定日志文件名,请使用--general_log_file=*file_name*。要指定日志目的地,请使用log_output系统变量(如第 7.4.1 节,“选择通用查询日志和慢查询日志输出目的地”中所述)。

注意

如果指定了TABLE日志目的地,请参阅日志表和“打开文件过多”错误。

如果未为通用查询日志文件指定名称,则默认名称为*host_name*.log。服务器会在数据目录中创建文件,除非给定绝对路径名以指定不同的目录。

要在运行时禁用或启用通用查询日志或更改日志文件名,请使用全局general_loggeneral_log_file系统变量。将general_log设置为 0(或OFF)以禁用日志,设置为 1(或ON)以启用日志。设置general_log_file以指定日志文件的名称。如果已经打开了日志文件,则会关闭该文件并打开新文件。

当启用通用查询日志时,服务器会将输出写入由log_output系统变量指定的任何目的地。如果启用日志,服务器会打开日志文件并将启动消息写入其中。但是,除非选择了FILE日志目的地,否则不会进一步记录查询到文件中。如果目的地是NONE,即使启用了通用日志,服务器也不会写入任何查询。如果日志目的地值不包含FILE,设置日志文件名对日志记录没有影响。

服务器重启和日志刷新不会导致生成新的通用查询日志文件(尽管刷新会关闭并重新打开它)。要重命名文件并创建一个新文件,请使用以下命令:

代码语言:javascript复制
$> mv *host_name*.log *host_name*-old.log
$> mysqladmin flush-logs general
$> mv *host_name*-old.log *backup-directory*

在 Windows 上,使用rename而不是mv

您还可以通过禁用日志来在运行时重命名通用查询日志文件:

代码语言:javascript复制
SET GLOBAL general_log = 'OFF';

禁用日志后,通过外部重命名日志文件(例如,从命令行)然后再次启用日志:

代码语言:javascript复制
SET GLOBAL general_log = 'ON';

这种方法适用于任何平台,不需要服务器重启。

要为当前会话禁用或启用一般查询日志记录,请将会话 sql_log_off 变量设置为 ONOFF。(这假定一般查询日志本身已启用。)

写入一般查询日志的语句中的密码会被服务器重写,以避免以明文形式出现。可以通过使用 --log-raw 选项启动服务器来阻止一般查询日志的密码重写。这个选项可能对诊断目的有用,以查看服务器接收到的语句的确切文本,但出于安全原因,不建议在生产环境中使用。另请参见 Section 8.1.2.3, “Passwords and Logging”。

密码重写的一个影响是无法解析的语句(例如由于语法错误)不会被写入一般查询日志,因为无法知道它们是否不包含密码。需要记录所有语句(包括带有错误的语句)的用例应该使用 --log-raw 选项,需要注意的是这也会绕过密码重写。

只有在预期明文密码时才会进行密码重写。对于期望密码哈希值的语法的语句,不会进行重写。如果错误地为这种语法提供了明文密码,则密码将按原样记录,而不进行重写。

log_timestamps 系统变量控制着写入一般查询日志文件(以及慢查询日志文件和错误日志)中的时间戳的时区。它不影响写入日志表的一般查询日志和慢查询日志消息的时区,但是从这些表中检索的行可以通过 CONVERT_TZ() 或设置会话 time_zone 系统变量将其从本地系统时区转换为任何所需的时区。

7.4.4 二进制日志

原文:dev.mysql.com/doc/refman/8.0/en/binary-log.html

7.4.4.1 二进制日志格式

7.4.4.2 设置二进制日志格式

7.4.4.3 混合二进制日志格式

7.4.4.4 更改 mysql 数据库表的日志格式

7.4.4.5 二进制日志事务压缩

二进制日志包含描述数据库更改的“事件”,例如表创建操作或表数据更改。它还包含可能已经进行更改的语句的事件(例如,一个DELETE未匹配任何行),除非使用基于行的日志记录。二进制日志还包含更新数据的每个语句所花费的时间信息。二进制日志有两个重要目的:

  • 对于复制,复制源服务器上的二进制日志提供了要发送到副本的数据更改记录。源服务器将其二进制日志中包含的信息发送给其副本,副本会重现这些事务以进行与源服务器上进行的相同数据更改。参见第 19.2 节,“复制实现”。
  • 某些数据恢复操作需要使用二进制日志。在备份被恢复后,备份后记录的二进制日志中的事件将被重新执行。这些事件将数据库从备份点更新到最新状态。参见第 9.5 节,“时间点(增量)恢复” Recovery")。

二进制日志不用于诸如SELECTSHOW等不修改数据的语句。要记录所有语句(例如,以识别问题查询),请使用一般查询日志。参见第 7.4.3 节,“一般查询日志”。

启用二进制日志记录的服务器运行性能略有下降。然而,二进制日志在启用复制和进行恢复操作方面的好处通常超过了这种轻微的性能降低。

二进制日志对意外停止是有弹性的。只有完整的事件或事务才会被记录或读取回来。

写入二进制日志的语句中的密码由服务器重写,以避免明文出现。另请参见第 8.1.2.3 节,“密码和日志记录”。

从 MySQL 8.0.14 开始,二进制日志文件和中继日志文件可以加密,有助于保护这些文件以及其中可能包含的敏感数据免受外部攻击者的滥用,也免受存储它们的操作系统用户的未经授权查看。 您可以通过将 binlog_encryption 系统变量设置为 ON 在 MySQL 服务器上启用加密。 有关更多信息,请参见 Section 19.3.2, “加密二进制日志文件和中继日志文件”。

以下讨论描述了一些影响二进制日志记录操作的服务器选项和变量。 完整列表,请参见 Section 19.1.6.4, “二进制日志记录选项和变量”。

二进制日志记录默认启用(log_bin 系统变量设置为 ON)。 例外情况是,如果您使用 mysqld 手动调用 --initialize--initialize-insecure 选项初始化数据目录,则默认情况下禁用二进制日志记录,但可以通过指定 --log-bin 选项启用。

要禁用二进制日志记录,您可以在启动时指定 --skip-log-bin--disable-log-bin 选项。 如果指定了其中任何一个选项,并且同时指定了 --log-bin,则后面指定的选项优先。

--log-slave-updates--slave-preserve-commit-order选项需要进行二进制日志记录。如果禁用二进制日志记录,要么省略这些选项,要么指定--log-slave-updates=OFF--skip-slave-preserve-commit-order。当指定--skip-log-bin--disable-log-bin时,MySQL 默认禁用这些选项。如果同时指定--log-slave-updates--slave-preserve-commit-order--skip-log-bin--disable-log-bin,将发出警告或错误消息。

--log-bin[=*base_name*]选项用于指定二进制日志文件的基本名称。如果不提供--log-bin选项,MySQL 将使用binlog作为二进制日志文件的默认基本名称。为了与早期版本兼容,如果提供了--log-bin选项但没有字符串或为空字符串,则基本名称默认为*host_name*-bin,使用主机机器的名称。建议您指定一个基本名称,这样如果主机名更改,您可以轻松地继续使用相同的二进制日志文件名称(参见 Section B.3.7, “Known Issues in MySQL”)。如果在日志名称中提供了扩展名(例如,--log-bin=*base_name.extension*),则扩展名会被静默删除并忽略。

mysqld会在二进制日志基本名称后附加一个数字扩展名以生成二进制日志文件名称。每次服务器创建新的日志文件时,该数字会增加,从而创建一个有序的文件系列。每当发生以下事件之一时,服务器都会在系列中创建一个新文件:

  • 服务器启动或重新启动
  • 服务器会刷新日志。
  • 当��日志文件的大小达到max_binlog_size设置的大小。

如果使用大型事务,二进制日志文件可能会比max_binlog_size设置的大小更大,因为事务会一次性写入文件,而不会在文件之间分割。

为了跟踪已使用的二进制日志文件,mysqld还会创建一个包含二进制日志文件名称的二进制日志索引文件。默认情况下,这个文件与二进制日志文件具有相同的基本名称,扩展名为'.index'。您可以使用--log-bin-index[=*file_name*]选项更改二进制日志索引文件的名称。在mysqld运行时不应手动编辑此文件;这样做会使mysqld混淆。

术语“二进制日志文件”通常表示包含数据库事件的单个编号文件。术语“二进制日志”集体表示一组编号的二进制日志文件和索引文件。

默认的二进制日志文件和二进制日志索引文件的位置是数据目录。您可以使用--log-bin选项来指定另一个位置,只需在基本名称前添加绝对路径名以指定不同的目录。当服务器从二进制日志索引文件中读取条目时(该文件跟踪已使用的二进制日志文件),它会检查条目是否包含相对路径。如果包含相对路径,则使用--log-bin选项设置的绝对路径将替换路径的相对部分。在二进制日志索引文件中记录的绝对路径保持不变;在这种情况下,必须手动编辑索引文件以启用新路径或路径的使用。二进制日志文件基本名称和任何指定的路径可作为log_bin_basename系统变量使用。

在 MySQL 5.7 中,启用二进制日志记录时必须指定服务器 ID,否则服务器将无法启动。在 MySQL 8.0 中,默认情况下将server_id系统变量设置为 1。当启用二进制日志记录时,服务器可以使用此默认 ID 启动,但如果您不使用server_id系统变量显式指定服务器 ID,则会发出信息消息。对于用于复制拓扑的服务器,必须为每个服务器指定唯一的非零服务器 ID。

拥有足够权限设置受限会话系统变量的客户端(参见第 7.1.9.1 节,“系统变量权限”)可以通过使用SET sql_log_bin=OFF语句禁用自己语句的二进制日志记录。

默认情况下,服务器记录事件的长度以及事件本身,并使用这些信息来验证事件是否正确写入。您还可以通过设置binlog_checksum系统变量来导致服务器为事件编写校验和。从二进制日志中读取时,默认情况下源使用事件长度,但可以通过启用系统变量source_verify_checksum(从 MySQL 8.0.26 开始)或master_verify_checksum(在 MySQL 8.0.26 之前)来使用校验和(如果可用)。副本上的复制 I/O(接收器)线程还会验证从源接收的事件。您可以通过启用系统变量replica_sql_verify_checksum(从 MySQL 8.0.26 开始)或slave_sql_verify_checksum(在 MySQL 8.0.26 之前)来导致复制 SQL(应用程序)线程在从中继日志读取时使用校验和(如果可用)。

记录在二进制日志中的事件的格式取决于二进制日志格式。支持三种格式类型:基于行的日志记录、基于语句的日志记录和混合基于日志记录。所使用的二进制日志格式取决于 MySQL 版本。有关日志格式的一般描述,请参见 Section 7.4.4.1, “Binary Logging Formats”。有关二进制日志格式的详细信息,请参见 MySQL Internals: The Binary Log。

服务器以与--replicate-do-db--replicate-ignore-db选项相同的方式评估--binlog-do-db--binlog-ignore-db选项。有关此操作的信息,请参见 Section 19.2.5.1, “Evaluation of Database-Level Replication and Binary Logging Options”。

一个复制品默认启用系统变量log_replica_updates(从 MySQL 8.0.26 开始)或log_slave_updates(MySQL 8.0.26 之前),这意味着复制品会将从源接收到的任何数据修改写入自己的二进制日志。必须启用二进制日志才能使此设置生效(参见第 19.1.6.3 节,“复制品服务器选项和变量”)。此设置使复制品能够作为其他复制品的源。

您可以使用RESET MASTER语句删除所有二进制日志文件,或使用PURGE BINARY LOGS删除其中的一部分。请参见第 15.7.8.6 节,“RESET 语句”,以及第 15.4.1.1 节,“PURGE BINARY LOGS 语句”。

如果您正在使用复制,应在确定没有复制品仍然需要使用旧二进制日志文件之前,不要删除源上的旧二进制日志文件。例如,如果您的复制品永远不会落后于三天,那么每天您可以在源上执行mysqladmin flush-logs binary,然后删除三天前的任何日志。您可以手动删除文件,但最好使用PURGE BINARY LOGS,这也会安全地为您更新二进制日志索引文件(并且可以接受日期参数)。请参见第 15.4.1.1 节,“PURGE BINARY LOGS 语句”。

您可以使用mysqlbinlog实用程序显示二进制日志文件的内容。当您想要重新处理日志中的语句以进行恢复操作时,这可能很有用。例如,您可以按以下方式从二进制日志更新 MySQL 服务器:

代码语言:javascript复制
$> mysqlbinlog *log_file* | mysql -h *server_name*

mysqlbinlog还可以用于显示复制品上中继日志文件的内容,因为它们使用与二进制日志文件相同的格式进行编写。有关mysqlbinlog实用程序及其使用方法的更多信息,请参见第 6.6.9 节,“mysqlbinlog — 用于处理二进制日志文件的实用���序”。有关二进制日志和恢复操作的更多信息,请参见第 9.5 节,“时间点(增量)恢复”。

二进制日志记录在语句或事务完成后立即进行,但在释放任何锁或执行任何提交之前。这确保了日志按提交顺序记录。

对非事务表的更新会立即存储在二进制日志中。

在未提交的事务中,所有更新(UPDATEDELETEINSERT)对更改事务表(如 InnoDB 表)的操作都会被缓存,直到服务器接收到 COMMIT 语句。此时,mysqld 在执行 COMMIT 之前将整个事务写入二进制日志。

对非事务表的修改无法回滚。如果要回滚的事务包括对非事务表的修改,则整个事务将以 ROLLBACK 语句记录,以确保这些表的修改被复制。

当处理事务的线程启动时,它会分配一个大小为 binlog_cache_size 的缓冲区来缓冲语句。如果语句大于此值,线程将打开一个临时文件来存储事务。当线程结束时,临时文件将被删除。从 MySQL 8.0.17 开始,如果服务器上启用了二进制日志加密,则临时文件将被加密。

Binlog_cache_use 状态变量显示了使用此缓冲区(可能还包括临时文件)存储语句的事务数量。Binlog_cache_disk_use 状态变量显示了实际需要使用临时文件的事务数量。这两个变量可用于调整 binlog_cache_size 的值,使其足够大,避免使用临时文件。

max_binlog_cache_size 系统变量(默认为 4GB,也是最大值)可用于限制用于缓存多语句事务的总大小。如果事务大于此字节数,它将失败并回滚。最小值为 4096。

如果您正在使用二进制日志和基于行的日志记录,CREATE ... SELECTINSERT ... SELECT语句中的并发插入将转换为普通插入。这样做是为了确保您可以通过在备份操作期间应用日志来重新创建表的精确副本。如果使用基于语句的日志记录,则原始语句将写入日志。

二进制日志格式存在一些已知限制,可能会影响从备份中恢复。参见第 19.5.1 节,“复制功能和问题”。

存储程序的二进制日志记录如第 27.7 节,“存储程序二进制日志记录”所述。

请注意,由于复制功能的增强,MySQL 8.0 中的二进制日志格式与 MySQL 先前版本不同。请参见第 19.5.2 节,“MySQL 版本之间的复制兼容性”。

如果服务器无法写入二进制日志,刷新二进制日志文件,或将二进制日志同步到磁盘,复制源服务器上的二进制日志可能会变得不一致,副本可能会与源失去同步。binlog_error_action系统变量控制在遇到此类错误时采取的操作。

  • 默认设置ABORT_SERVER使服务器停止二进制日志记录并关闭。此时,您可以识别和纠正错误的原因。在重新启动时,恢复将如同意外服务器停止的情况一样进行(参见第 19.4.2 节,“处理副本意外停止”)。
  • 设置IGNORE_ERROR提供与旧版本 MySQL 的向后兼容性。使用此设置,服务器将继续进行进行中的事务并记录错误,然后停止二进制日志记录,但继续执行更新。此时,您可以识别和纠正错误的原因。要恢复二进制日志记录,必须重新启用log_bin,这需要重新启动服务器。只有在需要向后兼容性,并且二进制日志在此 MySQL 服务器实例上是非必需的情况下才使用此选项。例如,您可能仅将二进制日志用于服务器的间歇性审计或调试,并且不将其用于从服务器复制或依赖于其进行时间点还原操作。

默认情况下,二进制日志在每次写入时都会同步到磁盘(sync_binlog=1)。如果未启用sync_binlog,并且操作系统或机器(不仅仅是 MySQL 服务器)崩溃,那么二进制日志的最后几条语句可能会丢失。为了防止这种情况发生,启用sync_binlog系统变量,以在每个*N*提交组后将二进制日志同步到磁盘。参见第 7.1.8 节,“服务器系统变量”。sync_binlog的最安全值是 1(默认值),但这也是最慢的。

在早期的 MySQL 版本中,即使将sync_binlog设置为 1,如果发生崩溃,表内容和二进制日志内容之间仍可能存在不一致的情况。例如,如果您正在使用InnoDB表,并且 MySQL 服务器处理一个COMMIT语句,它会按顺序将许多准备好的事务写入二进制日志,同步二进制日志,然后将事务提交到InnoDB。如果服务器在这两个操作之间意外退出,InnoDB会在重新启动时回滚事务,但事务仍然存在于二进制日志中。在以前的版本中,通过在 XA 事务中启用InnoDB支持两阶段提交来解决了这个问题。在 MySQL 8.0 中,InnoDB对 XA 事务中的两阶段提交始终是启用的。

InnoDB对 XA 事务中的两阶段提交支持确保了二进制日志和InnoDB数据文件的同步。然而,MySQL 服务器还应配置为在提交事务之前将二进制日志和InnoDB日志同步到磁盘。InnoDB日志默认是同步的,而sync_binlog=1确保了二进制日志的同步。隐式InnoDB对 XA 事务中的两阶段提交支持和sync_binlog=1的效果是,在崩溃后重新启动后,在回滚事务后,MySQL 服务器会扫描最新的二进制日志文件以收集事务*xid*值,并计算二进制日志文件中的最后有效位置。然后,MySQL 服务器告诉InnoDB完成已成功写入二进制日志的任何准备好的事务,并将二进制日志截断到最后的有效位置。这确保了二进制日志反映了InnoDB表的确切数据,因此复制品保持与源的同步,因为它不会接收已回滚的语句。

如果 MySQL 服务器在崩溃恢复时发现二进制日志比应该的长度短,那么至少缺少一个成功提交的InnoDB事务。如果sync_binlog=1,并且磁盘/文件系统在被请求时进行了实际同步(有些不会),那么不应该发生这种情况,因此服务器会打印错误消息The binary log *file_name* is shorter than its expected size。在这种情况下,此二进制日志不正确,复制应该从源数据的新快照重新启动。

以下系统变量的会话值将被写入二进制日志,并在解析二进制日志时被复制实例所遵守:

  • sql_mode(除了NO_DIR_IN_CREATE模式不会被复制;参见第 19.5.1.39 节,“复制和变量”)
  • foreign_key_checks
  • unique_checks
  • character_set_client
  • collation_connection
  • collation_database
  • collation_server
  • sql_auto_is_null

0 人点赞