数据库日志redo和undo
数据库的ACID属性
Atomicity:原子性,以事物transact为最小单位,事物中的所有操作,要么都执行完,要么都不执行,不存在一部分操作执行,另一部分操作不执行的情况。
Consistency:一致性,在事物开始和事物完成后,数据库的完整性限制不会改变。
Isolation:隔离性,同一个数据库中同时并发执行多个事务,事物之间的操作不会相互影响。
Durability:持久性,事物完成之后,事物所作的操作会持久存在于数据库中。
Redo log 和undo log
Redo log:由DML(insert delete update)操作,引起的页面变化,都需要记录到redo log中,大部分为物理日志
在页面修改完成之后,在脏数据由cache写入到磁盘之前,会写入redo日志中。
日志先行,日志会先写入到磁盘中,数据后写入
聚簇索引/二级索引/undo页面的修改,均需要记录在redo日志中
Redo log是啥?官方文档解释如下:
Redo log是一个基于磁盘的数据格式,在数据库灾难恢复过程中,用于恢复未完成的事物,修复数据的。在正常的操作过程中,redo log将来自于SQL 语句或者其他API调用的请求,转化为数据表中的变化,当对数据的改变操作还未完成之前,遭遇了意外的停机,那这些变化会在数据库启动初始化的过程中进行replay重演,这个重演的过程,是在接受client请求之前,就会完成。
默认情况下,redo log在磁盘上的体现,一般是ib_logfile0和ib_logfile1两个文件,mysql以循环的方式,写这两个文件,在redo log中的数据,是以记录变化为编码,这些日志数据,也就体现了数据的变化,在log中的一段内容,就体现了一个已经增加的LSN增量。
在mysql的配置文件中,innodb_log_file_size设置了redo log文件的大小,innodb_log_file_in_group设置了日志文件的个数,这些设置必须重启才能生效,当innodb检测到设置的大小和当前的文件大小不一致时,会设置一个检查点,然后关闭该日志文件,删除旧文件,创建一个设置大小的日志文件,开始写入日志。
Redo log刷盘的组提交
和其他所有兼容ACID模型的数据库引擎一样,innodb数据引擎也是会在事物提交之前,先将redo log文件刷盘,而且innodb还使用了一种组提交机制,同时将多个事务的redo log刷到磁盘中,避免一个事物一个提交,通过该组提交机制,一次日志刷盘操作,会将同时进行的多个事务的redo log提交,提高了中断效率。
Undo log:由DML 操作导致的数据记录变化,均需要将变化前的镜像,写入到undo log中,是一种逻辑日志。
undo log是啥?官方文档解释如下:
undo log是一组undo log记录的集合,这些undo log记录是关于某个事物的,一个undo log记录中包含了描述如何将最后的更新回退到集群索引记录的信息,如果有某一个事物需要去使用原始数据(比如在一个一致性的读事物中),这些原始没有被修改的数据,就会通过undo log记录进行恢复。Undo log存在于undo log段中,undo log段中包含了回滚段,而回滚段存在于系统表空间、临时表空间和回滚表空间中。
Innodb支持128个回滚段,其中有32个是为临时表的事物操作预留的,每一个更新临时表的事物(不包含只读事物)会被分配2个回滚段,一个是启用了redo的回滚段,另一个是没有启用redo的回滚段。只读事物只会分配一个没有启用redo的回滚段,因为只读事物是只允许修改临时表的。
剩下的96个回滚段,每一个都支持1023个一致性数据修改事物,所以能够支持近似于96K的一致性数据修改事物,96K的限制是假设事物不会去修改临时表,如果所有的数据修改事物都修改了临时表,这个大小大约是32K。
既然DML操作,会引起redo log和undo log的变化,具体进行分析一下。
Insert 插入操作:
Insert插入操作,不会对原有数据产生影响,只是新产生一条记录和对应的索引,以前的记录和索引不会被修改,所以对undo log的要求不高,但是对redo log的要求就比较高了,用于replay,就需要整条插入的所有信息。
Undo log:记录insert插入记录的主键值
Redo log:记录日志操作页面(space_id,page_no)、完整的插入记录、系统列等
Delete删除操作
Delete删除操作是要从当前的库或者表中删除一部分已经存在的记录,如果在删除过程中出现了数据库的crash,在recovery过程中需要再次进行删除操作,而recovery中的replay利用的就是redo log,所以redo log中需要记录删除的具体信息,比如主键等关键信息;而在undo log中需要记录的信息就会更多了,因为有可能在执行删除事物之前,存在一个一致性的读事物,需要读取当前被删除的这些记录,所以这些删除的记录的原始数据,是要存放在undo log中的;另外,由于读查询是会使用到索引等信息,所以这些索引信息,也是要存放在undo log中的。所以综上:
Redo log:记录日志操作页面、删除记录的系统列,记录在页面中的位置,同时记录undo page的修改
Undo log:
- Delete操作在innodb中为delete mark操作,并不是真的删除数据,只是将记录标记为delete
- 记录当前删除记录的系统列
- 记录当前删除记录的主键
- 记录当前删除记录的所有索引
Update操作
Update的操作分为三种情况,对于不同的操作情况,redo log和undo log中记录的信息也是不一样的。
Section 1:未修改索引,修改的属性列长度不变
在这种update场景中,只是对非索引列的值进行了修改,并未修改该列的长度,所以在redo log中,会进行定点的update,会记录的是update log;而在undo log中,需要记录的是update操作的系统列、操作记录的主键、操作记录该列的原值,如果该update列中包含二级索引,二级索引的原值,也需要记录到undo log中。综上:
Redo log:记录update redo log,如果更新列中包含二级索引,则需要对二级索引进行delete mark操作,然后重新insert一条新的二级索引;同时对undo 页面的修改,同步也要写入到redo log中。
Undo log:记录update的系统列、操作记录的主键、操作记录该列的原值。如果该update列中包含二级索引,二级索引的原值,也需要记录到undo log中
Section 2:未修改索引,修改了属性列长度
这种update场景和section 1中的场景类似,唯一的区别是属性列长度发生了变化,这中变化,在undo log中记录的信息,和section 1中的信息形同,而redo log中记录的信息会发生变化,这个时候记录的不再是定点的update,应该是先delete原始的信息,然后insert一条信息。
undo log:记录信息和section 1中的undo log信息相同
redo log:不能定点的update了,会记录delete+insert redo log
section 3:修改索引列值
在数据库中,修改某条记录的索引列值,实际上的操作是将该记录delete,然后重新插入一条新的记录,然后生成索引,更新索引表。在这一连串的操作过程中,redo log实际上是要记录一个delete和一个insert的redo log,而undo log上是要记录原始的记录(delete操作)和insert的操作记录。
LSN:log sequence number
日志序列号,递增产生,一个LSN可以唯一标识一个redo log,其中有一个叫checkpoint LSN,用来标识数据库crash的redo 起始点,LSN和日志文件位置意义对应。
数据库日志redo和undo的更多相关文章
- MySQL数据库日志文件(redo与undo)
+++++++++++++++++++++++++++++++++++++++++++标题:MySQL数据库日志文件时间:2019年2月25日内容:MySQL数据库日志文件(redo日志和undo日志 ...
- 数据库篇:mysql日志类型之 redo、undo、binlog
前言 可以说mysql的多数特性都是围绕日志文件实现,而其中最重要的有以下三种 redo 日志 undo 日志 binlog 日志 关注公众号,一起交流:微信搜一搜: 潜行前行 1 redo日志 in ...
- SQL Server 中日志的的作用(Redo和Undo)
简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用. 数据库的可靠性 在关系数据库系统中,我们需要数据库可靠,所谓的可靠就是当遇见 ...
- MySQL redo与undo日志解析
前言: 前面文章讲述了 MySQL 系统中常见的几种日志,其实还有事务相关日志 redo log 和 undo log 没有介绍.相对于其他几种日志而言, redo log 和 undo log 是更 ...
- 【Mysql】三大日志 redo log、bin log、undo log
@ 目录 redo log(物理日志\重做日志) binlog(逻辑日志/归档日志) update语句执行流程 Uodolog(回滚日志/重做日志) undo log+redo log保证持久性 re ...
- 当数据库没有备份,redo或undo损坏
数据库在没有备份的情况下,如果数据库redo或undo损坏,可以通过如下方法处理,但是不一定成功 把init文件中的: undo_management=manual 然后启动数据库到mount 状态后 ...
- 【转】ORACLE的REDO与UNDO
一.什么是redo?redo:oracle在在线或者归档重做日志文件中的记录的信息,外以出现失败时可以利用这些数据来"重放"事务.每个oracle数据都至少有二个在线重做日志组,每 ...
- 09 redo and undo
本章提要-----------------------------------------------redo, undo 定义redo, undo 如何工作如何访问 redo, undo提交和回滚- ...
- Oracle 9 - redo和undo
1.redo redo 有在线redo日志和归档redo日志, 从Oracle 10g开始还新增加了flashback技术. 每个Oracle数据库至少有2个在线重做日志组,循环写. 只有INSERT ...
随机推荐
- PLSQL 汉化
自动导入PLSQL安装目录: 一直下一步就可以了: 之后重新打开:
- Eclipse:报错Failed to read artifact descriptor for org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.
导入SVN下载的MAVEN项目时springboot报错: pom.xml文件报错 Failed to read artifact descriptor for org.springframework ...
- 牛客网-2018年全国多校算法寒假训练营练习比赛(第四场)-A
解题思路:二分图的最大匹配,但这题是所有点都遍历一遍,所以答案/2: 代码: #include<iostream> #include<algorithm> #include&l ...
- Python中csv模块解析
导入模块 import csv 2.读取csv文件 file1 = open('test1.csv', 'rb') reader = csv.reader(file1) rows = [row for ...
- A/B HDU - 1576 (exgcd)
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). Input数据的第一行是一个T,表示有T组数据. 每组数据有两 ...
- ionic报错: Failed to load resource
隔了一天,才发现是代码写错了 出错的原因是在ts 文件中使用这样的定义 data: [] = ['高新区', '经开区', '其他园区']; 错误在于这个定义的类型,不能是 [],修改成 any就没有 ...
- 解决 phpstorm 运行卡,自动关闭等问题
解决 phpstorm 自动关闭问题: 使用文件搜索工具(可在本博客搜索“管理工具”,或查找安装目录) 找到phpstorm.vmoptions文件,使用记事本打开. 添加以下两行代码: -Dawt. ...
- MT【251】椭圆中的好题
已知直线$l:x+y-\sqrt{3}=0$过椭圆$E:\dfrac{x^2}{a^2}+\dfrac{y^2}{b^2}=1,(a>b>0)$的右焦点且与椭圆$E$交于$A,B$两点,$ ...
- 【BZOJ4543】Hotel加强版(长链剖分)
[BZOJ4543]Hotel加强版(长链剖分) 题面 BZOJ,没有题面 洛谷,只是普通版本 题解 原来我们的\(O(n^2)\)做法是设\(f[i][j]\)表示以\(i\)为根的子树中,距离\( ...
- rt-thread中软件定时器组件超时界限的一点理解
@2019-01-15 [小记] 对 rt-thread 中的软件定时器组件中超时界限的一点理解 rt_thread_timer_entry(void *parameter)函数中if ((next_ ...