您的位置 首页 java

SQL语句是怎样写入磁盘的?

SQL语句是怎样写入磁盘的?

  • data数据在本地的存储形式
  • data从存储引擎层写入磁盘过程

我们都知道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中,集齐一定数量,再由缓冲区写入磁盘,而这个写入磁盘的时机在两种情况下成立

  1. 当事务提交的时候,强制刷新到磁盘
  2. 可手动设置刷新时机,如果要求强一致性,可以每次写入立即刷新,也可以设置每隔一秒刷新一次。

日志写好后Buffer Pool将根据checkpoint时机刷新脏页到内存中。checkpoint有两种情况

  1. Buffer Pool内存满了,会将Buffer Pool里的脏页写入内存
  2. 磁盘中redo log文件(通常有两个)都写满了,会将Buffer Pool里的脏页写入内存,redo log文件存在的目的就是在提交事务但是由于意外情况数据丢失时用户数据恢复,既然保存的日志信息都已经写入磁盘了,那redo log文件中的内容也就可以清空了。

刷新脏页到磁盘也不是一步成功,其中还要经过Double Check双重认证,这是因为内存操作的最小单位是16
k,而操作系统操作的最小单位是4k,一个数据页实际上操作系统要进行四次操作才能写入磁盘,此时如果其中一次操作发生故障,那么就需要double check来对数据进行验证。这与redo log目的一致,但是发生的场景并不相同,redo log是提交事务后数据丢失的恢复,double check是操作系统将数据写入磁盘,由于最小操作单元与页的大小不一致,导致数据没有正常写入是进行数据验证和恢复。

文章来源:智云一二三科技

文章标题:SQL语句是怎样写入磁盘的?

文章地址:https://www.zhihuclub.com/177596.shtml

关于作者: 智云科技

热门文章

网站地图