InnoDB存储引擎

InnoDB是如今使用的最多的储存引擎了吧。来看看它的特色:node

ACID事务mysql

行锁算法

MVCCsql

外键数据库

一致性非锁定读缓存

不支持全文索引数据结构

 

InnoDB的体系架构架构

主要是由内存块组成的内存池。oop

内存池的主要工做性能

1.维护内部数据结构

2.缓存重作日志

3.缓存磁盘上的数据,数据进入内存以前就存储在这里

后台线程负责刷新内存池,保证内存池中的缓存数据是最新的。

还有,将已经修改的数据存储到磁盘中。

 

后台线程

默认状况下,InnoDB有7个线程:4个IO线程、1个master 线程、1个错误监控线程、一个锁监控线程。

4个IO线程分别是:

insert buffer thread

log thread

read thread

write thread

在Linux系统中,IO线程的数量是不能调整的,可是在插件版的InnoDB中,read和write线程增长到了4个,

而且配置文件中没有innodb_file_io_threads这个参数。

-------- FILE I/O -------- 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)

参数换成了innodb_read_io_threads和innodb_write_io_threads

mysql> show variables like 'innodb_version'\G; *************************** 1. row *************************** Variable_name: innodb_version Value: 5.6.36
1 row in set (0.00 sec) ERROR: No query specified mysql> show variables like 'innodb_%io_threads'\G; *************************** 1. row *************************** Variable_name: innodb_read_io_threads Value: 4
*************************** 2. row *************************** Variable_name: innodb_write_io_threads Value: 4
2 rows in set (0.00 sec)

 

内存

InnoDB引擎的内存由如下几部分组成:

缓冲池

mysql> show variables like 'innodb_buffer_pool_size'\G; *************************** 1. row *************************** Variable_name: innodb_buffer_pool_size Value: 134217728
1 row in set (0.00 sec)

 

重作日志缓冲池

mysql> show variables like 'innodb_log_buffer_size'\G; *************************** 1. row *************************** Variable_name: innodb_log_buffer_size Value: 8388608
1 row in set (0.00 sec)

 

额外的内存池

mysql> show variables like 'innodb_additional_mem_pool_size'\G; *************************** 1. row *************************** Variable_name: innodb_additional_mem_pool_size Value: 8388608
1 row in set (0.00 sec)

 

缓冲池占用的内存最大,用来缓存数据。

存储引擎工做方式:

将数据库文件按页(16K)读取到缓冲池中,而后按照最少使用(LRU)算法来保留缓冲池中的数据。

若是数据须要修改,优先修改缓冲池中的数据,修改后的页叫作脏页。

最后后台线程将脏页刷新到文件中。

 

mysql> show engine innodb status\G;

每一个帧为16K,因此缓冲池大小为8192*16/1024=128M。

Free buffers 当前空闲的缓冲帧数量。

Database pages 已经使用的缓冲帧

Modified db pages 脏页的数量

从上面的数据能够看出,缓冲池还剩下5.5%左右可使用。数据库压力比较大。

Per second averages calculated from the last 30 seconds

该命令显示的是过去30秒的状态,并不是最新的状态。

 

数据页的类型

索引页

数据页

undo页

插入缓冲(insert buffer)

自适应哈希索引(adaptive hash index)

InnoDB存储的锁信息(lock info)

数据字典信息(data dictionary)

 

日志缓冲将日志文件先放入缓冲区,而后刷新到重作日志。通常每秒就会将重作日志缓冲刷新到日志文件,日志缓冲的值不须要设置很大,大于每秒的事务量便可。

 

InnoDB引擎管理内存的方式叫作内存堆(heap)

在对某些数据结构自己进行内存分配时,首先从额外内存池分配,不够用就从缓冲池分配。

InnoDB实例的缓冲池中,缓冲帧对应的缓冲控制对象所需的内存也是从额外内存池分配的,

因此当缓冲池很大时,额外内存池的大小也要增长。

 

master thread

InnoDB引擎的主要工做都是在master thread由完成的。

master thread线程的优先级最高,经过分析其源代码能够知道,其内部由几个循环构成:

主循环(loop)

后台循环

暂停循环

刷新循环

master thread基本就是在这几个循环之间来回切换。

 

主循环(loop)

大部分操做都在此循环中完成,分为2大部分:每秒钟的操做和每10秒的操做

 

 从代码中能够看出,是可能有延迟的。

每一秒的操做包括:

重作日志缓冲刷新到磁盘,即便这个事务尚未提交(老是)。

合并插入缓冲(可能)。

最多刷新100个InnoDB缓冲池中的脏页到磁盘(可能)。

若是当前没有用户活动,切换到后台循环(可能)。

即便事务没有提交,重作日志缓冲每秒也会被刷新到磁盘中的重作日志文件,这也是为何再大的事务提交的时间也很快。

 

合并插入缓冲并非每秒都发生。InnoDB引擎会判断一秒内发生的IO次数是够小于5次,若是小于5次,InnoDB认为IO压力很小,

就会执行插入缓冲合并。

 

一样,最多刷新100个脏页也不是必定发生。InnoDB会判断当前缓冲区脏页的比例是否超过了配置文件中innodb_max_dirty_pages_pct

参数(默认90%),若是超过了该值,就会刷新100个脏页到磁盘中。

 

接着来看每10秒的操做:

刷新100个脏页到磁盘(可能)。

合并至多5个插入缓冲(老是)。

将日志缓冲刷新到磁盘(老是)。

删除无效的重作页(老是)。

刷新100个或者10个脏页到磁盘(老是)。

产生一个检查点(老是)。

以上过程当中,InnoDB首先会判断过去10秒内,IO操做是否超过200次,

若是没有,将会把100个脏页刷新到磁盘。

以后,会合并插入缓冲。

以后,会将日志缓冲刷新到磁盘。

而后,删除无用的Undo页。

在执行update或者delete操做时,由于一致性读的关系,这些行的版本信息会被保留,

在进行Undo时,会去判断这些被删除的行是否能够删除

若是能够,当即删除。经过源代码能够知道,最多一次删除20个Undo页

而后,InnoDB回去判断缓冲池中脏页的比例,若是大于70%,则刷新100个脏页,不然,刷新10个脏页

最后,InnoDB会产生一个检查点,在此刻,InnoDB会将最老日志序列号(oldest LSN)的页写入磁盘。

 

接着来看后台循环

若是数据库没有活动,数据库空闲或者数据库关闭时,就会切换到这个模式。

这个循环会执行的操做:

删除无用的Undo页(老是)。

合并20个插入缓冲(老是)。

跳回到主循环  (老是)。

不断刷新100个页,知道符号条件(可能,跳转到flush loop中完成)

若是刷新循环没有什么活动,会切换到暂停循环,将master thread挂起。

若是启用了InnoDB引擎,却没有任何基于InnoDB的表,就是处于这个状态。

 

master thread的潜在问题

从上面的知识能够知道,源代码对IO作了限制。每秒最大刷新100个脏页或者刷新20个插入缓冲。

这个可能在某些程序中会致使master thread忙不过来

因此在InnoDB Plugin版本中加入了innodb_io_capacity参数,

用来表示磁盘IO吞吐量

mysql> show variables like 'innodb_io%'\G; *************************** 1. row *************************** Variable_name: innodb_io_capacity Value: 200

规则以下:

在合并插入缓冲时,数量为该值的5%

在刷新脏页时,数量为该值

 

若是使用了SSD和进行了Raid操做,能够将该值设置的高点。

 

另外一个问题是参数innodb_max_dirty_pages_pct,在mysql5.1(包括此版本),默认值为90%,

意味着脏页占缓冲池的90%,这个太大了!在InnoDB Plugin版本,该值被调整为了75%,

因此能够兼顾脏页刷新频率和磁盘IO。

 

InnoDB Plugin的另外一个参数是innodb_adaptive_flushing(自适应的刷新),该值影响每秒脏页的数量

mysql> show variables like 'innodb_adaptive_%'\G; *************************** 1. row *************************** Variable_name: innodb_adaptive_flushing Value: ON

这个参数会致使,当脏页在缓冲池的比例小于innodb_max_dirty_pages_pct时,也会刷新必定数量的脏页。

因此,最好使用InnoDB Plugin版本,对数据库的性能会有提高。

 

关键特性

InnoDB的关键特性还包括插入缓冲,2次写,自适应哈希索引。

插入缓冲

咱们知道,主键是行的惟一标识符,在表中,行的插入顺序是按照主键递增的

插入缓冲的使用要知足2个条件

索引是辅助索引

索引不是惟一的

 

2次写

这个能够保证数据的可靠性。

架构

 

 当脏页刷新时,并非直接将其写入磁盘,而是先将其写入内存中的doublewrite buffer。

每次写入1M到共享表空间的磁盘中。这样若是数据库崩溃了,能够在共享表空间找到页的副本,

在应用重作日志来恢复。

 

自适应哈希索引

哈希是一种快速的查找方法。

经常使用语join操做

InnoDB引擎会监控表上的索引查找,若是观察到创建哈希索引会带来速度的提高,

就会创建哈希索引,这就是自适应哈希索引。

启动自适应哈希索引,能够带来读写性能2倍的提升;

能够带来辅助索引性能5倍的提升;

------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 276707, node heap has 402 buffer(s) 0.00 hash searches/s, 0.00 non-hash searches/s

默认开启

*************************** 3. row *************************** Variable_name: innodb_adaptive_hash_index Value: ON

 

启动、关闭和恢复

 innodb_fast_shutdown参数影响InnoDB引擎的行为,默认为1

mysql> show variables like 'innodb_fast_shutdown'\G;
*************************** 1. row ***************************
Variable_name: innodb_fast_shutdown
        Value: 1
1 row in set (0.00 sec)

0 表示关闭数据库时,须要完成全部的full purge和merge insert buffer操做

若是在升级InnoDB Plugin,能够将该值设置为0

2 表示不完成full purge和merge insert buffer操做,也不将缓冲池中的数据脏页写会磁盘,而是写在日志。

 

innodb_force_recovery参数影响引擎的恢复状况,默认值为0
mysql> show variables like 'innodb_force_recovery'\G;
*************************** 1. row ***************************
Variable_name: innodb_force_recovery
        Value: 0
1 row in set (0.00 sec)

相关文章
相关标签/搜索