没有合适的资源?快使用搜索试试~ 我知道了~
2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?.doc
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 0 下载量 165 浏览量
2022-07-09
09:07:10
上传
评论 2
收藏 3.28MB DOC 举报
温馨提示
试读
36页
2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?.doc
资源推荐
资源详情
资源评论
2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?
笔者:小林 coding
计算机八股文网站:/
大家好,我是小林。
从这篇「执行一条 SQL 查询语句,期间发生了什么?」中,我们知道了一条查询语句经
历的过程,这属于「读」一条记录的过程,如下图:
查询语句执行流程
那么,执行一条 update 语句,期间发生了什么?,比如这一条 update 语句:
UPDATEt_userSETname=‘xiaolin’WHEREid=1;
查询语句的那一套流程,更新语句也是同样会走一遍:
客户端先通过连接器建立连接,连接器自会判断用户身份;
因为这是一条 update 语句,所以不需要经过查询缓存,但是表上有更新语句,是会把整
个表的查询缓存情空的,所以说查询缓存很鸡肋,在 MySQL 8.0 就被移除这个功能了;
解析器会通过词法分析识别出关键字 update,表名等等,构建出语法树,接着还会做语
法分析,判断输入的语句是否符合 MySQL 语法;
预处理器会判断表和字段是否存在;
优化器确定执行计划,因为 where 条件中的 id 是主键索引,所以决定要使用 id 这个索
引;
执行器负责具体执行,找到这一行,然后更新。
不过,更新语句的流程会涉及到 undo log(回滚日志)、redo log(重做日志) 、binlog
(归档日志)这三种日志:
undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要
用于事务回滚和 MVCC。
redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要
用于掉电等故障恢复;
binlog (归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制;
所以这次就带着这个问题,看看这三种日志是怎么工作的。
为什么需要 undo log?
我们在执行执行一条“增删改”语句的时候,虽然没有输入 begin 开启事务和 commit 提
交事务,但是 MySQL 会隐式开启事务来执行“增删改”语句的,执行完就自动提交事务的,
这样就保证了执行完“增删改”语句后,我们可以及时在数据库表看到“增删改”的结果了。
执行一条语句是否自动提交事务,是由 autocommit 参数决定的,默认是开启。所以,执
行一条 update 语句也是会使用事务的。
那么,考虑一个问题。一个事务在执行过程中,在还没有提交事务之前,如果 MySQL 发
生了崩溃,要怎么回滚到事务之前的数据呢?
如果我们每次在事务执行过程中,都记录下回滚时需要的信息到一个日志里,那么在事务
执行中途发生了 MySQL 崩溃后,就不用担心无法回滚到事务之前的数据,我们可以通过
这个日志回滚到事务之前的数据。
实现这一机制就是 undo log(回滚日志),它保证了事务的 ACID 特性中的原子性
(Atomicity)。
undo log 是一种用于撤销回退的日志。在事务没提交之前,MySQL 会先记录更新前的数
据到 undo log 日志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。如下图:
回滚事务
每当 InnoDB 引擎对一条记录进行操作(修改、删除、新增)时,要把回滚时需要的信
息都记录到 undo log 里,比如:
在插入一条记录时,要把这条记录的主键值记下来,这样之后回滚时只需要把这个主键值
对应的记录删掉就好了;
在删除一条记录时,要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组
成的记录插入到表中就好了;
在更新一条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧
值就好了。
在发生回滚时,就读取 undo log 里的数据,然后做原先相反操作。比如当 delete 一条记
录时,undo log 中会把记录中的内容都记下来,然后执行回滚操作的时候,就读取 undo log
里的数据,然后进行 insert 操作。
不同的操作,需要记录的内容也是不同的,所以不同类型的操作(修改、删除、新增)产
生的 undo log 的格式也是不同的,具体的每一个操作的 undo log 的格式我就不详细介绍
了,感兴趣的可以自己去查查。
一条记录的每一次更新操作产生的 undo log 格式都有一个 roll_pointer 指针和一个 trx_id
事务 id:
通过 trx_id 可以知道该记录是被哪个事务修改的;
通过 roll_pointer 指针可以将这些 undo log 串成一个链表,这个链表就被称为版本链;
版本链如下图:
版本链
另外,undo log 还有一个作用,通过 ReadView + undo log 实现 MVCC(多版本并发控
制)。
对于「读提交」和「可重复读」隔离级别的事务来说,它们的快照读(普通 select 语句)
是通过 Read View + undo log 来实现的,它们的区别在于创建 Read View 的时机不同:
「读提交」隔离级别是在每个 select 都会生成一个新的 Read View,也意味着,事务期
间的多次读取同一条数据,前后两次读的数据可能会出现不一致,因为可能这期间另外一个
事务修改了该记录,并提交了事务。
「可重复读」隔离级别是启动事务时生成一个 Read View,然后整个事务期间都在用这个
Read View,这样就保证了在事务期间读到的数据都是事务启动前的记录。
这两个隔离级别实现是通过「事务的 Read View 里的字段」和「记录中的两个隐藏列
(trx_id 和 roll_pointer)」的比对,如果不满足可见行,就会顺着 undo log 版本链里找到
满足其可见性的记录,从而控制并发事务访问同一个记录时的行为,这就叫 MVCC(多版
本并发控制)。具体的实现可以看我这篇文章:事务隔离级别是怎么实现的?
因此,undo log 两大作用:
实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执 行了
ROLLBACK 语句,MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前
的状态。
实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过 ReadView + undo log 实
现的。undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)
的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的
记录。
为什么需要 Buffer Pool?
MySQL 的数据都是存在磁盘中的,那么我们要更新一条记录的时候,得先要从磁盘读取
该记录,然后在内存中修改这条记录。那修改完这条记录是选择直接写回到磁盘,还是选择
缓存起来呢?
当然是缓存起来好,这样下次有查询语句命中了这条记录,直接读取缓存中的记录,就不
需要从磁盘获取数据了。
为此,Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。
剩余35页未读,继续阅读
书博教育
- 粉丝: 1
- 资源: 2837
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页