一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群

MySQL内部模块连接器(JDBC、ODBC等) =>
[MYSQL 内部
[Connection Pool] (授权、线程复用、连接限制、内存检测等)=>[SQL Interface] (DML、DDL、Views等) [Parser] (Query Translation、Object privilege) [Optimizer] (Access Paths、 统计分析) [Caches & Buffers]=>[Pluggable Storage Engines]复制代码]
=> [File]
一条SQL执行过程先看看一条查询SQL 

一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群

文章插图
 
  • (这里提供一下官方对各存储引擎的文档说明 Mysql存储引擎)
一条 update SQL执行update的执行 从客户端 => ··· => 执行引擎 是一样的流程,都要先查到这条数据,然后再去更新 。要想理解 UPDATE 流程我们先来看看,Innodb的架构模型 。
Innodb 架构上一张 MYSQL 官方InnoDB架构图:
一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群

文章插图
 
内存结构这里有个关键点,当我们去查询数据时候会先 拿着我们当前查询的 夜 去 缓冲池 中查询 当前页是否在缓冲池中 。如果在,则直接获取 。
当是update时,则会直接修改 Buffer中的值 。这个时候,缓冲池中的数据就和磁盘中存储的数据不一致了,称为网页 。每隔一段时间,Innodb存储引擎就会把脏页数据刷入磁盘 。
一般来说当更新一条数据,我们需要将数据给读取到buffer中修改,然后写回磁盘,其中有一次 IO 操作 。
图中缓冲池中有一块区域叫做:change buffer 。当更新一个没有 unique index 的数据时,直接将修改的数据放到 change buffer,然后通过 merge 操作完成更新,从而减少了 IO 操作 。
  • 为什么要没有唯一索引的数据更新时才能这样呢,因为我们更新数据后,可能更新后的数据和已经存在的数据有重复,所以必须从磁盘中把所有数据读出来比对才行 。
  • 所以当我们的数据是 写多读少 的时候,就可以通过 增加 innodb_change_buffer_max_size 来调整 change buffer在buffer pool 中所占的比例,默认25(即:25%)
问题又来了,merge是如何运作的有四种情况:
  1. 有其他访问,访问到了当前页的数据,就会合并到磁盘
  2. 后台线程定时
  3. 系统正常shut down之前
  4. redo log写满的时候
一、redo log是什么谈到redo,就要谈到innodb的 crash safe,使用 WAL 的方式实现(write Ahead Logging,在写之前先记录日志)
这样就可以在,当数据库崩溃的后,直接从 redo log中恢复数据,保证数据的正确性
  • redo log 默认存储在两个文件中 ib_logfile0 ib_logfile1,这两个文件都是固定大小的 。为什么需要固定大小?这是因为redo log的顺序读取的特性造成的,必须是连续的存储空间
二、随机读写与顺序读写看一张图
一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群

文章插图
 
一般我们的数据都是分散在磁盘上的: 机械硬盘:
  1. 定位到磁道
  2. 等待旋转到对应扇区
  3. 开始读写
固态;
  1. 直接定位到闪存芯片(这也是为啥固态比机械快)
  2. 开始读写
而我们去存储时,是通过文件系统与磁盘打交道的,而他们打交道的方式就有两个 。随机读写和顺序读写
  1. 随机读写存储的数据是分布在不同的 块(默认 1block=8扇区=4K)
  2. 而顺序存储,顾名思义,数据是分布在一串连续的块中,这样读取速度就大大提升了
三、回到我们架构图 
一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群

文章插图
 
看到buffer pool中的Log Buffer,其就是用来写 redo log 之前存在的缓冲区
在这里,redo log具体的执行策略有三种:
  1. 不用写Log Buffer,只需要每秒写redo log 磁盘数据一次,性能高,但会造成数据 1s 内的一致性问题 。适用于强实时性,弱一致性,比如评论区评论
  2. 写Log Buffer,同时写入磁盘,性能最差,一致性最高 。适用于弱实时性,强一致性,比如支付场景
  3. 写Log Buffer,同时写到os buffer(其会每秒调用 fsync 将数据刷入磁盘),性能好,安全性也高 。这个是实时性适中 一致性适中的,比如订单类 。
【一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群】我们通过innodb_flush_log_at_trx_commit就可以设置执行策略 。默认为 1
内存结构小结 
一文让你搞懂MYSQL底层原理。-内部结构、索引、锁、集群


推荐阅读