执行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这个机制。
①在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 也很难容下所有的数据,那缓存区的数据怎么写到磁盘中呢?
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是一棵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操作的页的数量不同。
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。