《MySQL 技术内幕-InnoDB 存储引擎》阅读小记(一)

2018/09/05

[TOC]

MySQL 体系结构

InnoDB 存储引擎

概述

体系架构

后台线程

内存

缓冲池

innodb 是基础磁盘存储的,将记录按照页的方式进行管理,是基础磁盘的数据库系统(disk-base database)

所以用缓冲池技术提高数据库的整体性能

所以缓冲池的大小影响数据库的整体性能

innodb 内存数据对象

从 1.0.x 开始,可以有多个缓冲池实例,每个页根据哈希值平均分配到不同的缓冲池实例,可以通过 innodb_buffer_pool_instances 设置,默认为 1

LRU list / Free list / Flush list

缓冲池通过 LRU(lastest recent used , 最近最少使用)算法进行管理:最先释放最不经常使用的数据

innodb 对 lru 算法进行了一个优化:将新数据不放在首部,而是中间部位 midpoint 位置:扫描的时候读了一次数据就再也不用了,避免热点数据排除 lru list。

这个算法叫做 midpoint insertion strategy,midpoint 位置由参数 innodb_old_blocks_pct 控制,默认是 lru list 的 58 处。

midpoint 之后的 list 叫做 old list,之前的 list 叫做 new list。

Checkpoint 技术

做的什么事情

解决下面几个问题

innodb 存储引擎使用 LSN(log sequence number)标记版本,是一个 8 字节的数字,单位是字节。

每个页有 LSN,重做日志也有 LSN,checkpoint 也有 LSN

checkpoint 发生的时间、条件、脏页的选择等都非常复杂

innodb 内部有两种 checkpoint

master thread 工作方式

主要工作都是在这里完成的

innodb 1.0.x 之间版本的 master thread

Master thread 内部有多个循环 loop 组成:

主循环 loop

在主循环里面会有一个每秒进行的操作和一个每 10 秒进行的操作

每秒进行的操作:

每 10 秒进行的操作:

Backgroup loop

如果没有用户活动或者数据库关闭(shutdown)就会切换到这个线程

执行以下操作:

Innodb 1.2.x 之前版本的 master thread

刷新数量不再硬编码,而是使用百分比控制

当使用 ssd 之类的时候,就可以调高 innodb_io_capacity,知道符合磁盘 IO 的吞吐量

将 innodb_max_dirty_pages_pct 从 90 调整到 80

innodb 1.2.x 版本的 master thread

innodb 的关键特性

包括

缓冲插入 insert buffer

带给 innodb 的是性能的提升

1. insert buffer

缓冲池里面有 insert buffer,物理页里面也有

在 innodb 中,主键是唯一的标识符。插入的时候会寻找到主键的位置,然后插入。

所以如果主键是逐渐递增的,那么就是磁盘的顺序 IO,速度很快。

但是在一个表不会只有一个主键,可能还有其他索引,那么在 B+树的叶子节点上,就要寻找到第二个索引所在的位置进行插入,也就是随机 IO。

为了优化这种随机 IO,创建了 insert buffer:先判断插入的索引页是不是在缓冲池,如果是,就插入到缓冲池;如果不是,就先放到一个 insert buffer 中。然后再以一定的频率和情况将 insert buffer 和所以也子节点 merge。这个时候通常能够将多个插入合并到一个操作里面(因为在一个索引页),大大提高了非聚集索引插入的性能。

insert buffer 的使用需要同时满足以下两个条件:

insert buffer 的问题

2. change buffer

1.0.x 引入了 change buffer,可视为 insert buffer 的升级,可以对 dml 操作都进行缓冲,分别是:

同样有非唯一的限制

对一个记录进行 update 操作有两个过程

提供 innodb_change_buffering 参数,用来控制开启哪种 buffer

3. Insert buffer 的内部实现

insert buffer 是一个全局的放在共享空间的 B+树

???

4. merge isnert buffer

什么时候将 insert buffer 的数据 merge 到辅助索引页

两次写 double write

带给 innodb 的是数据页的可靠性

假如写输入到一个页中,写到一半,发生宕机(部分写失效 partial page write),导致页损坏,那么可能会导致数据丢失。这个是不能通过重做日志恢复,因为页本身已经损坏,重做日志(对页的物理操作)没有意义。

需要先通过页的副本还原该页,再使用重做日志,这个叫做 doublewrite。

??????

自适应哈希索引 adaptive hash index

哈希:一次就可以定位数据

B+树:取决于树的高度,生产环境一般是 3-4 层,所以需要查询 3-4 次

AHI(adaptive hash index):观察到一个访问模式访问频繁,就会建立哈希索引

异步 IO async io

刷新邻接页 flush neighbor page

刷新一个脏页的时候,检测这个页所在的区(extent)的所有页,如果是脏页,就一起刷新。

所以可以利用 AIO 将多个 io 合并为一个 io

问题