MySQL --- 读书笔记 --- 事务日志

事务的ACID特性是基于什么机制实现的

  • 事务的隔离性是由锁机制实现的
  • 而原子性、一致性、持久性由事务的redoundo日志来保证的
    • redo日志,叫做重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。是存储引擎生成的日志,记录的是物理级别上的页修改操作,比如页号xxx,偏移量yyy,写入zzz数据。主要为了保证数据的可靠性
    • undo日志,叫做回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。是存储引擎生成的日志,记录的是逻辑操作的日志,比如对某一行数据进行INSERT语句操作,那么undo日志就会记录一条与之相反的DELETE操作。主要用于事务的回滚和一致性非锁定读(MVCC)

1. redo日志

InnoDB是以页为单位管理存储空间的,在访问页之前,都需要将页从磁盘上缓存到Buffer Pool中才可以访问。所有的记录变更都需要先更新Buffer Pool上的数据,然后Buffer Pool中的脏页会以一定的频率刷新到磁盘,通过缓存来优化CPU和磁盘之间的鸿沟,保证整体性能不会下降太快

1.1 为什么需要redo日志

一方面,缓存可以帮助消除CPU和磁盘之间速度差,checkpoint机制可以保证数据的最终落盘,然而checkpoint不是每次变更都会触发,而是由master线程隔一段时间去处理的。那么在最坏情况下,一定会出现数据丢失。

另一方面,事务包含持久性的特性,也就是当事务提交成功后,即使系统崩溃,这个事务对数据库的修改也不能丢失。

那么,我们不需要在每次修改的时候,就马上刷新脏页到磁盘,如果修改的数据量很小,太浪费资源,而且修改的页不一定是连续的,出现随机I/O后,磁盘更新更慢。所以,我只需要记录一下,修改了什么。

InnoDB采用了WAL技术(Write-Ahead Logging),这种技术的思想是先写日志,再写磁盘,只有日志写入成功,才算事务提交成功,当发生宕机且数据未刷到磁盘的时候,可以通过redo日志恢复

1.2 redo日志的好处、特点

优点

存储表空间ID、页号、偏移量、以及需要更新的值,所需的空间小,刷盘快

  • 降低了刷盘频率
  • 占用空间小

特点

  • 日志是顺序写入磁盘,顺序I/O效率更高
  • 事务执行过程中,日志不断记录

1.3 redo日志的组成

  • redo log buffer

在服务器启动时,就申请了一大片的连续空间,默认是16MB,这边内存空间被划分成若干个连续的redo log block,一个block占用512byte

  • redo log file

1.4 redo的整体流程

1.5 redo的刷盘策略

注意,redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中,只是刷入文件系统缓存(page cache)中,真正的写入是由操作系统来决定。那么对于InnoDB来说就有一个问题,如果系统宕机了,数据就没了。

针对这种情况,InnoDB给出了innodb_flush_log_at_trx_commit参数,该参数控制事务提交的时候,如何将redo log buffer中的日志刷新到redo log file。它有三种策略

  • 设置0:表示事务提交时不进行刷新(系统默认每隔1s进行一次redo日志的同步)
  • 设置1:每次事务提交都将进行同步,刷盘操作(默认)
  • 设置2:每次提交事务都只把redo log buffer写入page cache,不进行同步,由os决定同步

2. Undo日志

在事务中,更新数据之前,需要写入一个undo log

此外,undo log会产生redo log,这是因为undo log也需要持久性

2.2 undo日志的作用

  • 回滚数据

undo逻辑日志,因此只是将数据库恢复到原来的样子,所有修改都被逻辑取消了,但是数据结构和页本身在回滚之后可能大不相同。

这是因为在多用户并发系统中,可能会有成百上千的并发事务,数据库的主要任务是协调对数据记录的并发访问。比如一个事务修改当前一个页的几个记录,同时也有一个事务修改同一个页的其他几个记录,因此,不能将一个页回滚到事务开始的样子,这样会影响其他事务正在进行的工作

  • MVCC

在InnoDB中MVCC的实现是通过undo日志来完成的。当用户读取一条记录时,若记录已经被其他事务占用了,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取

undo日志的生成过程

1. 简要

2. 详细

行记录都有的隐藏记录:事务ID和回滚指针

回滚指针:当新增或者修改一个行记录,会首先产生一个undo log,然后记录的回滚指针就会指向这个undo log,同时如果是更新操作,那么新的undo log会有指向旧的undo log的指针

posted @   huang1993  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示