概述
本章,您将学习 MySQL 中有关日志管理方面的内容。
日志分类
MySQL 中,日志被划分为 2 大类 7 种日志:
-
服务层面的日志,主要有:
- 错误日志(Error log) - 记录 MySQL 实例启动、停止以及运行过程中的错误等方面的日志。默认开启,无法关闭
- 常规查询日志(General query log) - 记录当客户端连接后执行了哪些 SQL 语句。默认关闭,即系统变量 general_log 的默认值为 OFF
- 二进制日志(Bin log) - 记录任何 成功执行 后引起 数据变化 的日志。select 语句、show 语句、事务的回滚、SQL 语法错误未能成功执行等不会被记录。默认开启,即系统变量
log_bin的值为 ON - 慢查询日志(Slow query log) - 用来记录在 MySQL 中响应时间超过阀值的语句。例如当当前 MySQL 实例的性能下降时,可开启该日志进行分析处理。默认关闭,即系统变量
slow_query_log的值为 OFF - 中继日志(Relay log) - 主从复制中,从服务器记录与主服务器同步后接受到的数据变更
-
存储引擎日志(主要指的是 InnoDB 存储引擎),主要有:
- 重做日志(Redo log) - 属于事务日志,保证事务ACID种的D(持久性)
- 回滚日志(Undo log) - 属于事务日志,保证事务ACID种的A(原子性)
这几种日志类型当中,可以直接通过 vim 等打开的有:
- 错误日志(Rrror log)
- 常规查询日志(General query log)
只能通过 mysqlbinlog 命令打开的有:
- 二进制日志(Bin log)
- 慢查询日志(Slow query log)
- 中继日志(Relay log)
- 重做日志(Redo log)
- 回滚日志(Undo log)
错误日志
通常而言,错误日志都会在 /etc/my.cnf 配置文件中进行配置。当 MySQL 实例成功启动后,我们可以通过相关的进程查看到:
Shell > cat /etc/my.cnf
...
[mysqld]
...
log-error = /usr/local/mysql8/data/mysqld_start.err
...
Shell > /usr/local/mysql8/bin/mysqld_safe --user=mysql &
Shell > ps -lef
4 S mysql 1894 1564 43 80 0 - 713335 x64_sy 13:58 pts/0 00:00:05 /usr/local/mysql8/bin/mysqld --basedir=/usr/local/mysql8/ --datadir=/usr/local/mysql8/data --plugin-dir=/usr/local/mysql8//lib/plugin --user=mysql --log-error=/usr/local/mysql8/data/mysqld_start.err --pid-file=HOME01.pid --socket=/tmp/mysql.sock --port=3306
Shell > cat /usr/local/mysql8/data/mysqld_start.err
...
2025-11-02T05:59:04.269876Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2025-11-02T05:59:04.269959Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2025-11-02T05:59:04.413908Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock
2025-11-02T05:59:04.415252Z 0 [System] [MY-010931] [Server] /usr/local/mysql8/bin/mysqld: ready for connections. Version: '8.4.6' socket: '/tmp/mysql.sock' port: 3306 Source distribution.
可以看到错误日志的结构是比较标准的,其由以下几部分组成:
- 时间戳 - 精确到微秒的时间戳,T 表示日期和时间的分隔符,Z 表示标准 UTC+0 时区(ISO 8601 国际标准)
- 线程 ID - 0 表示由 MySQL 守护进场本身进行生成,其他值表示特定的工作线程
- 事件的类型或级别 - 事件的来源
- 错误代码 - MySQL 内部定义的错误代码,如 [MY-010931]
- 子系统 - 标识错误的来源模块,如 Server、InnoDB 等
- 错误消息 - 对该条日志的描述说明
通常而言,若您的 MySQL 实例在启动方面遇到困难,请优先查看错误日志的内容。
常规查询日志
常规查询日志通过以下的配置项(系统变量)来控制:
log_output- 定义常规查询日志的输出位置,其值是一个用逗号分隔的列表,可以是 FILE、TABLE、NONE 或这三个值的任意组合。NONE 表示禁用常规查询日志,若列表中包含了 NONE 值,则它的优先级最高。若列表包含了 TABLE 值,则表示将日志保存到mysql.general_log表中。默认值为 FILEgeneral_log_file- 开启常规查询日志之后文件的保存位置。默认值为在数据目录下以主机名开头且以 .log 结尾的文件。general_log- 是否开启常规查询日志,默认值为 OFF(0)
这些系统变量的默认值如下:
show session variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | FILE |
+---------------+-------+
1 row in set (0.03 sec)
show session variables like 'general%';
+------------------+-----------------------------------+
| Variable_name | Value |
+------------------+-----------------------------------+
| general_log | OFF |
| general_log_file | /usr/local/mysql8/data/HOME01.log |
+------------------+-----------------------------------+
2 rows in set (0.01 sec)
关闭当前 MySQL 实例,在配置文件中配置常规查询日志:
Shell > /usr/local/mysql8/bin/mysqladmin -u root --password='MyNewPass4!' shutdown
Shell > vim /etc/my.cnf
...
[mysqld]
...
log-output = file
general-log = 1
general-log-file = /usr/local/mysql8/data/HOME01.log
...
Shell > /usr/local/mysql8/bin/mysqld_safe --user=mysql &
用客户端连接工具进行连接并执行一些 SQL 语句,接着查看常规查询日志,其内容为:
...
2025-11-02T06:53:27.332612Z 8 Connect [email protected] on using TCP/IP
2025-11-02T06:53:27.333810Z 8 Query SHOW GLOBAL VARIABLES LIKE '%sql_mode%'
2025-11-02T06:53:27.348661Z 8 Query SHOW DATABASES
2025-11-02T06:53:27.373369Z 8 Query SHOW FUNCTION STATUS
2025-11-02T06:53:27.450883Z 8 Query SHOW PROCEDURE STATUS
2025-11-02T06:53:27.454627Z 8 Query SELECT *, EVENT_SCHEMA AS `Db`, EVENT_NAME AS `Name` FROM information_schema.`EVENTS`
2025-11-02T06:53:27.473149Z 8 Query SHOW VARIABLES LIKE '%vers%'
2025-11-02T06:53:27.478958Z 8 Query SHOW COLLATION
2025-11-02T06:53:27.486617Z 9 Connect [email protected] on using TCP/IP
2025-11-02T06:53:27.486971Z 11 Connect [email protected] on using TCP/IP
2025-11-02T06:53:27.487034Z 10 Connect [email protected] on using TCP/IP
2025-11-02T06:53:27.489703Z 10 Query SHOW ENGINES
其日志结构由以下几部分组成:
- 时间戳
- 线程 ID
- 查询类型
- 具体的 SQL 语句
开启常规查询日志不仅会降低 MySQL 实例的性能,而且日志内容会占用大量的磁盘空间,因此除非业务需要,否则通常情况下都不建议开启。
将配置项还原:
Shell > /usr/local/mysql8/bin/mysqladmin -u root --password='MyNewPass4!' shutdown
# 将常规查询日志的三个配置项删除
Shell > vim /etc/my.cnf
Shell > rm -rf /usr/local/mysql8/data/HOME01.log
二进制日志
该日志的主要作用:
- 主从复制,在主从复制的模式中,主服务器(master)必须开启 binlog 来保证数据的一致性
- 基于时间点的恢复还原,因为 binlog 是以事件(event)的形式记录到文件当中。在前面的 《Redis进阶篇04 — 复制技术(一)》 文章中介绍过
- 更改数据的操作进行审计
bin log 有三种格式:
- ROW - 默认格式,不记录具体的 SQL 语句,仅保存 SQL 语句执行成功后的每一行数据修改。该格式的特点是记录非常详细,占用的存储空间大,但是它能解决主从同步数据不一致的问题
- STATEMENT - 以 SQL 语句的形式保存修改数据,SQL 语句可以是 DDL、DML 等
- MIXED - 前两者的混合
每当 MySQL 实例重启或启动时,binlog 就会自动生成带数字后缀的文件名,如 binlog.000001、binlog.000002 这样的。
开启二进制日志之后,由于相关文件的文件内容是二进制形式,因此需要使用 mysqlbinlog 命令进行查看。
二进制日志的相关系统变量(配置项)
涉及到 bin log 的系统变量非常多,如下:
Shell > /usr/local/mysql8/bin/mysqld_safe --user=mysql &
Shell > /usr/local/mysql8/bin/mysql -u root --password='MyNewPass4!'
show session variables like '%log_bin%';
+---------------------------------+-------------------------------------+
| Variable_name | Value |
+---------------------------------+-------------------------------------+
| log_bin | ON |
| log_bin_basename | /usr/local/mysql8/data/binlog |
| log_bin_index | /usr/local/mysql8/data/binlog.index |
| log_bin_trust_function_creators | OFF |
| sql_log_bin | ON |
+---------------------------------+-------------------------------------+
5 rows in set (0.00 sec)
show session variables like "%binlog%";
+------------------------------------------------+----------------------+
| Variable_name | Value |
+------------------------------------------------+----------------------+
| binlog_cache_size | 32768 |
| binlog_checksum | CRC32 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_encryption | OFF |
| binlog_error_action | ABORT_SERVER |
| binlog_expire_logs_auto_purge | ON |
| binlog_expire_logs_seconds | 2592000 |
| binlog_format | ROW |
| binlog_group_commit_sync_delay | 0 |
| binlog_group_commit_sync_no_delay_count | 0 |
| binlog_gtid_simple_recovery | ON |
| binlog_max_flush_queue_time | 0 |
| binlog_order_commits | ON |
| binlog_rotate_encryption_master_key_at_startup | OFF |
| binlog_row_event_max_size | 8192 |
| binlog_row_image | FULL |
| binlog_row_metadata | MINIMAL |
| binlog_row_value_options | |
| binlog_rows_query_log_events | OFF |
| binlog_stmt_cache_size | 32768 |
| binlog_transaction_compression | OFF |
| binlog_transaction_compression_level_zstd | 3 |
| binlog_transaction_dependency_history_size | 25000 |
| innodb_api_enable_binlog | OFF |
| log_statements_unsafe_for_binlog | ON |
| max_binlog_cache_size | 18446744073709547520 |
| max_binlog_size | 1073741824 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| sync_binlog | 1 |
+------------------------------------------------+----------------------+
29 rows in set (0.00 sec)
主要系统变量的说明:
log_bin- 是否开启 bin log,默认开启(ON,1)。log_bin_basename- 保存二进制日志文件的基本名称和路径log_bin_index- 保存二进制日志索引文件的基本名称和路径log_bin_trust_function_creators- 是否信任用户创建的存储例程(存储过程与存储函数),MySQL 8.x 版本为了安全考虑,默认为 0 值。在前面的 《MySQL基础18 — 存储过程与存储函数》 文章中遇到过sql_log_bin- 用于控制当前会话是否将执行的 SQL 语句记录到二进制日志中。当设置为 OFF 值时,当前连接会话执行的所有数据变更操作都不会被记录到二进制日志文件中
次要系统变量的说明:
binlog_cache_size- 定义在事务处理期间 binlog event 的内存缓冲区大小,单位为字节,默认值为 32768 ,需要log_bin=1才能生效。只有 InnoDB 存储引擎才支持事务binlog_checksum- 通过特定校验和算法来确保二进制日志数据完整性,默认值为 CRC32。不需要修改,保持默认即可。binlog_direct_non_transactional_updates- 是否让非事务性的语句直接写入到二进制日志文件中,默认 OFFbinlog_encryption- 是否启用对此服务器上的二进制日志文件和中继日志文件的加密,若要开启,则必须安装和配置密钥环插件,默认 OFFbinlog_error_action- 当服务器遇到错误时所需要的执行动作,这里的错误指的是无法写入、刷新或同步二进制日志等。默认值为 abort_server ,表示遇到 binlog 错误后,直接停止当前的 MySQL 服务器并中止记录。其他值还有 ignore_errorbinlog_expire_logs_seconds- 以秒为单位设置二进制日志的过期时间,过期之后,二进制日志文件可以被删除。默认值为 2592000 (即 30 天)。如果需要到期时间后不自动删除二进制日志文件,可以设置为 0 值(需要 binlog_expire_logs_auto_purge= ON )。binlog_expire_logs_auto_purge- 启用或禁用二进制日志文件的自动清除,默认值为 1 (ON)binlog_format- 二进制日志文件的格式,默认 ROW 即可。binlog_group_commit_sync_delay- 延迟多少秒后才将二进制日志文件组(即多个事务的提交)同步到磁盘,默认值为 0binlog_group_commit_sync_no_delay_count- 等待延迟提交的最大事务数。若binlog_group_commit_sync_delay参数规定的时间没到,但是等待的最大事务数到了,则直接同步到磁盘。若binlog_group_commit_sync_delay为0 ,则此参数不生效。binlog_gtid_simple_recovery- GTID(Global Transaction ID,全局事务ID),该系统变量控制 MySQL 服务重启或启动时,在搜索 GTID 期间应该如何遍历二进制日志文件。默认为 1 (ON)能提升 MySQL 的性能binlog_max_flush_queue_time- 被弃用的变量,忽略binlog_order_commits- 提交事务的顺序是否按照 binlog 文件的顺序,默认值为 1 (ON)binlog_rotate_encryption_master_key_at_startup- 在 MySQL 服务器启动时,是否对 binlog 进行主密钥的轮询binlog_row_event_max_size- 二进制日志的格式是 ROW 时,事件的最大大小,单位为字节。binlog_row_image- 当二进制日志的格式是 ROW 是,记录数据变更的详细程度,允许的值有full、minimal、noblob。默认值为 full,对于 update 或 delete 操作,会记录变更前所有列的数据以及变更之后的所有列的数据。binlog_row_metadata- MySQL 8.x 版本中的系统变量。当二进制日志的格式是 ROW 时,记录元数据的详细程度,允许的值有 full 和 minimal。minimal 是默认值,即仅记录最基础的表元数据信息,包括库名称、表名称、以及表字段的类型和大小等最核心的元数据binlog_row_value_options- 针对 JSON 数据类型的一个优化参数,默认值为空字符串。binlog_rows_query_log_events- 控制在 ROW 或 MIXED 二进制日志格式下,是否在 binlog 文件中记录原始的 SQL 查询语句,默认值为 OFF。调试的相关工作通常需要开启该系统变量。binlog_stmt_cache_size- 在事务执行过程中,缓存非事务性语句的二进制日志的大小。单位为字节binlog_transaction_compression- 对二进制日志文件中的事务是否启用压缩功能。binlog_transaction_compression_level_zstd- zstd 算法的压缩级别,需要启用二进制日志的事务压缩功能,值范围为 1 到 9binlog_transaction_dependency_history_size- MySQL 8.x 中的新功能,为保存在内存中并用于查找最后修改给定行的行哈希数设置上限。一旦达到此哈希数,历史记录将被清除。该参数关联到并行复制 WriteSet 机制以及事务冲突检测。innodb_api_enable_binlog- 使用 InnoDB memcached 插件时是否启用二进制日志log_statements_unsafe_for_binlog- 是否将可能产生不确定结果的 SQL 语句记录到二进制日志中max_binlog_cache_size- 单个事务在二进制日志缓存中能够使用的最大存储空间,单位为字节max_binlog_size- 控制单个二进制日志文件大小,单位为字节。如果当前使用的二进制日志文件超过此系统变量的值,MySQL 则会轮替二进制日志(关闭当前的二进制文件并打开下一个二进制文件)max_binlog_stmt_cache_size- 在事务执行过程中,缓存非事务性语句的二进制日志的上限大小,单位为字节-
sync_binlog- 控制 binlog 同步到磁盘的频率- 0 - 表示禁用
- 1 - 表示在提交事务之前启用二进制日志到磁盘的同步,最安全的设置,但由于磁盘写入次数增加,可能会对性能产生负面影响
- N - 指的是 0 或 1 以外的值,在收集了 N 个 binlog 提交组之后,将二进制日志同步到磁盘。在电源故障或操作系统崩溃的情况下,服务器可能提交了尚未刷新到二进制日志的事务。由于磁盘写入次数增加,此设置可能会对性能产生负面影响。值越大,性能越高,但数据丢失的风险也会相应增加。
为了在 INNODB 的事务中获得最好的一致性与持久性,请设置
innodb-flush-log-at-trx-commit=1和sync-binlog=1。这在前面的 配置文件 文章中提到过
慢查询日志
该日志的主要作用用来分析当前 MySQL 实例的性能瓶颈问题(当超过了 long_query_time=10 时就会被记录),默认未开启(slow_query_log=0)。同样,也可以写入到配置文件种永久更改。
show session variables like '%long_query%';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.01 sec)
show session variables like "%slow%";
+-----------------------------+----------------------------------------+
| Variable_name | Value |
+-----------------------------+----------------------------------------+
| log_slow_admin_statements | OFF |
| log_slow_extra | OFF |
| log_slow_replica_statements | OFF |
| log_slow_slave_statements | OFF |
| slow_launch_time | 2 |
| slow_query_log | OFF |
| slow_query_log_file | /usr/local/mysql8/data/HOME01-slow.log |
+-----------------------------+----------------------------------------+
7 rows in set (0.00 sec)
慢查询日志的相关系统变量(配置项)
long_query_time- 定义阈值时间,如果超过本值,则记录到慢查询中。记录位置可以是表或文件log_slow_admin_statements- 是否将执行缓慢的管理语句记录到慢查询日志中,默认值为 OFFlog_slow_extra- 当启用了慢查询日志且输出位置为 FILE,是否将附加字段写入到日志文件行中,以提供更加详细的慢查询信息log_slow_replica_statements- 在从服务器上执行的重放语句是否记录到慢查询日志中,默认为 OFF。该配置项需要配置在从服务器上。从 MySQL 8.0.26 开始代替log_slow_slave_statements环境变量log_slow_slave_statementsslow_launch_time- 当 MySQL 服务器创建新线程的耗时超过slow_launch_time设定的阈值(单位:秒)时,会触发 Slow_launch_threads 状态变量计数增加。该环境变量主要用于诊断线程创建阶段的性能问题,而非记录慢查询。slow_query_log- 是否开启慢查询日志slow_query_log_file- 控制慢查询日志文件的保存位置,需要log_output=file
中继日志
主从复制中,从服务器为了与主服务器保持一致,要从主服务器中读取二进制日志的内容,并将读取到的信息写入到本地的日志文件中(该文件通常位于数据目录下),这个从服务器的本地日志文件即 中继日志。从服务器读取中继日志并根据中继日志的内容对从服务器的数据进行更新,完成主从服务器的数据同步。
中继日志由一组日志文件和一个索引文件组成。这一组日志文件由特定的命名构成,通常是以主机名加 -relay-bin 加数字编号结尾,如 home02-relay-bin.000001 。
与查看二进制日志文件的内容一样,中继日志也是可以通过命令工具 mysqlbinlog 进行查看。
中继日志的相关系统变量(配置项)
show session variables like '%relay%';
+-----------------------+-----------------------------------------------+
| Variable_name | Value |
+-----------------------+-----------------------------------------------+
| max_relay_log_size | 0 |
| relay_log | HOME01-relay-bin |
| relay_log_basename | /usr/local/mysql8/data/HOME01-relay-bin |
| relay_log_index | /usr/local/mysql8/data/HOME01-relay-bin.index |
| relay_log_purge | ON |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
| sync_relay_log | 10000 |
| sync_relay_log_info | 10000 |
+-----------------------+-----------------------------------------------+
9 rows in set (0.00 sec)
max_relay_log_size- 当中继日志超过这个变量的值时,就会发生轮替(即停止上一个中继日志的写入并打开新建下一个中继日志),默认值为 0。当默认值为 0 时,MySQL 会默认采用max_binlog_size的值作为中继日志文件的大小限制relay_log- 指定中继日志文件的基本名称relay_log_basename- 保存中继日志文件的基本名称和完整路径relay_log_index- 指定中继日志索引文件的保存路径以及名称relay_log_purge- 当不需要中继日志文件时,是否开启自动清除,默认开启。relay_log_recovery- 是否启用中继日志的自动恢复,默认关闭。当从服务器的从库因为意外宕机了,若中继日志损坏,会导致一部分的中继日志没有处理并出现主从服务器数据不一致的情况,通常在主从架构中,我们强烈建议开启自动恢复。relay_log_space_limit- 限制所有中继日志文件可以占用的最大磁盘空间总量。当所有中继日志文件的总大小超过此限制时,MySQL 会自动清理最旧的中继日志文件以释放空间sync_relay_log- 和sync_binlog差不多,控制中继日志同步到磁盘的频率sync_relay_log_info- 从 MySQL 8.0 版本开始不推荐使用,推荐使用sync_relay_log
存储引擎日志
对于 InnoDB 存储引擎,这是的日志主要与事务相关(仅 InnoDB 存储引擎支持事务)。
存储引擎日志的相关系统变量(配置项)
innodb_redo_log_encrypt- 对重做日志是否启用加密,默认关闭。开启加密的先决条件是需要有对应的插件 —— mysql密钥环innodb_max_undo_log_size- 定义单个回滚日志的大小上限,单位为字节innodb_undo_directory- 定义回滚日志的保存目录。若未指定,则默认保存在数据目录中innodb_undo_log_encrypt- 对回滚日志是否启用加密,默认关闭-
innodb_undo_log_truncate- 是否启用回滚日志的自动截断功能,MySQL 8.x 版本中默认开启。当单个回滚日志的文件大小超过了innodb_max_undo_log_size设定的上限后,启用自动截断功能会回收磁盘空间,释放出可用的磁盘空间。要成功触发回滚日志的自动截断,需要满足以下几个条件:innodb_undo_log_truncate的值必须是 ONinnodb_undo_tablespaces的值必须大于或等于 2。从 MySQL 8.0.14 版本开始,系统默认会创建两个独立的 Undo 表空间,并且不再支持通过配置这个变量来修改其数量。- 定义了
innodb_max_undo_log_size的大小 innodb_purge_rseg_truncate_frequency控制 Purge 线程清理回滚段的频率,其默认值为 128
show status like 'Innodb_undo_tablespaces%';
+----------------------------------+-------+
| Variable_name | Value |
+----------------------------------+-------+
| Innodb_undo_tablespaces_total | 2 |
| Innodb_undo_tablespaces_implicit | 2 |
| Innodb_undo_tablespaces_explicit | 0 |
| Innodb_undo_tablespaces_active | 2 |
+----------------------------------+-------+
4 rows in set (0.00 sec)









