mysql45讲知识点

本文详细介绍了MySQL的redo log和binlog,包括它们的概念、作用、不同点以及如何保证crash safe机制。redo log用于记录物理日志,循环写,确保数据页的crash safe;binlog则是逻辑日志,追加写,用于主从复制和数据恢复。两阶段提交协议确保了redo log和binlog的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. redo log的概念是什么? 为什么会存在.

在这里插入图片描述
redo log是固定大小的文件,这也决定了它是需要循环使用文件空间的,write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。
checkpoint是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

redo log是物理日志,记录的是对数据库页的修改,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
由于更新数据的时候引擎并不是按条更新的,而是以页为最小单位更新。如果没有redolog,每次更新一条数据都要把整页的数据刷新到磁盘。如果更新多条数据,很可能一次就要更新多页,而且这些io是随机io,磁盘i/o就会多且慢。有了redolog,就不需要每次直接按页更新磁盘,而是把更新写到redolog中,然后等空闲时间再把redolog中的更新写入到磁盘。这样做的好处是redolog是顺序写的,而且是按条不是按页写。所以虽然多了一步,实际上是比直接更新快的。

2. 什么是WAL(write-ahead log)机制, 好处是什么.

WAL就是在将数据进行刷盘时,需要先将数据记录在日志中,也称为预写日志,是数据库系统中常见的一种手段,用于保证数据操作的原子性和持久性。

这个问题相信很多同学都能猜出来,MySQL更改数据的时候,之所以不直接写磁盘文件中的数据,最主要就是性能问题。因为直接写磁盘文件是随机写,开销大性能低,没办法满足MySQL的性能要求。所以才会设计成先在内存中对数据进行更改,再异步落盘。但是内存总是不可靠,万一断电重启,还没来得及落盘的内存数据就会丢失,所以还需要加上写日志这个步骤,万一断电重启,还能通过日志中的记录进行恢复。

写日志虽然也是写磁盘,但是它是顺序写,相比随机写开销更小,能提升语句执行的性能(针对顺序写为什么比随机写更快,可以比喻为你有一个本子,按照顺序一页一页写肯定比写一个字都要找到对应页写快得多)。

3. redo log 为什么可以保证crash safe机制,那binlog可以做crash safe吗.

先介绍下 crash safe的基本概念

它是指MySQL服务器宕机重启后,能够保证:

  • 所有已经提交的事务的数据仍然存在。
  • 所有没有提交的事务的数据自动回滚。

redo log 是什么?

一个固定大小,“循环写”的日志文件,记录的是物理日志——“在某个数据页上做了某个修改”。

binlog 是什么?

一个无限大小,“追加写”的日志文件,记录的是逻辑日志——“给 ID=2 这一行的 c 字段加1”。

redo logbinlog 有一个很大的区别就是,一个是循环写,一个是追加写。也就是说 redo log只会记录未刷盘的日志,已经刷入磁盘的数据都会从 redo log这个有限大小的日志文件里删除。binlog 是追加日志,保存的是全量的日志。

当数据库 crash 后,想要恢复未刷盘但已经写入 redo logbinlog的数据到内存时,binlog是无法恢复的。虽然 binlog拥有全量的日志,但没有一个标志让 innoDB 判断哪些数据已经刷盘,哪些数据还没有。

举个栗子,binlog 记录了两条日志:

给 ID=2 这一行的 c 字段加1
给 ID=2 这一行的 c 字段加1
在记录1刷盘后,记录2未刷盘时,数据库 crash。重启后,只通过binlog数据库无法判断这两条记录哪条已经写入磁盘,哪条没有写入磁盘,不管是两条都恢复至内存,还是都不恢复,对 ID=2 这行数据来说,都不对。

redo log 不一样,只要刷入磁盘的数据,都会从redo log中抹掉,数据库重启后,直接把 redo log中的数据都恢复至内存就可以了。这就是为什么 redo log具有 crash-safe 的能力,而 binlog不具备。

4. binlog的概念是什么, 起到什么作用?

binlog是属于MySQL Server层面的,又称为归档日志,属于逻辑日志,是以二进制的形式记录的是这个语句的原始逻辑,依靠binlog是没有crash-safe能力的

作用是用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
用于数据库的基于时间点的还原。

5. binlog和redolog的不同点有哪些?

  • redo log是属于innoDB层面,binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。
  • redo log是物理日志,记录该数据页更新的内容;binlog是逻辑日志,记录的是这个更新语句的原始逻辑
  • redo log是循环写,日志空间大小固定;binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。
  • binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

6. 物理一致性和逻辑一致性各应该怎么理解?

//TODO

7. 执行器和innoDB在执行update语句时候的流程是什么样的?

执行语句前要先连接数据库,这是连接器的工作。

在一个表上有更新的时候,跟这个表有关的查询缓存会失效,所以这条语句就会把表 T 上所有缓存结果都清空。这也就是不建议使用查询缓存的原因。

接下来,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。

8. 如果数据库误操作, 如何执行数据恢复?

个人理解,有误请指正

这时候可以去查询binlog,找出最近的一次备份,然后执行回滚sql语句,再根据redo log细微调整数据页

9. 什么是两阶段提交, 为什么需要两阶段提交, 两阶段提交怎么保证数据库中两份日志间的逻辑一致性(什么叫逻辑一致性)?

引用一个小栗子

一个完整的交易过程:账本记上 卖一瓶可乐(redo log为 prepare状态),然后收钱放入钱箱(bin
log记录)然后回过头在账本上打个勾(redo log置为commit)表示一笔交易结束。
如果收钱时交易被打断,回过头来整理此次交易,发现只有记账没有收钱,则交易失败,删掉账本上的记录(回滚);如果收了钱后被终止,然后回过头发现账本有记录(prepare)而且钱箱有本次收入(bin
log),则继续完善账本(commit),本次交易有效。

因为redo log影响主库的数据,binlog影响从库的数据,所以redo log和binlog必须保持一致才能保证主从数据一致,这是前提。

相信很多有过开发经验的同学都知道分布式事务,这里的redo log和binlog其实就是很典型的分布式事务场景,因为两者本身就是两个独立的个体,要想保持一致,就必须使用分布式事务的解决方案来处理。而将redo log分成了两步,其实就是使用了两阶段提交协议(Two-phase Commit,2PC)。

下面对更新语句的执行流程进行简化,看一下MySQL的两阶段提交是如何实现的:
在这里插入图片描述
从图中可看出,事务的提交过程有两个阶段,就是将redo log的写入拆成了两个步骤:prepare和commit,中间再穿插写入binlog。

10. 如果不是两阶段提交, 先写redo log和先写bin log两种情况各会遇到什么问题?

update T set c=c+1 where ID=2;

用该update语句来做例子。假设当前 ID=2 的行,字段 c 的值是 0,再假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢?

先写redo log后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。
但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。
然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。

先写 binlog后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把 c 从 0 改成 1”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。

可以看到,如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。

借鉴的博客:
为什么 redo log 具有 crash-safe 的能力,是 binlog 无法替代的?
MySQL日志系统:redo log、binlog、undo log 区别与作用
MySQL 的 crash-safe 原理解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值