MySQL InnoDB 概述(一) 引擎的线程和内存

523 阅读5分钟

前言

深入了解一下 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 缓冲池时,需要合理配置额外内存池。