08 - InnoDB Engine

08 - InnoDB 引擎

目前使用最广泛的数据库引擎

1. 逻辑存储结构

1.1. 表空间 tablespace...

ibd 文件 一个 mysql 实例对应多个表空间

用于存储记录,索引等数据

1.2. 段 segment

分为:

  • 数据段 Leaf node segment

  • 索引段 non-leaf node segment

  • 回滚段 rollback segment

数据段是 B+ Tree 的叶子节点

索引段是 非叶子节点

段用来管理多个 Extent

1.3. 区 extent

表空间的单元结构 每个区的大小为 1M 默认情况下,InnoDB 存储引擎页大小为 16K,即一个区中一共有 64 个连续的页

1.4. 页 page

是 InnoDB 存储引擎磁盘清理的最小单元,每个页的大小默认为 16 KB

为了保证 页的连续性 InnoDB每次申请磁盘的 4-5 个区

1.5. 行 row

InnoDB 存储引擎数据是按行进行存放的

2. 架构

擅长事务处理,具有崩溃恢复特性...

2.1. 内存架构

Buffer Pool 缓冲池是主内存的一个一区...

增删查改先改缓冲池...每隔一段短时间再刷新到磁盘(减少磁盘I/O 加快处理)

  • 缓冲池以 Page 为单位

Page 分为三类

  1. free page 空闲 page 未被使用

  2. clean page 被使用 page 数据没有被修改过

  3. dirty page 脏页 被使用的 page 数据被修改过,数据与磁盘中的不一致?

Change Buffer

更改缓冲区(非唯一的二级索引)如果这些数据不在 buffer pool 中,会先操作 change buffer...

未来会先变更 change buffer 再合并到 buffer pool 再刷新到 磁盘 IO

意义:与聚集索引不同,二级索引是非唯一的,相对随机的顺序插入二级索引...

删除和更新操作可能会影响索引书中不相邻的二级索引页...

自适应哈希

默认不支持 哈希索引,但是支持 B+ 索引

哈希索引查询速度块,但是不适合返回查询...

自适应哈希索引,无需人工干预

MySQL判断是建立哈希索引快还是正常查询快

SHOW VARIABLES LIKE '%hash_index%';

Log Buffer

日志缓冲区

SHOW VARIABLES LIKE '%log_buffer_size%';
SHOW VARIABLES LIKE '%log_flush_log_at_trx_commit%';

log_flush_log_at_trx_commit:

  • 1 日志在每次事务提交时写入并刷新到磁盘

  • 0 每秒将日志写入并刷新到磁盘一次

  • 2 日志在每次事务提交后写入,并每秒刷新到磁盘一次

2.2. 磁盘结构

System Tablespace 系统表空间

File-Per-Table Tablespace 每个表的表空间文件

General Tablespace 通用表空间

需要自己创建

CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENGINE = InnoDB;

CREATE TABLE a(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50))
ENGINE = InnoDB TABLESPACE ts1;

Doublewrite Buffer Files 双写缓冲区

数据也从 Buffer Pool 刷新到磁盘前先写入双写缓冲区

便于系统异常的数据恢复

Redo Log 重做日志

实现事务的持久性

2.3. 后台线程

Buffer Pool 的数据在合适的时机刷入 磁盘...

Master Thread

核心后台线程,负责调度其他线程

IO Thread

  • Read therad

  • Write thread

  • Log thread

  • Insert buffer thread

Purge Thread

回收事务已经提交的 undo log

Page Cleaner Thread

协助 Master Thread...

3. 事务原理

事务是一组操作的集合...是一个不可分割的工作单位。

提交和撤销都需要整体请求

3.1. 特性

  • 原子性 Atomicity 要么全部成功 要么全部失败

  • 一致性 Consistency 数据一致性

  • 隔离性 Isolation

  • 持久性 Durability 事务一旦提交或回滚,对于数据库的改变就是永久的

3.2. 事务原理

隔离性 Isolation ---- 锁机制 MVCC

原子性 Atomicity 一致性 Consistency 隔离性 Isolation ------- redo log 和 undo log

3.3. Redo Log

重做日志 记录事务提交时数据页的物理修改...

重做日志分为 重做日志缓冲 + 重做日志文件

redo log buffer 在内存中

redo log file 在磁盘中

WAL 机制

Write-Ahead Logging

而且是循环性的,提交如果成功写入磁盘就会自动清理

3.4. Undo Log

原子性

回滚日志,记录被修改前的信息

  • 提供回滚

  • MVCC 多版本控制

当执行 rollback 的时候,可以从 undo log 中的逻辑记录读取到相应内容,进行回滚

4. MVCC 多版本并发控制...

基本概念:

当前读

  • 读取最新的数据

  • 而且保证互斥

快照读

  • 保证可重复读

  • 读取历史版本

MVCC

  • Multi-Version Concurrency Control 多版本并发控制

  • 维护一个数据的多个版本...使得读写操作没有冲突...

  • 需要依赖:三个隐式字段、undo log日志、readView

4.1. MVCC 实现原理

记录当中的隐藏字段...

  1. DB_TRX_ID 最近修改事务 ID

  2. DB_ROLL_PTR 回滚指针,隐藏上一个版本

  3. DB_ROW_ID 隐藏主键,如果没有主键,会生成该此字段

Undo Log日志

回滚日志

在 insert update delete 的时候产生

  • insert:事务提交后立即删除 undo log

  • update delete:事务提交后不会立即被删除

Undo log 版本链

不同事务或相同事务对同一条记录进行修改 会导致该纪录的 undo log 生成一条记录版本链表,链表头部是最新的旧纪录,链表尾部是最早的旧纪录...

Read View

读视图 快照读 SQL 执行时 MVCC 提取数据时的一句...记录维护当前活跃事务的 id

包含 4 个核心字段

  1. m_ids 当前活跃的事务 ID 集合

  2. min_trx_id 最小活跃事务 ID

  3. max_trx_id 预分配事务 ID 当前最大事务 ID + 1

  4. creator_trx_id ReadView 创建者的事务 ID

版本链数据访问规则

  1. trx_id == creator_trx_id

    1. 这个版本是当前事务自己创建的

    2. 当前事务可以看到这个版本

    3. 事务总是能看到自己所做的修改,即使这些修改尚未提交

  2. trx_id < min_trx_id

    1. 说明这个版本是在 ReadView 创建之前就已经提交的

    2. 当前事务可以看到这个版本

  3. trx_id > max_trx_id

    1. 说明这个版本是在 ReadView 创建之后才开始的

    2. 当前事务不能看到这个版本

  4. min_trx_id <= trx_id <= max_trx_id 且 trx_id not in m_ids

    1. 如果版本的 trx_id 在 min_trx_id 和 max_trx_id 之间,并且不在 m_ids(活跃事务ID列表)中,说明这个版本的事务已经提交

    2. 当前事务可以看到这个版本

生成时机

READ COMMITTED 事务中每一次执行快照读时生成 ReadView

REPEATABLE READ 仅在事务中第一次执行快照读生成 ReadView 后续复用,COMMIT 后结束...

Last updated