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

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

旅途过程:

  1. 首先 insert 进入 server 层后,会进行一些必要的检查,检查的过程中并不会涉及到磁盘的写入。

  2. 检查没有问题之后,便进入引擎层开始正式的提交。我们知道 InnoDB 会将数据页缓存至内存中的 buffer pool,所以 insert 语句到了这里并不需要立刻将数据写入磁盘文件中,只需要修改 buffer pool 当中对应的数据页就可以了。

  • buffer pool 中的数据页刷盘并不需要在事务提交前完成,其中的交互过程我们会在下一张图中分解。

但仅仅写入内存的 buffer pool 并不能保证数据的持久化,如果 MySQL 宕机重启了,需要保证 insert 的数据不会丢失。redo log 因此而生,当 innodb_flush_log_at_trx_commit=1 时,每次事务提交都会触发一次 redo log 刷盘。(redo log 是顺序写入,相比直接修改数据文件,redo 的磁盘写入效率更加高效)

如果开启了 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: 事务提交后的数据文件写入

旅途过程:

  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 直接刷盘

    1. 关闭 double write

    2. 不需要 double write 保障,如 drop table 等操作

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

insert 语句_[原理解析] MySQL insert语句的磁盘写入之旅相关推荐

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

    作者及简介: 黄 炎,爱可生首席技术官: 王 悦,爱可生研发团队成员,负责数据库管理平台相关项目的开发和故障排查,好奇 MySQL 技术原理及各类数据库实现方案. 本文来源:转载自公众号-图解 MyS ...

  2. select计数语句_从零开始学 MySQL SELECT 语句详解

    阅读本文大概需要 7 分钟 前言上篇文章我们学习了 MySQL 的五种约束,今天这篇文章我们来学习下 SELECT 语句.在数据库操作语句中,使用最频繁,也被认为最重要的是 SELECT 查询语句.在 ...

  3. mysql新增列并同时增加数据_图解MySQL | [原理解析] MySQL 为表添加列 是怎么quot;立刻quot;完成的...

    在上一期图解 图解MySQL | MySQL DDL为什么成本高?中,我们介绍了: 传统情况下,为表添加列需要对表进行重建 腾讯团队为 MySQL 引入了 Instant Add Column 的方案 ...

  4. mysql新增字段位置_图解MySQL | [原理解析] MySQL 为表添加列 是怎么quot;立刻quot;完成的...

    在上一期图解 图解MySQL | MySQL DDL为什么成本高?中,我们介绍了: 传统情况下,为表添加列需要对表进行重建 腾讯团队为 MySQL 引入了 Instant Add Column 的方案 ...

  5. mysql 查询和修改组合_## 超详细MySQL常用语句,增删查改

    ## MySQL常用语句,增删查改,安装配置mysql服务 ***#新手博客,应届生,谢谢支持哟 记得点赞关注哟*** ***-----sql常见命令:--------*** 安装服务:mysqld ...

  6. asscess 一条记录更新数据_一条MySQL更新语句是怎么执行的?

    流程图 这是在网上找到的一张流程图,写的比较好,大家可以先看图,然后看详细阅读下面的各个步骤. 执行流程: 1.连接验证及解析 客户端与MySQL Server建立连接,发送语句给MySQL Serv ...

  7. mysql使索引失效语句_会导致索引失效语句

    1.使用like关键字模糊查询时,% 放在前面索引不起作用,只有"%"不在第一个位置,索引才会生效(like '%文'–索引不起作用) 2.使用联合索引时,只有查询条件中使用了这些 ...

  8. mysql插入长字符串_求助! php mysql insert 长字符串不能插入问题.

    语句是这样的: $sql = "INSERT INTO `{$table->column_list_page}` set nID='{$_REQUEST['NodeID']}',Tit ...

  9. mysql 的dcl语句_详解MySQL第三篇—DCL语句

    DCL(Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句.这些语句定义了数据库.表.字段.用户的访问权限和安全级别.主要的语句关键字包括 g ...

最新文章

  1. 配置SSH是出现: sign_and_send_pubkey: signing failed: agent refused operation Permission denied
  2. 三维点云课程第一章:应用
  3. AC日记——传染病控制 洛谷 P1041
  4. 深圳大学计算机暑期学校,The First Day-深度学习暑期学校
  5. 转载:Java 内存区域和GC机制
  6. 使用logrotate做nginx日志分割
  7. tensorflow从入门到放弃(二)
  8. 动态分享到微信朋友圈的方法,果断收藏——(摘抄至他人)
  9. cat /etc/redhat-release 查看centos版本
  10. css3中的transform中的3d变换:translatez()与transform-origin-z()的区别
  11. day16——oracle灾备2
  12. 并行计算圆周率 c语言,并行计算:圆周率计算
  13. BackdoorBench
  14. HDOJ 1025 DP
  15. 合成孔径雷达(微波遥感)的应用
  16. QT小项目练手——用QTimer做一个倒计时程序
  17. 我对于部门经理、项目经理与技术经理的理解
  18. Python解释器及IDLE的使用
  19. 原生JavaScript实现AJAX、JSONP
  20. Dynamics Ax 微软官方社区地址

热门文章

  1. 如何使用小的显存训练大的batch_size
  2. 代码荣辱观-以运用风格为荣,以随意编码为耻
  3. Quartz之入门实例
  4. Fiddler抓取数据并分析(完整的配置教程)
  5. Carring data across redirect requests
  6. Linux下的摄影后期处理软件
  7. Testing tools
  8. Apache防止DDOS***的模块--mod_evasive
  9. Spark快速上手-WordCount案例
  10. matplotlib画图中文显示