Skip to content

MySQL 日志满故障处理

紧急处理步骤

步骤1:确认故障原因

检查磁盘空间

bash
# 查看磁盘使用情况
df -h

# 查看目录使用情况
du -sh /path/to/mysql/datadir/*

定位占用空间的日志文件

bash
# 查找大文件
find /path/to/mysql/datadir -type f -size +1G

# 按大小排序
ls -lhS /path/to/mysql/datadir/*.log /path/to/mysql/datadir/binlog.*

步骤2:临时清理空间

清理二进制日志

注意:在主从架构中,清理前需确保从库已应用所有二进制日志

sql
-- 查看当前使用的二进制日志
SHOW MASTER STATUS;

-- 清理指定日志之前的所有日志
PURGE BINARY LOGS TO 'binlog.000123';

-- 按时间清理
PURGE BINARY LOGS BEFORE '2023-12-31 23:59:59';

-- 清理所有二进制日志(谨慎使用)
RESET MASTER;

清理错误日志

bash
# 备份并清空错误日志
cp /path/to/error.log /path/to/error.log.bak
> /path/to/error.log

# 重启MySQL让日志重新生成
systemctl restart mysql

清理慢查询日志

bash
# 备份并清空慢查询日志
cp /path/to/slow.log /path/to/slow.log.bak
> /path/to/slow.log

# 或者通过MySQL命令重置
SET GLOBAL slow_query_log = 'OFF';
SET GLOBAL slow_query_log = 'ON';

步骤3:恢复服务

启动MySQL服务

bash
# 启动MySQL
systemctl start mysql

# 检查服务状态
systemctl status mysql

验证服务功能

sql
-- 测试连接
mysql -u root -p

-- 执行简单查询
SELECT 1;

-- 检查复制状态(主从架构)
SHOW SLAVE STATUS\G;

根本原因分析

常见原因

  1. 配置不当:未配置日志过期时间或轮转策略
  2. 监控缺失:未监控磁盘空间和日志大小
  3. 复制延迟:从库延迟导致主库二进制日志无法清理
  4. 异常流量:突发的大量慢查询或错误
  5. 硬件限制:磁盘空间过小,无法满足业务需求
  6. 应用问题:应用程序产生大量错误或慢查询

分析方法

查看错误日志

bash
# 查看错误日志最后N行
tail -n 100 /path/to/error.log

# 搜索与磁盘空间相关的错误
grep -i "disk\|space\|full" /path/to/error.log

检查日志配置

sql
-- 查看二进制日志配置
SHOW VARIABLES LIKE 'expire_logs_days';
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';

-- 查看慢查询日志配置
SHOW VARIABLES LIKE '%slow%';

-- 查看错误日志配置
SHOW VARIABLES LIKE 'log_error';
SHOW VARIABLES LIKE 'log_error_verbosity';

分析复制状态

sql
-- 查看从库状态
SHOW SLAVE STATUS\G;

-- 查看主库二进制日志状态
SHOW MASTER LOGS;

长期解决方案

日志配置优化

二进制日志优化

ini
# my.cnf配置
# 设置二进制日志过期时间(秒)
binlog_expire_logs_seconds = 2592000  # 30天

# 或设置过期天数(MySQL 5.6及之前)
# expire_logs_days = 30

# 设置二进制日志大小限制
max_binlog_size = 1G

# 启用二进制日志校验
binlog_checksum = CRC32

错误日志优化

ini
# my.cnf配置
# 设置错误日志路径
log_error = /var/log/mysql/error.log

# 设置错误日志级别(1-3)
log_error_verbosity = 2

# 启用错误日志轮转
# 注意:需要配合外部工具如logrotate

慢查询日志优化

ini
# my.cnf配置
# 设置慢查询日志路径
slow_query_log_file = /var/log/mysql/slow.log

# 设置慢查询阈值
long_query_time = 1

# 启用慢查询日志
slow_query_log = 1

# 记录未使用索引的查询
log_queries_not_using_indexes = 0

日志轮转配置

使用logrotate

创建配置文件/etc/logrotate.d/mysql

txt
/var/log/mysql/*.log {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    create 640 mysql mysql
    postrotate
        # 重启MySQL或刷新日志
        systemctl reload mysql > /dev/null 2>&1 || true
    endscript
}

/path/to/mysql/datadir/binlog.* {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    notifempty
    postrotate
        # 清理过期二进制日志
        mysql -u root -p"password" -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);" > /dev/null 2>&1 || true
    endscript
}

手动轮转方法

sql
-- 轮转二进制日志
FLUSH BINARY LOGS;

-- 轮转错误日志(MySQL 5.5+)
FLUSH ERROR LOGS;

-- 轮转慢查询日志
SET GLOBAL slow_query_log = 'OFF';
SET GLOBAL slow_query_log = 'ON';

监控与预警

磁盘空间监控

Prometheus配置示例

yaml
- job_name: 'node'
  static_configs:
    - targets: ['localhost:9100']
  metrics_path: /metrics
  scrape_interval: 15s

Grafana告警规则

  • 磁盘使用率 > 80% 触发警告
  • 磁盘使用率 > 90% 触发严重告警

日志大小监控

自定义监控脚本

bash
#!/bin/bash

# 检查二进制日志大小
BINLOG_SIZE=$(du -s /path/to/mysql/datadir/binlog.* | awk '{sum += $1} END {print sum/1024/1024 " MB"}')

# 检查慢查询日志大小
SLOWLOG_SIZE=$(du -h /path/to/slow.log | awk '{print $1}')

# 检查错误日志大小
ERRORLOG_SIZE=$(du -h /path/to/error.log | awk '{print $1}')

# 输出结果
echo "Binary log size: $BINLOG_SIZE"
echo "Slow query log size: $SLOWLOG_SIZE"
echo "Error log size: $ERRORLOG_SIZE"

# 发送告警(可集成到监控系统)

架构优化

存储分离

  • 将日志存储在独立的磁盘分区
  • 使用SSD存储提高日志读写性能
  • 配置合适的磁盘配额

复制架构优化

  • 监控并解决复制延迟问题
  • 考虑使用多源复制减少单点依赖
  • 配置复制过滤,减少不必要的日志传输

备份策略优化

  • 定期备份日志文件到外部存储
  • 使用压缩备份减少存储空间
  • 实现增量备份策略

预防措施

日常维护

  1. 定期检查:每周检查磁盘空间和日志大小
  2. 配置审核:每月审核MySQL配置,确保日志设置合理
  3. 监控验证:每季度验证监控系统的有效性
  4. 容量规划:根据业务增长预测,提前规划存储需求
  5. 演练测试:定期进行故障演练,测试应急响应能力

最佳实践

配置最佳实践

ini
# 推荐的日志相关配置

# 二进制日志
server-id = 1
binlog_format = ROW
binlog_expire_logs_seconds = 2592000  # 30天
max_binlog_size = 1G
sync_binlog = 1

# 错误日志
log_error = /var/log/mysql/error.log
log_error_verbosity = 2

# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 0
log_slow_admin_statements = 0
log_slow_slave_statements = 0

# 通用查询日志(建议禁用)
general_log = 0

监控最佳实践

  • 设置合理的告警阈值:磁盘使用率80%警告,90%严重
  • 多维度监控:监控磁盘空间、I/O使用率、日志增长速度
  • 趋势分析:分析日志增长趋势,预测未来空间需求
  • 自动清理:配置自动清理策略,避免人工干预

应急响应最佳实践

  • 建立标准流程:制定详细的日志满故障处理流程
  • 准备工具包:准备常用的磁盘清理和日志管理工具
  • 定期培训:培训运维人员掌握故障处理技能
  • 文档更新:及时更新故障处理文档,总结经验教训

常见问题(FAQ)

Q1: 如何判断是哪种日志导致的磁盘空间不足

A1: 识别方法:

  • 检查文件大小:使用du -sh命令查看各日志文件大小
  • 查看目录结构:检查datadir目录下的文件分布
  • 分析文件类型
    • binlog.*:二进制日志文件
    • *.err:错误日志文件
    • *-slow.log:慢查询日志文件
    • general.log:通用查询日志文件
  • 监控工具:使用监控工具查看磁盘使用趋势

Q2: 紧急情况下如何快速清理日志空间

A2: 紧急清理步骤:

  • 二进制日志:使用PURGE BINARY LOGS命令清理旧日志
  • 错误日志:备份后清空错误日志文件
  • 慢查询日志:临时关闭再开启慢查询日志
  • 通用查询日志:如果启用了,立即关闭
  • 注意事项
    • 主从架构中需确保从库已应用所有二进制日志
    • 备份重要日志文件,避免数据丢失
    • 记录清理操作,便于后续分析

Q3: 如何配置日志自动清理

A3: 自动清理配置:

  • 二进制日志
    ini
    # MySQL 5.6+
    binlog_expire_logs_seconds = 2592000  # 30天
    # 或 MySQL 5.5及之前
    expire_logs_days = 30
  • 其他日志:使用logrotate配置轮转
    txt
    /var/log/mysql/*.log {
        daily
        rotate 7
        missingok
        compress
        delaycompress
        notifempty
        create 640 mysql mysql
        postrotate
            systemctl reload mysql > /dev/null 2>&1 || true
        endscript
    }

Q4: 复制环境中如何安全清理二进制日志

A4: 复制环境清理策略:

  • 检查复制状态:确保所有从库已应用待清理的日志
  • 使用MASTER_POS_WAIT:等待从库同步到指定位置
  • 配置过期时间:设置合理的binlog_expire_logs_seconds
  • 定期监控:监控复制延迟,及时处理异常
  • GTID模式:在GTID模式下,确保所有从库都已同步

Q5: 如何监控日志增长情况

A5: 监控方法:

  • Prometheus + Grafana:配置磁盘空间和文件大小监控
  • 自定义脚本:定期检查日志大小并发送告警
  • 系统工具:使用dfdu等命令监控
  • MySQL指标:监控Binlog_cache_disk_use等状态变量
  • 告警阈值
    • 磁盘使用率 > 80% 警告
    • 磁盘使用率 > 90% 严重告警
    • 日志增长速度异常告警

Q6: 如何避免日志满故障的发生

A6: 预防措施:

  • 合理配置:设置适当的日志过期时间和轮转策略
  • 监控到位:实时监控磁盘空间和日志大小
  • 容量规划:根据业务增长预测存储需求
  • 定期清理:定期清理过期日志文件
  • 架构优化
    • 将日志存储在独立分区
    • 使用SSD提高日志读写性能
    • 考虑使用云存储或外部存储

Q7: 日志满故障对业务的影响及应对

A7: 影响与应对:

  • 业务影响
    • 写入操作失败
    • 连接无法建立
    • 服务可能崩溃
    • 复制中断
  • 应对策略
    • 建立应急响应流程
    • 准备回滚方案
    • 与业务方沟通,制定降级策略
    • 定期演练故障处理流程

Q8: 不同MySQL版本的日志管理有什么差异

A8: 版本差异:

  • MySQL 5.5
    • 支持FLUSH ERROR LOGS
    • 使用expire_logs_days控制二进制日志过期
  • MySQL 5.6
    • 新增binlog_expire_logs_seconds参数
    • 增强了日志管理功能
  • MySQL 5.7
    • 进一步优化了日志性能
    • 提供了更多日志相关的系统变量
  • MySQL 8.0
    • 提供了更多日志管理的性能改进
    • 增强了日志安全性

Q9: 如何处理云环境中的日志满问题

A9: 云环境处理:

  • 使用云存储:将日志存储在对象存储服务中
  • 自动扩容:配置云磁盘自动扩容
  • 生命周期管理:设置日志文件的生命周期规则
  • 监控集成:使用云平台的监控和告警服务
  • 备份策略:利用云备份服务,减少本地存储压力

Q10: 日志管理的最佳实践有哪些

A10: 最佳实践:

  • 配置层面
    • 设置合理的日志过期时间
    • 配置适当的日志级别
    • 使用logrotate进行日志轮转
  • 监控层面
    • 实时监控磁盘空间
    • 监控日志增长速度
    • 设置合理的告警阈值
  • 运维层面
    • 定期检查日志配置
    • 定期清理过期日志
    • 记录日志管理操作
  • 应急层面
    • 建立日志满故障处理流程
    • 准备应急工具包
    • 定期演练故障处理

案例分析

案例1:二进制日志满导致主库宕机

背景

  • 主从复制架构
  • 从库因网络问题延迟7天
  • 主库二进制日志未配置过期时间
  • 磁盘空间100GB,二进制日志占用95GB

故障过程

  1. 从库网络中断,复制停止
  2. 主库二进制日志持续增长
  3. 磁盘空间耗尽,主库写入失败
  4. 应用无法连接数据库,业务中断

解决方案

  1. 紧急处理:在从库恢复网络连接前,临时清理部分旧的二进制日志
  2. 根本解决:配置binlog_expire_logs_seconds = 2592000(30天)
  3. 监控增强:添加二进制日志大小监控,设置80%告警阈值
  4. 架构优化:实现多从库架构,避免单点复制依赖

预防措施

  • 配置合理的二进制日志过期时间
  • 监控复制延迟,及时处理异常
  • 实施存储分离,将日志放在独立分区

案例2:慢查询日志导致测试环境满盘

背景

  • 测试环境MySQL实例
  • 启用了慢查询日志,未配置轮转
  • 开发人员执行了大量全表扫描查询
  • 磁盘空间50GB,慢查询日志占用45GB

故障过程

  1. 开发人员执行性能测试,产生大量慢查询
  2. 慢查询日志快速增长
  3. 磁盘空间耗尽,测试环境无法使用
  4. 其他服务受影响,测试中断

解决方案

  1. 紧急处理:备份并清空慢查询日志
  2. 配置优化:配置slow_query_log_file路径,设置合理的轮转策略
  3. 权限控制:限制开发人员在生产环境执行全表扫描
  4. 监控添加:添加慢查询日志大小监控

预防措施

  • 在测试环境也配置合理的日志轮转
  • 对开发人员进行SQL优化培训
  • 实施SQL审核,避免低效查询