InnoDB的buffer pool缓冲池 (一个SQL执行的时候,会在buffer pool里面做哪些 *** 作)

InnoDB的buffer pool缓冲池 (一个SQL执行的时候,会在buffer pool里面做哪些 *** 作),第1张

InnoDB的buffer pool缓冲池 (一个SQL执行的时候,会在buffer pool里面做哪些 *** 作

视频地址:https://www.bilibili.com/video/BV1Kh41147RV/

文章目录
    • 一、前言
    • 二、事物
    • 三、undo log
    • 四、redo log
    • 五、binlog
    • N、其他
      • N-1、为什么要在内存中 *** 作,但对于日志还是写入硬盘呢?
      • N-2、为什么有了redo log 还要binlog

一、前言

上次我们讲过一条SQL从应用程序到数据库要经历哪些过程,想必大家都已经有了大致的了解。

但是在讲到buffer pool的时候,我们省略了其中的细节,只是说到数据会先从磁盘加载到内存中去,然后在内存中进行我们的 *** 作,今天我们就来具体看看它在缓冲池中具体要做哪些 *** 作。


二、事物

在具体讲解细节之前,我们先来明确一个概念 事物,大家应该都知道啥是事物,简单来说就是一组命令要么都执着成功,要么都不执行成功。

我们 *** 作数据库的时候,不管是一条SQl还是多条SQL都是以事物为维度去执行的。

假设一个这样的场景:A向B转500块钱,这时候我们要做两个 *** 作,在A的账户下 -500,在B的账户下 +500,并且这两个修改都必须同时成功或失败。


三、undo log

但是我们也知道 *** 作不管怎样都是有前后顺序的对不对?那么为了保证 *** 作的原子性,也就是如果后面的SQL执行失败了,我们可以把前面的 *** 作复原,那这就需要我们把前面的 *** 作记录下来。这个记录的地方就是 undo log

现在我们已经知道了undo log是用来存储修改之前的旧数据,它的作用主要是两个

  • 用于事物的回滚
  • 用于MVCC里面的读视图

undo log的类型也有两种 insert undo log 、 update undo log

  • insert undo log 数据库在插入数据的时候产生,只有在当前事物回滚的时候才有用,所以在当前事物结束的时候它就没用了,就会被删除。
  • update undo log 数据库在更新、删除的时候产生,除了当前事物会使用,在快照读的时候也会使用,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除

四、redo log

刚刚我们已经把数据修改了,但只是在内存中进行修改的,这就存在如果系统宕机了,那修改不就丢失了吗?

这里我们就要引入一个新的日志 redo log 重做日志,对数据做的增删改都会记录到这个redo log里面去,如果我们的服务崩了,就可以拿这个redo log里面的数据进行恢复。

上面我们看到这个redo log是先写入内存中去的,只要是没落盘那么都存在数据丢失的可能,MySQl提供了redo log落盘策略,我们可以通过配置 innodb_flush_log_at_trx_commit 来控制

  • 0:提交事物的时候不会把redo log buffer 里的数据刷入磁盘
  • 1:提交事物的时候,必须把日志刷入磁盘中,可以严格保证数据不丢失 (默认、且推荐的)
  • 2:提交事物的时候,先把日志刷入磁盘文件对应的 os cache 缓存里,隔一段时间再把数据刷入磁盘

五、binlog

在之前的学习中,我们或多或少的听过这样一个日志 binlog ,它是用来备份数据,或者主从之间复制数据的。

对数据的增删改也需要同步记录到这个 binlog里面去,binlog刷盘策略通过 sync_binlog 来配置

  • 0: 它是写入os cache内存缓存,并不是写入磁盘 (默认的)
  • 1: 同步将日志写入磁盘 (推荐的)
  • N: 每写N次 *** 作系统缓冲就执行一次刷新 ***

通过上面的描述,我们知道不管是redo log 还是 binlog,都是推荐直接写入磁盘的。

这里还有一个问题,比如我们修改了一条数据,这个数据还存在内存中,查询的时候没关系反正查询的也是内存,但是数据不存入磁盘这肯定是不行的,所以还有一个线程会不定期的把这些修改过的数据刷入磁盘。

注:这个修改过的数据叫做脏页,至于为什么这么叫后续讲解。

经过上面的描述,我们最终的图应当是这样的

整个过程:读取数据到内存 > 写入undo log > 修改数据 > 写入redo log缓存 > 提交事物 > redo log 入盘 > binlog 入盘 > 数据入盘(不定时)


N、其他 N-1、为什么要在内存中 *** 作,但对于日志还是写入硬盘呢?

之所以要把数据读取到内存中进行 *** 作,和大家想的一样:内存 *** 作更快。

可能有小伙伴有疑问了,一顿 *** 作猛如虎,结果还是要把日志写入到硬盘中去,这里要和大家说明下,写入日志的时候是顺序写入的,也就是在之前的内容后面追加,这个写入的速度会非常的快,而进行数据修改写入是随机写入,这个就很慢了。


N-2、为什么有了redo log 还要binlog
  • redo log 是属于InnoDB引擎的,binlog是属于MySQL数据库的
  • redo log是物理日志,记录的是“在某个数据页上做了什么修改”(数据页上某个偏移量的值);binlog是逻辑日志,记录的是这个语句的原始逻辑(sql、数据行)
  • redo log是循环写入的,当空间不足的时候,就会覆盖之前的数据,而binlog是追加方式写入,一块区域写满了,就会新开一个

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5582509.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存