图解MySQL | [原理解析] MySQL insert 语句的磁盘写入之旅[亲测有效]

图解MySQL | [原理解析] MySQL insert 语句的磁盘写入之旅[亲测有效]作者及简介: 黄 炎,爱可生首席技术官; 王 悦,爱可生研发团队成员,负责数据库管理平台相关项目的开发和故障排查,好奇 MySQL 技术原理及各类数据库实现方案。 本文来源:转载自公众号-图解 My…

图解MySQL | [原理解析] MySQL insert 语句的磁盘写入之旅


一条 insert 语句在写入磁盘的过程中到底涉及了哪些文件?顺序又是如何的?下面我们用两张图和大家一起解析 insert 语句的磁盘写入之旅。

图 1:事务提交前的日志文件写入

图解MySQL | [原理解析] MySQL insert 语句的磁盘写入之旅[亲测有效]

旅途过程:

  1. 首先 insert 进入 server 层后,会进行一些必要的检查,检查的过程中并不会涉及到磁盘的写入。
  2. 检查没有问题之后,便进入引擎层开始正式的提交。我们知道 InnoDB 会将数据页缓存至内存中的 buffer pool,所以 insert 语句到了这里并不需要立刻将数据写入磁盘文件中,只需要修改 buffer pool 当中对应的数据页就可以了。
  • buffer pool 中的数据页刷盘并不需要在事务提交前完成,其中的交互过程我们会在下一张图中分解。
  1. 但仅仅写入内存的 buffer pool 并不能保证数据的持久化,如果 MySQL 宕机重启了,需要保证 insert 的数据不会丢失。redo log 因此而生,当 innodb_flush_log_at_trx_commit=1 时,每次事务提交都会触发一次 redo log 刷盘。(redo log 是顺序写入,相比直接修改数据文件,redo 的磁盘写入效率更加高效)
  2. 如果开启了 binlog 日志,我们还需将事务逻辑数据写入 binlog 文件,且为了保证复制安全,建议使用 sync_binlog=1 ,也就是每次事务提交时,都要将 binlog 日志的变更刷入磁盘。

综上(在 InnoDB buffer pool 足够大且上述的两个参数设置为双一时),insert 语句成功提交时,真正发生磁盘数据写入的,并不是 MySQL 的数据文件,而是 redo log 和 binlog 文件。然而,InnoDB buffer pool 不可能无限大,redo log 也需要定期轮换,很难容下所有的数据,下面我们就来看看 buffer pool 与磁盘数据文件的交互方式。

名词背景说明

double write 背景

InnoDB buffer pool 一页脏页大小为 16 KB,如果只写了前 4KB 时发生宕机,那这个脏页就发生了写失败,会造成数据丢失。为了避免这一问题,InnoDB 使用了 double write 机制(InnoDB 将 double write 的数据存于共享表空间中)。在写入数据文件之前,先将脏页写入 double write 中,当然这里的写入都是需要刷盘的。有人会问 redo log 不是也能恢复数据页吗?为什么还需要 double write?这是因为 redo log 中记录的是页的偏移量,比如在页偏移量为 800 的地方写入数据 xxx,而如果页本身已经发生损坏,应用 redo log 也无济于事。

insert buffer 背景

InnoDB 的数据是根据聚集索引排列的,通常业务在插入数据时是按照主键递增的,所以插入聚集索引一般是顺序磁盘写入。但是不可能每张表都只有聚集索引,当存在非聚集索引时,对于非聚集索引的变更就可能不是顺序的,会拖慢整体的插入性能。为了解决这一问题,InnoDB 使用了 insert buffer 机制,将对于非聚集索引的变更先放入 insert buffer ,尽量合并一些数据页后再写入实际的非聚集索引中去。

图 2:事务提交后的数据文件写入

图解MySQL | [原理解析] MySQL insert 语句的磁盘写入之旅[亲测有效]

旅途过程:

  1. 当 buffer pool 中的数据页达到一定量的脏页或 InnoDB 的 IO 压力较小 时,都会触发脏页的刷盘操作。
  2. 当开启 double write 时,InnoDB 刷脏页时首先会复制一份刷入 double write,在这个过程中,由于double write的页是连续的,对磁盘的写入也是顺序操作,性能消耗不大。
  3. 无论是否经过 double write,脏页最终还是需要刷入表空间的数据文件。刷入完成后才能释放 buffer pool 当中的空间。
  4. insert buffer 也是 buffer pool 中的一部分,当 buffer pool 空间不足需要交换出部分脏页时,有可能将 insert buffer 的数据页换出,刷入共享表空间中的 insert buffer 数据文件中。
  5. 当 innodb_stats_persistent=ON 时,SQL 语句所涉及到的 InnoDB 统计信息也会被刷盘到 innodb_table_stats 和 innodb_index_stats 这两张系统表中,这样就不用每次再实时计算了。
  6. 有一些情况下可以不经过 double write 直接刷盘
  • a. 关闭 double write
  • b. 不需要 double write 保障,如 drop table 等操作

汇总两张图,一条 insert 语句的所有涉及到的数据在磁盘上会依次写入 redo log,binlog,(double write,insert buffer) 共享表空间,最后在自己的用户表空间落定为安。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/9103.html

(0)
上一篇 2023-02-15
下一篇 2023-02-15

相关推荐

  • redis 存储之 redisObject[亲测有效]

    redis 存储之 redisObject[亲测有效]redisObject redis 是 key-value 存储系统,其中key类型一般为字符串,而 value 类型则为 redis 对象(redisObject)。Redis 对象可以绑定各种类型

    2023-03-13
    161
  • [MySQL]MySQL8.0的一些注意事项以及解决方案[通俗易懂]

    [MySQL]MySQL8.0的一些注意事项以及解决方案[通俗易懂]MySQL8.0 注意事项以及解决方案 1. MySQL8.0 修改大小写敏感配置 天坑MySQL8.0! 在安装后, 便无法通过修改配置文件,重启服务,或者执行sql来更改数据库配置, 要想配置的话

    2023-05-10
    145
  • Redis 集群演进探讨和总结「建议收藏」

    Redis 集群演进探讨和总结「建议收藏」Redis为什么需要集群? 首先Redis单实例主要有单点,容量有限,流量压力上限的问题。 Redis单点故障,可以通过主从复制 ,和自动故障转移 哨兵机制。 但Redis单 实例提供读写服务,仍然有

    2023-03-03
    145
  • Python连接字符串

    Python连接字符串在Python编程中,字符串是不可或缺的基本数据类型之一。然而,在实际应用中,我们经常需要将多个字符串拼接在一起,成为一个新的字符串。这个过程称为字符串连接(string concatenation)。Python提供了多种方法来连接字符串,本文将一一介绍。

    2024-04-21
    73
  • 数据结构第六章树和二叉树自测题答案_数据结构第三章答案

    数据结构第六章树和二叉树自测题答案_数据结构第三章答案树和森林 这篇博客继续我们的《数据结构导论》课程,今天重点说说树和森林怎么备考自考和通过期末考试。 在开始之前,上篇博客最后其实还有一点没有写完,就是如何通过已知序列,恢复一棵二叉树 看例题吧 假设一

    2023-01-22
    157
  • Python工程师——cat函数核心使用技巧

    Python工程师——cat函数核心使用技巧在编程中,常常需要读取文件内容,并将其打印到终端或者进行其他操作。对于Linux和Unix操作系统中的开发人员来说,cat函数是一个非常常用的命令。在Python中,也有对应的cat函数可以使用,本文将介绍cat函数的核心使用技巧。

    2024-06-15
    48
  • Oracle快速入门_day01

    Oracle快速入门_day01技术背景: 公司目前项目使用到了Oracle数据库 本人之前接触不多 计划4天 将Oracle数据库 快速入门 并结合开发使用,Oracle与MySql语法相似度很高,要一起学的小伙伴压力不要太大 …

    2023-02-28
    145
  • Python中的Dictionary.items()方法简介

    Python中的Dictionary.items()方法简介在Python中,字典(dictionary)是一种非常有用的数据类型,它也被称为哈希表或关联数组。字典由一些键(key)和与其对应的值(value)组成。在Python中,字典是无序的(key-value不一定按照添加顺序排列),可变的(dict支持增、删、改、查的操作),同时也是可迭代的(iterable)对象。

    2024-04-11
    92

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注