InnoD存储引擎的关键特性

今天在阅读InnoDB 存储引擎后,对其的一些了解,并对它的关键特性做了一下总结:

1.插入缓冲(insert buffer)
   1)使用插入缓冲的原因:
        非聚集索引叶子节点的插入不再是顺序的了,需要离散的访问分聚集索引,由于随机读取的存在而导致了插入的性能降低,这是因为B+树的特性决定了非聚集索引的离散性,
       因此innodb存储引擎设计了插入缓冲,对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在就直接插入,不在。则先放入到一个insert buffer对象中,然后再以一定的频率和情况进行insert  buffer和辅助索引叶子节点的合并操作,通常能将多个插入合并到一个操作中(引起欸在一个索引页中),大大提高了非聚集索引插入的性能。
    2)   insert buffer使用需要满足的条件:
          1.索引是辅助索引
          2. 索引不是唯一的
     3) 但是使用insert buffer存在的一个问题是:在写密集的情况下,插入缓冲会占用过多的缓冲池内存,默认最大可以占用1/2的缓冲池内存,修正这个问题可以修改默认值对插入缓冲的大小进行控制。

innodb1.0.x版本:对insert buffer升级为change buffer,其使用的对象依然是非唯一的辅助索引,从这个版本开始,innodb存储引擎可以对dml(数据操纵语言)操作---insert  delete  update进行缓冲,分别是insert  buffer 、delete buffer、purge buffer,并提供参数innodb_change_buffering用来开启各种buffer的选项,可选值为inserts、deletes、purges、changes(表示启用inserts和deletes)、all(表示启用所有)、none(表示都不启用),默认为all
innodb 1.2.x版本:通过参数innodb_change_buffer_max_size来控制change buffer最大使用内存的数量,默认为25,表示最多使用1/4的缓冲池内存空间,该参数最大有效值为50.
    4)insert buffer的内部实现:
        insert buffer内部是一颗B+树,mysql4.1之前是每张表有一颗insert buffer B+树,而现在的版本是全局只有一颗B+树,负责对所有的表的辅助索引进行insert buffer, 
       非叶节点存放的是查询的search key(键值):      
  
    search key一共占有9个字节,space表示待插入记录所在表的表空间id,占用4个字节,每个表有唯一的space id,可通过space id查询是哪张表,marker占用1字节,用来兼容老版本的insert buffer,offset表示页所在的偏移量,占用4字节。
    
  前面和非叶子结点的含义相同,一共占用9个字节,metadata占用4个字节,从第5列开始,就是实际插入记录的各个字段了,所以与原插入记录相比较,B+树的叶子节点记录需要额外记录13字节的开销,
  merge insert buffer 的操作可能会发生在以下几种情况:
     1.辅助索引页被读取到缓冲池时,
      2.insert buffer bitmap(启用insert  buffer后,辅助索引页中的记录可能被插入到insert buffer B+树中,为了保证每次的merge insert buffer页成功,通过insert buffer bitmap类型的特殊页来记录辅助索引页的可用空间,)追踪到该辅助索引页已无可用空间时
      3.master thread:此线程中每秒或者每10秒进行一次merge insert buffer操作,
2.两次写(doublewrite)
    两次写带给innodb存储引擎的是数据页的可靠性.
   1). 使用两次写的原因:
         当innodb存储引擎正在写入某个页到表中,而这个页只写了一部分就发生了宕机,称为部分写失效,会导致数据丢失,可以通过重做日志恢复,可是重做日志中记录的是对页的物理操作,如果这个页本身已经损坏,则重做也没意义,因此,可以在应用重做之前,用户需要一个页的副本,当发生写失效时,通过副本还原该页,再进行重做,这就是doublewrite,
    2)doublewrite的构成:
          一部分是内存的doublewrite buffer,大小为2MB,另一部分是物理磁盘上共享空间中的连续128页,两个区,大小也为2MB,
  3)doublewrite的应用:
          在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是通过memcpy函数将脏页先复制到内存中的doublewrite buffer中,之后通过doublewrite buffer分两次,每次1MB顺序的写入共享表空间的物理磁盘上,然后调用fsync函数,同步磁盘,完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,因此在操作系统将页写入磁盘的过程中发生了崩溃,innodb可以从共享表空间中的doublewrite中找到该页的副本,将其复制到表空间文件,再应用重做日志恢复,
   4)doublewrite的设置:
         参数skip_innodb_doublewrite可以禁止使用两次写功能,这时可能会发生写失效问题,
         有些文件系统本身就提供了部分写失效的防范机制,比如ZFS文件系统,因此用户就可以不必启用两次写功能。   

3.自适应哈希索引
      1)含义:
        innodb存储引擎会监控对表上的各索引页的查询,如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引(Adaptive hash index,AHI).AHI是通过缓冲池的B+树构造而来,因此简历速度很快,innodb会自动根据访问的频率和模式自动的为某些热点页建立哈希索引。
     2).建立要求:
         1)对于这个页的连续访问模式必须是一样的,即指查询条件一样,
        2)以该模式访问了100次
        3)页通过该模式访问了N次,其中N=页中记录*1/16
    3)限制:
        哈希索引只能用来搜索等值的查询,如select * from table where index_col="xxx";而对于其他查找类型,如范围查找不能使用哈希索引,通过参数innodb_adptive_hash_index来禁止或者开启此特性,默认AHI为开启状态。
 
4.异步io
    1)目的:
      为了提高磁盘操作性能,使用异步io(asynchronous io,AIO)的方式来处理磁盘操作,
    2)含义:
       用户可以在发出一个io请求后立即再发出另一个io请求,当全部io请求发送完毕后,等待所有的io操作完成,称为AIO,AIO还可以进行io merge操作,也就是将多个io合并为一个io.
    3)实现:
       在innodb1.1.x之前,Aio是通过innodb存储引擎的代码模拟实现,而从innodb1.1.x开始,提供了内核级别AIO的支持,即为native AIO,
5.刷新邻接页
    1)工作原理:
          当刷新一个脏页时,innodb会检测该页所在区的所有页,如果是脏页,那么一起刷新,参数innodb_flush_neighbors来开启或关闭该特性,为0则关闭

你可能感兴趣的:(sql,mysql,存储)