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


  • 一、前言

  • 二、事物

  • 三、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

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

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

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

undo log的类型也有两种 insert undo logupdate undo log

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


四、redo log


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

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

InnoDB的buffer pool缓冲池 (一个SQL执行的时候,会在buffer pool里面做哪些操作)
在这里插入图片描述

上面我们看到这个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,都是推荐直接写入磁盘的。

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

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

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

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

整个过程:读取数据到内存 > 写入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是追加方式写入,一块区域写满了,就会新开一个




原文始发于微信公众号(小道仙97):InnoDB的buffer pool缓冲池 (一个SQL执行的时候,会在buffer pool里面做哪些操作)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/41352.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!