Mysql Innodb体系结构

Innodb体系结构

  • Innodb存储引擎主要包括内存池以及后台线程。
  • 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据、缓存磁盘数据,修改文件前先修改内存、redo log
  • 后台线程:刷新内存池中的额

内存

缓冲池

  • Innodb的数据以页的形式存储在磁盘,因此采用内存作为缓存页数据。
  • 读页数据时,先将磁盘上的页数据“FIX”到缓冲池,下次读即可直接从缓冲池中读。
  • 修改数据时,先修改缓冲池中的页数据,然后刷新到磁盘,并不是每次都刷新而是通过Checkpoint机制刷新到磁盘。
  • 数据页类型:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引、锁信息、数据字典信息等
  • 缓存池通过LRU算法管理。

LRU、Free List、Flush List

  • 普通LRU:最频繁的处于列表前端,最少使用处于尾端,先释放列表尾端的页。
  • Innodb LRU:在LRU队列中加入midpoint位置,默认值5/8,表示新读取的页加入到列表的5/8位置。midpoint之后列表成为old表,之前称为new表。即列表尾端到表尾37%为old表,其余为new表。new表存放活跃数据。
  • Free List:数据库启动时LRU表为空,页均存放在Free List中。需要使用时从该表中获取。
  • Flush List管理缓存中被修改过的页。
  • unzip_LRU,压缩页大小为1、2、4、8KB,其还是属于LRU管理。unzip_LRU对不同大小页分开管理,采用伙伴算法分配内存。

redo log buffer

redo log先都写入该buffer,而后按一定频率刷新到磁盘(1s/次),默认8M。其刷到磁盘主要一下几个情况:

  1. Master Thread每秒执行一次。
  2. 事物提交时。
  3. redo log buffer剩余空间小于1/2。

额外的内存池

对一些数据结构本身的内存分配是从额外内存池分配。


线程

Master Thread

负责将缓存池中的数据异步刷新到磁盘,包括脏页。合并插入缓存(INSERT BUFFER)、UNDO页的回收等。

IO Thread

Innodb中大量使用AIO处理写请求,IO Thread则主要处理这些请求的回调,包括write、read、insert buffer和log IO Thread。

Purge Thread

主要用来回收undo log,Innodb1.1之前由Master Thread负责。

Page Cleaner Thread

清理已提交事物的UNDO log。


Checkpoint

事务型数据库一般采用Write Ahead Log策略,当事物提交时先写redo log而后修改内存中的页。当数据库宕机对于还未写入磁盘的修改数据可以通过redo log恢复。Checkpoint作用在于保证该点之前的所有修改的页均已刷新到磁盘,这之前的redo log在恢复数据时可以不需要了。

Sharp Checkpoint

发生在数据库关闭时,将所有脏页写入磁盘,数据库运行时一般不使用。

Fuzzy Checkpoint

只刷新部分部分脏页。

  1. Master Thread Checkpoint:Master Thread异步已一定频率刷新一定比例脏页。
  2. Flush_LRU_LIST Checkpoint:为了保证LRU中有一定数量的空闲页,Page Clear Thread将对LRU中尾端页进行移除,如果存在脏页则做刷新。
  3. Async/Sync Flush Checkpoint:为了保证redo log循环使用(覆盖),对于需要将redo文件中不可用的脏页进行刷新到磁盘。
  4. Dirty Page too much Checkpoint:脏页数量太多。

Master Thread工作方式

Innodb 1.2.x之前

主要包括主loop、background loop、flush loop和suspend loop。其中的参数可以配置。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

while(true){

    //差不多1s一次

    for(int in 0..9){

        刷新日志缓存到磁盘

        //1s内的统计值

        if IO < 5

            合并插入缓存

        if 脏页比例 > 预定值

            刷新部分脏页(不超过100)

        if  没有用户活动

            进入background loop{

                删除无用undo页

                合并20个插入缓冲

                可能跳到flush loop{

                    可能跳到suspend loop

                }

                跳回主loop

            }

        sleep 1s;

    }

    //差不多10s一次

    if IO < 200 //10s内

        刷新100个脏页到磁盘

    合并最多5个插入缓冲

    刷新日志缓冲

    删除无用undo

    刷新100或10个脏页

}

  

Innodb 1.2.x

Master Thread中的脏页刷新功能完全由Page Cleaner Thread执行。

+

  

nnodb关键特性

插入缓冲

  • 当插入数据需要更新非聚集索引时,如果每次都更新则需要进行多次随机IO,因此将这些值写入缓冲对相同页的进行合并提高IO性能。
  • 插入非聚集索引时,先判断该索引页是否在缓冲池中,在则直接插入。否则写入到Insert Buffer对象。
  • 条件:二级索引,索引不能是unique(因为如果是unique则必须保证唯一性,此时得检查所有索引页,还是随机IO了)
  • Change Buffer:包括Insert Buffer、Delete Buffer、Purge Buffer,update操作包括将记录标记为已删除和真正将记录删除两个过程,对应后两个Buffer。
  • Insert Buffer内部是一颗B+树
  • Merge Insert Buffer三种情况:
    1. 对应的索引页被读入缓冲池。
    2. 对应的索引页的可用空间小于1/32,则强制进行合并。
    3. Master Thread中的合并插入缓冲。

两次写

在对脏页刷新到磁盘时,如果某一页还没写完就宕机,此时该页数据已经混乱无法通过redo实现恢复。innodb提供了doublewrite机制,其刷新脏页步骤如下:

1. 先将脏页数据复制到doublewrite buffer中(2MB内存)
2. 将doublewrite buffer分两次,每次1MB写入到doublewrite磁盘(2MB)中。
3. 马上同步脏页数据到磁盘。对于数据混乱的页则可以从doublewrite中读取到,该页写到共享表空间。

  

自适应哈希索引

InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应(adaptive) 的。自适应哈希索引通过缓冲池的B+树构造而来,因此建立的速度很快。而且不需要将整个表都建哈希索引,InnoDB存储引擎会自动根据访问的频率和模式 来为某些页建立哈希索引。

异步IO

linux和windows中提供异步IO,其可以对连续的页做合并连续页的IO操作使随机IO变顺序IO。

刷新邻接页

刷新页时判断相邻页是否也是脏页。

时间: 2024-10-26 08:56:53

Mysql Innodb体系结构的相关文章

【转】数据库介绍(MySQL安装 体系结构、基本管理)

[转]数据库介绍(MySQL安装 体系结构.基本管理) 第1章 数据库介绍及mysql安装 1.1 数据库简介 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增.截取.更新.删除等操作. 所谓“数据库”系以一定方式储存在一起.能予多个用户共享.具有尽可能小的冗余度.与应用程序彼此独立的数据集合. 1.1.1 什么是数据 数据是指对客观事件进行记录并可以鉴别的符号,是对客观 事物的性质.状态以及相互关系等进行记载的物理符号或这些物 理符号的组合.它是可识别

MySQL InnoDB 存储引擎原理浅析

注:本文主要基于MySQL 5.6以后版本编写,多数知识来着书籍<MySQL技术内幕++InnoDB存储引擎>,本文章仅记录个人认为比较重要的部分,有兴趣的可以花点时间读原书. 一.MySQL体系结构 主要包含以下几部分: 1.管理服务于工具组件. 2.连接池与鉴权. 3.SQL接口. 4.查询分析器. 5.优化器组件. 6.缓存与缓冲区. 7.各式的插件式存储引擎. 8.物理文件. 其中存储引擎是基于表,而非数据库. 二.InnoDB体系结构 InnoDB引擎包含几个重要部分: 1.后台进程

使用mysql innodb 使用5.7的json类型遇到的坑和解决办法

---------------------------------------------- #查询JSON的某个字段 select data -> '$.Host' from temp #创建虚拟列 ALTER TABLE temp ADD host varchar(128) GENERATED ALWAYS AS (json_extract(data,'$.Host')) VIRTUAL; #给虚拟列创建索引 ALTER TABLE temp ADD INDEX index_temp_hos

巧用MySQL InnoDB引擎锁机制解决死锁问题(转)

该文会通过一个实际例子中的死锁问题的解决过程,进一步解释innodb的行锁机制 最近,在项目开发过程中,碰到了数据库死锁问题,在解决问题的过程中,笔者对MySQL InnoDB引擎锁机制的理解逐步加深. 案例如下: 在使用Show innodb status检查引擎状态时,发现了死锁问题: *** (1) TRANSACTION: TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OS thread id 278546 starti

优化导入数据到MariaDB、Mysql(InnoDB)的速度

关键配置:关闭binlog 环境:8G的sql文件,300多个InnoDB数据表,(用MysqlWorkbench导出的数据,用HeidiSql导入,因为正式环境是mysql,可以用MysqlWorkbench,而MariaDB用不了导出,要用HeidiSql,直接用mysqldump.source命令也可以).导出耗时6分钟,导入耗时55分钟(有待提高,跟进中) 版本:MariaDB 10 1.注释"log-bin=mysql-bin"."binlog_format=mix

MYSQL INNODB PAGE一督

MYSQL INNODB PAGE一督 MYSQL INNODB PAGE一督,布布扣,bubuko.com

mysql innodb存储引擎的聚集索引

InnoDB聚集索引 MySQL有没有支持聚集索引,取决于采用哪种存储引擎. MySQL InnoDB一定会建立聚集索引,所谓聚集,指实际数据行和相关的键值保存在一块,这也决定了一个表只能有一个聚集索引,即MySQL不会一次把数据行保存在二个地方.InnoDB通常根据主键值(primary key)进行聚集,但是当一个表没有PK怎么办?InnoDB选取聚集索引参照列的顺序是: 1.如果声明了主键(primary key),则这个列会被做为聚集索引2.如果没有声明主键,则会用一个唯一且不为空的索引

MySQL InnoDB内存压力判断以及存在的疑问

本文出处:http://www.cnblogs.com/wy123/p/7259866.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误进行修正或补充,无他) 与其他数据一样,内存对数据库的性能有着至关重要的影响,MySQL InnoDB也一样通过内存来缓存数据,在访问数据的时候通过访问内存中缓存的数据来提高数据的访问效率.MySQL中通过show variables like 'Innodb_buffer_pool%'命令或者直接

浅谈mysql innodb缓存策略

浅谈mysql innodb缓存策略: The InnoDB Buffer Pool Innodb 持有一个存储区域叫做buffer pool是为了在内存中缓存数据和索引,知道innodb bufferpool怎么工作,和利用它读取频繁访问的数据,是mysql优化重要的方面. 理想状况下,把bufferpool的大小调整到足够大,留下足够的内存空间给其他该服务器上的进程(使其无缺页即可).bufferpool越大,innodb 月表现为内存型数据库,从硬盘上一次读取数据,之后并成了从内存中读取数