您的位置:首页 > 数据库 > MySQL

MySql - InnoDB 存储引擎

2017-06-07 14:47 267 查看
InnoDB存储引擎是MySql第一个完整支持事务的存储引擎,最早由第三方公司开发,并不是MySql的官方引擎,在MySql 5.6后被作为默认引擎推出。

特点

InnoDB设计是为OLTP(在线事务处理类型)应用设计,支持事务是最大的特点,此外还有如下特点:

事务:完整的ACID及4级事务隔离级别支持;

基于行锁设计:支持行锁、表锁,可通过扩展sql主动S和X锁,不能主动加表锁;

支持外键:可以设定外键及外键的完整性约束;

支持MVVC:多版本并发控制技术,实现了多个版本数据的读写;

一致性非锁定读:类似Oracle,提高并发,不是所有的读都会加锁,大部分读不加锁;

InnoDB的版本

InnoDB的跨界版本是1.0.x,建议使用最新版本获取更好的性能;

体系结构

InnoDB能很好的利用内存和CPU,它的大部分操作都是利用异步IO技术,屏蔽磁盘和内存的速度差,从而获得更高的性能;

多个后台线程:通过多个后台线程,每个线程完成自己的任务,后台线程的主要作用是刷新内存池中的数据,保持磁盘和内存数据一致;

内存池:使用内存缓冲技术,建立多种缓冲池来缓冲数据、索引,内存管理采用基于页的管理方式,让读写效率更高;

InnoDB的核心线程

Master Thread:核心线程,将数据异步刷新到磁盘,分为多种状态,每秒、每10秒的处理逻辑都不同;

IO Thread : 采用AIO异步刷新数据到磁盘;

Purge Thread:清理线程,实际执行update、insert、delete操作,回收undo页;

Page Cleander Thread:刷新脏页数据到磁盘,保持数据同步;

内存池

InnoDB通过内存池技术来解决磁盘读写速度问题,其内存池管理结构如下:



可以看到,InnoDB是通过页的方式来管理数据,类似操作系统的内存管理方式,热点页常驻内存,采用LRU等算法进行页的管理,InnoDB通过多种参数和配置可以影响内存池大小和数据页的换入换出。

InnoDB每个page的大小是16k

内存池参数

在mysql中可以通过如下参数影响InnoDB内存池的大小及行为:

观察InnoDB状态:Show engine innodb status \G

内存池大小:innodb_buffer_pool_size;
page被hit多少次后加入LRU列表的热点区:innodb_old_blocks_time


InnoDB状态参数的含义:

Buffer Pool Hit Rate : 缓存命中策略 不应该小于 95%

Free Buffers + Buffer Pool Size  != DataBase Size


重做日志

为了实现数据库事务,基本上所有的数据库引擎都需要重做日志,重做日志包括:redo log 和undo log,统称重做日志,重做日志保证了事务的原子性、一致性、持久性,但是重做日志本身会带来开销。

Checkpoint技术

检查点技术被很多需要保证系统高可用的程序采用,InnoDB为了解决磁盘的速度问题,采用内存缓冲方式,也就是很多最新的数据都是在内存中的,但是内存不是持久的,一旦内存断电,这些修改和操作没有更新到物理文件中,那么就会造成数据的丢失和不一致性。InnoDB使用一些技术来保证不会发生这些情况。

InnoDB采用两种方式将数据异步刷新到磁盘,保证高可用和数据一致性:

- 通过多线程,尤其是核心Master Thread使用一些策略来将数据、日志、操作刷新到磁盘;

- 检测点技术,在一些关键的点上触发磁盘操作,将数据、日志、操作刷新到磁盘;

InnoDB的检查点技术主要目的:

缩短数据库恢复时间:减少恢复数据量;

缓冲池不够的时候,将脏页刷新到磁盘,释放缓冲或者防止数据不一致;

重做日志不可用时,刷新到磁盘,防止重做日志丢失;

Checkpoint的核心技术是通过LSN(log sequence number)来标记版本号,很多增量备份工具也是使用这个特性。

Checkpoint的触发时机:

数据库关闭时,触发Sharp Checkpoint;

Master Thread 每十几秒触发一次 Fuzzy Checkpoint;

页空间不足的时候时触发Fuzzy Checkpoint;

重做日志不足,这时磁盘空间不够了,日志达到了指定大小,覆盖日志失败了,都触发Fuzzy Checkpoint;

内存池中脏页太多触发Fuzzy Checkpoint。

InnoDB的一些关键技术

关键技术和特性不一样,关键技术是实现过程中的一些做法,这些做法带来了特性。下面是InnoDB采用的一些关键技术,有些是独创的,极大的提高了InnoDB的性能。

插入缓冲:insert buffer,解决辅助索引的插入性能问题;

两次写:double write,提高数据的可靠性,保证数据一致;

自适应哈希索引:adaptive hash index,提升索引效率;

异步IO:Async IO,使用异步IO不进行同步等待,可以一次发出多个IO指令,底层还会合并多个IO到一次IO;

刷新邻接表:提升脏页刷新效率。

Insert Buffer

对于非聚集类索引,也叫辅助索引,如果索引不是唯一的,不需要做唯一性校验,InnoDB会先将索引放入到缓冲区不会每次都调整索引的B+树,大致思路:

每次insert的时候,如果辅助索引字段不是唯一的,不需要做唯一性校验;

InnoDB 先不去实际insert index,不刷新磁盘,也不会产生B+树的旋转,也就不会引起随机的IO,等到一定时机,将多个索引的insert merge为一个insert,提高索引的插入效率。

merge insert buffer的时机:

辅助索引页被读取到缓冲池中;

Insert Buffer Bitmap追踪到辅助索引页无可用空间;

Master Thread触发;

Double Write

提高数据可靠性,尤其是将脏页刷新到磁盘的时候,防止如果部分写入失败了,那么将产生数据不一致情况;

自适应Hash索引

InnoDB通过监控B+ Tree的索引,如果适用Hash索引,则建立Hash索引。在实际生产环节中,B+ Tree的高度一般为3 - 4,需要 3 - 4的逻辑IO,远没有Hash索引快。

Hash索引仅适用于等值索引,不适合范围索引,也就是如果频繁的用where id > ‘100’ 这类操作不会建立自适应Hash索引。

AIO

异步IO,连续发出多个IO,进行IO Merge,提升磁盘的IOPS。

刷新邻接表

刷新dirty的page时会检查这个page所在的区域的所有page,如果这些page也是dirty,则一起刷新,通过AIO的merge操作,提升性能。机械硬盘有很大用途;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql innodb