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

本文深入探讨了MySQL的内部结构,包括内存结构中的缓冲池、变更缓冲区和日志缓冲,以及硬盘结构如表空间、系统表空间等。详细阐述了SQL执行过程,特别是UPDATE操作,涉及InnoDB架构和redo log的作用。文章还介绍了索引的类型和作用,以及事务隔离级别的实现,特别是如何解决幻读问题。最后,讨论了锁的实现和死锁预防,以及MySQL的优化策略,包括连接池、第三方缓存和数据库集群设计。
摘要由CSDN通过智能技术生成

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

image.png

  • (这里提供一下官方对各存储引擎的文档说明 Mysql存储引擎)

一条 update SQL执行

update的执行 从客户端 => ··· => 执行引擎 是一样的流程,都要先查到这条数据,然后再去更新。要想理解 UPDATE 流程我们先来看看,Innodb的架构模型。

Innodb 架构

上一张 MYSQL 官方InnoDB架构图:

image.png

内存结构

这里有个关键点,当我们去查询数据时候会先 拿着我们当前查询的 夜 去 缓冲池 中查询 当前页是否在缓冲池中。如果在,则直接获取。

当是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的顺序读取的特性造成的,必须是连续的存储空间

二、随机读写与顺序读写

看一张图

image.png

一般我们的数据都是分散在磁盘上的: 机械硬盘:

  1. 定位到磁道
  2. 等待旋转到对应扇区
  3. 开始读写

固态;

  1. 直接定位到闪存芯片(这也是为啥固态比机械快)
  2. 开始读写

而我们去存储时,是通过文件系统与磁盘打交道的,而他们打交道的方式就有两个。随机读写和顺序读写

  1. 随机读写存储的数据是分布在不同的 块(默认 1block=8扇区=4K)
  2. 而顺序存储,顾名思义,数据是分布在一串连续的块中,这样读取速度就大大提升了

三、回到我们架构图

image.png

看到buffer pool中的Log Buffer,其就是用来写 redo log 之前存在的缓冲区

在这里,redo log具体的执行策略有三种:

  1. 不用写Log Buffer,只需要每秒写redo log 磁盘数据一次,性能高,但会造成数据 1s 内的一致性问题。适用于强实时性,弱一致性,比如评论区评论
  2. 写Log Buffer,同时写入磁盘,性能最差,一致性最高。 适用于弱实时性,强一致性,比如支付场景
  3. 写Log Buffer,同时写到os buffer(其会每秒调用 fsync 将数据刷入磁盘),性能好,安全性也高。这个是实时性适中 一致性适中的,比如订单类。

我们通过innodb_flush_log_at_trx_commit就可以设置执行策略。默认为 1

内存结构小结

image.png

  1. Buffer Pool 用于加速读
  2. Change Buffer 用于没有非唯一索引的加速写
  3. Log Buffer 用于加速redo log写
  4. 自适应Hash索引主要用于加快查询 页。在查询时,Innodb通过监视索引搜索的机制来判断当前查询是否能走Hash索引。比如LIKE运算符和% 通配符就不能走。

硬盘结构

一、System Tablespace

存储在一个叫ibdata1的文件中,其中包含:

  1. InnoDB Data Dictionary,存储了元数据,比如表结构信息、索引等
  2. Doublewrite Buffer 当Buffer Pool写入数据页时,不是直接写入到文件,
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值