为什么MySQL需要binlog、undo log、redo log 3种日志?

server/2024/11/14 2:46:36/

binlog是 server层生成的日记,而 undo log、redo log 是Innodb 存储引擎层生成的日志

binlog,是 binary log的英文缩写,翻译为二进制日志或者归档日志(带有业务含义),它是从 MySQL 3.23.14版本引入的。binlog是在 MySQL Server层实现,因此所有数据库引擎都可以使用它。

包含的信息

binlog主要包含两种信息:

1. MySQL数据库所有的表结构变更以及表数据修改的二进制日志(像 select,show这种查询类的操作,不会记录);

2. 每条语句使用更新数据多长时间的信息;

三个用途

binlog的用途有 3个:

1. 归档日志

2. 主从复制

3. 数据恢复

三种类型

binlog有 3种类型:

1. 语句模式(Statement-based logging): 包含产生数据更改(插入、更新、删除)的 SQL语句;

2. 行模式(Row-based logging): 用于记录单个行的更改,从 MySQL 5.1版本引入;

3. 混合模式(Mixed logging): 默认使用语句模式,可以按需自动切换到行模式,从 MySQL 5.1版本引入;

 

undo log, 中文翻译为撤销日志或回滚日志,用于事务回滚,保证了事务 ACID 特性中的原子性(Atomicity),同时还可以配合 ReadView 实现多版本控制(MVCC)。

相关参数

可以通过 show variables like ‘%undo%’; 指令查看 undo log相关参数:

 

  • innodb_max_undo_log_size:一个 undo log文件对应的最大值,默认 1G;
  • innodb_undo_directory:undo log文件存放的目录;
  • innodb_undo_log_encrypt:是否对 undo log文件开启空间压缩,默认是关闭;
  • innodb_undo_log_truncate:单个文件超过最大值时,是否对 undo log文件进行切分,默认为打开状态;
  • innodb_undo_tablespaces:单个文件超过最大值时,undo log文件会被切分为几份,默认是 2;

事务回滚

在事务提交之前,MySQL 会将更新前的数据记录到 undo log 日志文件里,当事务回滚时,可以利用 undo log 来进行回滚。

 

每当 InnoDB 引擎执行一条更新操作(修改、删除、新增)时,就会生成对应的一条回滚指令记录在 undo log 里,比如:

  • InnoDB 引擎执行 insert 操作,则会在 undo log 日志里面保存一条相反的 delete 语句;比如:insert into t(id, name) values(1,’zhangsan’); 则 undo log 对应的回滚日志为 delete from t where id = 1;
  • InnoDB 引擎执行 delete 操作,则会在 undo log 日志里面保存一条相反的 insert 语句;比如:delete from t where id = 1; 则 undo log 对应的回滚日志为 insert into t(id, name) values(1,’zhangsan’);
  • InnoDB 引擎执行 update 操作,则会在 undo log 日志里面保存一条相反的 update 语句;比如:update t set name = ‘lisi’ where id = 1; 则 undo log 对应的回滚日志为 update t set name = ‘zhangsan’ where id = 1;

 

undo log 和 ReadView 实现多版本控制(MVCC)

在 InnoDB引擎中,可以多个事务对同一条数据记录进行更新操作,当出现异常时,能及时进行数据回滚,那么InnoDB是如何能精确地把数据回滚到具体的哪一个版本呢?这就是 InnoDB的多版本控制机制。

 

redo log

redo log,翻译成重做日志,用于crash-safe,即当数据库发生异常重启,可以保证之前提交的记录不会丢失,它是 InnoDB引擎独有的日志。

redo log 是物理日志,记录了某个数据页做了什么修改,比如对某表空间中的 某数据页某偏移量的地方做了某更新,每当执行一个事务就会产生这样的一条或者多条物理日志。

在事务提交时,只要先将 redo log 持久化到磁盘即可,可以不需要等到将缓存在 Buffer Pool 里的脏页数据持久化到磁盘。

当系统崩溃时,虽然脏页数据没有持久化,但是 redo log 已经持久化,接着 MySQL 重启后,可以根据 redo log 的内容,将所有数据恢复到最新的状态。

为什么需要 redo log?

为了防止断电导致数据丢失的问题,当有一条记录需要更新的时候,InnoDB 引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以 redo log 的形式记录下来,这个时候更新就算完成了。

后续,InnoDB 引擎会在适当的时候,由后台线程将缓存在 Buffer Pool 的脏页刷新到磁盘里,这就是 WAL (Write-Ahead Logging)技术。

WAL 技术指的是, MySQL 的写操作并不是立刻写到磁盘上,而是先写日志,然后在合适的时间再写到磁盘上。

 

 

MySQL 如何辨别 binlog 的完整性?

  • statement 格式的 binlog,文件末尾有 COMMIT;
  • row 格式的 binlog,文件末尾有一个 XID event。

redo log 和 binlog 是怎么关联起来的?

它们有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有commit 的 redo log,就直接提交;如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去binlog 找对应的事务。

处于 prepare 阶段的 redo log 加上完整 binlog,重启就能恢复,MySQL 为什么要这么设计?

其实,这个问题还是跟我们在反证法中说到的数据与备份的一致性有关。在时刻 B,也就是 binlog 写完以后MySQL 发生崩溃,这时候 binlog 已经写入了,之后就会被从库(或者用这个 binlog 恢复出来的库)使用。所以,在主库上也要提交这个事务。采用这个策略,主库和备库的数据就保证了一致性。

为什么需要两阶段提交呢?

两阶段提交是经典的分布式系统问题,并不是 MySQL 独有的。如果必须要举一个场景,来说明这么做的必要性的话,那就是事务的持久性问题。对于 InnoDB 引擎来说,如果 redo log 提交完成了,事务就不能回滚(如果这还允许回滚,就可能覆盖掉别的事务的更新)。而如果 redo log 直接提交,然后 binlog 写入的时候失败,InnoDB 又回滚不了,数据和 binlog 日志又不一致了。两阶段提交就是为了给所有人一个机会,当每个人都说“我 ok”的时候,再一起提交。

总结

 

  • undo log(回滚日志):是 Innodb 存储引擎层的逻辑日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。
  • redo log(重做日志):是 Innodb 存储引擎层的物理日志,是循环写,实现了事务中的持久性,主要用于掉电等故障恢复;
  • binlog (归档日志):是 Server 层生成的日志,所有引擎都可使用,主要用于数据备份、数据恢复和主从复制;

 

 


http://www.ppmy.cn/server/45908.html

相关文章

JVM学习-垃圾回收(三)

System.gc 通过System.gc()或Runtime.getRuntime().gc()的调用,会显示触发Full GC,同时对老年代和方法区进行回收,尝试释放被丢弃对象占用的内存然后System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用JVM实现者可以通…

ARM架构:鸿道Intewell操作系统芯生态之·瑞芯微RK3399

鸿道Intewell作为一个面向未来新型工业的智能操作系统,支持多种芯片平台,可以适应不同应用场景的需求。以下是鸿道Intewell操作系统与瑞芯微RK3399的介绍: 瑞芯微RK3399芯片 RK3399是瑞芯微(Rockchip)推出的一款高性…

如何重塑思维,轻松学会React

大家好,今天我们来聊聊如何通过重塑思维模式,轻松掌握React开发技能。React作为现代前端开发的热门框架之一,其核心功能和概念对很多初学者来说可能会有些难以理解。本文将带你深入解析React的精髓,帮助你快速上手。如果你不喜欢看…

阴影技术在AI去衣中的角色扮演

引言: 人工智能去衣技术,在最初期可能听起来有些令人不安,但它实际上包括了一系列进步的图像处理和机器学习技术,有助于各种领域的革新,例如虚拟试衣室、电影制作中的特效,乃至在线零售的个性化体验。在这些…

C++系列——————类和对象(上)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、面向对象的三大特征二、类的引入2.1类的定义 三.类的访问限定符3.1访问限定符的介绍3.2.访问限定符的使用 四、类的作用域五、类的实例化六、类对象模型6.1…

计算24点的python代码

计算24点的python代码 GPT-4o 确实不错,以后3.5和4.0都难以一次性解决的问题,4.0都要对话许多次才能完美实现,现在4o一次就解决了,记录一下。 import itertools import operator# Define the basic operations ops {: operator…

2024版能源领域网络与数据安全政策全集

能源是工业的粮食,能源安全事关国家根本安全。当今国际局势风云变幻,全球地缘政治、经济、科技体系正经历深刻变化,能源局势将更加错综复杂,威胁能源安全的各种“灰犀牛”“黑天鹅”事件时有发生,促使国际能源版图深刻…

Android 系统中AHardwareBuffer、ANativeWindowBuffer和GraphicBuffer的关系

Android Camera软件系统中,每路Stream的Buffer都是DMA-BUF,这种Buffer通常对外暴露的结构是ANativeWindowBuffer或GraphicBuffer(跨进程传递时用的native_handle_t),本文介绍Android系统中AHardwareBuffer、ANativeWin…