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

作者及简介:

黄 炎,爱可生首席技术官;

王 悦,爱可生研发团队成员,负责数据库管理平台相关项目的开发和故障排查,好奇 MySQL 技术原理及各类数据库实现方案。

本文来源:转载自公众号-图解 MySQL

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

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

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

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

检查没有问题之后,便进入引擎层开始正式的提交。我们知道 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:事务提交后的数据文件写入

旅途过程:当 buffer pool 中的数据页达到一定量的脏页或 InnoDB 的 IO 压力较小 时,都会触发脏页的刷盘操作。

当开启 double write 时,InnoDB 刷脏页时首先会复制一份刷入 double write,在这个过程中,由于double write的页是连续的,对磁盘的写入也是顺序操作,性能消耗不大。

无论是否经过 double write,脏页最终还是需要刷入表空间的数据文件。刷入完成后才能释放 buffer pool 当中的空间。

insert buffer 也是 buffer pool 中的一部分,当 buffer pool 空间不足需要交换出部分脏页时,有可能将 insert buffer 的数据页换出,刷入共享表空间中的 insert buffer 数据文件中。

当 innodb_stats_persistent=ON 时,SQL 语句所涉及到的 InnoDB 统计信息也会被刷盘到 innodb_table_stats 和 innodb_index_stats 这两张系统表中,这样就不用每次再实时计算了。

有一些情况下可以不经过 double write 直接刷盘关闭 double write

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

监控mysql主从复制监控_shell脚本监控mysql主从同步状态

mysql做了主从同步之后,偶尔出现过几次主从同步报错或延迟,由于没有任何监控和报警机制,只有在应用程序报错的时候才能发现数据同步出问题了。所以写了个shell脚本用来检测mysql数据库的同步状态#!/bin/bash#monitor_mysql_slave statusUSERN…

apscheduler mysql_APScheduler (重点)

定时校正需求: mysql和redis两个系统, mysql增加数据成功, redis未必添加成功, 这样两个系统的数据可能出现偏差, 所以需要定期对mysql和redis的数据进行同步解决方案: 每天执行一次定时任务, 让mysql数据和redis数据进行同步crontab是linux系统一个内置命令, 依赖于linux系统,…

qpsk 锁相环_本科毕业设计课题—QPSK相干解调的MATLAB仿真(4)

继续看参考资料!现在常用的数字调制方式有二相移相键控(BPSK)、正交移相键控(QPSK)、偏移四项移相键控(OQPSK)、最小移频键控(MSK)等。它们具有相同的功率效率。BPSK 频谱利用率差,抗非线性能力差,实现简单;QPSK频谱利用率好&…

c语言程序后退_c语言中向后退一格是啥符号?

展开全部是 \b,也就是backspace,这是一个转义32313133353236313431303231363533e4b893e5b19e31333337393466字符,详解如下:所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示…

mysql数据库行业应用_腾讯云发布MySQL 8.0数据库 可应用至更多行业场景

7月8日,腾讯云正式发布了MySQL 8.0数据库。据悉,该数据库相比MySQL官方版本,无论是单机模式、异步模式还是同步模式下,读写性能都取得了大幅提升。据腾讯云数据库相关负责人介绍,采用MySQL 8.0内核的实例最高QPS(每秒查…

中控ecs700 mysql_浙大中控ECS700工程指导手册.pdf

浙大中控ECS700工程指导手册VisualFieldWARNING: Indicates information that a potentially hazardous situation which, if not avoided,could result in serious injury or death.Risk of electrical shock: Indicates information that Potential shock hazard whereHAZARD…

postgresql是如何求年龄的_Postgresql 通过出生日期获取年龄的操作

三个基础的时间表示函数 current_date/current_time/now()select current_date ;返回当前日期以 年-月-日(yyyy-mm-dd)的形式:2019-01-10select current_time;返回当日时间以 时:分:秒时区(hh:mm:ss )的形式:17:49:11.58530808select now();返回当前时间…

python关闭浏览器删除session_Django操作session 的方法

session是存放在服务端的,在django中使用session必须要先在数据库中创建django_session表,session相关信息都要依赖此表获取sessionrequest.session[status]request.session.get(status)#一般用get,无此键返回None不报错设置session#在使用se…

python压缩文件不带根路径_python 压缩文件(解决压缩路径问题)

#压缩文件def Zip_files(): datapath filepath# 证据路径file_newname datapath .zip# 压缩文件的名字log.debug(file_newname) z zipfile.ZipFile(file_newname,w,zipfile.ZIP_DEFLATED) for dirpath,dirmanes,filenames in os.walk(datapath): fpath dirpath.replace(da…

python网页保存为图片_使用Python保存网页上的图片或者保存页面为截图

Python保存网页图片这个是个比较简单的例子,网页中的图片地址都是使用http://。。。。.jpg这种方式直接定义的。使用前,可以先建立好一个文件夹用于保存图片,本例子中使用的文件夹是 d:\\pythonPath这个文件夹代码如下:# -*- codi…

libnss mysql_Ubuntu通过LDAP集成AD域账号登录(libnss-ldap方式)

Ubuntu通过LDAP集成AD域账号登录(libnss-ldap方式):# apt-get install libnss-ldap (中间直接回车,忽略)# vi /etc/nsswitch.confpasswd: files ldapgroup: files ldapshadow: files ldap:wq# vi /etc/ldap.confbase dcming,dccomuri ldap://10.0.0.2…

mysql分页查询减轻压力_mysql分页查询优化

在实际的项目中,分页查询是在寻常不过的,甚至说不可避免的。通常数据量较少的时候,很难遇到效率的影响。但是当数据量较大时,一个普通的分页sql能让你恶心到家。我们常用的分页sql如下:1 SELECT * FROM table_name LIM…

python csv读写方法_python中csv文件的若干读写方法小结

如下所示: //用普通文本文件方式打开和操作with open("file.csv") as cf:linescf.readlines()...... //用普通文本方式打开,用csv模块操作import csvwith open("file.csv") as cf:linescsv.reader(cf)for line in lines:print(line)…

unity 世界坐标间角度_Unity 世界坐标局部坐标下的旋转

一、旋转方法在 Unity 中为物体旋转提供了各种 API ,例如 RotateAround、Rotate、LookAt 等方法。但为了避免万向节死锁的问题,一般使用四元数来表示物体的旋转。四元数的乘法可以看作对一个物体施加两次旋转,最终的旋转角度由这两次旋转的角…

删除mysql会不会留下痕迹_MySQL使用痕迹清理~/.mysql_history

mysql会给出咱们最近执行的SQL命令和脚本;同linux command保存在~/.bash_history同样,你用mysql链接MySQL server的全部操做也会被记录到~/.mysql_history文件中,这样就会有很大的安全风险了,如添加MySQL用户的sql也一样会被明文记…

ioc框架 java_从零开始实现一个简易的Java MVC框架(三)--实现IOC

Spring中的IOCIoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想。而DI(Dependency Injection),即依赖注入就是Ioc的一种实现方式。关于Ioc和DI的具体定义和优缺点…

java word文档生成目录_JAVA合并word文档生成目录

/*** 先临时生成一个合并完成后的docx格式文档,doc会出现乱码。*parampathList 所有需要合并的文档的绝对路径*paramsavePath 一个路径,但是没有文件的后缀,之后进行拼接。*return状态,是否保存成功*/public static boolean merge…

java 链表实现堆栈_《Java数据结构与算法》笔记-CH5-链表-4用链表实现堆栈

//用链表实现堆栈/*** 节点类*/class LinkS {private long data;public LinkS next;public LinkS(long d) {this.data d;}public String toString() {return String.valueOf(data);}}/*** 链表类*/class LinkSList {private LinkS first;public LinkSList() {first null;}pub…

java set去重复元素_java List去掉重复元素的几种方式

使用LinkedHashSet删除arraylist中的重复数据(有序)List words Arrays.asList("a","b","b","c","c","d");HashSet setnew LinkedHashSet<>(words);for(String word:set){System.out.println(word);}使用Has…

b树索引 java_B树索引最通俗易懂的介绍

先来一段有莫的对话&#xff1a;前几天下班回到家后正在处理一个白天没解决的bug&#xff0c;厕所突然传来对象的声音&#xff1a;对象&#xff1a;xx&#xff0c;你有《时间简史》吗&#xff1f;我&#xff1a;我去&#xff01;妹子&#xff0c;你这啥癖好啊&#xff0c;我有时…