InnoDB存储引擎 Ch1-2简介

第1章

数据库:物理操作系统文件或其他形式文件类型的集合。
实例:MySQL数据库由后台线程和一个共享内存区组成。

MySQL是一个单进程多线程架构的数据库。
MySQL最大特点:插件式的表存储引擎。存储引擎是基于表的,不是数据库。

第2章 InnoDB存储引擎

版本

SHOW VARIABLES LIKE 'innodb_version';
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| innodb_version | 8.0.21 |
+----------------+--------+
1 row in set, 1 warning (0.08 sec)

体系架构

InnoDB架构

1. 后台线程

1. Master Thread
将缓冲池中的数据异步刷新到磁盘。包括脏页刷新、INSERT BUFFER、UNDO页的回收。
由多个循环组成。主循环(loop),后台循环(backgroup loop),刷新循环(flush loop),暂停循环(suspend loop)。

主循环loop
每1秒完成:

  1. 日志缓冲刷新到磁盘。注意即使事务没有提交,InnoDB也会把重做日志缓冲中的内容刷新到重做日志,因此事务提交很快。
  2. 合并插入缓冲。若前一秒的IO小于5次就会发生。
  3. 如果缓冲池中脏页比例低于预设,刷新100个或以下的脏页到磁盘。脏页比例参数为buf_get_modified_ratio_pct,预设为配置文件中innodb_max_dirty_pages_pct,默认为90%。
  4. 如果当前没有用户活动,则切换到background loop

每10秒完成:
5. 过去10秒内,磁盘IO小于200次时,刷新100个脏页到磁盘。
6. 合并最多5个插入缓冲。
7. 将日志缓冲刷新到磁盘。
8. 删除Undo页。(full purge)。每次最多尝试20页。
9. 刷新100个(脏页比例高于70%)或10个(低于70%)脏页到磁盘。

后台循环backgroup loop
10. 删除无用的Undo页
11. 合并20个插入缓冲
12. 跳回主循环
13. 不断刷新100个页知道符合条件(可能,跳转到flush loop中完成)

刷新循环flush loop
当脏页比例高于某个值,刷新100页

暂停循环suspend loop
将Master Thread挂起,等待事件发生

其他参数
innodb_io_capacity 影响合并插入缓冲的数量(5%)和刷新脏页的数量(90%)。当磁盘IO速度高时,可以调成更高的值。

SHOW VARIABLES LIKE 'innodb_io_capacity';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_io_capacity | 200   |
+--------------------+-------+
inno

innodb_max_dirty_pages_pct = 75 需要平衡内存和服务器压力的问题。
innodb_adaptive_flushing表示自适应刷新数量,和innodb_max_dirty_pages_pct一起影响每秒刷新脏页的数量。
innodb_purge_batch_size控制每次full purge回收的undo页数量,默认为20。

2 IO Thread
负责Async IO的回调处理。

	SHOW VARIABLES LIKE 'innodb_%io_threads';
	+-------------------------+-------+
	| Variable_name           | Value |
	+-------------------------+-------+
	| innodb_read_io_threads  | 4     |
	| innodb_write_io_threads | 4     |
	+-------------------------+-------+

采用SHOW ENGINE INNODB STATUS;指令,在FILE I/O下面查看线程的当前状态。
I/O thread 0是insert buffer thread
I/O thread 1是log thread

	SHOW ENGINE INNODB STATUS;
	--------
	FILE I/O
	--------
	I/O thread 0 state: wait Windows aio (insert buffer thread)
	I/O thread 1 state: wait Windows aio (log thread)
	I/O thread 2 state: wait Windows aio (read thread)
	I/O thread 3 state: wait Windows aio (read thread)
	I/O thread 4 state: wait Windows aio (read thread)
	I/O thread 5 state: wait Windows aio (read thread)
	I/O thread 6 state: wait Windows aio (write thread)
	I/O thread 7 state: wait Windows aio (write thread)
	I/O thread 8 state: wait Windows aio (write thread)
	I/O thread 9 state: wait Windows aio (write thread)

3 Purge Thread
回收已经使用并分配的undo页,即回收undolog。下面的代码表示目前有4个purge thread进程。

	SHOW VARIABLES LIKE 'innodb_purge_threads';
	+----------------------+-------+
	| Variable_name        | Value |
	+----------------------+-------+
	| innodb_purge_threads | 4     |
	+----------------------+-------+

4 Page Cleaner Thread
完成脏页的刷新工作。

1.2 InnoDB关键特性
1.2.1 插入缓冲
  • Insert Buffer: 物理页的组成部分之一。一般针对非聚集索引(辅助索引)和Insert操作。
  • Change Buffer:Insert Buffer的升级版,对辅助索引有DML操作。分为Insert Buffer, Delete Buffer, Purge Buffer(UPDATE)。
  • Merge Insert Buffer:将Insert Buffer中的记录合并到真正的辅助索引。
1.2.2 Double Write

部分写失效
16KB的页只写了前4KB就出现了宕机。
doublewrite
部分写失效发生时,当页本身发生了损坏,无法通过重写日志进行恢复。因此在写入前,得到页副本,出现损坏时可以通过副本还原该页,再进行重做。
分为两个区。首先,将副本放入doublewrite buffer,其次在共享表空间上写入,并刷新到磁盘。
具体见p68

1.2.3 自适应哈希索引, Adaptive Hash Index, AHI

多次连续相同访问的等值查询。略过

1.2.4 异步IO,Asynchronous IO, AIO

全部IO请求发送完毕后,等待所有IO操作的完成。
AIO也可以进行IO Merge操作。
Native AIO可以提高回复速度。
Innodb的read ahead(预读),脏页刷新,磁盘写入都由AIO完成。

1.2.5 刷新邻接页

刷新脏页时,检测该页所在区(extent)是否存在其他脏页,若存在则一起刷新。
innodb_flush_neighbors 控制是否启用。固态硬盘可以关闭。

2. 内存

2.1 缓冲池

InnoDB基于磁盘存储,按页的方式管理记录。将其视为基于磁盘的数据库系统,缓冲池大小决定了数据库整体性能。
读取页:首先将从磁盘读到的页放在缓冲池;下一次读时,判断页是否位于缓冲池。是则直接读出;否则从磁盘重新读取。
修改页:首先修改在缓冲池中的页,再以一定的频率刷新到磁盘上。

缓冲池中数据页的类型:
InnoDB内存数据对象
查看缓冲池大小

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| innodb_buffer_pool_size | 8388608 |
+-------------------------+---------+

查看缓冲池实例个数。个数增加可以提高数据库并发处理的能力。

SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+

两种方法查看缓冲池的信息。
1) SHOW ENGINE INNODB STATUS可以看到每个缓冲池的size, free buffers, database pages, pending reads, 读取速度等消息。位于INDIVIDUAL BUFFER POOL INFO下面。
2) 查看information_schema架构下的innodb_buffer_pool_stats表。

USE information_schema;
SELECT POOL_ID, POOL_SIZE, FREE_BUFFERS, DATABASE_PAGES FROM innodb_buffer_pool_stats;
+---------+-----------+--------------+----------------+
| POOL_ID | POOL_SIZE | FREE_BUFFERS | DATABASE_PAGES |
+---------+-----------+--------------+----------------+
|       0 |       512 |            0 |            509 |
+---------+-----------+--------------+----------------+
2.2 LRU List, Free List and Flush List

LRU LIST
LRU (Latest Recent Used)最近最少使用:最频繁在LRU最前面,最少使用在末端。缓冲池满则释放尾端的页。新读取的页插入LRU中的midpoint,默认配置下在LRU的5/8处,或距离LRU尾端37%的位置。midpoint之前称为new列表(63%),之后称为old列表(37%)。可以修改innodb_old_blocks_pct参数扩大new列表的长度。

SHOW VARIABLES LIKE 'innodb_old_blocks_pct';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37    |
+-----------------------+-------+
SET GLOBAL innodb_old_blocks_pct = 20;

缓冲池中页的默认大小为16KB。innodb_old_blocks_time参数控制了从页被读取到mid位置后(old),等待多久会被加入LRU列表的热端(new)。页从old到new称为page made young。由于等待时间超过bolck time,页未被移到new称为page not made young。

SET GLOBAL innodb_old_blocks_time=1000

FLUSH LIST
在LRU中的页如果经过了修改,则称为脏页(dirty page),此时缓冲池中的这一页与磁盘上不一致。Flush列表用于管理这些脏页(脏页存在LRU中,并不是在Flush中拥有了副本,猜测类似指针)。刷回硬盘采用CHECKPOINT机制

Write Ahead log

事务提交时,先写重做日志,再修改页。数据若出现丢失,则通过重做日志恢复数据,保证durability。

CHECK POINT机制

作用:

  1. 缩短数据库的回复时间;
  2. 缓冲池不够用时,LRU的old溢出,若其中存在脏页,将脏页刷新到磁盘;
  3. 重做日志不可用时,刷新脏页。重做日志不可用指的是这一部分的重做日志已经不需要了。如果还需要使用,则强制产生Chekpoint,并且将缓冲池中的页至少刷新到当前重做日志的位置。
2.3 重做日志缓冲redo log buffer

redo log buffer存储重做日志信息,按一定频率刷新到重做日志文件。默认大小为8MB。
刷新redo log buffer到日志的三种情况:

  1. 每一秒由Master Thread刷新
  2. 每个事务提交时
  3. redo log buffer剩余空间小于1/2时
    调整大小的方法:SET GLOBAL innodb_log_buffer_size = n;
2.4 额外的内存池

不懂

2.5 启动、关闭与恢复

innodb_fast_shutdown在数据库关闭时的操作p71
innodb_force_recovery需要恢复时是否进行恢复操作,或写入错误日志+宕机(crash)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值