共计 3855 个字符,预计需要花费 10 分钟才能阅读完成。
Thresh
从 MySQL 5.5 版本开始默认应用 InnoDB 作为引擎,它善于处理事务,具备主动解体复原的个性。上面是官网的 InnoDB 引擎架构图,次要分为内存构造和磁盘构造两大部分。
InnoDB 内存构造
内存构造次要包含 Buffer Pool、Change Buffer、Adaptive Hash Index 和 Log Buffer 四大组件。
Buffer Pool:缓冲池,简称 BP。
BP 以 Page 页为单位,默认大小 16K,BP 的底层采纳链表数据结构治理 Page。在 InnoDB 拜访表记录和索引时会在 Page 页中缓存,当前应用能够缩小磁盘 IO 操作,晋升效率。
Page 管理机制
Page 依据状态能够分为三种类型:
free page:闲暇 page,未被应用
clean page:被应用 page,数据没有被批改过
dirty page:脏页,被应用 page,数据被批改过,页中数据和磁盘的数据产生了不统一
针对上述三种 page 类型,InnoDB 通过三种链表构造来保护和治理
free list:示意闲暇缓冲区,治理 free page
flush list:示意须要刷新到磁盘的缓冲区,治理 dirty page,外部 page 按批改工夫排序。脏页即存在于 flush 链表,也在 LRU 链表中,然而两种互不影响
LRU 链表负责管理 page 的可用性和开释,而 flush 链表负责管理脏页的刷盘操作。lru list:示意正在应用的缓冲区,治理 clean page 和 dirty page
缓冲区以 midpoint 为基点,后面链表称为 new 列表区
寄存常常拜访的数据,占 63%;前面的链表称为 old 列表区,寄存应用较少数据,占 37%。
改进型 LRU 算法保护
- 一般 LRU:
开端淘汰法,新数据从链表头部退出,开释空间时从开端淘汰
- 改性 LRU:
链表分为 new 和 old 两个局部,退出元素时并不是从表头插入,而是从两头 midpoint 地位插入,如果数据很快被拜访,那么 page 就会向 new 列表头部挪动,如果数据没有被拜访,会逐渐向 old 尾部挪动,期待淘汰。
- 每当有新的 page 数据读取到 buffer pool 时,InnoDb 引擎会判断是否有闲暇页,是否足够,如果有就将 free page 从 free list 列表删除,放入到 LRU 列表中。没有闲暇页,就会依据 LRU 算法淘汰 LRU 链表默认的页,将内存空间开释调配给新的页。
Buffer Pool 配置参数
show variables like '%innodb_page_size%'; // 查看 page 页大小
show variables like '%innodb_old%'; // 查看 lru list 中 old 列表参数
show variables like '%innodb_buffer%'; // 查看 buffer pool 参数
倡议:将 innodb_buffer_pool_size 设置为总内存大小的 60%-80%,innodb_buffer_pool_instances 能够设置为多个,这样能够防止缓存抢夺。
Change Buffer:写缓冲区,简称 CB。
在进行 DML 操作时,如果 BP 没有其相应的 Page 数据,并不会立即将磁盘页加载到缓冲池,而是在 CB 记录缓冲变更,等将来数据被读取时,再将数据合并复原到 BP 中。
ChangeBuffer 占用 BufferPool 空间,默认占 25%,最大容许占 50%,能够依据读写业务量来
进行调整。
参数 innodb_change_buffer_max_size;
当更新一条记录时,该记录在 BufferPool 存在,间接在 BufferPool 批改,一次内存操作。如果该记录在 BufferPool 不存在(没有命中),会间接在 ChangeBuffer 进行一次内存操作,不必再去磁盘查问数据,防止一次磁盘 IO。当下次查问记录时,会先进性磁盘读取,而后再从 ChangeBuffer 中读取信息合并,最终载入 BufferPool 中。
写缓冲区,仅实用于非惟一一般索引页,为什么?
如果在索引设置唯一性,在进行批改时,InnoDB 必须要做唯一性校验,因而必须查问磁盘,做一次 IO 操作。会间接将记录查问到 BufferPool 中,而后在缓冲池批改,不会在 ChangeBuffer 操作。
Adaptive Hash Index:自适应哈希索引,用于优化对 BP 数据的查问。
InnoDB 存储引擎会监控对表索引的查找,如果察看到建设哈希索引能够带来速度的晋升,则建设哈希索引,所以称之为自适应。InnoDB 存储引擎会主动依据拜访的频率和模式来为某些页建设哈希索引。
Log Buffer:日志缓冲区
用来保留要写入磁盘上 log 文件(Redo/Undo
)的数据,日志缓冲区的内容定期刷新到磁盘 log 文件中。日志缓冲区满时会主动将其刷新到磁盘,当遇到 BLOB
或多行更新的大事务操作时,减少日志缓冲区能够节俭磁盘 I /O。LogBuffer
次要是用于记录 InnoDB
引擎日志,在 DML
操作时会产生 Redo
和Undo
日志。LogBuffer
空间满了,会主动写入磁盘。能够通过将 innodb_log_buffer_size
参数调大,缩小磁盘 IO 频率 innodb_flush_log_at_trx_commit
参数管制日志刷新行为,默认为 1
0:每隔 1 秒写日志文件和刷盘操作(写日志文件 LogBuffer-->OS cache,刷盘 OS cache--> 磁盘文件),最多失落 1 秒数据
1:事务提交,立即写日志文件和刷盘,数据不失落,然而会频繁 IO 操作
2:事务提交,立即写日志文件,每隔 1 秒钟进行刷盘操作
InnoDB 磁盘构造
InnoDB 磁盘次要蕴含 Tablespaces,InnoDB Data Dictionary,Doublewrite Buffer、Redo Log 和 Undo Logs。
表空间(Tablespaces)
用于存储表构造和数据。表空间又分为零碎表空间、独立表空间、通用表空间、长期表空间、Undo 表空间等多种类型;
零碎表空间(The System Tablespace)
蕴含 InnoDB 数据字典,Doublewrite Buffer,Change Buffer,Undo Logs 的存储区域。零碎表空间也默认蕴含任何用户在零碎表空间创立的表数据和索引数据。零碎表空间是一个共享的表空间因为它是被多个表共享的。该空间的数据文件通过参数 innodb_data_file_path
管制,默认值是 ibdata1:12M:autoextend(文件名为 ibdata1、12MB、主动扩大)
独立表空间(File-Per-Table Tablespaces)
默认开启,独立表空间是一个单表表空间,该表创立于本人的数据文件中,而非创立于零碎表空间中。当 innodb_file_per_table
选项开启时,表将被创立于表空间中。否则,innodb 将被创立于零碎表空间中。每个表文件表空间由一个.ibd 数据文件代表,该文件默认被创立于数据库目录中。表空间的表文件反对动静(dynamic)和压缩(commpressed)行格局。
通用表空间(General Tablespaces)
通用表空间为通过 create tablespace 语法创立的共享表空间。通用表空间能够创立于 mysql 数据目录外的其余表空间,其能够包容多张表,且其反对所有的行格局。
CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd Engine=InnoDB; // 创立表空间 ts1
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1; // 将表增加到 ts1 表空间
撤销表空间(Undo Tablespaces)
撤销表空间由一个或多个蕴含 Undo 日志文件组成。在 MySQL 5.7 版本之前 Undo 占用的是 System Tablespace 共享区,从 5.7 开始将 Undo 从 System Tablespace 拆散了进去。InnoDB 应用的 undo 表空间由 innodb_undo_tablespaces
配置选项管制,默认为 0。参数值为 0 示意应用零碎表空间 ibdata1; 大于 0 示意应用 undo 表空间 undo_001、undo_002 等。
长期表空间(Temporary Tablespaces)
分为 session temporary tablespaces 和 global temporary tablespace 两种。
session temporary tablespaces 存储的是用户创立的长期表和磁盘外部的长期表。global temporary tablespace 存储用户长期表的回滚段(rollback segments)。mysql 服务器失常敞开或异样终止时,长期表空间将被移除,每次启动时会被从新创立。
重做日志(Redo Log)
重做日志是一种基于磁盘的数据结构,用于在解体复原期间更正不残缺事务写入的数据。
MySQL 以循环形式写入重做日志文件,记录 InnoDB 中所有对 Buffer Pool 批改的日志。当呈现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须 redo,从新把数据更新到数据文件。读写事务在执行的过程中,都会一直的产生 redo log。默认状况下,重做日志在磁盘上由两个名为 ib_logfile0 和 ib_logfile1 的文件物理示意。
撤销日志(Undo Logs)
吊销日志是在事务开始之前保留的被批改数据的备份,用于例外情况时回滚事务。吊销日志
属于逻辑日志,依据每行记录进行记录。吊销日志存在于零碎表空间、吊销表空间和长期表
空间中。