SQL语句是怎样写入磁盘的?
我们都知道SQL语句是存储存储在磁盘上的,但是执行SQL语句后的数据是先存在InnoDB存储引擎的内存中的,那它究竟是怎么记录到磁盘中的呢?要想了解这个,我们首先要知道SQL数据在本地到底是什么类型的文件进行存储。
data数据在本地的存储形式
在本地mysql对应库中,data数据实际上是以ibd文件存储,其中包括数据页和索引页(页是磁盘和内存交互的最小单位,一页大小是16k,页也就是B+树的叶子结点)。
data数据在内存中对应的空间为Buffer Pool,其中也包括数据页和索引页部分。
data从存储引擎层写入磁盘过程

写数据到磁盘的过程也被称为脏页落盘,之所以称之为脏页是因为此时内存中的数据和磁盘上的数据还不一致。
首先,SQL语句对数据页的改动将储存在InnoDB的内存中,也就是Buffer Pool中。
接下来是先写日志,再更新数据到磁盘。之所以如此,和数据在磁盘上的存储状态也有关系,日志在磁盘上往往是存储在一块连续区域,采用顺序IO即可,而数据在磁盘上往往是分散的,在读取的时候需要进行寻址等操作,属于随机IO,效率会比较低,因此先进行日志存储,再写入数据,这样对于数据意外丢失时的恢复,有着更高的效率。
在执行完一条命令后,为了保证持久性,要先写日志,但是并不能每条日志都立即追加写在磁盘上,因为这样连续IO会占用大量的处理器性能,因此,先将redo log写在缓冲区redo log Buffer中,集齐一定数量,再由缓冲区写入磁盘,而这个写入磁盘的时机在两种情况下成立
- 当事务提交的时候,强制刷新到磁盘
- 可手动设置刷新时机,如果要求强一致性,可以每次写入立即刷新,也可以设置每隔一秒刷新一次。
日志写好后Buffer

SQL语句执行后的数据首先存储在InnoDB的Buffer Pool内存中,然后通过脏页落盘过程写入磁盘。这个过程中,先写redo log,再更新数据,确保数据持久性。脏页在事务提交或Buffer Pool满时写入,redo log写入磁盘后,Buffer Pool根据checkpoint时机刷新脏页,整个过程涉及Double Check确保数据正确性。

6325

被折叠的 条评论
为什么被折叠?



