MySQL学习笔记Ⅰ-存储引擎

  • 存储引擎

    • InnoDB: MySQL 8.0中的默认存储引擎。InnoDB是MySQL的事务安全(符合ACID)存储引擎,具有提交、回滚和崩溃恢复功能,以保护用户数据。InnoDB的行级锁(没有升级到更粗粒度的锁)和Oracle风格的一致无锁读取增加了多用户并发性和性能。InnoDB在集群索引中存储用户数据,以减少基于主键的普通查询的I/O。为了保持数据的完整性,InnoDB也支持FOREIGN KEY参考完整性约束。其表有两个文件:.frm、.idb。
    • MyISAM:表的占用空间小。表级锁限制了读/写工作负载的性能,所以它经常被用于网络和数据仓库配置中的只读或主要是读的工作负载。其表有三个文件:.frm、.MYD、.MYI。
    • Memory:将所有数据存储在RAM中,以便在需要快速查找非关键数据的环境中快速访问。这个引擎以前被称为HEAP引擎。它的使用情况越来越少;InnoDB及其缓冲池内存区提供了一种通用和持久的方式,将大部分或所有数据保存在内存中,而NDBCLUSTER为巨大的分布式数据集提供快速的键值查询
    • csv:它的表格实际上是带有逗号分隔值的文本文件。CSV表让你以CSV格式导入或转储数据,与读写相同格式的脚本和应用程序交换数据。因为CSV表没有索引,所以你通常在正常操作中把数据保存在InnoDB表中,而只在导入或导出阶段使用CSV表
    • Archive:紧凑的、无索引的表,用来存储和检索大量很少参考的历史、归档或安全审计信息。
    • Blackhole、NDB、Merge、Federated、Example

    MySQL体系结构总结

    模块详解

    • Connector:用来支持各种语言和SQL的交互,比如Java的JDBC。
    • Management Services & Utilities:系统管理和控制工具,包括备份恢复、MySQL复制,集群等
    • Connection Pool:连接池,管理需要缓冲的资源,包括用户密码权限线程等
    • SQL Interface:用来接收用户的SQL命令,返回用户需要的查询结果
    • Parse:用来解析SQL语句
    • Optimizer:查询优化器
    • Cache and Buffer:查询缓存,除了行记录的缓存之外还有表缓存,key缓存,权限缓存等
    • Pluggable Storage Engine:插件式存储引擎,提供API给服务层使用,跟具体的文件打交道

    架构分层

    执行操作的服务层,和存储管理数据的存储引擎层

    • 服务层:包括客户端与服务端的链接,查询缓存的判断,对SQL语句进行词法和语法的解析。然后是优化器,MySQL底层根据一定的规则对语句进行优化,最后交给执行器去执行。
    • 存储引擎:是数据真正存放的地方,再往下就是文件管理系统,内存或者磁盘。

    一条更新语句是如何执行的

    首先需要了解一下数据是如何在MySQL中存在的。

    1. 缓冲池 Buffer Pool

      对于InnoDB存储引擎来说,数据都是存储在磁盘上的,要操作数据必须先要将磁盘里的数据加载到内存中才行。这里很像操作系统的内存机制。

      InnoDB设定了一个最小单位,叫做页,默认大小为16KB,他是一个逻辑单位,修改该值的大小必须修改源码重新编译安装。

      InnoDB使用了一种缓冲池的技术,就是把磁盘读的页放到一块内存区域中,下次再次读取该页先判断是否在内存中。这个内存区域就是Buffer Pool。

      修改数据的时候,先修改缓冲池中的页,与磁盘不一致的时候称为脏页。InnoDB有一个专门的后台线程将数据写入到磁盘,每隔一段时间就一次性的将多个修改写入磁盘,这个动作称之为脏刷

    2. InnoDB的内存结构和磁盘结构

      内存结构里面主要是Buffer Pool、Change Buffer、Log Buffer、AHI

      • Buffer Pool:默认大小为128MB

      • (redo) Log Buffer:由上面脏刷操作可以知道数据刷新不是实时的,若在未刷入时系统发生宕机或者重启,数据就会丢失。故内存的数据必须要有一个持久化的措施。

        于是,InnoDB把所有对页面的修改操作专门写入一个日志文件,先写日志再写磁盘。如果有未同步到磁盘的数据,数据库在启动的时候,会从这个日志文件进行恢复操作(实现crash-safe)。事务中的ACID的D(持久性)就是用它实现的。

        这个日志文件就是redo log(重做日志),默认48M(大小固定),2个。是InnoDB独有的特性

        刷盘是随机I/O,而记录日志是顺序I/O(连续写的),顺序IO的效率更高,因此先把修改写入日志文件,在保证了内存数据的安全性的情况下,可以延迟刷盘时机,进而提升系统吞吐。

        还有一个有关的undo log,用于将数据从逻辑上恢复至事务之前的状态,属于逻辑结构的日志。

    3. 后台线程

      主要作用是负责刷新内存池中的数据和修改的数据页刷新到磁盘。分为master thread,IO thread、

      purge thread、page cleaner thread。除了InnoDB架构中的日志文件,MySQL的server层也有一个日志文件,佳作binlog,可以被所有的存储引擎使用。

    4. Binlog

      binlog以事件的形式记录了所有的DDL和DML语句,属于逻辑日志。可以用来做主从复制和数据恢复,和redo log不同,它的文件内容是可以追加的,没有固定大小限制。

      在开启binlog的情况下可以将其导出为SQL语句,把所有的操作重放一遍来实现数据的恢复。

    5. 更新过程

      image-20230105221615853

      总结重点:

      1. 先记录到内存(buffer pool),再写日志文件
      2. 记录redo log分为两个阶段:prepare 和 commit
      3. 存储引擎和server分别记录不同的日志
      4. 先记录redo在记录binlog

    作者: Meow Mii

    本文链接: https://blog.yiochin.top/p/99fbc96.html

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议,转载请注明出处!


    📝 Comment