第432集数据库日志管理
|字数总计:5.3k|阅读时长:20分钟|阅读量:
数据库日志管理
1. 数据库日志概述
1.1 日志的重要性
数据库日志是MySQL运行过程中产生的各种记录信息,是数据库运维、性能优化、故障排查和数据恢复的重要依据。合理配置和管理日志系统,对于保障数据库的稳定运行至关重要。
日志的核心价值:
- 故障排查:快速定位问题和错误原因
- 性能优化:分析慢查询,优化SQL语句
- 安全审计:记录用户操作,追踪异常行为
- 数据恢复:通过二进制日志实现数据恢复
- 监控告警:基于日志进行监控和告警
1.2 MySQL日志类型
MySQL提供了多种类型的日志,每种日志都有其特定的用途:
| 日志类型 |
用途 |
默认状态 |
| 错误日志 |
记录MySQL服务启动、运行、关闭过程中的错误信息 |
开启 |
| 查询日志 |
记录所有SQL语句的执行情况 |
关闭 |
| 慢查询日志 |
记录执行时间超过阈值的SQL语句 |
关闭 |
| 二进制日志 |
记录数据变更操作,用于数据恢复和主从复制 |
关闭 |
| 中继日志 |
主从复制中,从服务器保存主服务器的二进制日志 |
主从复制时开启 |
| 事务日志 |
InnoDB引擎的事务日志(redo log、undo log) |
自动开启 |
1.3 日志管理原则
1. 合理配置日志
- 根据实际需求开启必要的日志
- 避免开启过多日志影响性能
- 合理设置日志级别和过滤条件
2. 日志存储管理
- 日志文件存储在独立的磁盘分区
- 定期清理和归档历史日志
- 设置日志文件大小和保留时间
3. 日志安全保护
- 设置适当的文件权限
- 定期备份重要日志
- 保护日志文件不被篡改
4. 日志分析监控
- 定期分析日志内容
- 建立日志监控告警机制
- 使用工具进行日志分析
2. 错误日志
2.1 错误日志概述
MySQL的错误日志(Error Log)记录mysqld服务进程启动、关闭或运行过程中遇到的错误信息。错误日志是排查MySQL问题的重要依据。
错误日志记录的内容:
- MySQL服务启动和关闭信息
- 运行过程中的错误信息
- 警告信息
- 关键操作信息
2.2 配置错误日志
1. 在配置文件中设置
编辑MySQL配置文件 /etc/my.cnf:
配置示例:
1 2
| [mysqld] log-error=/log/mysql/err.log
|
配置说明:
log-error:指定错误日志文件路径
- 路径可以是绝对路径或相对路径
- 建议使用绝对路径
2. 创建日志目录和文件
1 2 3 4 5 6 7 8 9 10 11
| [root@sql ~]
[root@sql ~]
[root@sql ~]
[root@sql ~]
|
权限说明:
- 文件所有者:mysql用户
- 文件组:mysql组
- 权限:640(所有者可读写,组可读,其他用户无权限)
3. 重启数据库生效
1 2 3 4 5
| [root@sql ~]
[root@sql ~]
|
2.3 查看错误日志
方法一:直接查看日志文件
1 2 3 4 5
| [root@vm-70-161 ~]
2018-05-07T02:46:08.487851Z 0 [ERROR] unknown option '--dasdasdsadas'
|
常用查看命令:
1 2 3 4 5 6 7 8 9 10 11
| tail -n 100 /log/mysql/err.log
tail -f /log/mysql/err.log
grep -i "error" /log/mysql/err.log
grep "2018-05-07" /log/mysql/err.log
|
方法二:通过MySQL终端查看
1 2 3 4 5 6 7 8 9
| mysql> SHOW VARIABLES LIKE "log_error%"; + | Variable_name | Value | + | log_error | /log/mysql/err.log | | log_error_verbosity | 3 | + 2 rows in set (0.00 sec)
|
参数说明:
log_error:错误日志文件路径
log_error_verbosity:错误日志详细程度(1-3,3最详细)
2.4 错误日志级别
log_error_verbosity参数
1 2 3 4 5 6 7
| SHOW VARIABLES LIKE 'log_error_verbosity';
[mysqld] log_error_verbosity = 3
|
级别说明:
- 1:只记录错误信息
- 2:记录错误和警告信息
- 3:记录错误、警告和提示信息(最详细)
2.5 错误日志分析
常见错误类型
1. 启动错误:
1
| [ERROR] Can't start server: Bind on TCP/IP port: Address already in use
|
原因:端口被占用
2. 配置错误:
1
| [ERROR] unknown option '--dasdasdsadas'
|
原因:配置文件中有未知选项
3. 权限错误:
1
| [ERROR] Can't create/write to file '/log/mysql/err.log'
|
原因:文件权限不足
4. 表损坏错误:
1
| [ERROR] Table 'database.table' is marked as crashed
|
原因:表文件损坏
2.6 错误日志管理
1. 日志轮转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
cat > /etc/logrotate.d/mysql-error <<EOF /log/mysql/err.log { daily rotate 7 compress delaycompress missingok notifempty create 640 mysql mysql sharedscripts postrotate /bin/kill -HUP \$(cat /var/run/mysqld/mysqld.pid 2> /dev/null) 2> /dev/null || true endscript } EOF
|
2. 定期清理
1 2
| find /log/mysql -name "err.log.*" -mtime +30 -delete
|
3. 查询日志
3.1 查询日志概述
普通查询日志(General Query Log)记录客户端连接信息和执行的所有SQL语句信息。查询日志默认关闭,因为它会记录所有操作,对性能有一定影响。
查询日志记录的内容:
- 客户端连接和断开信息
- 所有执行的SQL语句
- SQL语句的执行时间
- 连接ID和线程ID
适用场景:
3.2 开启查询日志
1. 在配置文件中设置
编辑MySQL配置文件 /etc/my.cnf:
1 2 3 4
| [root@sql ~] [mysqld] general_log=ON general_log_file=/log/mysql/select.log
|
配置参数:
general_log:是否开启查询日志(ON/OFF)
general_log_file:查询日志文件路径
2. 创建日志目录和文件
1 2 3 4 5 6 7 8 9 10 11 12
| [root@sql ~]
[root@sql ~]
[root@sql ~] [root@sql ~]
[root@sql ~]
|
3.3 查看查询日志
查看日志内容
1 2 3 4 5 6 7 8 9 10 11 12
| [root@sql ~]
/usr/sbin/mysqld, Version: 5.7.22-log (MySQL Community Server (GPL)). started with: Tcp port: 0 Unix socket: /var/lib/mysql/mysql.sock Time Id Command Argument 2018-05-07T03:05:28.890758Z 4 Query insert into t5 values (1,"test") 2018-05-07T03:06:08.983337Z 4 Query update t5 set name='tt' where name='test' 2018-05-07T03:06:19.528444Z 4 Query show databases 2018-05-07T03:06:25.949473Z 4 Query drop database test 2018-05-07T03:06:25.972178Z 4 Query SELECT DATABASE()
|
日志格式说明:
Time:执行时间
Id:连接ID
Command:命令类型(Query、Connect、Quit等)
Argument:执行的SQL语句
通过MySQL终端查看配置
1 2 3 4 5 6 7 8 9
| mysql> SHOW VARIABLES LIKE 'general_log%'; + | Variable_name | Value | + | general_log | ON | | general_log_file | /log/mysql/select.log | + 2 rows in set (0.01 sec)
|
3.4 动态开启/关闭查询日志
临时开启查询日志
1 2 3
| mysql> SET GLOBAL general_log = ON; Query OK, 0 rows affected (0.00 sec)
|
临时关闭查询日志
1 2 3
| mysql> SET GLOBAL general_log = OFF; Query OK, 0 rows affected (0.00 sec)
|
说明:
SET GLOBAL:全局设置,立即生效
- 不需要重启MySQL服务
- 重启后会恢复配置文件中的设置
动态修改日志文件路径
1 2
| SET GLOBAL general_log_file = '/log/mysql/new_select.log';
|
3.5 查询日志分析
分析SQL执行情况
1 2 3 4 5 6 7 8
| grep "Query" /log/mysql/select.log | awk '{print $4}' | sort | uniq -c | sort -rn
grep "SELECT.*FROM.*users" /log/mysql/select.log
grep "Connect" /log/mysql/select.log | wc -l
|
3.6 查询日志管理建议
1. 生产环境谨慎开启
建议:
- 生产环境一般不开启查询日志
- 只在需要调试或审计时临时开启
- 开启后定期检查磁盘空间
2. 使用日志轮转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cat > /etc/logrotate.d/mysql-general <<EOF /log/mysql/select.log { daily rotate 3 compress missingok notifempty create 640 mysql mysql sharedscripts postrotate mysqladmin flush-logs endscript } EOF
|
3. 性能考虑
1 2 3 4 5
| SET GLOBAL general_log = ON;
SET GLOBAL general_log = OFF;
|
4. 慢查询日志
4.1 慢查询日志概述
慢查询日志(Slow Query Log)记录执行时间超过阈值的SQL语句。慢查询日志是性能优化的关键工具,可以帮助识别需要优化的SQL语句。
慢查询日志的价值:
- 性能优化:识别执行缓慢的SQL语句
- 索引优化:发现缺少索引的查询
- SQL调优:分析SQL执行计划
- 容量规划:了解数据库负载情况
4.2 开启慢查询日志
1. 在配置文件中设置
编辑MySQL配置文件 /etc/my.cnf:
1 2 3 4 5 6
| [root@sql ~] [mysqld] slow_query_log = ON slow_query_log_file = /log/mysql/slow.log long_query_time = 2 log_queries_not_using_indexes = ON
|
配置参数说明:
| 参数 |
说明 |
默认值 |
slow_query_log |
是否开启慢查询日志 |
OFF |
slow_query_log_file |
慢查询日志文件路径 |
hostname-slow.log |
long_query_time |
慢查询阈值(秒) |
10 |
log_queries_not_using_indexes |
记录未使用索引的查询 |
OFF |
log_slow_admin_statements |
记录管理语句 |
OFF |
min_examined_row_limit |
最小扫描行数 |
0 |
2. 创建日志目录和文件
1 2 3 4 5 6 7 8 9 10 11 12
| [root@sql ~]
[root@sql ~]
[root@sql ~] [root@sql ~]
[root@sql ~]
|
4.3 测试慢查询日志
执行慢查询语句
1 2
| mysql> SELECT BENCHMARK(50000000, 2*3);
|
BENCHMARK说明:
BENCHMARK(count, expr):执行表达式expr共count次
- 用于测试和性能基准测试
- 会消耗CPU资源,谨慎使用
检查慢查询日志
1 2 3 4 5 6 7 8 9 10 11 12
| [root@sql ~]
use bgx; SET timestamp=1525663627;
SET timestamp=1525651122; select BENCHMARK(500000000,2*3);
|
日志格式说明:
Time:执行时间
User@Host:用户和主机
Query_time:查询执行时间(秒)
Lock_time:锁定时间(秒)
Rows_sent:返回的行数
Rows_examined:扫描的行数
4.4 慢查询日志配置详解
long_query_time参数
1 2 3 4 5 6 7
| SHOW VARIABLES LIKE 'long_query_time';
SET GLOBAL long_query_time = 1;
|
阈值设置建议:
- 开发环境:0.1-0.5秒
- 测试环境:0.5-1秒
- 生产环境:1-2秒
- 高负载环境:2-5秒
log_queries_not_using_indexes
1 2
| SET GLOBAL log_queries_not_using_indexes = ON;
|
说明:
- 记录所有未使用索引的查询
- 即使执行时间小于阈值也会记录
- 有助于发现索引缺失问题
log_slow_admin_statements
1 2
| SET GLOBAL log_slow_admin_statements = ON;
|
4.5 慢查询日志分析
使用mysqldumpslow工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| mysqldumpslow /log/mysql/slow.log
mysqldumpslow -s t /log/mysql/slow.log
mysqldumpslow -s c /log/mysql/slow.log
mysqldumpslow -t 10 /log/mysql/slow.log
mysqldumpslow -a /log/mysql/slow.log
|
使用pt-query-digest工具
1 2 3 4 5 6 7 8
| yum install percona-toolkit
pt-query-digest /log/mysql/slow.log
pt-query-digest /log/mysql/slow.log > slow_report.txt
|
手动分析
1 2 3 4 5 6 7 8
| grep "Query_time" /log/mysql/slow.log | sort -k2 -rn | head -10
grep "FROM.*table_name" /log/mysql/slow.log
grep "Rows_examined" /log/mysql/slow.log | awk '$4 > 1000'
|
4.6 慢查询优化流程
1. 收集慢查询
1 2 3
| SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 1;
|
2. 分析慢查询
1 2
| pt-query-digest /log/mysql/slow.log
|
3. 优化SQL
4. 验证优化效果
5. 二进制日志
5.1 二进制日志概述
二进制日志(Binary Log,简称binlog)记录数据被修改的相关信息,包括数据变更的SQL语句或数据本身。二进制日志是MySQL最重要的日志之一。
二进制日志的用途:
- 数据恢复:通过binlog恢复误删除的数据
- 主从复制:主服务器将binlog发送给从服务器
- 数据审计:记录所有数据变更操作
- 增量备份:基于binlog进行增量备份
二进制日志的特点:
- 以二进制格式存储
- 只记录数据变更操作(INSERT、UPDATE、DELETE)
- 不记录SELECT和SHOW等查询操作
- 可以按时间点或位置点恢复
5.2 开启二进制日志
1. 在配置文件中设置
编辑MySQL配置文件 /etc/my.cnf:
1 2 3 4 5
| [root@sql ~] [mysqld] server-id = 161 log-bin = /log/mysql/bin/sql_70_161 expire_logs_days = 30
|
配置参数说明:
| 参数 |
说明 |
必需 |
server-id |
服务器唯一标识(主从复制必需) |
是 |
log-bin |
binlog文件路径和前缀 |
是 |
expire_logs_days |
日志保留天数 |
否 |
max_binlog_size |
单个binlog文件最大大小 |
否 |
binlog_format |
binlog格式(ROW/STATEMENT/MIXED) |
否 |
2. 创建日志目录和文件
1 2 3 4 5 6 7 8
| [root@vm-70-161 ~]
[root@vm-70-161 ~]
[root@sql ~]
|
说明:
- MySQL会自动创建binlog文件
- 文件命名格式:
前缀.序号(如:sql_70_161.000001)
- 文件大小达到
max_binlog_size时自动切换
5.3 查看二进制日志
使用mysqlbinlog工具
1 2 3 4 5 6 7 8
| [root@sql ~]
[root@sql ~]
[root@sql ~]
|
在MySQL中查看
1 2 3 4 5 6 7 8
| SHOW BINARY LOGS;
SHOW MASTER STATUS;
SHOW BINLOG EVENTS IN 'sql_70_161.000001';
|
5.4 二进制日志格式
1 2 3 4 5 6
| SHOW VARIABLES LIKE 'binlog_format';
[mysqld] binlog_format = ROW
|
格式类型:
| 格式 |
说明 |
优点 |
缺点 |
| STATEMENT |
记录SQL语句 |
日志文件小,可读性好 |
可能主从不一致 |
| ROW |
记录数据变更 |
主从一致性好 |
日志文件大 |
| MIXED |
混合模式 |
兼顾两者优点 |
复杂度高 |
推荐:生产环境使用ROW格式。
5.5 二进制日志管理
1. 日志切割
方法一:重启MySQL服务
1 2
| systemctl restart mysqld
|
方法二:使用FLUSH LOGS
1 2 3
| mysql> FLUSH LOGS; Query OK, 0 rows affected (0.01 sec)
|
方法三:使用RESET MASTER(危险)
1 2 3
| mysql> RESET MASTER; Query OK, 0 rows affected (0.00 sec)
|
警告:RESET MASTER会删除所有binlog文件,通常只在从服务器上使用。
2. 删除部分binlog日志
按文件名删除:
1 2 3
| mysql> PURGE MASTER LOGS TO 'sql_70_161.000004'; Query OK, 0 rows affected (0.01 sec)
|
说明:删除sql_70_161.000004之前的所有binlog文件。
按时间删除:
1 2 3
| mysql> PURGE BINARY LOGS BEFORE '2018-05-07 11:57:33'; Query OK, 0 rows affected (0.01 sec)
|
自动删除:
1 2 3 4 5 6
| [mysqld] expire_logs_days = 30
SET GLOBAL expire_logs_days = 30;
|
说明:自动删除30天前的binlog文件。
5.6 二进制日志恢复
1. 使用时间点恢复
恢复指定时间范围的数据:
1 2 3 4 5 6 7 8
| mysqlbinlog mysql.000002 \ --start-datetime="2018-05-07 12:05:00" \ --stop-datetime="2018-05-07 11:02:54" | mysql -uroot -p
mysqlbinlog mysql.000002 \ --start-datetime="2018-12-05 10:02:56" | mysql -uroot -p
|
2. 使用位置点恢复
恢复指定位置范围的数据:
1 2 3 4 5 6 7 8 9 10 11 12
| mysqlbinlog mysql.000002 \ --start-position=124 \ --stop-position=336 | mysql -uroot -p
mysqlbinlog mysql.000002 \ --start-position=124 | mysql -uroot -p
mysqlbinlog mysql.000002 \ --stop-position=124 | mysql -uroot -p
|
3. 完整恢复流程
步骤1:停止数据库写入
1 2 3 4
| FLUSH TABLES WITH READ LOCK;
|
步骤2:恢复全量备份
1 2
| mysql -uroot -p < full_backup.sql
|
步骤3:恢复增量数据(binlog)
1 2 3 4 5
|
mysqlbinlog mysql.000002 \ --start-datetime="2018-05-07 10:00:00" \ --stop-datetime="2018-05-07 11:00:00" | mysql -uroot -p
|
步骤4:解锁表
5.7 二进制日志最佳实践
1. 定期备份binlog
1 2 3 4
| cp /log/mysql/bin/sql_70_161.* /backup/binlog/
|
2. 监控binlog大小
1 2 3 4 5 6 7
| SHOW BINARY LOGS;
SELECT ROUND(SUM(file_size)/1024/1024, 2) AS total_size_mb FROM information_schema.binary_log_file_summary;
|
3. 设置合理的保留时间
1 2 3
|
SET GLOBAL expire_logs_days = 8;
|
4. 使用binlog进行增量备份
1 2 3 4 5 6 7 8
|
BACKUP_DIR="/backup/binlog" LOG_DIR="/log/mysql/bin" DATE=$(date +%Y%m%d)
mkdir -p $BACKUP_DIR/$DATE cp $LOG_DIR/* $BACKUP_DIR/$DATE/
|
6. 日志管理最佳实践
6.1 日志配置建议
生产环境推荐配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| [mysqld]
log-error=/log/mysql/err.log log_error_verbosity=2
slow_query_log=ON slow_query_log_file=/log/mysql/slow.log long_query_time=2 log_queries_not_using_indexes=ON
server-id=1 log-bin=/log/mysql/bin/mysql-bin binlog_format=ROW expire_logs_days=7 max_binlog_size=100M
general_log=OFF
|
6.2 日志存储管理
1. 独立磁盘分区
2. 日志轮转配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cat > /etc/logrotate.d/mysql <<EOF /log/mysql/*.log { daily rotate 7 compress delaycompress missingok notifempty create 640 mysql mysql sharedscripts postrotate /bin/kill -HUP \$(cat /var/run/mysqld/mysqld.pid) 2> /dev/null || true endscript } EOF
|
3. 定期清理
1 2 3 4 5
|
LOG_DIR="/log/mysql"
find $LOG_DIR -name "*.log.*" -mtime +30 -delete
|
6.3 日志监控告警
1. 监控日志大小
1 2 3 4 5 6 7 8 9 10 11 12
|
LOG_DIR="/log/mysql" MAX_SIZE=10G
for log in $(find $LOG_DIR -name "*.log"); do size=$(du -sh $log | awk '{print $1}') if [ $(du -sm $log | awk '{print $1}') -gt 10240 ]; then echo "Warning: $log size is $size" fi done
|
2. 监控错误日志
1 2 3 4 5
| tail -f /log/mysql/err.log | grep --line-buffered "ERROR" | while read line; do echo "Error detected: $line" done
|
6.4 日志分析工具
1. 使用ELK Stack
- Elasticsearch:存储日志
- Logstash:收集和解析日志
- Kibana:可视化分析
1 2 3 4 5
| pt-query-digest /log/mysql/slow.log
pt-table-checksum
|
3. 自定义分析脚本
1 2 3 4 5
| mysqldumpslow -s t -t 10 /log/mysql/slow.log
grep "ERROR" /log/mysql/err.log | awk '{print $NF}' | sort | uniq -c
|
7. 日志安全考虑
7.1 文件权限
1 2 3
| chmod 640 /log/mysql/*.log chown mysql.mysql /log/mysql/*.log
|
7.2 日志加密
1 2 3 4 5
| [mysqld] ssl-ca=ca.pem ssl-cert=server-cert.pem ssl-key=server-key.pem
|
7.3 敏感信息保护
8. 总结
8.1 日志管理的核心价值
- 故障排查:快速定位问题和错误
- 性能优化:分析慢查询,优化SQL
- 数据恢复:通过binlog恢复数据
- 安全审计:记录操作,追踪异常
8.2 日志管理原则
- 合理配置:根据需求开启必要的日志
- 定期清理:避免日志文件占满磁盘
- 安全保护:设置适当的文件权限
- 监控分析:建立日志监控和分析机制
8.3 架构师建议
- 日志策略:制定清晰的日志管理策略
- 存储规划:日志存储在独立分区
- 监控告警:建立日志监控和告警机制
- 定期审查:定期审查和分析日志内容
- 备份保护:重要日志定期备份
8.4 日志管理检查清单
相关文章: