• 图解 MySQL 日志体系:让你明明白白记住各种 Log

图解 MySQL 日志体系:让你明明白白记住各种 Log

2025-06-19 10:00:06 栏目:宝塔面板 61 阅读

面试官:MySQL的日志系统了解吗?

我:MySQL有binlog、redo log...

面试官:那它们分别解决什么问题?为什么需要这么多种日志?

我:这个...(尴尬)

相信这样的对话很多同学都经历过。大家都知道MySQL有各种日志,但要说清楚它们的作用和关系,往往就不那么容易了。

作为一名有着7年MySQL开发经验的老兵,今天我用最通俗的语言,帮你彻底理解MySQL日志体系。

一、为什么MySQL需要日志系统?

让我们从一个最基础的数据库操作说起:

// 用户消费100元
UPDATE account SET balance = balance - 100 WHERE id = 1;

这条简单的SQL语句,实际上给数据库带来了三大挑战:

  • 可靠性问题:如果数据库突然宕机,这笔交易记录会不会丢失?
  • 一致性问题:如果用户要求退款,如何安全地回滚这笔交易?
  • 同步问题:如何确保其他数据库节点也正确记录了这笔交易?

为解决这些问题,MySQL设计了三种核心日志:

数据库操作 ──────────────────┐
                            ↓
┌─── Redo Log(临时记事本)
│     记录:"账户1减少100元"
│     作用:确保交易记录不丢失
│
├─── Undo Log(原始凭证)
│     记录:"账户1原有500元"
│     作用:随时可以撤销交易
│
└─── Binlog(总账本)
      记录:"完整交易记录"
      作用:用于数据同步和备份

二、重做日志(Redo Log):数据库的"草稿纸"

1. 场景:会计小徐的烦恼

超市收银员小徐要记录1000笔交易。

传统方式(没有Redo Log):

-- 每笔交易都要立即写入硬盘
UPDATE accounts SET balance = balance + 100;
UPDATE products SET stock = stock - 1;

结果:
┌─────────────────────┐
│ ❌ 频繁随机写入硬盘  │
│ ❌ I/O效率极低      │
│ ❌ 系统性能下降     │
└─────────────────────┘

Redo Log的解决方案:

1. 先写入速记本(Redo Log)
   ┌────────────────────┐
   │ 交易1: +100元,-1件 │ 
   │ 交易2: +200元,-2件 │ ➜ 顺序写入,速度快
   │ ...               │
   └────────────────────┘

2. 数据先放内存
   ┌────────────────┐
   │ 内存中快速汇总  │ ➜ 响应迅速
   └────────────────┘

3. 定期整理同步
   ┌────────────────┐
   │ 批量写入硬盘    │ ➜ 提高效率
   └────────────────┘

2. Redo Log工作原理详解

以顾客购买2箱牛奶为例:

// 顾客买了2箱牛奶(每箱100元)
UPDATE accounts SET balance = balance + 200;
UPDATE stock SET quantity = quantity - 2;

步骤1:速记本记录(Redo Log)

在Redo Log中记录交易信息:

交易编号

时间

操作类型

表名

修改内容

状态

001

09:01:01

UPDATE

accounts

账户余额+200

已记录

002

09:01:01

UPDATE

stock

牛奶库存-2

已记录

特点:

  • 顺序写入:像流水账,效率高
  • 记录简单:快速记录交易信息

步骤2:临时汇总(内存)

在内存中快速更新数据:

账户

余额

现金

1200

商品

库存数量

牛奶

98

特点:

  • 快速更新:客户立即看到结果
  • 数据在内存中:但断电会丢失

步骤3:持久化阶段,定期刷盘

在以下时机将数据写入硬盘:

  • 营业员交接班时
  • 系统空闲时
  • 速记本快写满时
  • 固定时间间隔

Redo Log 工作流程图:

三、回滚日志(Undo Log):数据库的"后悔药"

1. 场景:超市的退货处理

传统退货方式(没有Undo Log):

顾客:我要退刚买的牛奶 

小徐:抱歉,我们没记录原价,不知道该退多少钱...

现代方式(使用Undo Log)

顾客:我要退刚买的牛奶 

小徐:好的,让我查看下交易记录

  • 找到原始购买记录
  • 确认购买价格是100元
  • 确认库存状态
  • 可以安全退货

2. Undo Log 工作原理详解

场景:用户下单扣款

// 顾客购买2箱牛奶
UPDATE accounts SET balance = balance + 200;  // 收款200元
UPDATE stock SET quantity = quantity - 2;    // 库存减2

交易记录阶段(Undo Log记录)

编号

时间

表名

修改前数据

修改后数据

回滚指针

T001

09:01:01

accounts

balance=1000

balance=1200

-> T000

T002

09:01:01

stock

quantity=100

quantity=98

-> T001

T003

09:05:30

accounts

balance=1200

balance=1000

-> T002

T004

09:05:30

stock

quantity=98

quantity=100

-> T003

数据版本链(MVCC实现):

牛奶库存记录的版本链:
+-------------------------+
| 当前版本:98箱          | 
| 交易号:T002           |
+-------------------------+
          ↓
+-------------------------+
| 上一版本:100箱         |
| 交易号:T001           | 
+-------------------------+
          ↓
+-------------------------+
| 初始版本:100箱         |
| 交易号:T000           |
+-------------------------+

Undo Log 工作流程图:

3. Undo Log的两大作用

(1) 支持事务回滚

  • 记录数据修改前的状态
  • 支持出错时回滚
  • 保证事务原子性

(2) 实现MVCC(多版本并发控制)

  • 不同事务看到不同版本的数据
  • 提高并发性能
  • 避免加锁带来的性能问题

四、二进制日志(binlog):数据库的"保险箱"

1. 场景:连锁超市的账务管理

小徐是连锁超市的总经理,每天要处理这些数据管理问题:

场景一:商品管理
总店:上架100种新商品
┌─────────────────┐
│ 商品1: 牛奶     │
│ 商品2: 面包     │ ➜ 分店:一个个手动添加?
│ ...100条记录... │
└─────────────────┘

场景二:数据安全
┌─────────────────┐
│ 昨日销售数据    │ ➜ 系统崩溃,数据丢失!
└─────────────────┘

场景三:变更追踪
老板:这个商品谁改的价格?
小徐:¯_(ツ)_/¯ 不知道...

而有了Binlog(二进制日志)后:

MySQL Binlog
├── 自动同步
│   总店改价格 ──➜ 所有分店秒级更新
│
├── 数据保护
│   系统崩溃 ──➜ 从日志恢复数据
│
└── 操作追踪
    谁改了价格?──➜ 查看变更历史

2. Binlog的记录格式:如何记录数据变更?

让我们看看Binlog是如何记录数据变更的:

-- 一笔简单的商品价格调整
UPDATE products SET price = 98 WHERE name = '牛奶';

这条SQL语句在Binlog中有三种不同的记录方式:

(1) STATEMENT格式:记录SQL语句

# 直接记录SQL
UPDATE products SET price = price * 0.9 
WHERE category = '饮品';

优势:日志量小
风险:可能导致主从不一致(比如NOW()函数)

(2) ROW格式:记录数据变化

{
  "before": {"id": 1, "name": "牛奶", "price": 100},
  "after":  {"id": 1, "name": "牛奶", "price": 90}
}

优势:数据准确
特点:日志量较大

(3) MIXED格式:智能选择

# 根据SQL类型自动选择格式
简单UPDATE:使用STATEMENT
复杂函数:使用ROW

五、三大日志协同工作机制

以顾客购买2箱牛奶为例,操作内容如下:

  • 更新库存(-2箱)
  • 更新账户(+200元)

1. 两阶段提交工作流程

(1) 第一阶段(Prepare):

记录原始数据(Undo Log):

  • 库存:100箱
  • 账户:1000元

更新内存数据:

  • 库存:98箱
  • 账户:1200元

记录操作状态(Redo Log):

  • 状态:准备中
  • 内容:库存-2,账户+200

(2) 第二阶段(Commit):

记录交易信息(Binlog):

  • 时间:2025-04-14 09:00:00
  • 操作:售出牛奶2箱,收款200元

标记操作完成(Redo Log):

  • 状态:已完成

详细的执行流程表:

步骤

操作

日志类型

内容

状态

1

记录原数据

Undo Log

库存=100,余额=1000

已记录

2

更新内存

Buffer Pool

库存=98,余额=1200

已更新

3

预提交

Redo Log

更新操作记录

prepare

4

记录变更

Binlog

交易详细信息

已写入

5

最终提交

Redo Log

更新操作记录

commit

两阶段提交流程图:

六、总结

通过本文,我们深入了解了MySQL日志系统的核心内容:

三大日志的作用与原理:

  • Redo Log:确保数据持久性,像草稿纸,记录每一步操作。
  • Undo Log:支持事务回滚,类似价格标签,随时可以撤销错误。
  • Binlog:用于数据复制和恢复,犹如记账本,记录所有交易历史。

在数据库的世界里,日志不仅是记录,更是保障数据安全与一致性的基石。希望这些内容能帮助你更深入地理解MySQL日志系统的关键作用!


本文地址:https://www.yitenyun.com/297.html

搜索文章

Tags

数据库 API FastAPI Calcite 电商系统 MySQL Web 应用 异步数据库 数据同步 ACK 双主架构 循环复制 TIME_WAIT 运维 负载均衡 JumpServer SSL 堡垒机 跳板机 HTTPS JumpServer安装 堡垒机安装 Linux安装JumpServer esxi esxi6 root密码不对 无法登录 web无法登录 Deepseek 宝塔面板 Linux宝塔 Docker 生命周期 序列 核心机制 HexHub Windows Windows server net3.5 .NET 安装出错 HTTPS加密 服务器 管理口 宝塔面板打不开 宝塔面板无法访问 查看硬件 Linux查看硬件 Linux查看CPU Linux查看内存 Oracle 处理机制 InnoDB 数据库锁 Windows宝塔 Mysql重置密码 连接控制 机制 监控 无法访问宝塔面板 ES 协同 Serverless 无服务器 语言 技术 开源 PostgreSQL 存储引擎 Spring Redis 异步化 分页查询 索引 group by 高可用 机器学习 缓存方案 缓存架构 缓存穿透 SQL 动态查询 服务器性能 响应模型 SVM Embedding Undo Log 自定义序列化 日志文件 MIXED 3 GreatSQL 连接数 ​Redis 推荐模型 云原生 数据 主库 工具 PG DBA Netstat Linux 服务器 端口 Linux 安全 SQLark AI 助手 R edis 线程 Postgres OTel Iceberg scp Linux的scp怎么用 scp上传 scp下载 scp命令 向量数据库 大模型 R2DBC 存储 SQLite-Web SQLite 数据库管理工具 共享锁 openHalo 查询 电商 系统 RocketMQ 长轮询 配置 Recursive OB 单机版 Rsync Ftp 聚簇 非聚簇 架构 • 索引 • 数据库 Hash 字段 数据分类 加密 优化 万能公式 人工智能 推荐系统 磁盘架构 流量 sftp 服务器 参数 防火墙 黑客 MVCC 业务 场景 同城 双活 信息化 智能运维 MySQL 9.3 修改DNS Centos7如何修改DNS redo log 重做日志 Doris SeaTunnel 高效统计 今天这篇文章就跟大家 线上 库存 预扣 向量库 Milvus 数据备份 mini-redis INCR指令 RDB AOF 缓存 窗口 函数 INSERT COMPACT 不宕机 网络架构 网络配置 Redisson 锁芯 传统数据库 向量化 Python Web PostGIS 事务 Java 开发 Canal 引擎 性能 B+Tree ID 字段 IT运维 prometheus Alert 崖山 新版本 核心架构 订阅机制 锁机制 分布式 集中式 MongoDB 数据结构 ZODB 读写 数据脱敏 加密算法 容器化 容器 数据类型 虚拟服务器 虚拟机 内存 OAuth2 Token filelock Redis 8.0 分库 分表 DBMS 管理系统 JOIN 自动重启 网络故障 模型 QPS 高并发 微软 SQL Server AI功能 部署 聚簇索引 非聚簇索引 启动故障 排行榜 排序 Testcloud 云端自动化 发件箱模式 SSH Go 数据库迁移 Web 接口 Pottery 频繁 Codis 原子性 工具链 Caffeine CP SpringAI Entity 速度 服务器中毒 事务隔离 分页方案 排版 数据页 悲观锁 乐观锁 StarRocks 数据仓库 数据集成工具 池化技术 连接池 MCP 开放协议 sqlmock LRU 1 单点故障 AIOPS 网络 大表 业务场景 优化器 分页 EasyExcel MySQL8 Redka 意向锁 记录锁 dbt 数据转换工具 Order 仪表盘 事务同步 分布式架构 分布式锁​ 日志 行业 趋势 IT 对象 国产数据库 单线程 InfluxDB RAG HelixDB 字典 双引擎 编程 Ansible LLM UUID ID 订单 Crash 代码 UUIDv7 主键 Valkey Valkey8.0 主从复制 代理 List 类型 Pump 播客 线程安全 ReadView 产业链 兼容性 Next-Key 数据字典 语句 解锁 调优 恢复数据 MGR 分布式集群 表空间 关系数据库 失效 Weaviate GitHub Git 慢SQL优化 国产 用户 RR 互联网 算法 查询规划 矢量存储 数据库类型 AI代理 快照读 当前读 视图 千万级 分布式锁 Zookeeper 神经系统 count(*) count(主键) 行数 并发控制 恢复机制 拦截器 动态代理 CAS 多线程 技巧 闪回