前言
深入了解一下 InnoDB
概念
- 数据库:物理数据库的文件及其他文件类型的集合。
- 实例:MySQL 数据库由后台线程以及一个共享内存区域组成。共享内存可以被运行的后台线程所共享。实例是用于操作数据库文件的。实例表示的是一个管理软件。
- 存储引擎
面向表的一种存储结构和算法实现。不同的存储引擎会有不同的特性,适应不同的场合。
- InnoDB MySQL5.5 后的默认引擎。支持事务,表独立的 ibd 文件,支持 MVCC 来获得高并发性。存储方式为 聚集(clustered) 。
- MyISAM 不支持事务,数据和索引文件分开存储,缓冲池只缓冲索引文件,支持全文索引。
- MySQL 连接方式
- TCP/IP 套接字 最常用
- UNIX 域套接字 本机上使用
- 管道、共享内存 (比较少用)
- OLTP 和 OLAP
- OLTP:联机事务处理(on-line transaction processing)。主要是基本的,日常的事务处理,例如银行交易。强调数据库的内存效率,并发等,主要面向数据库。
- OLAP:联机分析处理(On-Line Analytical Processing)。数据仓库的主要应用,支持复杂的分析操作,并提供直观易懂的查询效果。主要面向数据仓库,强调应用的磁盘IO,分区等功能。
InnoDB 体系
- InnoDB 是实现 OLTP 应用的首选存储引擎。
InnoDB 存储引擎的体系架构
体系架构整体来说,简单可以分为文件,内存池和多个进程/线程。引擎的主要工作就是维护线程,并操作线程去刷新内存池的数据,保证内存池的缓存是最近的数据(性能),在异常情况下需要保证InnoDB能够恢复到正常运行状态(日志)。
实例 后台线程
- 1、Master Thread:核心后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页刷新、合并插入缓冲、UNDO页的回收。
- 2、IO Thread:InnoDB 存储引擎大量使用了 AIO 来处理IO请求,这样可以大大提高数据库的性能。IO Thread 主要是负责处理这些 IO 请求的回调处理。
// IO Thread 组默认有9个,1个insert buffer,1个log,4个read线程,4个write线程
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
- 3、Purge Thread 事务被提交后,所用的undolog不需要来,因此需要 Purge Thread 进行回收。线程的数量可以通过以下配置进行设定。这个原来是 Master Thread 的工作,这个设定是为了减轻 Master Thread 的工作。
[mysqld]
innodb_purge_threads=1
- 4、Page Cleaner Thread InnDB 1.2.x 引入的,用于把脏页的刷新操作写到磁盘中,本来是Master Thread做的,这个设定为了减轻Master Thread 的操作。
实例 内存
1、缓冲池
- 1.1 FIX 表示把磁盘的页数据读取到缓存中
- 1.2 命中 线程读取到缓存中的页数据
- 1.3 Checkpoint 机制缓存回写磁盘 (这属于Cache中 Write Behind Caching 技术)
- 1.4 缓冲池包含以下数据
- 1.4.1 索引页 (大部分)
- 1.4.2 数据页 (大部分)
- 1.4.3 undo页
- 1.4.4 插入缓冲页
- 1.4.5 自适应哈希索引
- 1.4.6 锁信息 等等
InnoDB 存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。CPU 和 磁盘的速度鸿沟,就要靠缓冲池技术来提高数据库的整体性能。
2、LRU List、Free List 和 Flush List 对上面的缓冲池进行管理
一般来说,数据库的缓冲池是通过 LRU 算法进行管理的。最频繁使用的页在 LRU 的前端,最少使用的页在 LRU 的尾端。当缓冲池不能存放新读取到的页时,优先放弃 LRU 尾端的页数据。
InnoDB 对 LRU 做了一些优化,增加 midpoint,防止一些SQL大量加载数据时,对 LRU 队列直接刷新,导致热点数据快速缓存失效和加载。这个算法首先会把新数据写在midpoint的位置,而不是热端,等到这个数据等待一定时间后(innodb_old_blocks_time=1000)时,才会被写入热端。
Free List,控制空白页的数据结构。当数据库刚启动时,所有的缓存都是空的,那个所有的页信息都记录在 Free List 中。加载磁盘页数据时,假如空闲页存在,则直接选择空闲页写入,并注册到 LRU 列表中。否则走 LRU 淘汰。
Flush List,用于管理将页刷回磁盘的工作。这个和LRU List不一样,LRU List是管理页是否可用的。
3、redo log buffer
在内存部分,重做缓存日志 redo log buffer 是帮助实例快速写入 redo log 而设立的。一般会每 1s 刷新缓存到日志文件中。大小默认设置为 16M。MySQL 8
mysql> show variables like 'innodb_log_buffer_size'\G;
*************************** 1. row ***************************
Variable_name: innodb_log_buffer_size
Value: 16777216
1 row in set (0.00 sec)
4、额外的内存池
在向缓冲池申请内存时,每个缓冲池中的帧缓存(frame buffer),还需要对应地申请缓冲控制对象(buffer control block),因此,申请了很大的 InnoDB 缓冲池时,需要合理配置额外内存池。