MySQL日志:binlog、事务日志(redo、undo)

事务的隔离性是通过锁实现,而事务的原子性、一致性和持久性则是通过日志实现。Mysql的日志可以分为:

  • binlog:server层实现
  • 事务日志:包括redo log、undo log,引擎层(innodb)实现

redo log

redo log是用于备份事务中操作得到的最新数据的地方,记录数据页的物理修改。

redo log通常是物理日志,记录的是数据页的物理修改,而不是记录某一行或某几行的修改,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。

在innoDB的存储引擎中,事务日志通过重做日志(redo log)和innoDB存储引擎的日志缓冲(redo Log Buffer)实现。事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是DBA们口中常说的“日志先行”(Write-Ahead Logging)。当事务提交之后,在Buffer Pool中映射的数据文件才会慢慢刷新到磁盘。此时如果数据库崩溃或者宕机,那么当系统重启进行恢复时,就可以根据redo log中记录的日志,把数据库恢复到崩溃前的一个状态。未完成的事务,可以继续提交,也可以选择回滚,这基于恢复的策略而定。

即事务在修改数据时,innodb只修改数据的内存拷贝,然后把修改行为记录到持久在磁盘的事务日志(redo log)中,在事务日志持久化后,内存中被修改的数据在后台慢慢刷回磁盘。
即修改数据时需要写两次磁盘:

  • 先将操作记录到redo log buffer,然后持久化redo log到磁盘
  • 将redo log中记录的数据持久化到磁盘

为什么需要redo log(为什么采用两次写磁盘,而不直接持久化新数据?)

既然redo log是将数据持久化到磁盘上,那么必然也对应一次IO操作,那么每次修改数据直接将其刷新到磁盘的话,也是一次IO操作,按道理说效率应该一样,那么为什么还要引入redo log?
事实上,redo log写入文件尾是顺序写过程,虽然也是一次IO操作但磁头不需要移动(即事务日志采用追加的方式,因此是顺序IO)。而每次都将数据更新到磁盘其实是将 buffer pool中的数据缓存页写入磁盘的数据也中,其中涉及到要寻找数据页在哪的操作,这是一个随机写过程,需要移动磁头,磁盘的随机写过程更耗时,耗资源,因此引入redo log是很有必要的。

undo log

undo log是用于事务中,在操作数据之前,备份需操作的数据的地方,undo log 记录数据的逻辑修改。

undo log用来实现事务的原子性,在innodb引擎中还用来实现事务的多版本并发控制。
undo log记录了数据在每个操作前的状态,如果事务执行过程中需要回滚,就可以根据undo log进行回滚操作。单个事务的回滚,只会回滚当前事务做的操作,并不会影响到其他的事务做的操作。
在操作数据库之前先将数据备份到一个地方,这个存储数据备份的地方就是undo log。然后再进行数据的修改,如果中途发生错误或者用户执行的rollback语句,系统就可以利用undo log中的备份将数据回复到事务开始前的状态。

undo log 是逻辑日志,可以理解为每次操作之前都会记录相反反操作:

  • 当delect一条语句时,undo log 中会记录一条对应的insert语句
  • 当insert一条语句时,undo log 中会记录一条对应的delect语句
  • 当update一条语句时,undo log 中会记录一条相反的update语句

undo+redo事务的简化过程

假设有2个数值,分别为A和B,值为1,2

	1. start transaction;2. 记录 A=1 到undo log;3. update A = 3;4. 记录 A=3 到redo log buffer;5. 记录 B=2 到undo log;6. update B = 4;7. 记录B = 4 到redo log buffer;8. 将redo log buffer 刷新到磁盘9. 执行器(Server层)生成写操作的binlog日志,并将binlog写入磁盘(通过XA事务保证redo log 和 binlog的一致性)10. commit

在1-8的任意一步系统宕机,事务未提交,该事务就不会对磁盘上的数据做任何影响。如果在8-10之间宕机,恢复之后可以选择回滚,也可以选择继续完成事务提交,因为此时redo log已经持久化。若在10之后系统宕机,内存映射中变更的数据还来不及刷回磁盘,那么系统恢复之后,可以根据redo log把数据刷回磁盘。
所以,redo log其实保障的是事务的持久性和一致性,而undo log则保障了事务的原子性

binlog

binlog是server层的日志,记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
当执行写操作的SQL(INSERT、UPDATE、DELETE…)时,会把相应的SQL写入到对应的binlog,可以简单理解为binlog是记录数据库增删改,不记录查询的二进制日志,可以利用binlog进行备份、数据恢复。

binlog的三种模式

(1)Row Level 行模式

日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改

  • 优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
  • 缺点:row level,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。

(2)Statement Level(默认)

每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行

  • 优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能,因为它只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息。
  • 缺点:由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成Mysql的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。

(3) Mixed 自动模式

在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

binlog与redolog 的区别

  • binlog主要用于备份、主从同步;redo log用于实现事务的一致性和持久性,防止数据丢失。
  • redo log 是innodb引擎特有的,而binlog由服务层实现是所有存储引擎都可以使用的
  • redo log是物理日志,记录的是某页上具体的做的修改。binlog是逻辑日志,记录的是这个语句的原始逻辑。
  • redo log是循环写过程,空间有限,空间不够时会覆盖之前的信息。binlog是追加写过程不会覆盖之前的信息。

执行器(Server)和InnoDB引擎在执行update内部流程

1、执行器先找到ID=2这一行,ID是主键,引擎用树搜索找到这一行,如果ID=2这一行所在的数据页本来就在内存中,就直接返回给执行器。否则需要从磁盘中读入磁盘中,然后再返回。

2、执行器拿到引擎给的行数据,把这个值加上1,得到一行新的数据,再调用引擎接口,写入这行数据。

3、引擎将这行新的数据写入到内存中,同时将这个更新操作记录到redo log里面,此时redo log处于prepare状态,然后告知执行器执行完成了,随时可以提交事务。

4、执行器生成这个操作的binlog日志,并将binlog写入磁盘。

5、执行器调用引擎的提交事务的接口,引擎把刚刚写入的redo log改成提交(commit)状态,更新完成。

在这里插入图片描述

binlog 和 redo log一致性

此部分为引用,详细请阅读:MySQL中binlog和redo log的一致性问题

在MySQL内部,在事务提交时利用两阶段提交(内部XA的两阶段提交)很好地解决了binlog和redo log的一致性问题:

  • 第一阶段: InnoDB Prepare阶段。此时SQL已经成功执行,并生成事务ID(xid)信息及redo和undo的内存日志。此阶段InnoDB会写事务的redo log,但要注意的是,此时redo log只是记录了事务的所有操作日志,并没有记录提交(commit)日志,因此事务此时的状态为Prepare。此阶段对binlog不会有任何操作。
  • 第二阶段:commit 阶段,这个阶段又分成两个步骤。第一步写binlog(先调用write()将binlog内存日志数据写入文件系统缓存,再调用fsync()将binlog文件系统缓存日志数据永久写入磁盘);第二步完成事务的提交(commit),此时在redo log中记录此事务的提交日志(增加commit 标签)。

可以看出,此过程中是先写redo log再写binlog的。但需要注意的是,在第一阶段并没有记录完整的redo log(不包含事务的commit标签),而是在第二阶段记录完binlog后再写入redo log的commit 标签。还要注意的是,在这个过程中是以第二阶段中binlog的写入与否作为事务是否成功提交的标志。

通过上述MySQL内部XA的两阶段提交就可以解决binlog和redo log的一致性问题。数据库在上述任何阶段crash,主从库都不会产生不一致的错误。

参考

  • 推荐阅读:MYSQL中的事务日志
  • 推荐阅读:日志系统:redo log和binlog
  • 好文:MySQL中的事务日志
  • 详细分析MySQL事务日志(redo log和undo log)
  • MySQL binlog三种模式
  • 深入理解MySQL之redo日志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vmware安装centos8步骤

【readme】 vmware 安装centos8; 【1】新建虚拟机 step1) 下载 centos8 http://download.nus.edu.sg/mirror/centos/8-stream/isos/x86_64/ 补充,通过代理服务器下载会快很多; step2)vmare,点击文件&…

并发编程 – Concurrent 用户指南

转载自 并发编程 – Concurrent 用户指南1. java.util.concurrent – Java 并发工具包Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包。这个包包含有一系列能够让 Java 的并发编程变得更加简单轻松的类。在这个包被添加以前,你需要自己去…

小微企业名录查询系统_欢迎访问辽宁小微企业名录系统

欢迎访问辽宁小微企业名录系统http://xwqy.lngs.gov.cn辽宁小微企业名录系统是小微企业扶持政策的实施公示台、集装箱,通过访问该系统网站,及时全面知晓小微企业复工复产、“个转企”等各类扶持政策。按照《国务院关于扶持小型微型企业健康发展的意见》(…

常用限流算法分析

一、计数器(固定窗口)算法 计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。 此算法在单机还是分布式环境下实现都非常简单&#…

nginx学习小结

nginx 【0】README 本文po处理 nginx的主要内容,包括反向代理,负载均衡,动静分离,高可用集群等; 本文引用链接: vmware安装centos8,refer2 https://blog.csdn.net/PacosonSWJTU/article/detail…

缓存与数据库的一致性:先操作缓存还是先操作数据库?

数据缓存 在我们实际的业务场景中,一定有很多需要做数据缓存的场景,比如售卖商品的页面,包括了许多并发访问量很大的数据,它们可以称作是是“热点”数据,这些数据有一个特点,就是更新频率低,读…

Object.hashCode()与Object.equals()

【README】 本文旨在po出 hashCode , equals的api描述,以加深理解; 本文翻译自 jdk 文档; 【1】Object.hashCode() 1)介绍:返回对象的哈希码值。支持此方法是为了有利于哈希表,例如由 java.u…

for in for of区别_(for…in) VS (for…of)

这篇文章应该是在一年多之前读过的,那会看完感觉作者文采不错,就做了收藏,做此分享,希望能帮助到你更好的理解js中的循环~~~以下正文。。。今天可是个好日子!你问我为什么?你这都不知道,ChinaJo…

Innodb中的事务隔离级别和锁的关系

前言 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式。同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力…

并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究

转载自 并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究一、 前言 常用的并发队列有阻塞队列和非阻塞队列,前者使用锁实现,后者则使用CAS非阻塞算法实现,使用非阻塞队列一般性能比较好,下面就看看常用的非阻塞Concurrent…

(转)如何保障微服务架构下的数据一致性?

转自: https://cloud.tencent.com/developer/article/1459734 【1】写在前面 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台。就像前边的文章说的,微服务架构为业务开发带来了诸多好处的同时,例如单一…

python中math库_Python的math库、random库实际应用

昨天在说那个列表的时候,我挖了一个坑,不知道你们看出来没有?就是用循环语句写迭代的时候,总是运行不了结果,其实是因为我没有缩进的问题,因为有一个for循环,下面print如果没有对应的缩进&#…

(转)漫画:什么是分布式事务?

转自: https://blog.csdn.net/bjweimengshu/article/details/79607522 假如没有分布式事务 在一系列微服务系统当中,假如不存在分布式事务,会发生什么呢?让我们以互联网中常用的交易业务为例子: 上图中包含了库存和订…

Java 线程池框架核心代码分析

转载自 Java 线程池框架核心代码分析前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的。线程池应运而生,成为我们管理线程的利器。Java 通过Executor接口,提供了一种标准的方法将任务的提…

python渐变色代码_如何在Python中创建颜色渐变?

6 个答案: 答案 0 :(得分:54) 我还没有看到一个简单的答案就是使用colour package。 通过pip安装 pip install colour 如此使用: from colour import Color red Color("red") colors list(red.range_to(Color("green"),10)) # col…

(转)web.xml 中的listener、 filter、servlet 加载顺序及其详解

转&#xff1a; https://www.cnblogs.com/Jeely/p/10762152.html web.xml 中的listener、 filter、servlet 加载顺序及其详解 一、概述 1、启动一个WEB项目的时候&#xff0c;WEB容器会去读取它的配置文件web.xml&#xff0c;读取<listener>和<context-param>两个…

柱状图python_python柱状图一行

编写计算柱状图的python程序有很多种方法。 通过柱状图,我指的是一个计算对象在 iterable 并在字典中输出计数。例如: >>> L abracadabra >>> histogram(L) {a: 5, b: 2, c: 1, d: 1, r: 2} 编写此函数的一种方法是: def histogram(L): d {} for x in L: i…

HashMap 和 HashTable 到底哪不同 ?

转载自 HashMap 和 HashTable 到底哪不同 &#xff1f;代码版本 JDK每一版本都在改进。本文讨论的HashMap和HashTable基于JDK 1.7.0_67。源码见这里 1. 时间 HashTable产生于JDK 1.1&#xff0c;而HashMap产生于JDK 1.2。从时间的维度上来看&#xff0c;HashMap要比HashTable出…

架构师成长之路(内附推荐书籍)

转&#xff1a; https://www.jianshu.com/p/f661f098b88a 想要成为架构师&#xff0c;对技术的深度和广度都有很高的要求&#xff0c;本文列举出成为一个架构师必备的技能和学习路线。 对于学习途径有疑惑或苦恼&#xff0c;或者有优秀资料可以提供的同学&#xff0c;可加留言&…