MYSQL - innoDB引擎

从MySQL 5.5 版本开始默认使用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 配置参数
// 查看page 页大小
show variables like '%innodb_page_size%';
// 查看lru list 中old 列表参数
show variables like '%innodb_old%'
// 查看buffer pool 参数
show variables like '%innodb_buffer%'

建议: 将innodb_buffer_pool_size 设置为总内存的60%-80%,innodb_buffer_pool_instances 可以设置为多个,这样可以避免缓存争夺。

  • 配置Buffer Pool 的大小
    当服务器正运行时,用户可以离线(启动时)或在线配置InnoDB缓冲池大小。这部分描述的行为适用这两种方法。

    当增加或减少innodb_buffer_pool_size时,该操作按照数据块(chunks)执行。数据块的大小通过innodb_buffer_pool_chunk_size配置选项进行定义,该选项默认为128M.

    缓冲池大小必须总是等于innodb_buffer_pool_chunk_size* innodb_buffer_pool_instances或为其倍数。如果将innodb_buffer_pool_size配置为不等于innodb_buffer_pool_chunk_size *

    innodb_buffer_pool_instances或不为其倍数,则缓冲池大小自动调整为等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances或不小于指定缓冲池大小的该乘积的倍数。

  • Change Buffer: 写缓存区,简称CB。在进行DML 操作的时候,如果没有相应的Page 数据,并不会立即将磁盘页加载到缓冲区,而是在CB 记录缓冲变更,等未来数据被读取时,再将数据合并恢复到BP 中。

    ChangeBuffer 占BufferPool 空间,默认占25%,最大允许占50%,可以更根据读写业务量来进行调整。

    参数innodb_change_buffer_max_size。

    当更新一条记录时,该记录在Buffer Pool 存在,直接在Buffer Pool 修改,一次内存操作,如果该记录在BufferPool 不存在(没有命中),会直接在Change Buffer 进行一次内存操作,不用再去磁盘查询数据,避免一次磁盘I/O。当下次查询记录时,会先进行磁盘读取,然后再从Change Buffer 中读取信息合并,最终载入Buffer Pool 中。

    写缓冲区,仅适用于非唯一普通索引页,为什么?
    如果在索引设置唯一性,在进行修改时,InnoDB 必须要做唯一性校验,因此必须查询磁盘,做一次I/O 操作。会直接将记录查询到Buffer Pool 中,然后在缓冲池修改,不会在Chaneg Buffer 操作。

  • Adapative Hash Index: 自适应哈希所有,用于优化对BP 数据的查询。InnoDB 存储引擎会监控对表索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应。InnoDB 存储引擎会根据访问的频率和模式来为某些页建立哈希索引。

  • Log Buffer: 日志缓冲区,用来保存要写入磁盘上log 文件(Redo log/ undo)数据,日志缓冲区的内容定期刷新到磁盘log 文件中。日志缓冲区默认16M, 缓冲区满时也会自动将其刷新到磁盘,当遇到BLOG 或多行更新的大事务操作时,增加日志缓冲区可以节省磁盘I/O。

    Log Buffer 主要是用于记录InnoDB 引擎日志,在DML 操作时会产生Redo 和 Undo 日志。
    Log Buffer 空间满了,会自动写入磁盘。

    innodb_flush_log_at_trx_commit 参数控制日志刷新行为,默认为1
    0:每隔1秒写日志文件和刷盘操作(写日志文件Log Buffer --> OS Cache, 刷盘 OS cache --> 磁盘文件),最多丢失1秒的数据
    1:事务提交,立即写日志文件和刷盘,数据不丢失,但是会频繁IO 操作
    2:事务提交,立即写日志文件,每隔1秒进行刷盘操作

二、新版本演变

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值