编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

MySQL存储引擎(mysql存储引擎实现原理)

wxchong 2025-03-25 18:25:52 开源技术 9 ℃ 0 评论

前几天看到了一篇关于MySql的文章,满满的干货。原文很长,现摘出对于存储引擎介绍,能认真读完的话受益匪浅。包括以下几部分

1. 存储引擎概述
2. InnoDB 和 MyIsam 对比
3. InnoDB 简介

01 存储引擎概述

存储引擎是 MySQL 中具体与文件打交道的子系统,它是根据 MySQL AB 公司提供的文件访问层抽象接口定制的一种文件访问机制,这种机制就叫作存储引擎,下面是一些常用的存储引擎,有远古时期的 MyISAM、支持事务的 InnoDB、内存类型的 Memory、归档类型的 Archive、列式存储的 Infobright,以及一些新兴的存储引擎,以 RocksDB 为底层基础的 MyRocks 和 RocksDB,和以分形树索引组织存储的 TokuDB,当然现在还有极数云舟出品的分布式存储引擎 ArkDB,如下图所示。


在 MySQL 5.6 版本之前,默认的存储引擎都是 MyISAM,但 5.6 版本以后默认的存储引擎就是 InnoDB 了。

InnoDB 存储引擎的具体架构如下图所示。上半部分是实例层(计算层),位于内存中,下半部分是物理层,位于文件系统中。

  • 实例层
  • 我们先来看实例层。实例层分为线程和内存。InnoDB 重要的线程有 Master Thread,Master Thread 是 InnoDB 的主线程,负责调度其他各线程。

    Master Thread 的优先级最高, 其内部包含几个循环:主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop)。Master Thread 会根据其内部运行的相关状态在各循环间进行切换。

    大部分操作在主循环(loop)中完成,其包含 1s 和 10s 两种操作。

  • 1s 操作主要包括如下。
  • 日志缓冲刷新到磁盘(这个操作总是被执行,即使事务还没有提交)。
  • 最多可能刷 100 个新脏页到磁盘。
  • 执行并改变缓冲的操作。
  • 若当前没有用户活动,可能切换到后台循环(background loop)等。

  • 10s 操作主要包括如下。
  • 最多可能刷新 100 个脏页到磁盘。
  • 合并至多 5 个被改变的缓冲(总是)。
  • 日志缓冲刷新到磁盘(总是)。
  • 删除无用的 Undo 页(总是)。
  • 刷新 100 个或者 10 个脏页到磁盘(总是)产生一个检查点(总是)等。
  • buf_dump_thread 负责将 buffer pool 中的内容 dump 到物理文件中,以便再次启动 MySQL 时,可以快速加热数据。
  • page_cleaner_thread 负责将 buffer pool 中的脏页刷新到磁盘,在 5.6 版本之前没有这个线程,刷新操作都是由主线程完成的,所以在刷新脏页时会非常影响 MySQL 的处理能力,在5.7 版本之后可以通过参数设置开启多个 page_cleaner_thread。
  • purge_thread 负责将不再使用的 Undo 日志进行回收。
  • read_thread 处理用户的读请求,并负责将数据页从磁盘上读取出来,可以通过参数设置线程数量。
  • write_thread 负责将数据页从缓冲区写入磁盘,也可以通过参数设置线程数量,page_cleaner 线程发起刷脏页操作后 write_thread 就开始工作了。
  • redo_log_thread 负责把日志缓冲中的内容刷新到 Redo log 文件中。
  • insert_buffer_thread 负责把 Insert Buffer 中的内容刷新到磁盘。实例层的内存部分主要包含 InnoDB Buffer Pool,这里包含 InnoDB 最重要的缓存内容。数据和索引页、undo 页、insert buffer 页、自适应 Hash 索引页、数据字典页和锁信息等。additional memory pool 后续已不再使用。Redo buffer 里存储数据修改所产生的 Redo log。double write buffer 是 double write 所需的 buffer,主要解决由于宕机引起的物理写入操作中断,数据页不完整的问题。

  • 物理层
  • 下面我们来看看物理层,物理层在逻辑上分为系统表空间、用户表空间和 Redo日志。

    系统表空间里有 ibdata 文件和一些 Undo,ibdata 文件里有 insert buffer 段、double write段、回滚段、索引段、数据字典段和 Undo 信息段。

    用户表空间是指以 .ibd 为后缀的文件,文件中包含 insert buffer 的 bitmap 页、叶子页(这里存储真正的用户数据)、非叶子页。InnoDB 表是索引组织表,采用 B+ 树组织存储,数据都存储在叶子节点中,分支节点(即非叶子页)存储索引分支查找的数据值。

    Redo 日志中包括多个 Redo 文件,这些文件循环使用,当达到一定存储阈值时会触发checkpoint 刷脏页操作,同时也会在 MySQL 实例异常宕机后重启,InnoDB 表数据自动还原恢复过程中使用。


  • 内存和物理结构
  • 上面我们介绍了 MySQL InnoDB 存储引擎的具体架构,下面重点讲解内存和物理结构,如下图所示。

    用户读取或者写入的最新数据都存储在 Buffer Pool 中,如果 Buffer Pool 中没有找到则会读取物理文件进行查找,之后存储到 Buffer Pool 中并返回给 MySQL Server。Buffer Pool 采用LRU 机制,具体的内存队列和刷新机制建议你课后学习了解下,这里不详细讲述。

    Buffer Pool 决定了一个 SQL 执行的速度快慢,如果查询结果页都在内存中则返回结果速度很快,否则会产生物理读(磁盘读),返回结果时间变长,性能远不如存储在内存中。但我们又不能将所有数据页都存储到 Buffer Pool 中,比如物理 ibd 文件有 500GB,我们的机器不可能配置能容得下 500GB 数据页的内存,因为这样做成本很高而且也没必要。在单机单实例情况下,我们可以配置 Buffer Pool 为物理内存的 60%~80%,剩余内存用于 session 产生的 sort 和 join 等,以及运维管理使用。如果是单机多实例,所有实例的buffer pool总量也不要超过物理内存的80%。开始时我们可以根据经验设置一个 Buffer Pool 的经验值,比如 16GB,之后业务在 MySQL 运行一段时间后可以根据 show global status like '%buffer_pool_wait%' 的值来看是否需要调整 Buffer Pool 的大小。

    Redo log 是一个循环复用的文件集,负责记录 InnoDB 中所有对 Buffer Pool的物理修改日志,当 Redo log文件空间中,检查点位置的 LSN 和最新写入的 LSN 差值(checkpoint_age)达到 Redo log 文件总空间的 75% 后,InnoDB 会进行异步刷新操作,直到降至 75% 以下,并释放 Redo log 的空间;当 checkpoint_age 达到文件总量大小的 90% 后,会触发同步刷新,此时 InnoDB 处于挂起状态无法操作。

    这样我们就看到 Redo log 的大小直接影响了数据库的处理能力,如果设置太小会导致强行 checkpoint 操作频繁刷新脏页,那我们就需要将 Redo log 设置的大一些,5.6 版本之前 Redo log 总大小不能超过 3.8GB,5.7 版本之后放开了这个限制。那既然太小影响性能,是不是设置得越大越好呢,这个问题留给你课后自己思考。

    事务提交时 log buffer 会刷新到 Redo log 文件中,具体刷新机制由参数控制,你可以课后学习并根据自身业务特点进行配置。

    若参数 innodb_file_per_table=ON,则表示用户建表时采用用户独立表空间,即一个表对应一组物理文件,.frm 表定义文件和 .ibd 表数据文件。

    当然若这个参数设置为 OFF,则表示用户建表存储在 ibdata 文件中,不建议采用共享表空间,这样会导致 ibdata 文件过大,而且当表删除后空间无法回收。独立表空间可以在用户删除大量数据后回收物理空间,执行一个 DDL 就可以将表空间的高水位降下来了。


    02 InnoDB 和 MyISAM

    这里对比几个主流的存储引擎,如下图所示。从图中可以详细看到 InnoDB 和 MyISAM 的对比。

    接下来重点在功能和性能上对比 InnoDB 和 MyISAM。


  • 功能对比
  • InnoDB 和 MyISAM 的功能对比如下图所示。

  • InnoDB 支持 ACID 的事务 4 个特性,而 MyISAM 不支持;
  • InnoDB 支持 4 种事务隔离级别,默认是可重复读 Repeatable Read 的,MyISAM 不支持;
  • InnoDB 支持 crash 安全恢复,MyISAM 不支持;
  • InnoDB 支持外键,MyISAM 不支持;
  • InnoDB 支持行级别的锁粒度,MyISAM 不支持,只支持表级别的锁粒度;
  • InnoDB 支持 MVCC,MyISAM 不支持;

  • InnoDB 表最大还可以支持 64TB,支持聚簇索引、支持压缩数据存储,支持数据加密,支持查询/索引/数据高速缓存,支持自适应hash索引、空间索引,支持热备份和恢复等,如下图所示。

    03 InnoDB 存储引擎

  • 核心特性
  • InnoDB 存储引擎的核心特性包括:MVCC、锁、锁算法和分类、事务、表空间和数据页、内存线程以及状态查询。其中锁和事务会在下一节课时讲解。本课时我们已经学习了 InnoDB 的表空间和实例等。思维导图如下所示,由于时间有限有些内容不能展开讲,建议你课下多下功夫重点研究。


    ARIES 三原则

    ARIES 三原则,是指 Write Ahead Logging(WAL)。

    1. 先写日志后写磁盘,日志成功写入后事务就不会丢失,后续由 checkpoint 机制来保证磁盘物理文件与 Redo 日志达到一致性;
    2. 利用 Redo 记录变更后的数据,即 Redo 记录事务数据变更后的值;
    3. 利用 Undo 记录变更前的数据,即 Undo 记录事务数据变更前的值,用于回滚和其他事务多版本读。

    show engine innodb status\G 的结果里面有详细的 InnoDB 运行态信息,分段记录的,包括内存、线程、信号、锁、事务等,请你多多使用,出现问题时从中能分析出具体原因和解决方案。


    04 总结回顾

    现在回顾本课时学习的内容。我们学习了 MySQL 数据库的体系结构,SQL 的执行流程,存储引擎和分类,重点讲解了 InnoDB 存储引擎的体系结构、特性,对比了 InnoDB 和 MyISAM存储引擎的功能和性能,在各方面 InnoDB 都完胜 MyISAM,InnoDB 也是 MySQL 今后重点发力的地方,很多地方都默认采用 InnoDB 进行存储,还有 InnoDB 引擎内部的组成和各版本对比,如下图所示。

    公众号:看起来很美(kanqilaihenmei_)

    Tags:

    本文暂时没有评论,来添加一个吧(●'◡'●)

    欢迎 发表评论:

    最近发表
    标签列表