MySQL日志

日志分类

1.错误日志

①作用:记录MySQL服务器启动、运行、关闭过程中的关键事件,

包括:服务启动/关闭的详细信息

严重错误(如权限不足、内存溢出、表损坏)

警告信息(如配置参数不推荐使用)

②配置方法

错误日志默认强制开启,无需手动启用,仅需配置存储路径。

步骤1:修改配置文件

  • Linux系统:配置文件通常为 /etc/my.cnf/etc/mysql/my.cnf
  • Windows系统:配置文件通常为 D:\MySQL\my.ini

添加/修改如下参数:

复制代码
[mysqld]
log-error = /var/log/mysql/mysql-error.log  # Linux路径示例
# log-error = "C:/ProgramData/MySQL/MySQL Server 8.0/data/mysql-error.log"  # Windows路径示例

步骤2:重启服务生效

复制代码
# Linux重启命令(根据系统版本选择)
systemctl restart mysqld  # CentOS 7+/Ubuntu 16+
service mysql restart     # 旧版本系统

动态查看配置(无需重启):

复制代码
SHOW VARIABLES LIKE 'log_error';  -- 查看错误日志路径
查看与分析

错误日志为文本格式,可直接用文本工具查看:

复制代码
# 查看最新10行错误日志
tail -n 10 /var/log/mysql/mysql-error.log

# 搜索关键词(如"error")
grep -i "error" /var/log/mysql/mysql-error.log

常见错误场景

  • 启动失败:检查端口占用(Port 3306 is already in use)、权限不足(Permission denied
  • 崩溃日志:搜索 mysqld got signal 11(段错误),通常与内存或引擎异常相关
管理策略
  • 日志轮转:通过 logrotate(Linux)定期切割日志,避免单个文件过大:

    创建logrotate配置(/etc/logrotate.d/mysql-error)

    /var/log/mysql/mysql-error.log {
    daily # 每天轮转
    rotate 7 # 保留7天日志
    compress # 压缩旧日志
    missingok # 日志不存在时不报错
    postrotate # 轮转后重启服务(可选)
    systemctl restart mysqld > /dev/null 2>&1
    endscript
    }

  • 权限设置:确保日志文件属主为 mysql 用户(chown mysql:mysql /var/log/mysql/*),避免写入失败。

2. 查询日志(General Log)

作用

记录所有客户端的连接行为(连接/断开)及执行的所有SQL语句 (包括SELECTINSERT等),可用于追踪异常操作(如误删数据)。

注意事项
  • 默认关闭(因高并发场景下会产生大量IO,严重影响性能)。
  • 仅建议在临时调试时开启(如定位某条SQL的执行来源),调试完成后立即关闭。
配置方法

方法1:通过配置文件永久开启

复制代码
[mysqld]
general_log = ON               # 开启查询日志(1/ON为开启,0/OFF为关闭)
general_log_file = /var/log/mysql/mysql-general.log  # 日志路径

重启服务生效。

方法2:动态开启(无需重启,临时生效)

复制代码
-- 查看当前状态
SHOW VARIABLES LIKE 'general_log';
SHOW VARIABLES LIKE 'general_log_file';

-- 动态开启
SET GLOBAL general_log = ON;
-- 动态修改日志路径(需确保mysql用户有写入权限)
SET GLOBAL general_log_file = '/var/log/mysql/new-general.log';
查看与分析

查询日志为文本格式,每行记录包含时间、客户端IP、SQL语句:

复制代码
tail -f /var/log/mysql/mysql-general.log  # 实时查看日志

示例日志内容:

复制代码
2025-08-14T08:30:00.123456Z 123 Connect root@192.168.1.100 on test using TCP/IP
2025-08-14T08:30:05.678901Z 123 Query SELECT * FROM users WHERE id = 1
2025-08-14T08:30:10.112233Z 123 Quit
关闭与清理

调试完成后务必关闭,避免性能损耗:

复制代码
SET GLOBAL general_log = OFF;  -- 动态关闭

日志文件可直接删除(需先关闭日志或重启服务),或通过日志轮转工具管理。

3. 慢查询日志(Slow Query Log)

作用

记录执行时间超过阈值(默认10秒)的SQL语句,是性能优化的核心工具,可快速定位低效查询(如未加索引、全表扫描的SQL)。

配置方法

核心参数说明

  • slow_query_log:是否开启(1/ON开启,0/OFF关闭)
  • slow_query_log_file:日志存储路径
  • long_query_time:慢查询阈值(单位:秒,支持小数如0.5,即500毫秒)
  • log_queries_not_using_indexes:是否记录未使用索引的查询(即使不慢,建议开启)
  • log_slow_admin_statements:是否记录管理员语句(如ALTER TABLE,可选开启)

方法1:配置文件永久生效

复制代码
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1  # 阈值设为1秒(根据业务调整)
log_queries_not_using_indexes = ON  # 记录未用索引的查询
log_slow_admin_statements = ON  # 记录慢管理语句

重启服务生效。

方法2:动态配置(临时生效)

复制代码
-- 开启慢查询日志
SET GLOBAL slow_query_log = ON;
-- 修改阈值为0.5秒
SET GLOBAL long_query_time = 0.5;
-- 开启未用索引记录
SET GLOBAL log_queries_not_using_indexes = ON;
日志分析工具

慢查询日志为文本格式,但直接查看效率低,推荐使用专业工具分析:

  • mysqldumpslow(MySQL自带): 简单统计慢查询TOP N(如最多执行次数、最长时间):

    查看执行次数最多的10条慢查询

    mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log

    查看平均时间最长的10条慢查询

    mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

  • pt-query-digest(Percona Toolkit,推荐): 更强大的分析工具,支持按SQL模板、用户、客户端等维度统计:

    安装(CentOS示例)

    yum install percona-toolkit -y

    分析慢查询日志并生成报告

    pt-query-digest /var/log/mysql/mysql-slow.log > slow_analysis.report

管理策略
  • 阈值调整:根据业务场景设置合理的long_query_time(如OLTP系统建议0.1-1秒)。
  • 日志轮转:同错误日志,使用logrotate定期切割,避免文件过大。
  • 定期分析:结合业务低峰期(如凌晨)运行pt-query-digest,输出优化清单。

4. 二进制日志(Binary Log)

作用

记录所有数据变更操作 (如INSERT/UPDATE/DELETECREATE/DROP等),不记录纯查询(SELECT)。核心用途:

  • 主从复制:主库通过binlog将变更同步到从库,保证数据一致性。
  • 数据恢复:通过回放binlog中指定时间段的操作,恢复误删/误改的数据。
配置方法

核心参数

  • log_bin:开启binlog并指定路径(如/var/log/mysql/mysql-bin,文件名自动加编号)。
  • binlog_format:日志格式(row/statement/mixed,推荐row)。
  • expire_logs_days:自动过期时间(天,默认0即永不过期)。
  • max_binlog_size:单个binlog文件最大大小(默认1GB,满后自动切换新文件)。

配置示例

复制代码
[mysqld]
log_bin = /var/log/mysql/mysql-bin  # 开启binlog
binlog_format = row  # 记录行级变更(避免主从数据不一致)
expire_logs_days = 7  # 7天后自动删除旧日志
max_binlog_size = 500M  # 单个文件最大500MB
server-id = 1  # 主从架构中必须设置唯一ID(主库1,从库2,3...)

重启服务生效(主从架构中需确保server-id唯一)。

关键操作
  • 查看binlog列表

    SHOW BINARY LOGS; -- 列出所有binlog文件及大小

  • 查看当前正在写入的binlog

    SHOW MASTER STATUS;

  • 查看binlog内容 (需用mysqlbinlog工具):

    查看指定binlog的文本格式内容(包含时间、SQL操作)

    mysqlbinlog --base64-output=decode-rows -v /var/log/mysql/mysql-bin.000001

    按时间筛选(如2025-08-14 08:00到09:00的操作)

    mysqlbinlog --start-datetime="2025-08-14 08:00:00" --stop-datetime="2025-08-14 09:00:00" /var/log/mysql/mysql-bin.000001

  • 手动删除binlog(谨慎操作):

    -- 删除指定文件之前的所有binlog(保留mysql-bin.000005及之后)
    PURGE BINARY LOGS TO 'mysql-bin.000005';

    -- 删除3天前的binlog
    PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);

数据恢复实战

假设误删了users表的数据,可通过binlog恢复:

  1. 找到误操作时间点(如2025-08-14 10:30)。

  2. 确定对应binlog文件(通过SHOW BINARY LOGS和时间匹配)。

  3. 提取误操作前的SQL并回放:

    导出2025-08-14 10:20到10:30(误操作前)的操作

    mysqlbinlog --start-datetime="2025-08-14 10:20:00" --stop-datetime="2025-08-14 10:30:00" /var/log/mysql/mysql-bin.000001 > recover.sql

    执行恢复SQL(注意先备份当前数据)

    mysql -u root -p < recover.sql

5. 中继日志(Relay Log)

作用

仅存在于从库,是主从复制的"中间载体":

  • 从库的IO线程读取主库binlog,写入本地中继日志。
  • 从库的SQL线程读取中继日志,执行其中的SQL操作,实现数据同步。
配置与管理
  • 默认路径:从库数据目录(如/var/lib/mysql/),文件名格式为host-relay-bin.xxxxxx

  • 核心参数:

    [mysqld]
    relay_log = /var/lib/mysql/relay-bin # 自定义中继日志路径
    relay_log_purge = ON # 自动清理已执行的中继日志(默认开启,避免占用空间)
    relay_log_recovery = ON # 从库崩溃后重启时,自动重新同步主库binlog(推荐开启)

  • 查看中继日志状态:

    SHOW SLAVE STATUS\G # 查看中继日志相关信息(如Relay_Log_File、Relay_Log_Pos)

6. InnoDB引擎日志(Redo Log & Undo Log)

作用与原理

InnoDB作为MySQL默认存储引擎,通过这两类日志保障事务ACID特性:

日志类型 核心作用 与事务的关系
重做日志(Redo Log) 记录数据页的修改,确保事务持久性(崩溃后可恢复) 事务提交时写入,支持"预写日志(WAL)"机制
回滚日志(Undo Log) 记录事务前的数据状态,支持回滚和MVCC 事务执行中动态生成,提交后标记删除

MVCC(Multi-Version Concurrency Control,多版本并发控制)是 MySQL InnoDB 存储引擎实现高并发读写的核心机制。它通过为数据记录维护多个版本,让读写操作可以无冲突地并行执行(读不阻塞写,写不阻塞读),同时保证事务隔离性。

简单来说:当多个事务同时操作同一份数据时,MVCC 会为每个事务提供独立的「数据版本」,使得事务之间的操作互不干扰,最终通过一套规则决定事务能看到哪个版本的数据。

配置与管理

Redo Log配置

复制代码
[mysqld]
innodb_log_file_size = 512M  # 单个redo log文件大小(默认48M,建议设为512M-2G)
innodb_log_files_in_group = 2  # 日志文件数量(默认2个,如ib_logfile0、ib_logfile1)
innodb_log_group_home_dir = ./  # 日志路径(默认数据目录)

注意:修改innodb_log_file_size需先停止服务,删除旧日志文件,重启后自动生成新文件。

Undo Log配置

复制代码
[mysqld]
innodb_undo_directory = ./  # undo log存储路径
innodb_undo_logs = 128  # undo日志段数量(默认128)
innodb_undo_tablespaces = 3  # 独立undo表空间数量(避免共享表空间膨胀)

三、日志管理最佳实践

1.按需开启日志

  • 必须开启:错误日志、二进制日志(主从或需恢复场景)、InnoDB日志(默认开启)。
  • 按需开启:慢查询日志(长期开启)、查询日志(仅临时调试)。

2.性能与存储平衡

  • 日志文件存储在独立磁盘(避免与数据盘IO竞争)。
  • 高并发场景下,long_query_time不宜设得过小(如<0.1秒),避免慢查询日志写入频繁。

3.自动化管理

  • 所有日志配置logrotate轮转(切割、压缩、删除旧日志)。
  • 监控日志目录磁盘使用率(如通过Prometheus+Grafana),避免占满磁盘。

4.安全与权限

  • 日志文件权限设为600(仅mysql用户可读写),避免敏感信息泄露(如binlog包含数据变更)。
  • 定期备份二进制日志(用于数据恢复),并加密存储。

四、常见问题与解决方案

问题场景 排查步骤 解决方案
服务启动失败 查看错误日志,搜索"error"关键词 检查端口占用、权限、配置文件语法错误
慢查询日志无记录 确认slow_query_log=ON,且SQL执行时间≥阈值 调整long_query_time,检查log_queries_not_using_indexes
主从同步延迟 从库执行SHOW SLAVE STATUS\G,查看中继日志 优化从库SQL线程(如slave_parallel_workers
binlog文件过大 检查max_binlog_sizeexpire_logs_days 调小单个文件大小,设置自动过期时间