前文回顾
我们在之前的三篇文章史上最简单MySQL教程详解(进阶篇)之事务处理 、史上最简单MySQL教程详解(进阶篇)之锁与事务处理分离水平(一)、史上最简单MySQL教程详解(进阶篇)之锁与事务处理分离水平(二)对于事务的处理和锁定都进行了一些基本的介绍,掌握了这些知识后,可以很好的理解和使用事务,但为了更好的理解关于事务的原理,接下来将介绍一下关于数据库内部运行的机制。
事务处理的机制,简而言之就是留下更新日志。数据库会根据之前的日志信息,在必要时将旧数据取回,或者在数据库发生错误时,恢复到错误发生时间点前。与事务处理相关的日志可以分为两类:UNDO日志和REDO日志。
REDO日志
REDO日志根据数据库的不同,有时被称为事务处理日志或日志。
其实,通常我们所说的数据的“更新”并非是印象中的立即更新(直接就写入数据文件)的。实际上,数据的更新在数据库的内部要经历比较复杂的过程的。如下图所示:当数据的更新请求来临时,首先是写入了内存空间的缓冲区,并将这些保存到REDO日志文件,到这里的所有操作大家都可以理解为是实时的,没有任何的延迟,但是数据库为了避免频繁的操作给硬盘带来很高的负荷,对于从缓冲区写入数据文件的这一步是周期性执行的,只有当检查点(check point)来临时才会执行写入操作,这样一来就减少了硬盘的访问次数,性能得到改善。
那么这个时候就会面临一个了:当数据的更新请求来临时,已经完成了在缓冲区的数据更新,并写入了REDO日志文件,正在等待检查点的到来,但是这个时候突然断电了,造成了内存缓冲区的数据消失,但是客户端并不知道发生了断电,还以为数据的更新已经完成了,那这个时候该怎么办呢?没错,这个时候就只剩下REDO日志中的信息了,REDO日志文件也正是用于复原的。那么如何实现数据的复原的呢?数据库在错误排除后的第一次启动时,从REDO日志中抽取最后的检查点到错误发生点间的事务处理,然后重新执行一次,这样数据库就恢复到了错误发生点前的状态了。这样的操作被称为前滚(Roll forward)
UNDO日志
UNDO日志又被称为回滚段(Rollback Segment),在对数据进行操作时,保存变更前的数据。在表的内容中保存了指向UNDO日志的指针,ROLLBACK时根据这个指针来获得旧数据,覆盖新数据。ROLLBACK后,或者COMMIT后UNDO日志将被删除。
除此之外,UNDO日志也使用于保持数据读取的整合性。例如,在事务A对数据进行更新操作但尚未提交时,用户B要参照数据的时候,就只能通过保存的指针让UNDO日志中的数据呈现给用户B。
总结
我们就通过介绍有关UNDO日志和REDO日志的内容来让大家方便理解,事务是如何实现数据的回滚已经在错误发生时,如何恢复到错误发生时间前的状态的。
扫码关注作者个人技术公众号,不定期将有学习资源分享