跳过正文
  1. 全部/
  2. 笔记/
  3. 面试/
  4. 数据库/
  5. MySQL/

2 InnoDB 引擎

目录

事务,外键,行级锁

  • 连接层
  • 服务层
  • 引擎层:索引
  • 存储层

逻辑存储结构
#

MySQL 中每一张表的数据都存放在一个独立的 .ibd 文件。这个文件也称为独占表空间文件

表空间
#

  • 段:

    • 索引段:存放 B + 树的非叶子节点的区的集合;
    • 数据段:存放 B + 树的叶子节点的区的集合;
    • 回滚段:存放的是回滚数据的区的集合,MVCC 利用了回滚段实现了多版本查询数据。
  • 区:

    • B+ 树中每一层都是通过双向链表连接起来的,如果是以页为单位来分配存储空间,那么链表中相邻的两个页之间的物理位置并不是连续的,可能离得非常远,那么磁盘查询时就会有大量的随机I/O,随机 I/O 是非常慢的。
    • 在表中数据量大的时候,为某个索引分配空间的时候就不再按照页为单位分配了,而是按照区(extent)为单位分配。每个区的大小为 1MB,对于 16KB 的页来说,连续的 64 个页会被划为一个区,这样就使得链表中相邻的页的物理位置也相邻,就能使用顺序 I/O 了。
  • 页:16k,IO的最小单位,表中的记录存储在「数据页」里面

  • 行:

    • COMPACT 行格式
      Pasted image 20260319145618.png

    1. 变长字段长度列表
    #

    变长字段的真实数据占用的字节数会按照列的顺序逆序存放

    2. NULL 值列表
    #

    如果存在允许 NULL 值的列,则每个列对应一个二进制位(bit),二进制位按照列的顺序逆序排列。

    3. 记录头信息
    #

    • delete_mask :标识此条数据是否被删除。从这里可以知道,我们执行 detele 删除记录的时候,并不会真正的删除记录,只是将这个记录的 delete_mask 标记为 1。
    • next_record:下一条记录的位置。从这里可以知道,记录与记录之间是通过链表组织的。在前面我也提到了,指向的是下一条记录的「记录头信息」和「真实数据」之间的位置,这样的好处是向左读就是记录头信息,向右读就是真实数据,比较方便。
    • record_type:表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录

    4. 隐藏字段
    #

    • row_id:6B,没有主键或唯一约束的情况下
    • trx_id:事务id
    • roll_pointer:上版本指针

Compact 行格式针对行溢出的处理是这样的:当发生行溢出时,在记录的真实数据处只会保存该列的一部分数据,而把剩余的数据放在「溢出页」中,然后真实数据处用 20 字节存储指向溢出页的地址,从而可以找到剩余数据所在的页。

架构
#

内存结构
#

缓冲池(Buffer Pool): - 当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。 - 当修改数据时,如果数据存在于 Buffer Pool 中,那直接修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页(该页的内存数据和磁盘上的数据已经不一致),为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。

  1. Free List (空闲页链表),管理空闲页
  2. Flush List (脏页链表),管理脏页
  3. LRU List,管理脏页+干净页,将最近且经常查询的数据缓存在其中,而不常查询的数据就淘汰出去。;将 LRU 链表 分为young 和 old 两个区域,加入缓冲池的页,优先插入 old 区域;页被访问时,才进入 young 区域,目的是为了解决预读失效的问题。

更改缓冲区(Change Buffer):加快插入 自适应哈希索引:加快查找 Log Buffer:日志缓冲区的日志会定期刷新到磁盘中

磁盘架构
#

  1. 系统表空间
  2. 数据表空间(.idb)
  3. 通用表空间
  4. Undo Log
  5. Redo Log
  6. 临时表空间
  7. 双写缓冲区
  • db.opt,用来存储当前数据库的默认字符集和字符校验规则。
  • t_order.frm ,t_order 的表结构会保存在这个文件。在 MySQL 中建立一张表都会生成一个.frm 文件,该文件是用来保存每个表的元数据信息的,主要包含表结构定义。
  • t_order.ibd,t_order 的表数据会保存在这个文件。表数据既可以存在共享表空间文件(文件名:ibdata1)里,也可以存放在独占表空间文件(文件名:表名字.ibd)。
Reply by Email