一、进阶知识文字、表格介绍
我们用一个场景来串联一些概念:当我们要更新一条数据并查询
1、执行器要去调数据引擎检查这条数据所在的数据页在不在内存
2、不在内存中,非唯一索引将这个更新对应数据页操作记录在ChangeBuffer中(唯一索引会读去数据磁盘将数据页读入内存)
3、Undo Log Buffer记录这个更新操作的相反逻辑,属于逻辑日记(更新+3,记录-3;删除,记录插入记录;)
4、Redo Log Buffer记录ChangeBuffer的改变,属于物理日记,此时更新二阶段提交状态为第一阶段prepare,引擎层记录
5、Binlog Buffer记录这个更新逻辑操作,Server层记录
6、提交事务,此时更新二阶段提交状态为第二阶段commit
7、各个Buffer都有自己的刷盘时机,将内存中的日记通过OS Buffer写到日记磁盘中,即Undo Log File、Redo Log File和Binlog File
8、查询数据时,对应的数据页不在内存中,此时需要将数据页同步到内存中,并执行merge过程
9、线程空闲时等将内存中最新的数据页写入数据磁盘中,这个过程叫刷脏
概念解释表格
概念 | 解释(红:核心,绿:过程,黄:指引) |
---|---|
数据页 | MySQL是按照数据页为最小单位进行存储的,b+树的特性,一页默认16k,数据属于页,页包含数据。当操作一条数据的时候,实际上就是在操作一个数据页,多条数据可能是在一个数据页也可能是在多个数据页,看数据具体分布。后面对我将会一直提到数据页。 |
内存 | 内存是指:InnoDB引擎内存Buffer Pool,会缓存数据页。每次更新之前查数据先会查内存中对应的数据页。由内存Buffer Pool分割出去的有ChangeBuffer、Log Buffer(Redo、Undo)和Binlog Buffer等等。 |
ChangeBuffer | “ChangeBuffer” 是Buffer Pool分割出去的一块内存,记录更新操作,当更新没有用到唯一索引并且内存没有对应数据页,就不用从数据磁盘读入到内存,而是直接记录在ChangeBuffer中。 |
Log Buffer | “Log Buffer” 是Buffer Pool分割出去的一块内存总称,事务日记内存,Log Buffer又分成Redo log Buffer和Undo Log Buffer。 |
数据磁盘 | “数据磁盘” 是数据库存储数据的磁盘(自称) ,为了区分日记磁盘 |
Undo Log Buffer | Log Buffer的一块缓存,写Undo是先写入Undo Log Buffer,刷盘时机,通过OS Buffer写入Undo Log File日记磁盘。 |
逻辑日记 | “逻辑日记” 可以简单理解为记录的就是sql语句。Binlog和Undo log记录的是逻辑日记。 |
Redo Log Buffer | Log Buffer的一块缓存,写Rndo是先写入Redo Log Buffer,刷盘时机,通过OS Buffer写入Rndo Log File日记磁盘。 |
物理日记 | “物理日志” 记录的就是数据页变更 ,因为MySQL数据最终是保存在数据页中的,Redo Log记录的是物理日记。 |
二阶段提交 | “二阶段提交” 是指prepare和commit两个状态阶段,是保证Redo log 和 Binlog一致性所采取的方式。 |
prepare | “prepare” 是指预提交阶段,属于二阶段提交中的第一阶段。 |
Binlog Buffer | “Binlog Buffer” 是Buffer Pool分出的一块内存,除了查询操作的SQL都要进行记录在Binlog Buffer中,刷盘时机,通过OS Buffer写入Binlog File日记磁盘文件。 |
Server | “Server” 是MySQL基本架构的一层,MySQL基本架构分为Server层和引擎层,详细介绍可以参考--简单记一条查询SQL语句的执行全过程。 |
commit | “commit” 是指预提交阶段,属于二阶段提交中的第二阶段。 |
刷盘时机 | “刷盘时机” 是指啥时候,通过什么策略将内存日记中写入到日记磁盘中。因为日记每次都是先写入内存buffer中,然后通过刷盘时机设置的参数控制刷盘时机,最后才刷入日记磁盘。这个参数设置对于Undo、Redo和Binlog都有一套参数。 |
OS Buffer | “OS Buffer" 是指操作系统内存,数据库将内存中日记写入到日记磁盘都要经过操作系统的OS Buffer来间接写入。 |
日记磁盘 | “日记磁盘” 是指写入到磁盘的日记文件的统称,我将日记文件统称为日记磁盘好区分数据磁盘。 |
Undo Log File Redo Log File BinLog File |
是指写入到磁盘的日记文件,每个文件在内存中都有对应内容,最终都会写入到日记磁盘中。 |
merge | “merge” 是指将ChangeBuffer应用到内存中的,得到最新的内存页,并将数据页的改动记录到Redo中的一个过程。 |
刷脏 | “刷脏” 是指将内存的脏数据页刷到数据磁盘中,内存中的数据页是最新的和数据磁盘不同步时,将内存的数据页称为脏数据,数据库会在线程空闲或者其他时机将 “内存中的脏数据页” 刷到 “数据磁盘”中。 |
Log sequence number | 当前的redo log(in buffer)中的LSN,系统最大最新的LSN值,我叫它:redo log buffer lsn |
Log flushed up to | 已经刷到日记磁盘中的LSN,我叫它:redo log file lsn |
Pages flushed up | 已经刷到数据磁盘数据页上的LSN,每个数据页头部会记录一个LSN,我叫它:data disk lsn --额外加:内存中的LSN,我叫它:data buffer lsn |
Last checkpoint at | 日记磁盘上一次检查点记录的LSN,只有数据刷完才会记录。即小于此值的LSN的数据页一定已经刷入数据磁盘,大于的可能已经刷入,可能未刷入。我叫它:checkpoint sln |
二、进阶知识图片串联
所谓无图无真相,文字叙述还是比较僵硬的,下面用个画了好久的图来串一串帮助理解
三、进阶提示语
结束语:刷到这篇文章的你很幸运,因为你即将收获更多--几年了?作为一个码农终于把MySQL日记看懂了,为此肝出此文!!!