Mysql redo&&undo学习

Wesley13
• 阅读 670

     mysql通过锁机制来实现事务的隔离性,用redo log实现事务的原子性和持久性,用undo log实现事务的一致性。undo并不是redo的逆过程,redo和undo都可以看做一种恢复过程,redo恢复事务修改的页操作,redo记录的是物理日志,记录的是页的物理修改操作,redo log基本上都是顺序写的,在数据库运行时不需要对redo log的文件进行读取操作。undo回滚行记录到某个版本,undo记录的是逻辑日志,根据每行记录进行记录,undo log是需要进行随机读取的。

redo log是innodb存储引擎产生的,二进制日志则是mysql数据库层产生的,redo log在事务进行中不断的被写入redo log,这导致日志并不是随着事务的提交顺序进行写入的,而二进制日志只在事务提交后进行一次写入日志。

redo

redo日志由两部分构成:redo log buffer、redo log file。innodb是支持事务的存储引擎,在事务提交时,必须先将该事务的所有日志写入到redo日志文件中,待事务的commit操作完成才算整个事务操作完成。在每次将redo log buffer写入redo log file后,都需要调用一次fsync操作,因为重做日志缓冲只是把内容先写入操作系统的缓冲系统中,并没有确保直接写入到磁盘上,所以必须进行一次fsync操作。因此,磁盘的性能在一定程度上也决定了事务提交的性能。

但是,关于fsync这个操作用户是可以干预的,因为每次提交事务都执行一次fsync,确实影响数据库性能。通过innodb_flush_log_at_trx_commit来控制redo log刷新到磁盘的策略。该参数的默认值为0,表示每次提交事务时都执行一次fsync操作。0则表示事务提交时不进行写入重做日志,这个写入操作由master thread进程来完成,master thread每一秒会进行一次重做日志文件的fsync操作。2则表示事务提交时将重做日志写入重做日志文件,但仅写入文件系统的缓存中,并不进行fsync操作。用户可以通过设置0或者2啦提高事务提交的性能,也可以设置1来要求确保redo log是写入文件中的,总之三种方法各有利弊。redo log buffer将内存中的log block刷新到磁盘是有一定的规则的:事务提交时(前面已经提到)、当log buffer中有一半的内存空间被使用时、log checkpoint时。

innodb存储引擎中,redo log以512字节进行存储,这意味着重做日志是以块的方式保存的,如果一个页中的重做日志大于512字节,则需要分隔到多个块中进行存储。重做日志块由三部分构成:日志块头(12字节)、日志块尾(8字节)、日志本身。redo log buffer是由log block(512字节)组成的。redo log group其中包含多个重做日志文件,可以有多个log group,log group只是一个逻辑概念,并没有一个实际存储的物理文件来表示log group的信息。在log group中的每个重做日志文件大小都是相同的,在innodb版本1.2之前,重做日志文件的总大小要小于4G,1.2版本之后总大小提高到512G。重做日志文件中存储的就是在之前log buffer中保存的log block,因此其也是根据块的方式进行物理存储管理的,大小也是512字节。log block会被追加写入到redo log file的最后面,当一个redo log file被写满时,会接着写入下一个rdo log file,其使用方式是轮转的。redo log file除了保存log buffer刷新到磁盘的信息外,还保存了一些其他信息,每个redo log file的前2KB不保存log block信息,这2KB会保存log file header信息和一些checkpoint信息。

innodb引擎的存储管理是基于页的,因此其重做日志格式也是基于页的。在重做日志中有个LSN比较重要,它的全称是log sequence number,其代表的是日志序列号。LSN在存储引擎中单调递增,它表示重做日志写入的总量(单位为字节)、checkpoint的位置、页的版本。在每个页中有一个值记录了该页的LSN,在页中LSN表示该页最后刷新时LSN的大小,以为重做日志记录的是每个夜的日志,因此页中的LSN用来判断页是否需要进行恢复操作。假如:重做日志中的LSN小于页中的LSN则表示不需要重做,如果重做日志中的LSN大于页中的LSN,则表示需要将重做日志恢复到页中。

innodb存储引擎在启动时不管上次数据库是否正常关闭,都会尝试进行恢复操作,因为重做日志记录的是物理日志,因此恢复起来比逻辑日志要快,由于checkpoint记录的是已经刷新到磁盘页上的LSN,因此在恢复过程中仅需要恢复checkpoint开始的日志。

undo

undo就是对事务进行回滚操作的,innodb引擎在对数据库进行修改时,不但会产生redo也会产生一定量的undo。例如用户执行rollback时就会利用undo信息进行回滚。redo有redo log,undo则存放在数据库内部的一个特殊段中,称为undo段,undo段位于共享表空间内,undo是逻辑日志,因此只是将数据库逻辑的恢复到原来的样子,所有的修改都被逻辑的取消,但是数据结构和页本身在回滚之后可能不相同。因此,不能将一个页回滚到事务开始的样子,因为同一时刻可能还有其他事务在访问该页。

当innodb引擎进行回滚时,实际上做的是与之前相反的操作,例如对insert执行delete操作,undo除了回滚功能外,还有另外一个作用是MVCC,innodb中的MVCC是通过undo实现的。当用户读取一行记录,该记录被其他事务占用时,可以通过undo信息读取之前的行版本信息。不过要注意,undo会产生redo log。

innodb对undo的管理采用段的方式,innodb有rollback segment,每个rollback segment记录了1024个undo log segment,在每个undo log segment中申请undo页。在innodb1.1之后支持128个rollback segment。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL数据库InnoDB存储引擎Log漫游(1)
作者:宋利兵来源:MySQL代码研究(mysqlcode)0、导读本文介绍了InnoDB引擎如何利用UndoLog和RedoLog来保证事务的原子性、持久性原理,以及InnoDB引擎实现UndoLog和RedoLog的基本思路。00–UndoLogUndoLog是为了实现事务的原子性,
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这