一、一条 SQL 执行过程
先看看一条查问 SQL
(这里提供一下官网对各存储引擎的文档阐明 Mysql 存储引擎)
一条 update SQL 执行
update 的执行 从客户端 => ··· => 执行引擎 是一样的流程,都要先查到这条数据,而后再去更新。要想了解 UPDATE 流程咱们先来看看,Innodb 的架构模型。
Innodb 架构
上一张 MYSQL 官网 InnoDB 架构图:
外部模块
连接器(JDBC、ODBC 等) =>
[MYSQL 外部
[Connection Pool] (受权、线程复用、连贯限度、内存检测等)
=>
[SQL Interface] (DML、DDL、Views 等) [Parser] (Query Translation、Object privilege) [Optimizer] (Access Paths、统计分析) [Caches & Buffers]
=>
[Pluggable Storage Engines]
=> [File]
二、内存构造
这里有个关键点,当咱们去查问数据时候会先 拿着咱们以后查问的 page 去 buffer pool 中查问 以后 page 是否在缓冲池中。如果在,则间接获取。
而如果是 update 操作时,则会间接批改 Buffer 中的值。这个时候,buffer pool 中的数据就和咱们磁盘中理论存储的数据不统一了,称为脏页。每隔一段时间,Innodb 存储引擎就会把脏页数据刷入磁盘。一般来说当更新一条数据,咱们须要将数据给读取到 buffer 中批改,而后写回磁盘,实现一次 落盘 IO 操作。
为了进步 update 的操作性能,Mysql 在内存中做了优化,能够看到,在架构图的缓冲池中有一块区域叫做:change buffer。顾名思义,给 change 后的数据,做 buffer 的,当更新一个没有 unique index 的数据时,间接将批改的数据放到 change buffer,而后通过 merge 操作实现更新,从而缩小了那一次 落盘的 IO 操作。
- 咱们下面说的有个条件:没有惟一索引的数据更新时,为什么必须要没有惟一索引的数据更新时能力间接放入 changebuffer 呢?如果是有惟一束缚的字段,咱们在更新数据后,可能更新的数据和曾经存在的数据有反复,所以只能从磁盘中把所有数据读出来比对能力确定唯一性。
- 所以当咱们的数据是 写多读少 的时候,就能够通过 减少 innodb_change_buffer_max_size 来调整 change
buffer 在 buffer pool 中所占的比例,默认 25(即:25%)
问题又来了,merge 是如何运作的
有四种状况:
- 有其余拜访,拜访到了当前页的数据,就会合并到磁盘
- 后盾线程定时 merge
- 零碎失常 shut down 之前,merge 一次
- redo log 写满的时候,merge 到磁盘
学习材料视频收费获取,学习直通车。