文章目录
- [3. 日志简介](#3. 日志简介)
-
- [3.4 错误日志](#3.4 错误日志)
-
- [3.4.1 配置错误日志](#3.4.1 配置错误日志)
-
- [3.4.1.1 Windows 的默认错误日志路径](#3.4.1.1 Windows 的默认错误日志路径)
- [3.4.1.2 Unix 和Linux 系统的默认错误日志路径](#3.4.1.2 Unix 和Linux 系统的默认错误日志路径)
- [3.4.2 错误日志中事件的字段](#3.4.2 错误日志中事件的字段)
-
- [3.4.2.1 核心错误事件字段](#3.4.2.1 核心错误事件字段)
- [3.4.2.2 可选错误事件字段](#3.4.2.2 可选错误事件字段)
- [3.4.2.3 可以通过以下SQL查看已定义的错误类型](#3.4.2.3 可以通过以下SQL查看已定义的错误类型)
- [3.4.2.4 示例:](#3.4.2.4 示例:)
- [3.4.3 刷新错误日志文件和重命名](#3.4.3 刷新错误日志文件和重命名)
- [3.5 二进制日志](#3.5 二进制日志)
-
- [3.5.1 介绍](#3.5.1 介绍)
- [3.5.2 选项和变量](#3.5.2 选项和变量)
- [3.5.3 查看二进制日志](#3.5.3 查看二进制日志)
- [3.5.4 二进制日志格式](#3.5.4 二进制日志格式)
- [3.6 Redo Log 和 Undo Log](#3.6 Redo Log 和 Undo Log)
- [3.7 服务器日志维护](#3.7 服务器日志维护)
- [3.8 配置日志输出位置](#3.8 配置日志输出位置)
3. 日志简介
3.4 错误日志
错误日志一般会记录
mysqld启动和关闭的次数、诊断消息,以及服务器运行期间发生的错误和警告;例如MySQL需要自动检查或修复一个表,就会在错误日志中写入一条记录。错误日志默认使用UTF-8 ( utf8mb3 )编码格式,并使用英语生成记录。
3.4.1 配置错误日志
错误日志输出的位置,可以是控制台或指定文件,"控制台"表示
stderr标准错误输出。
3.4.1.1 Windows 的默认错误日志路径
在
Windows系统中,mysqld使用--log-error和--console选项来确定默认的错误日志目标是控制台还是文件,规则如下:
- 如果指定了
--console选项,默认在控制台输出错误日志,如果--console和--logerror同时指定,则--console优先级更高,并且--log-error将失效。- 如果没有指定
--log-error或者没有指定具体的文件名,默认在数据目录中生成名为host_name.err的日志文件。- 可以通过指定绝对路径,来更改默认的日志位置。
mysql
[mysqld]
log-error=D:/log/MySQL/Error/error_log.err # 自定义错误日志的路径
3.4.1.2 Unix 和Linux 系统的默认错误日志路径
在
Unix和Linux系统中,mysqld使用--log-error选项来指定默认错误日志目标,可以指定控制台或是文件,如果是文件,规则如下:
- 如果错误日志输出目标是控制台,则服务器将
log_error系统变量设置为stderr。否则,将以文件形式输入错误日志,并以log_error的值为文件名。- 如果显示写出
--log-error但没有指定具体文件,则默认路径是数据目录中host_name.err的文件;

- 可以通过指定绝对路径,来更改默认的日志位置。
mysql
[mysqld]
log-error=/var/log/mysql/error_log.err # 自定义错误日志的路径
3.4.2 错误日志中事件的字段
3.4.2.1 核心错误事件字段
time:件时间戳,精度为微秒;msg:事件消息字符串;prio:事件优先级,包括System event- 系统(0)、Error event- 错误(1)、Warning event- 警告(2)或Note/information event- 通知/提示事件(3),值越小优先级越高;err_code:事件错误代码;err_symbol:以字符串形式表示的事件错误符,例如'ER_DUP_KEY' ;SQL_state:事件SQLSTATE值,与err_symbol对应,例如'ER_DUP_KEY'对应的SQLSTATE为23000subsystem:事件发生的子系统。可能的值:InnoDB(InnoDB存储引擎)、Repl(复制子系统)、Server(其他)。
例如:MySQL :: MySQL 8.0 Error Reference :: 2 Server Error Message Reference

3.4.2.2 可选错误事件字段
OS_errno:操作系统错误号;OS_errmsg:操作系统错误消息;label:与值对应的prio描述 ;user:客户端用户;host:客户端主机;thread:产生错误事件 的线程的ID;query_id:查询ID。
3.4.2.3 可以通过以下SQL查看已定义的错误类型
mysql
mysql> SELECT * FROM performance_schema.events_errors_summary_global_by_error WHERE SUM_ERROR_RAISED <> 0\G
*************************** 1. row ***************************
ERROR_NUMBER: 1064
ERROR_NAME: ER_PARSE_ERROR
SQL_STATE: 42000
SUM_ERROR_RAISED: 1
SUM_ERROR_HANDLED: 0
FIRST_SEEN: 2026-05-12 15:50:19
LAST_SEEN: 2026-05-12 15:50:19
*************************** 2. row ***************************
ERROR_NUMBER: 1287
ERROR_NAME: ER_WARN_DEPRECATED_SYNTAX
SQL_STATE: HY000
SUM_ERROR_RAISED: 34
SUM_ERROR_HANDLED: 0
FIRST_SEEN: 2026-05-12 10:28:32
LAST_SEEN: 2026-05-12 10:28:32
*************************** 3. row ***************************
ERROR_NUMBER: 3778
ERROR_NAME: ER_WARN_DEPRECATED_UTF8MB3_COLLATION
SQL_STATE: HY000
SUM_ERROR_RAISED: 73
SUM_ERROR_HANDLED: 0
FIRST_SEEN: 2026-05-12 10:28:32
LAST_SEEN: 2026-05-12 10:28:32
3 rows in set (0.02 sec)
mysql>
错误代码参考:
例如:

3.4.2.4 示例:
mysql
2023-07-27T14:15:59.267828+08:00 1 [System] [MY-011012] [Server] Starting upgrade of data directory.
2023-07-27T14:15:59.267942+08:00 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2021-07-27T14:16:11.478109+08:00 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2023-07-27T14:16:11.719225+08:00 2 [Warning] [MY-010772] [Server] db.opt file not found for binlog database. Using default Character set.
2023-07-27T14:16:11.731900+08:00 2 [ERROR] [MY-013140] [Server] Invalid utf8 character string: 'C9F3C5'
2023-07-27T14:16:11.733024+08:00 2 [ERROR] [MY-013140] [Server] Invalid utf8 character string: 'C9F3C5'
2023-07-27T14:16:12.687947+08:00 2 [Warning] [MY-010772] [Server] db.opt file not found for tmpdir database. Using default Character set.
2023-07-27T14:16:12.992579+08:00 0 [ERROR] [MY-010022] [Server] Failed to Populate DD tables.
2023-07-27T14:16:12.994141+08:00 0 [ERROR] [MY-010119] [Server] Aborting
2023-09-20T08:23:49.135468Z 1 [Note] A temporary password is generated for
root@localhost: S3Gw_#UBNoqf
解释:
mysql
2023-07-27T14:15:59.267828+08:00 1 [System] [MY-011012] [Server] Starting
2023-07-27T14:15:59.267828+08:00---------------------时间
1----------------------------------------------------优先级
[System]---------------------------------------------表示属于系统级的通知,[Note]:一般的提示信息,[Warning]:警告信息,[Error]:错误信息。
[MY-011012]------------------------------------------错误码
[Server]---------------------------------------------子系统
[Server] Starting upgrade of data directory.---------日志详情
当
MySQL服务启动失败的时候,首先要干的就是查询错误日志。
mysql
root@yudukai:~# tail -n20 /var/log/mysql/error.log
不过有些情况不会被写入错误日志中,例如用户执行一些错误的SQL。

不过会给出一些错误提示,可能原因诸如:访问了不存在的库和表,语句错误,权限问题...
3.4.3 刷新错误日志文件和重命名
- 如果使用
FLUSH ERROR LOGS、FLUSH LOGS语句或mysqladmin flush-logs命令刷新错误日志,服务器会将正在写入的任何错误日志文件关闭并重新打开。比如我们把日志移动到别的地方去了,那么这个文件在打开的时候识别到这个文件没有了,就会重新生成一份。- 如果要手动重命名错误日志文件,可以在重命名操作之后执行刷新操作,服务器会以原文件名生成一个新的错误日志文件,例如日志文件名为
host_name.err,可以按以下步骤操作:
mysql
mv host_name.err host_name.err-old # 重命名日志文件
mysqladmin flush-logs # 刷新操作
mv host_name.err-old backup-directory # 把重命名的日志文件移动到备份目录
3.5 二进制日志
3.5.1 介绍
- 二进制日志包含数据库
更改的"事件",不会记录SELECT和SHOW,例如:记录表的创建操作或表数据的更改,二进制日志还包含每个语句更新数据时花费的时间信息,启动二进制日志,对服务器性能稍微有些影响,因为涉及磁盘I/O。- 除了基于行的日志模式,它还包含可能进行更改数据的语句事件,例如
DELETE操作没有匹配到查找到的行。- 二进制日志的作用:
- 主从节点数据复制:从节点服务器读取主节点服务器上的二进制日志文件,并根据二进制日志中记录的事件在从节点上执行相同的操作,保证主从节点服务器上数据一致,实现数据复制功能。在主从复制专题中我们重点讲解复制过程。
- 数据恢复:从某个时间点恢复备份数据后,将重新执行备份时间点之后记录在二进制日志中的事件。这些事件使数据库从备份点更新到当前最新状态。
- 二进制日志的语句中如果涉及用户的密码(服务器的密码),则由服务器进行加密,不会以纯文本形式出现。


3.5.2 选项和变量
• 查看二进制日志相关的系统变量
mysql
mysql> show variables like '%bin%';
查看二进制日志相关的状态变量
mysql
mysql> show variables like '%bin%';
+------------------------------------------------+-----------------------------+
| Variable_name | Value |
+------------------------------------------------+-----------------------------+
| bind_address | 127.0.0.1 |
| 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 |
| binlog_transaction_dependency_tracking | COMMIT_ORDER |
| innodb_api_enable_binlog | OFF |
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/binlog |
| log_bin_index | /var/lib/mysql/binlog.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| log_statements_unsafe_for_binlog | ON |
| max_binlog_cache_size | 18446744073709547520 |
| max_binlog_size | 104857600 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| mysqlx_bind_address | 127.0.0.1 |
| sql_log_bin | ON |
| sync_binlog | 1 |
+------------------------------------------------+-----------------------------+
38 rows in set (0.01 sec)
mysql>
默认情况下启用二进制日志,
log_bin系统变量为ON;禁用二进制日志,可以指定
--skip-log-bin或--disable-log-bin选项。如果同时指定了--log-bin和--skip-log-bin和则后指定的选项优先;选项
--log-bin[=base_name]用于指定二进制日志文件的基本名称,如果不指定--logbin选项,默认基本名称为binlog,建议为二进制日志指定一个基本名;二进制日志文件名是由基本名+数字扩展名组成的(二进制日志以事务为单位记录日志),服务器每次创建一个新的日志文件时,数字扩展名都会增加,从而保证有序的文件系列,发生以下事件时,服务器都会在创建一个新的日志文件:
服务器已启动或重新启动
服务器刷新日志
当前日志文件的大小达到
max_binlog_size(单个日志文件的最大字节数,最小值4096字节,最大值和默认值1GB)二进制日志文件大小可能会超出
max_binlog_size设定的值,因为二进制日志在记录事务时,会完整的记录整个事务,不存在把一个事务拆分的情况,如果遇到一个大事务时,即使记录整个事务会超过日志大小限制,也会保证事务的完整性
mysqld还会创建一个包含二进制日志文件名的日志索引文件,默认情况下,这与二进制日志文件具有相同的基本名称,扩展名为.index. 可以使用选项--log-bin-index[=file_name]修改索引文件名

- 二进制日志文件和索引文件的默认位置是数据目录。可以使用
--log-bin[=file_name]选项指定自定义路径,file_name格式 = 绝对路径+基本名。--log-bin对应的系统变量是log_bin_basename;MySQL 5.7中,启用二进制日志必须指定服务器ID,对应server_id选项,否则服务器将无法启动。在MySQL 8.0中,server_id系统变量默认设置为1,在集群环境中,每台MySQL服务器必须有唯一的server_id;- 二进制日志记录事件支持三种格式类型:基于行的日志记录、基于语句的日志记录和混合日志记录,稍候具体介绍;
- 二进制日志记录在语句或事务完成之后,释放锁或在提交完成之前进行。这样做是为了确保按照提交顺序记录日志;
- 在一个未提交的事务中,对支持事务的表(如
InnoDB表)的更改都会被缓存(UPDATE,DELETE或INSERT),直到服务器收到COMMIT语句,mysqld在执行COMMIT之前将整个事务写入二进制日志;- 如果事务回滚,则在整个事务中记录一个
ROLLBACK语句,但是对非事务性表(如MyISAM表)的修改不能回滚,所以这些修改将被复制到从节点;- 对非事务表的更新在执行后立即存储在二进制日志中;
- 当处理事务的线程启动时,它会分配一个大小为
binlog_cache_size的缓冲区来缓存语句。如果语句大小大缓冲区的值,线程则打开一个临时文件来存储事务,临时文件在线程结束时删除;Binlog_cache_use状态变量显示使用该缓冲区(可能还有临时文件)存储事务的数量;Binlog_cache_disk_use状态变量显示有多少事务实际上使用了临时文件。结合这两个变量可以把binlog_cache_size调优到一个足够大的值,从而避免使用临时文件;- 系统变量
max_binlog_cache_size(默认值和最大值都是4GB,最小值为4096)用于限制缓存区大小,如果事务语句大于这个值指定的字节数,事务将会失败并回滚;- 如果使用基于行的日志记录方式, 为了保证日志的准确性,
CREATE ... SELECT或INSERT ... SELECT语句的并发插入将转换为普通插入;如果使用基于语句的日志记录方式,则将原始语句写入日志。- 由于服务器崩溃或其他原因,导致对二进制日志文件无法进行写入、刷新或者同步到磁盘。那么主从节点上的日志就会出现不一致,当遇到这种问题时,可以通过系统变量
binloglog_error_action控制处理方式:
- 默认值
ABORT_SERVER,服务器停止二进制日志记录并关闭,排查完问题并重启后,服务器按意外停止执行恢复操作;IGNORE_ERROR表示,服务器继续进行当前的事务并记录错误,然后停止日志记录,排查问题后,需要确认启用log_bin,然后再次启动服务器,对日志要求不高的场景可以设置此值,不推荐在集群环境使用;- 默认情况下,
sync_binlog=1,表示每个事务在写入缓存后立即同步到磁盘,也可以设置为其他值,比如sync_binlog=N表示N次事务提交到缓存之后再同步到磁盘,如果sync_binlog=0则MySQL不控制同步磁盘的频率,完全由操作系统控制。需要注意:如果当sync_binlog的值设置为0或N那么当服务器崩溃时,缓上存中的有些日志不能同步到磁盘,可能造成一些更改丢失,所以sync_binlog=1是最安全的,但同时效率也是最低的。- 可以使用
RESET MASTER语句删除所有二进制日志文件,或者使用PURGE binary LOGS删除一部分二进制日志文件,具体演示:
mysql
# 重置二进行日志文件和索引文件为初始状态
mysql> RESET MASTER;
# 删除指定日志文件之前的所有日志文件并更新索引
mysql> PURGE BINARY LOGS TO 'mysql-bin.010';
# 删除指定时间之前的所有日志文件并更新索引
mysql> PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26'
- 两阶段提交时可能出现的问题及解决方法,将在详解两阶段提交章节详细介绍。
TIPS:术语 "二进制日志文件" 通常表示包含单独编号的日志文件。术语 "二进制日志" 表示所有二进制日志文件和索引文件。
3.5.3 查看二进制日志
- 使用客户端工具
mysqlbinlog查看
mysql
mysqlbinlog binlog.000001 > binlog.000001
二进制日志名 > 导出的目标文件名
- 通过
SQL语句查看
mysql
mysql> show binlog events in 'binlog.000001' from N limit S;


c
Log_name:二进制日志文件名
Pos:当前这条日志在文件中的起始偏移量
Event_type:查询日志
Server_id:服务器id,标明是哪台主机
End_log_pos:当前日志在文件中的结束偏移量
Info:具体执行的操作
3.5.4 二进制日志格式
记录二进制日志时使用的格式有以下几种:
- 基于语句的日志格式,最初
MySQL是基于SQL语句复制实现主从节点同步,通过指定选项--binlog-format=STATEMENT使用此格式 。- 基于行的日志格式(默认)中,主节点将事件写入二进制日志,表示各个表的行受到的影响,可以通过指定选项
--binlog-format=ROW使用此格式 。
- 当使用
MYSQL内部的一些函数时,必须以行的格式记录日志。例如:UUID()这样的函数有不确定性。当主节点执行了UUID函数的时候,会记录生成的具体的值,因为在从节点再次执行的话值会不一样。所以不能记录语句。- 混合日志记录格式,默认情况下使用基于语句的日志记录,如果
MySQL认为基于语句的格式不能保证主从复制过程中的数据安全时,会自动切换到基于行的日志格式,比如主节点在语句中用了UUID()函数,那么日志文件中记录的是UUID生成的真实值而不是直接使用原始的SQL语句,使用混合日志格式中以指定选项--binlog-format=MIXED。
TIPS: 设置二进制日志格式
--binlog-format=[STATEMENT|ROW|MIXED]
- 基于语句与基于行的区别:
mysql
# 基于语句,记录执行的SQL语句
update student set age = 18 where id between 10 and 20;
# 基于行,记录每一行的更改
update student set age = 18 where id = 10;
update student set age = 18 where id = 11;
update student set age = 18 where id = 12;
...
update student set age = 18 where id = 19;
update student set age = 18 where id = 20;
后续会进一步讨论。
3.6 Redo Log 和 Undo Log
Redo Log:重做日志,用于恢复数据。对于已提交的事务在服务器崩溃重启后,依然可以重新执行并写入磁盘。Undo Log:撤消日志用于回滚操作。后续会进一步讨论。
3.7 服务器日志维护
MySQL服务器可以创建多种不同的日志文件来帮助我们查看服务器的活动。但是必须定期清理这些文件,以免日志占用过多的磁盘空间。在启用日志的情况下,通常希望备份和删除旧的日志文件,并把日志写到新文件。
- 默认二进制日志的过期时间为
30天,过期后将自动删除,要指定自定义过期时间,可以使用系统变量binlog_expire_logs_seconds=N单位为秒,在下一次启动服务器和刷新日志时删除过期日志文件;- 强制使用新的日志文件可以手动刷新日志,当执行
FLUSH LOGS语句或mysqladmin flushlogs、mysqladmin refresh、mysqldump --flush-logs、mysqldump --master-data命令时,会发生日志刷新。此外当二进制日志文件大小达到max_binlog_size系统变量指定的值时,服务器会自动刷新二进制日志。FLUSH LOGS支持可选的修饰符以启用个别日志的选择性刷新:
mysql
FLUSH LOGS # 刷新所有日志
FLUSH BINARY LOGS # 刷新二进制日志
FLUSH ERROR LOGS # 刷新错误日志
FLUSH GENERAL LOGS # 刷新一般查询日志
FLUSH RELAY LOGS # 刷新中继日志
FLUSH SLOW LOGS # 刷新慢查询日志
- 刷新一般查询日志、慢查询日志或错误日志只是关闭并重新打开日志文件,如果要备份可以先重命名再执行刷新操作,比如一般查询日志、慢查询日志或错误日志文件名分别为:
mysql.log、mysql-slow.log和err.log,可以在命令行中使用如下一系列命令:
shell
cd mysql-data-directory #进入日志目录
mv mysql.log mysql.log.old #重命名一般查询日志
mv mysql-slow.log mysql-slow.log.old #重命名慢查询日志
mv err.log err.log.old #重命名错误日志
mysqladmin flush-logs #刷新日志
- 要在运行时重命名"一般查询日志"或"慢查询日志"
- 首先连接到服务器并禁用日志:(这里不能直接移动,因为如果没有禁用的话,他还在往里面写数据,这个时候移动会报错)
mysql
SET GLOBAL general_log = 'OFF';
SET GLOBAL slow_query_log = 'OFF';
在禁用日志的情况下,重命名日志文件,例如用
mv命令从命令行执行重命名操作。再次启用日志:
mysql
SET GLOBAL general_log = 'ON';
SET GLOBAL slow_query_log = 'ON';
这种方法适用于任何平台且不需要重启服务器
3.8 配置日志输出位置
mysql
# 服务器节点
[mysqld]
# 一般查询日志和慢查询日志记录方式为文件
log-output=FILE
# 开启一般查询日志
general-log=1
# 一般查询日志路径和文件名
general_log_file=/var/log/mysql/general.log
# 开启慢查询日志
slow-query-log=1
# 慢查询日志路径和文件名
slow_query_log_file=/var/log/mysql/slow-query.log
# 慢查询日志时间限制
long_query_time=10
# 错误日志路径和文件名
log-error=/var/log/mysql/error.err
# 二进制日志路径和基本名
log-bin=/var/log/mysql/binlog
# 服务器编号
server-id=1