执行insert语句之后插入的数据会不会立马保存在磁盘中

发布时间:2022-01-04 15:03:18 作者:柒染
来源:亿速云 阅读:277

执行insert语句之后插入的数据会不会立马保存在磁盘中,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。



这么一个问题:当你执行一条insert语句之后,插入的数据就立马保存在磁盘中了么?

答案是不一定!

下面我们来看一下insert语句在写入磁盘的过程中是如何的!

我们都知道数据在提交到数据库中会有事务这一步,所以我们可以分两步来看

 

一、提交事务前

执行insert语句之后插入的数据会不会立马保存在磁盘中

1、首先进入server层对sql会进行一些必要的检查,不会涉及到磁盘的写入。

2、进入引擎层开始正式提交执行数据。

这里我们首先来了解一下MySQL在InnoDB存储引擎中,数据是怎么存储的!

同大多数数据库一样,InnoDB有页(Page)的概念(也可以称为块),页是InnoDB磁盘管理的最小单位。在InnoDB存储引擎中,默认每个页的大小为16 KB。而从InnoDB 1.2.x版本开始,可以通过参数InnoDB_page_size将页的大小设置为4 K、8 K、16 K。若设置完成,则所有表中页的大小都为InnoDBpagesize,不可以对其再次进行修改。除非通过mysqldump导入和导出操作来产生新的库。

InnoDB的数据是按数据页为单位来读写的。也就是说,当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位,将其整体读入内存。

而将数据从磁盘读入内存涉及随机IO的访问,是数据库里面成本最高的操作之一,所以为了减少磁盘IO,InnoDB设计了change buffer这个机制。

 

什么叫做change buffer:

①在MySQL 5.5之前的版本中,由于只支持缓存insert操作,所以最初叫做insert buffer,只是后来的版本中支持了更多的操作类型缓存,才改叫change Buffer,这也是为什么代码中有大量的ibuf前缀开头的函数或变量。

然而使用写缓冲需要同时满足两个条件:

(1) 索引是辅助索引

插入聚簇索引一般是顺序的,一般不需要磁盘的随机读取,所以不需要使用change Buffer

(2) 索引不是唯一的

辅助索引不能是唯一的,因为在插入缓冲时,数据库并不去查找索引页来判断插入的记录的唯一性。如果去查找肯定又会有离散读取的情况发生,从而导致change buffer失去了意义。

②change Buffer的底层实现

change Buffer底层结构是一颗全局的B+树,负责对所有的表空间进行change Buffer。

所以insert语句并不需要立刻将数据写入磁盘文件中,只需要修改内存缓冲池当中对应的数据页就可以了。

4、都知道内存不能保证数据的持久化,如果数据库在这个过程中宕机了,怎么保证保存在缓存中的数据不丢失。redo log 因此而生,默认情况下每次事务提交都会触发一次 redo log 刷盘。

5、如果开启了 binlog 日志,事务逻辑数据将会被写入 binlog 文件,且为了保证复制安全,建议设置为每次事务提交时,都要将 binlog 日志的变更刷入磁盘。

综上insert语句成功提交时,数据不是发生立马磁盘数据写入的,而是通过 redo log 和 binlog 文件最后把数据写入到磁盘。然而数据库缓存区不可能无限大,redo log 也很难容下所有的数据,那缓存区的数据怎么写到磁盘中呢?

 

二、事务提交后

执行insert语句之后插入的数据会不会立马保存在磁盘中

1、当缓冲池中的数据页达到一定量或数据库的IO压力较小时,都会进行数据页刷盘操作。

2、当开启共享表空间时,刷新数据时首先会复制一份刷入共享表空间中,由于共享表空间的页是连续的,对磁盘的写入也是顺序操作,所以这个过程对性能消耗不大。

3、不管是否经过共享表空间,更新的数据页最终还是需要刷入表空间的数据文件。刷入完成后才能释放数据库缓存当中的空间。

4、change Buffer也是数据库缓存中的一部分,当数据库缓存空间不足需要交换出部分数据更新页时,有可能将写缓冲的数据页换出,刷入共享表空间中的 change Buffer数据文件中。

5、当 innodb_stats_persistent=ON 时,插入语句所涉及到的数据就会被刷盘到 innodb_table_stats 和 innodbi_ndex_stats 这两张系统表中。

综上,一条 insert 语句的所有涉及到的数据在磁盘上会依次写入 redo log,binlog,共享表空间,最后在自己的用户表空间落定为安。

 

延伸:

说了数据写入到磁盘,那么change Buffer中的记录何时合并(merge)到真正的辅助索引中呢?

从上文可知Change Buffer是一棵B+树。当需要实现插入记录的辅助索引页不在缓冲池中,辅助索引记录首先会插入到这棵B+树中。

merge操作可能发生在以下几种情况下:

①辅助索引页被读到缓存中

②Change buffer bitmap页追踪到的辅助页已无可用空间

③master thread工作

第一种情况为当辅助索引页被读取到缓冲池中时,例如这在执行正常的SELECT查询操作,这时需要检查Insert Buffer Bitmap页,然后确认该辅助索引页是否有记录存放于Insert Buffer B+树中。若有,则将Insert Buffer B+树中该页的记录插入到该辅助索引页中。对该页多次的记录操作通过几次操作合并到了原有的辅助索引页中,因此性能会有大幅提高。

第二种情况Insert Buffer Bitmap 页用来追踪每个辅助索引页的可用空间,并至少有1/32页的空间。若插入辅助索引记录时检测到插入记录后可用空间会小于1/32页,则会强制进行一个合并操作,即强制读取辅助索引页,将Insert Buffer B+树中该页的记录及待插入的记录插入到辅助索引页中。这就是上述所说的第二种情况。

第三种情况就是在Master Thread线程中每秒或每10秒会进行一次Merge Change Buffer的操作,不同之处在于根据线程的工作状态每次进行merge操作的页的数量不同。


看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

推荐阅读:
  1. Mybatis在执行insert语句返回自增主键
  2. 如何使用Python解决MongoDB插入数据时已存在则不执行,不存在则插入的问题

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

insert 磁盘

上一篇:Python小波变换去噪怎么使用

下一篇:JS的script标签属性有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》