一,错误日志
MySQL 的错误日志(Error Log)是数据库服务器记录运行过程中发生的错误、警告和其他重要信息的重要工具。它对于诊断数据库问题(如启动失败、崩溃、性能异常等)至关重要。
-
错误日志的位置
- 默认路径 :
- Linux :通常位于
/var/log/mysql/error.log
或/var/log/mysqld.log
,具体取决于安装方式。 - Windows :位于 MySQL 数据目录下(如
C:\ProgramData\MySQL\MySQL Server 8.0\Data\
),文件名格式为<hostname>.err
。
- Linux :通常位于
- 查看路径 :
- 执行 SQL 命令:
SHOW VARIABLES LIKE 'log_error';
- 或检查 MySQL 配置文件(
my.cnf
或my.ini
)中的log_error
参数。
- 执行 SQL 命令:
- 默认路径 :
-
错误日志的配置
在 MySQL 配置文件(
my.cnf
或my.ini
)中可调整以下参数:ini[mysqld] log_error = /path/to/error.log # 指定错误日志路径 log_error_verbosity = 3 # 日志详细级别(1: 错误,2: 错误+警告,3: 错误+警告+信息)
- MySQL 5.7+ 支持
log_error_verbosity
,控制日志的详细程度。 - MySQL 8.0+ 新增支持将错误日志输出到系统日志(如
syslog
)。
- MySQL 5.7+ 支持
-
错误日志的内容
- 启动/关闭信息:服务器启动成功或失败的原因。
- 关键错误:如权限问题、表损坏、内存不足等。
- 客户端连接问题:如无效的连接请求、连接中断。
- InnoDB 引擎错误:如事务回滚、死锁检测。
- 复制问题(主从复制):如二进制日志错误、Slave I/O 线程错误。
- 警告和诊断信息:如长时间运行的查询、临时表使用情况。
-
查看错误日志
-
直接查看文件:
bashtail -f /var/log/mysql/error.log # 实时监控日志(Linux)
-
通过 MySQL 命令查看:
sqlSHOW ENGINE INNODB STATUS; -- 显示InnoDB状态(部分错误信息)
-
使用工具:
mysqladmin
命令:mysqladmin -u root -p flush-logs
(归档当前日志并新建)。- 第三方工具(如
pt-query-digest
)分析日志。
-
-
管理错误日志
- 日志轮转(Rotation) :
- 使用
logrotate
工具(Linux)配置自动轮转。 - 手动轮转:重命名旧日志文件后执行
FLUSH ERROR LOGS;
(需 MySQL 8.0+)。
- 使用
- 清理日志 :
- 直接清空文件(需停止 MySQL 服务或确保无写入)。
- 使用
truncate
命令:truncate -s 0 /var/log/mysql/error.log
。
- 日志轮转(Rotation) :
-
高级用途
-
将错误日志写入系统表(MySQL 8.0+):
sqlSET GLOBAL log_error_services = 'log_filter_internal; log_sink_syseventlog';
-
过滤特定错误 :通过
log_filter_dragnet
插件自定义日志过滤规则。
-
二,二进制日志
2.1 介绍
MySQL 的二进制日志(Binary Log,简称 binlog)是数据库记录所有数据变更操作 的核心日志文件。它不记录查询语句(如 SELECT
),而是记录所有可能修改数据的操作(如 INSERT
、UPDATE
、DELETE
、DDL
等),主要用于 主从复制 和 数据恢复。
2.2 二进制日志的作用
- 主从复制(Replication):主库(Master)将二进制日志发送给从库(Slave),从库重放这些日志以保持数据同步。
- 数据恢复:通过重放二进制日志,可以将数据库恢复到某个特定时间点(Point-in-Time Recovery, PITR)。
- 数据审计:分析二进制日志可以追踪数据变更历史。
2.3 二进制日志的格式
二进制日志支持三种记录格式(通过 binlog_format
配置):
格式 | 说明 | 适用场景 |
---|---|---|
STATEMENT | 记录执行的 SQL 语句(如 UPDATE users SET name='John' WHERE id=1 ) |
日志量小,但某些函数可能导致主从不一致(如 NOW() )。 |
ROW | 记录数据行的实际变更(如修改前后的行数据) | 数据一致性高,但日志体积较大。 |
MIXED | 混合模式,默认使用 STATEMENT,仅在可能不一致时改用 ROW 格式。 | 平衡日志量和一致性 |
建议:
-
主从复制场景推荐使用 ROW 格式(MySQL 5.7+ 默认),确保数据一致性。
-
通过命令查看当前格式:
sqlSHOW VARIABLES LIKE 'binlog_format';
2.4 二进制日志的配置
在 MySQL 配置文件(my.cnf
或 my.ini
)中启用和配置二进制日志:
ini
[mysqld]
# 启用二进制日志
log_bin = /var/log/mysql/mysql-bin.log
# 设置日志格式(ROW/STATEMENT/MIXED)
binlog_format = ROW
# 设置日志过期时间(自动清理)
expire_logs_days = 7
# 单个日志文件的最大大小(默认1GB)
max_binlog_size = 100M
# 为事务性存储引擎(如InnoDB)提供崩溃安全保护
sync_binlog = 1
2.5 查看和管理二进制日志
2.5.1 查看二进制日志
-
列出所有二进制日志文件:
sqlSHOW BINARY LOGS;
diff+------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 177 | | mysql-bin.000002 | 154 | +------------------+-----------+
-
查看日志内容(需使用
mysqlbinlog
工具):bashmysqlbinlog /var/log/mysql/mysql-bin.000002
2.5.2 清理二进制日志
-
删除指定日志文件之前的日志:
sqlPURGE BINARY LOGS TO 'mysql-bin.000005'; -- 删除000001~000004
-
删除所有早于某时间的日志:
sqlPURGE BINARY LOGS BEFORE '2023-10-01 00:00:00';
2.6 数据恢复示例
通过二进制日志恢复误删除的数据:
-
定位误操作的时间点:
bashmysqlbinlog --start-datetime="2023-10-01 14:00:00" --stop-datetime="2023-10-01 14:05:00" mysql-bin.000002 > recovery.sql
-
编辑
recovery.sql
,删除误操作的语句。 -
重放日志:
bashmysql -u root -p < recovery.sql
三,查询日志
MySQL 的查询日志(General Query Log)用于记录所有客户端与数据库交互的 SQL 语句,包括 连接、查询、断开 等操作。与二进制日志(记录数据变更)和错误日志(记录错误信息)不同,查询日志会捕获所有请求(包括 SELECT
),是分析数据库行为、调试问题或审计操作的重要工具。
3.1 查询日志的作用
- 全量 SQL 记录:记录所有客户端发送的 SQL 语句(包括成功和失败的请求)。
- 行为分析:用于排查性能问题、审计用户操作或复现异常场景。
- 连接追踪:记录客户端的连接和断开信息(如 IP、用户名、时间戳)。
注意 :查询日志会显著增加磁盘 I/O 和空间占用,默认关闭,建议仅在需要时开启。
3.2 查询日志的配置
启用查询日志
在 MySQL 配置文件(my.cnf
或 my.ini
)中添加以下参数:
ini
[mysqld]
general_log = 1 # 启用查询日志(1/ON 启用,0/OFF 关闭)
general_log_file = /path/to/query.log # 指定日志文件路径
log_output = FILE # 输出方式(FILE/TABLE/NONE)
log_output
:FILE
:日志写入文件(默认)。TABLE
:日志存入mysql.general_log
系统表(方便 SQL 查询)。NONE
:禁用日志(即使general_log=1
)。
动态启用(无需重启)
sql
-- 开启查询日志
SET GLOBAL general_log = 'ON';
-- 修改日志路径
SET GLOBAL general_log_file = '/tmp/mysql_query.log';
3.3 查看查询日志
直接查看日志文件
bash
tail -f /path/to/query.log # 实时跟踪日志(Linux)
日志内容示例:
log
2023-10-05T10:02:45.123456Z 5 Connect root@localhost on test using TCP/IP
2023-10-05T10:02:48.654321Z 5 Query SELECT * FROM users WHERE id = 1
2023-10-05T10:02:50.987654Z 5 Quit
每行记录包含:
- 时间戳:操作发生的时间。
- 线程 ID:客户端连接的唯一标识。
- 操作类型 :
Connect
(连接)、Query
(查询)、Quit
(断开)等。 - 详细信息:如 SQL 语句、客户端来源等。
通过系统表查询(需 log_output=TABLE
)
sql
SELECT * FROM mysql.general_log;
3.4 管理查询日志
日志轮转(Rotation)
-
手动轮转:
-
重命名旧日志文件:
bashmv /path/to/query.log /path/to/query_old.log
-
刷新日志(重新生成新文件):
sqlFLUSH LOGS;
-
-
自动轮转(推荐) :使用
logrotate
工具(Linux)配置定期压缩和清理:conf/var/log/mysql/query.log { daily rotate 7 compress delaycompress missingok notifempty postrotate mysql -e "FLUSH LOGS;" endscript }
清理日志
-
清空文件:
bashtruncate -s 0 /path/to/query.log # 清空内容(保留文件句柄)
-
删除旧日志:确保 MySQL 未写入时直接删除旧文件。