MySQL的三大日志
前言
飞机失事靠黑匣子还原真相,MySQL崩溃靠三大日志保障数据安全。
作为一个工作多年的程序员,我见过太多因日志配置不当引发的灾难:数据丢失、主从同步中断、事务回滚失败...
今天,我将用最通俗的方式,带你彻底掌握MySQL三大日志的底层原理,希望对你会有所帮助。
一、引子:一个数据丢失的教训
事故现场:某电商平台数据库服务器宕机后,发现最近2小时订单数据丢失。
问题根源: 错误配置导致redo log刷盘失效:
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 0 | -- 应设为1
+--------------------------------+-------+
核心结论:
- 日志系统是MySQL的安全气囊
- 不理解日志机制,等于在数据安全上裸奔
二、Redo Log:保证持久性的守护神
2.1 核心作用:崩溃恢复
WAL原则(Write-Ahead Logging):

2.2 物理结构解析
循环写入机制:

关键参数:
-- 查看日志配置
SHOW VARIABLES LIKE 'innodb_log%';
+---------------------------+---------+
| Variable_name | Value |
+---------------------------+---------+
| innodb_log_file_size | 50331648| -- 单个日志文件大小
| innodb_log_files_in_group | 2 | -- 日志文件数量
| innodb_log_buffer_size | 16777216| -- 缓冲区大小
+---------------------------+---------+
2.3 刷盘策略实战
// JDBC事务提交示例
Connection conn = DriverManager.getConnection(url, user, pwd);
try {
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate("UPDATE account SET balance=balance-100 WHERE id=1");
stmt.executeUpdate("UPDATE account SET balance=balance+100 WHERE id=2");
// 核心配置:刷盘策略
conn.setClientInfo("innodb_flush_log_at_trx_commit", "1");
conn.commit(); // 触发redo log刷盘
} catch (SQLException e) {
conn.rollback();
}
刷盘策略对比:
| 参数值 | 安全性 | 性能 | 适用场景 |
|---|---|---|---|
| 0 | 低(每秒刷) | 最高 | 可丢失数据的缓存 |
| 1 | 最高(实时) | 最低 | 金融交易系统 |
| 2 | 中(OS缓存) | 较高 | 常规业务系统 |
三、Undo Log:事务回滚的时光机
3.1 MVCC实现原理
多版本控制流程:

3.2 回滚操作源码级解析
-- 事务回滚示例
START TRANSACTION;
UPDATE users SET name='张三' WHERE id=1;
-- 在undo log中记录:
-- | 事务ID | 行ID | 旧值 | 回滚指针 |
-- | 101 | 1 | '李四'| 0x7F8A9B|
ROLLBACK; -- 根据undo log恢复数据
3.3 长事务引发的灾难
问题场景:
-- 查询运行超过60秒的事务
SELECT * FROM information_schema.innodb_trx
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60;
严重后果:
- Undo Log暴涨占用磁盘空间
- 历史版本链过长导致查询性能下降
解决方案:
@Transactional(timeout = 30) // 单位:秒
public void updateOrder(Order order) {
// 业务逻辑
}
Spring Boot项目可以设置事务超时时间。
四、Binlog:主从复制的桥梁
4.1 三种格式深度对比
| 格式 | 特点 | 数据安全 | 复制效率 |
|---|---|---|---|
| STATEMENT | 记录SQL语句 | 低 | 高 |
| ROW | 记录行变化 | 高 | 低 |
| MIXED | 自动切换模式 | 中 | 中 |
ROW格式的优势:
-- 原始SQL
UPDATE users SET status=1 WHERE age>30;
-- ROW格式binlog实际记录
/* 修改前镜像 */
id:1, status:0, age:35
id:2, status:0, age:40
/* 修改后镜像 */
id:1, status:1, age:35
id:2, status:1, age:40
4.2 主从复制全流程剖析

4.3 数据恢复实战
场景:误删全表数据
恢复步骤:
# 1. 解析binlog找到删除位置
mysqlbinlog --start-position=763 --stop-position=941 binlog.000001 > recovery.sql
# 2. 提取回滚SQL
grep -i 'DELETE FROM users' recovery.sql
# 3. 生成反向补偿语句
sed 's/DELETE FROM/INSERT INTO/g' recovery.sql > rollback.sql
# 4. 执行恢复
mysql -u root -p < rollback.sql
五、三大日志协同工作图
更新语句执行流程:

两阶段提交关键点:
- redo log prepare 与 binlog 写入的原子性
- 崩溃恢复时的决策逻辑:
- binlog完整:提交事务
- binlog不完整:回滚事务
六、生产环境优化指南
6.1 参数调优模板
my.cnf 关键配置:
[mysqld]
# Redo Log
innodb_log_file_size = 2G # 建议4个日志文件
innodb_log_files_in_group = 4
innodb_flush_log_at_trx_commit = 1
# Undo Log
innodb_max_undo_log_size = 1G
innodb_undo_log_truncate = ON
innodb_purge_threads = 4
# Binlog
server_id = 1
log_bin = /data/mysql-bin
binlog_format = ROW
binlog_expire_logs_seconds = 604800 # 保留7天
sync_binlog = 1 # 每次提交刷盘
6.2 监控指标清单
-- 关键监控SQL
SELECT
/* Redo Log */
(SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME='Innodb_os_log_written') AS redo_written,
/* Undo Log */
(SELECT SUM(DATA_LENGTH)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA='mysql'
AND TABLE_NAME LIKE 'undo%') AS undo_size,
/* Binlog */
(SELECT VARIABLE_VALUE
FROM performance_schema.global_status
WHERE VARIABLE_NAME='Binlog_cache_disk_use') AS binlog_disk_use;
6.3 常见问题解决方案
问题1:redo log文件设置过小导致频繁checkpoint。
现象:
SHOW GLOBAL STATUS LIKE 'Innodb_log_waits';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Innodb_log_waits | 542 | -- 值>0表示存在等待
+------------------+-------+
解决:
# 动态调整(需重启生效)
SET GLOBAL innodb_log_file_size = 2147483648;
问题2:大事务导致binlog暴涨。
预防方案:
// 事务拆分示例
public void batchProcess(List<Order> orders) {
int batchSize = 100; // 每100条一个事务
for (int i=0; i<orders.size(); i+=batchSize) {
transactionTemplate.execute(status -> {
List<Order> subList = orders.subList(i, Math.min(i+batchSize, orders.size()));
processBatch(subList);
return null;
});
}
}
七、总结
Redo Log是生命线:
- 配置原则:
innodb_flush_log_at_trx_commit=1 + 足够大的日志文件 - 监控重点:
Innodb_log_waits应趋近于0
- 配置原则:
Undo Log是后悔药:
- 及时清理:开启
innodb_undo_log_truncate - 避免长事务:监控
information_schema.innodb_trx
- 及时清理:开启
Binlog是复制基石:
- 格式选择:金融级系统必须用ROW格式
- 同步策略:主从复制时
sync_binlog=1
数据库的可靠性不是偶然发生的,而是通过三大日志的精密协作实现的。
当你下次执行COMMIT时,请记住背后有三个强大的守护者在为你工作:
- Redo Log确保你的数据不会丢失
- Undo Log保证你的操作可以撤销
- Binlog让数据在集群间流动
敬畏日志,就是敬畏数据安全!
最后说一句(求关注,别白嫖我)
如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。
求一键三连:点赞、转发、在看。
关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。
本文收录于我的技术网站:http://www.susan.net.cn
MySQL的三大日志的更多相关文章
- 【Mysql】三大日志 redo log、bin log、undo log
@ 目录 redo log(物理日志\重做日志) binlog(逻辑日志/归档日志) update语句执行流程 Uodolog(回滚日志/重做日志) undo log+redo log保证持久性 re ...
- 女朋友说:你要搞懂了MySQL三大日志,我就让你嘿嘿嘿!
1. 背景 MySQL实现事务.崩溃恢复.集群的主从复制,底层都离不开日志,所以日志是MySQL的精华所在.只有了解MySQL日志,才算是彻底搞懂MySQL. 今天一灯就带你深入浅出的学习MySQL的 ...
- 必须了解的mysql三大日志-binlog、redo log和undo log
日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括错误日志.查询日志.慢查询日志.事务日志.二进制日志几大类.作为开发,我们重点需要关注的是二进制日志( ...
- 20180530利用Maxwell组件实时监听Mysql的binlog日志
转自:https://blog.csdn.net/qq_30921461/article/details/78320750 http://kafka.apache.org/quickstart htt ...
- mysql general log日志
注:应一直出现http://www.cnblogs.com/hwaggLee/p/6030765.html文章中的问题 故mysql general log日志.查看具体是什么命令导致的. 打开 ge ...
- MySQL慢查询日志总结
慢查询日志概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志 ...
- mysql慢查询日志分析工具 mysqlsla(转)
mysql数据库的慢查询日志是非常重要的一项调优辅助日志,但是mysql默认记录的日志格式阅读时不够友好,这是由mysql日志记录规则所决定的,捕获一条就记录一条,虽说记录的信息足够详尽,但如果将浏览 ...
- MySQL 慢查询日志分析及可视化结果
MySQL 慢查询日志分析及可视化结果 MySQL 慢查询日志分析 pt-query-digest分析慢查询日志 pt-query-digest --report slow.log 报告最近半个小时的 ...
- django+nginx+xshell简易日志查询,接上<关于《rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>》的反思>
纠正一下之前在<关于<rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>>的反思>中说到的PHP+MySQL太慢,这里只是说我技术不好,没 ...
- 关于《rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>》的反思
关于<rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>>的反思--链接--http://www.cnblogs.com/drgcaosheng/p/ ...
随机推荐
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(12)
1.问题描述: pushdeviceid的长度是固定的吗? 解决方案: 在鸿蒙系统中,设备ID的长度是固定的. 2.问题描述: 通过REST API三方推送IM类消息,如何实现应用处于前台时不展示三方 ...
- C#多线程编程(二)线程池与TPL
一.直接使用线程的问题 每次都要创建Thread对象,并向操作系统申请创建一个线程,这是需要耗费CPU时间和内存资源的. 无法直接获取线程函数返回值 无法直接捕捉线程函数内发生的异常 使用线程池可以解 ...
- springboot接口接收xml
对xml文件的操作也可以借助hutool的XmlUtil. 1. xml格式 <root> <deviceStatInfo onlineCount="64" of ...
- volatile修饰全局变量,可以保证线程并发安全吗?
今天被人问到volatile能不能保证并发安全? 呵,这能难倒我? 直接上代码: public class ThreadTest { // 使用volatile修饰变量 private static ...
- js判断iOS还是Android
/** * 运行设备引擎, 即iOS, Android还是H5 * 返回值注意大小写 * @return iOS, Android, H5 */ function engineType() { let ...
- 1、HTML常用标签
此文章为学习笔记以下内容为HTML常用标签. 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset=&quo ...
- Wireshark 的抓包和分析,看这篇就够了!
原文:Wireshark 的抓包和分析,看这篇就够了!
- 备注一下,SolidColorBrush,自定义颜色
new SolidColorBrush((Color)ColorConverter.ConvertFromString("#27212B"))
- 1安装docker
1安装docker 1.1主机环境 ssh://192.168.30.30:22 root 123QWEasd 1.2安装依赖 docker依赖于系统的一些必要的工具,可以提前安装. yum ...
- mysql——修改mysql提示符
参数 描述 \D 完整日期 \d 当前数据库 \h 服务器名称 \u 当前用户 连接客户端时通过参数指定 mysql -uroot -p密码 --prompt=提示符 mysql -h 192.168 ...